/src/libreoffice/sfx2/source/dialog/dinfdlg.cxx
Line | Count | Source |
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 <svl/eitem.hxx> |
21 | | #include <tools/datetime.hxx> |
22 | | #include <tools/duration.hxx> |
23 | | #include <tools/debug.hxx> |
24 | | #include <tools/urlobj.hxx> |
25 | | #include <utility> |
26 | | #include <vcl/svapp.hxx> |
27 | | #include <vcl/weld/TextView.hxx> |
28 | | #include <vcl/weld/Dialog.hxx> |
29 | | #include <vcl/weld/MessageDialog.hxx> |
30 | | #include <vcl/weld/weldutils.hxx> |
31 | | #include <unotools/datetime.hxx> |
32 | | #include <unotools/localedatawrapper.hxx> |
33 | | #include <unotools/cmdoptions.hxx> |
34 | | #include <comphelper/processfactory.hxx> |
35 | | #include <comphelper/propertyvalue.hxx> |
36 | | #include <comphelper/stl_types.hxx> |
37 | | #include <comphelper/xmlsechelper.hxx> |
38 | | #include <unotools/useroptions.hxx> |
39 | | #include <svtools/ctrlbox.hxx> |
40 | | #include <svtools/imagemgr.hxx> |
41 | | #include <sal/log.hxx> |
42 | | #include <osl/diagnose.h> |
43 | | #include <osl/file.hxx> |
44 | | #include <openuriexternally.hxx> |
45 | | #include <comphelper/lok.hxx> |
46 | | #include <LibreOfficeKit/LibreOfficeKitEnums.h> |
47 | | #include <tools/json_writer.hxx> |
48 | | |
49 | | #include <memory> |
50 | | |
51 | | #include <comphelper/sequence.hxx> |
52 | | #include <comphelper/string.hxx> |
53 | | #include <com/sun/star/security/DocumentSignatureInformation.hpp> |
54 | | #include <com/sun/star/security/DocumentDigitalSignatures.hpp> |
55 | | #include <unotools/syslocale.hxx> |
56 | | #include <rtl/math.hxx> |
57 | | #include <com/sun/star/beans/PropertyAttribute.hpp> |
58 | | #include <com/sun/star/beans/XPropertyContainer.hpp> |
59 | | #include <com/sun/star/beans/XPropertySet.hpp> |
60 | | #include <com/sun/star/frame/XModel3.hpp> |
61 | | #include <com/sun/star/util/DateTime.hpp> |
62 | | #include <com/sun/star/util/Date.hpp> |
63 | | #include <com/sun/star/util/DateTimeWithTimezone.hpp> |
64 | | #include <com/sun/star/util/DateWithTimezone.hpp> |
65 | | #include <com/sun/star/util/Duration.hpp> |
66 | | #include <com/sun/star/document/XDocumentProperties2.hpp> |
67 | | #include <com/sun/star/document/CmisProperty.hpp> |
68 | | #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
69 | | |
70 | | #include <vcl/timer.hxx> |
71 | | #include <vcl/settings.hxx> |
72 | | #include <sfx2/sfxresid.hxx> |
73 | | #include <sfx2/frame.hxx> |
74 | | #include <sfx2/filedlghelper.hxx> |
75 | | #include <sfx2/dinfdlg.hxx> |
76 | | #include <sfx2/sfxsids.hrc> |
77 | | #include <helper.hxx> |
78 | | #include <sfx2/objsh.hxx> |
79 | | #include <sfx2/docfile.hxx> |
80 | | #include <vcl/abstdlg.hxx> |
81 | | #include <sfx2/viewsh.hxx> |
82 | | |
83 | | #include <documentfontsdialog.hxx> |
84 | | #include <dinfdlg.hrc> |
85 | | #include <sfx2/strings.hrc> |
86 | | #include <strings.hxx> |
87 | | #include <comphelper/diagnose_ex.hxx> |
88 | | #include "securitypage.hxx" |
89 | | |
90 | | #include <algorithm> |
91 | | |
92 | | #include <vcl/tabs.hrc> |
93 | | |
94 | | using namespace ::com::sun::star; |
95 | | using namespace ::com::sun::star::uno; |
96 | | |
97 | | struct CustomProperty |
98 | | { |
99 | | OUString m_sName; |
100 | | css::uno::Any m_aValue; |
101 | | |
102 | | CustomProperty( OUString sName, css::uno::Any aValue ) : |
103 | 0 | m_sName(std::move( sName )), m_aValue(std::move( aValue )) {} |
104 | | |
105 | | bool operator==(const CustomProperty& rProp) const |
106 | 0 | { |
107 | 0 | return m_sName == rProp.m_sName && m_aValue == rProp.m_aValue; |
108 | 0 | } |
109 | | }; |
110 | | |
111 | 0 | SfxPoolItem* SfxDocumentInfoItem::CreateDefault() { return new SfxDocumentInfoItem; } |
112 | | |
113 | | namespace { |
114 | | |
115 | | OUString CreateSizeText( sal_Int64 nSize ) |
116 | 0 | { |
117 | 0 | OUString aUnitStr = " " + SfxResId(STR_BYTES); |
118 | 0 | sal_Int64 nSize1 = nSize; |
119 | 0 | sal_Int64 nSize2 = nSize1; |
120 | 0 | sal_Int64 nMega = 1024 * 1024; |
121 | 0 | sal_Int64 nGiga = nMega * 1024; |
122 | 0 | double fSize = nSize; |
123 | 0 | int nDec = 0; |
124 | |
|
125 | 0 | if ( nSize1 >= 10000 && nSize1 < nMega ) |
126 | 0 | { |
127 | 0 | nSize1 /= 1024; |
128 | 0 | aUnitStr = " " + SfxResId(STR_KB); |
129 | 0 | fSize /= 1024; |
130 | 0 | nDec = 0; |
131 | 0 | } |
132 | 0 | else if ( nSize1 >= nMega && nSize1 < nGiga ) |
133 | 0 | { |
134 | 0 | nSize1 /= nMega; |
135 | 0 | aUnitStr = " " + SfxResId(STR_MB); |
136 | 0 | fSize /= nMega; |
137 | 0 | nDec = 2; |
138 | 0 | } |
139 | 0 | else if ( nSize1 >= nGiga ) |
140 | 0 | { |
141 | 0 | nSize1 /= nGiga; |
142 | 0 | aUnitStr = " " + SfxResId(STR_GB); |
143 | 0 | fSize /= nGiga; |
144 | 0 | nDec = 3; |
145 | 0 | } |
146 | 0 | const SvtSysLocale aSysLocale; |
147 | 0 | const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData(); |
148 | 0 | OUString aSizeStr = rLocaleWrapper.getNum( nSize1, 0 ) + aUnitStr; |
149 | 0 | if ( nSize1 < nSize2 ) |
150 | 0 | { |
151 | 0 | aSizeStr = ::rtl::math::doubleToUString( fSize, |
152 | 0 | rtl_math_StringFormat_F, nDec, |
153 | 0 | rLocaleWrapper.getNumDecimalSep()[0] ) |
154 | 0 | + aUnitStr |
155 | 0 | + " (" |
156 | 0 | + rLocaleWrapper.getNum( nSize2, 0 ) |
157 | 0 | + " " |
158 | 0 | + SfxResId(STR_BYTES) |
159 | 0 | + ")"; |
160 | 0 | } |
161 | 0 | return aSizeStr; |
162 | 0 | } |
163 | | |
164 | | OUString ConvertDateTime_Impl( std::u16string_view rName, |
165 | | const util::DateTime& uDT, const LocaleDataWrapper& rWrapper ) |
166 | 0 | { |
167 | 0 | Date aD(uDT); |
168 | 0 | tools::Time aT(uDT); |
169 | 0 | static constexpr OUString aDelim( u", "_ustr ); |
170 | 0 | OUString aStr = rWrapper.getDate( aD ) |
171 | 0 | + aDelim |
172 | 0 | + rWrapper.getTime( aT ); |
173 | 0 | std::u16string_view aAuthor = comphelper::string::stripStart(rName, ' '); |
174 | 0 | if (!aAuthor.empty()) |
175 | 0 | { |
176 | 0 | aStr += aDelim + aAuthor; |
177 | 0 | } |
178 | 0 | return aStr; |
179 | 0 | } |
180 | | |
181 | | } |
182 | | |
183 | | |
184 | | SfxDocumentInfoItem::SfxDocumentInfoItem() |
185 | 0 | : m_AutoloadDelay(0) |
186 | 0 | , m_isAutoloadEnabled(false) |
187 | 0 | , m_EditingCycles(0) |
188 | 0 | , m_EditingDuration(0) |
189 | 0 | , m_nFileSize(-1) |
190 | 0 | , m_bHasTemplate( true ) |
191 | 0 | , m_bDeleteUserData( false ) |
192 | 0 | , m_bUseUserData( true ) |
193 | 0 | , m_bUseThumbnailSave( true ) |
194 | 0 | { |
195 | 0 | } |
196 | | |
197 | | SfxDocumentInfoItem::SfxDocumentInfoItem( const OUString& rFile, |
198 | | const uno::Reference<document::XDocumentProperties>& i_xDocProps, |
199 | | const uno::Sequence<document::CmisProperty>& i_cmisProps, |
200 | | bool bIs, bool _bIs, sal_Int64 _nFileSize ) |
201 | 0 | : SfxStringItem( SID_DOCINFO, rFile ) |
202 | 0 | , m_AutoloadDelay( i_xDocProps->getAutoloadSecs() ) |
203 | 0 | , m_AutoloadURL( i_xDocProps->getAutoloadURL() ) |
204 | 0 | , m_isAutoloadEnabled( (m_AutoloadDelay > 0) || !m_AutoloadURL.isEmpty() ) |
205 | 0 | , m_DefaultTarget( i_xDocProps->getDefaultTarget() ) |
206 | 0 | , m_TemplateName( i_xDocProps->getTemplateName() ) |
207 | 0 | , m_Author( i_xDocProps->getAuthor() ) |
208 | 0 | , m_CreationDate( i_xDocProps->getCreationDate() ) |
209 | 0 | , m_ModifiedBy( i_xDocProps->getModifiedBy() ) |
210 | 0 | , m_ModificationDate( i_xDocProps->getModificationDate() ) |
211 | 0 | , m_PrintedBy( i_xDocProps->getPrintedBy() ) |
212 | 0 | , m_PrintDate( i_xDocProps->getPrintDate() ) |
213 | 0 | , m_EditingCycles( i_xDocProps->getEditingCycles() ) |
214 | 0 | , m_EditingDuration( i_xDocProps->getEditingDuration() ) |
215 | 0 | , m_Description( i_xDocProps->getDescription() ) |
216 | 0 | , m_Keywords( ::comphelper::string::convertCommaSeparated( |
217 | 0 | i_xDocProps->getKeywords()) ) |
218 | 0 | , m_Subject( i_xDocProps->getSubject() ) |
219 | 0 | , m_Title( i_xDocProps->getTitle() ) |
220 | 0 | , m_nFileSize( _nFileSize ) |
221 | 0 | , m_bHasTemplate( true ) |
222 | 0 | , m_bDeleteUserData( false ) |
223 | 0 | , m_bUseUserData( bIs ) |
224 | 0 | , m_bUseThumbnailSave( _bIs ) |
225 | 0 | { |
226 | 0 | Reference< document::XDocumentProperties2 > xDocProps2(i_xDocProps, UNO_QUERY); |
227 | 0 | m_Contributor = ::comphelper::string::convertCommaSeparated(xDocProps2->getContributor()); |
228 | 0 | m_Coverage = xDocProps2->getCoverage(); |
229 | 0 | m_Identifier = xDocProps2->getIdentifier(); |
230 | 0 | m_Publisher = ::comphelper::string::convertCommaSeparated(xDocProps2->getPublisher()); |
231 | 0 | m_Relation = ::comphelper::string::convertCommaSeparated(xDocProps2->getRelation()); |
232 | 0 | m_Rights = xDocProps2->getRights(); |
233 | 0 | m_Source = xDocProps2->getSource(); |
234 | 0 | m_Type = xDocProps2->getType(); |
235 | |
|
236 | 0 | try |
237 | 0 | { |
238 | 0 | Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties(); |
239 | 0 | if ( xContainer.is() ) |
240 | 0 | { |
241 | 0 | Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY ); |
242 | 0 | const Sequence< beans::Property > lProps = xSet->getPropertySetInfo()->getProperties(); |
243 | 0 | for ( const beans::Property& rProp : lProps ) |
244 | 0 | { |
245 | | // "fix" property? => not a custom property => ignore it! |
246 | 0 | if (!(rProp.Attributes & css::beans::PropertyAttribute::REMOVABLE)) |
247 | 0 | { |
248 | 0 | SAL_WARN( "sfx.dialog", "non-removable user-defined property?"); |
249 | 0 | continue; |
250 | 0 | } |
251 | | |
252 | 0 | uno::Any aValue = xSet->getPropertyValue(rProp.Name); |
253 | 0 | AddCustomProperty( rProp.Name, aValue ); |
254 | 0 | } |
255 | 0 | } |
256 | | |
257 | | // get CMIS properties |
258 | 0 | m_aCmisProperties = i_cmisProps; |
259 | 0 | } |
260 | 0 | catch ( Exception& ) {} |
261 | 0 | } |
262 | | |
263 | | |
264 | | SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem& rItem ) |
265 | 0 | : SfxStringItem( rItem ) |
266 | 0 | , m_AutoloadDelay( rItem.getAutoloadDelay() ) |
267 | 0 | , m_AutoloadURL( rItem.getAutoloadURL() ) |
268 | 0 | , m_isAutoloadEnabled( rItem.isAutoloadEnabled() ) |
269 | 0 | , m_DefaultTarget( rItem.getDefaultTarget() ) |
270 | 0 | , m_TemplateName( rItem.getTemplateName() ) |
271 | 0 | , m_Author( rItem.getAuthor() ) |
272 | 0 | , m_CreationDate( rItem.getCreationDate() ) |
273 | 0 | , m_ModifiedBy( rItem.getModifiedBy() ) |
274 | 0 | , m_ModificationDate( rItem.getModificationDate() ) |
275 | 0 | , m_PrintedBy( rItem.getPrintedBy() ) |
276 | 0 | , m_PrintDate( rItem.getPrintDate() ) |
277 | 0 | , m_EditingCycles( rItem.getEditingCycles() ) |
278 | 0 | , m_EditingDuration( rItem.getEditingDuration() ) |
279 | 0 | , m_Description( rItem.getDescription() ) |
280 | 0 | , m_Keywords( rItem.getKeywords() ) |
281 | 0 | , m_Contributor(rItem.getContributor()) |
282 | 0 | , m_Coverage(rItem.getCoverage()) |
283 | 0 | , m_Identifier(rItem.getIdentifier()) |
284 | 0 | , m_Publisher(rItem.getPublisher()) |
285 | 0 | , m_Relation(rItem.getRelation()) |
286 | 0 | , m_Rights(rItem.getRights()) |
287 | 0 | , m_Source(rItem.getSource()) |
288 | 0 | , m_Type(rItem.getType()) |
289 | 0 | , m_Subject( rItem.getSubject() ) |
290 | 0 | , m_Title( rItem.getTitle() ) |
291 | 0 | , m_nFileSize ( rItem.m_nFileSize ) |
292 | 0 | , m_bHasTemplate( rItem.m_bHasTemplate ) |
293 | 0 | , m_bDeleteUserData( rItem.m_bDeleteUserData ) |
294 | 0 | , m_bUseUserData( rItem.m_bUseUserData ) |
295 | 0 | , m_bUseThumbnailSave( rItem.m_bUseThumbnailSave ) |
296 | 0 | { |
297 | 0 | for (auto const & pOtherProp : rItem.m_aCustomProperties) |
298 | 0 | { |
299 | 0 | AddCustomProperty( pOtherProp->m_sName, pOtherProp->m_aValue ); |
300 | 0 | } |
301 | |
|
302 | 0 | m_aCmisProperties = rItem.m_aCmisProperties; |
303 | 0 | } |
304 | | |
305 | | SfxDocumentInfoItem::~SfxDocumentInfoItem() |
306 | 0 | { |
307 | 0 | ClearCustomProperties(); |
308 | 0 | } |
309 | | |
310 | | SfxDocumentInfoItem* SfxDocumentInfoItem::Clone( SfxItemPool * ) const |
311 | 0 | { |
312 | 0 | return new SfxDocumentInfoItem( *this ); |
313 | 0 | } |
314 | | |
315 | | bool SfxDocumentInfoItem::operator==( const SfxPoolItem& rItem) const |
316 | 0 | { |
317 | 0 | if (!SfxStringItem::operator==(rItem)) |
318 | 0 | return false; |
319 | 0 | const SfxDocumentInfoItem& rInfoItem(static_cast<const SfxDocumentInfoItem&>(rItem)); |
320 | |
|
321 | 0 | return |
322 | 0 | m_AutoloadDelay == rInfoItem.m_AutoloadDelay && |
323 | 0 | m_AutoloadURL == rInfoItem.m_AutoloadURL && |
324 | 0 | m_isAutoloadEnabled == rInfoItem.m_isAutoloadEnabled && |
325 | 0 | m_DefaultTarget == rInfoItem.m_DefaultTarget && |
326 | 0 | m_Author == rInfoItem.m_Author && |
327 | 0 | m_CreationDate == rInfoItem.m_CreationDate && |
328 | 0 | m_ModifiedBy == rInfoItem.m_ModifiedBy && |
329 | 0 | m_ModificationDate == rInfoItem.m_ModificationDate && |
330 | 0 | m_PrintedBy == rInfoItem.m_PrintedBy && |
331 | 0 | m_PrintDate == rInfoItem.m_PrintDate && |
332 | 0 | m_EditingCycles == rInfoItem.m_EditingCycles && |
333 | 0 | m_EditingDuration == rInfoItem.m_EditingDuration && |
334 | 0 | m_Description == rInfoItem.m_Description && |
335 | 0 | m_Keywords == rInfoItem.m_Keywords && |
336 | 0 | m_Contributor == rInfoItem.m_Contributor && |
337 | 0 | m_Coverage == rInfoItem.m_Coverage && |
338 | 0 | m_Identifier == rInfoItem.m_Identifier && |
339 | 0 | m_Publisher == rInfoItem.m_Publisher && |
340 | 0 | m_Relation == rInfoItem.m_Relation && |
341 | 0 | m_Rights == rInfoItem.m_Rights && |
342 | 0 | m_Source == rInfoItem.m_Source && |
343 | 0 | m_Type == rInfoItem.m_Type && |
344 | 0 | m_Subject == rInfoItem.m_Subject && |
345 | 0 | m_Title == rInfoItem.m_Title && |
346 | 0 | comphelper::ContainerUniquePtrEquals(m_aCustomProperties, rInfoItem.m_aCustomProperties) && |
347 | 0 | m_aCmisProperties.getLength() == rInfoItem.m_aCmisProperties.getLength(); |
348 | 0 | } |
349 | | |
350 | | |
351 | | void SfxDocumentInfoItem::resetUserData(const OUString & i_rAuthor) |
352 | 0 | { |
353 | 0 | m_Author = i_rAuthor; |
354 | 0 | DateTime now( DateTime::SYSTEM ); |
355 | 0 | m_CreationDate = now.GetUNODateTime(); |
356 | 0 | m_ModifiedBy = OUString(); |
357 | 0 | m_PrintedBy = OUString(); |
358 | 0 | m_ModificationDate = util::DateTime(); |
359 | 0 | m_PrintDate = util::DateTime(); |
360 | 0 | m_EditingDuration = 0; |
361 | 0 | m_EditingCycles = 1; |
362 | 0 | } |
363 | | |
364 | | |
365 | | void SfxDocumentInfoItem::UpdateDocumentInfo( |
366 | | const uno::Reference<document::XDocumentProperties>& i_xDocProps, |
367 | | bool i_bDoNotUpdateUserDefined) const |
368 | 0 | { |
369 | 0 | if (isAutoloadEnabled()) { |
370 | 0 | i_xDocProps->setAutoloadSecs(getAutoloadDelay()); |
371 | 0 | i_xDocProps->setAutoloadURL(getAutoloadURL()); |
372 | 0 | } else { |
373 | 0 | i_xDocProps->setAutoloadSecs(0); |
374 | 0 | i_xDocProps->setAutoloadURL(OUString()); |
375 | 0 | } |
376 | 0 | i_xDocProps->setDefaultTarget(getDefaultTarget()); |
377 | 0 | i_xDocProps->setAuthor(getAuthor()); |
378 | 0 | i_xDocProps->setCreationDate(getCreationDate()); |
379 | 0 | i_xDocProps->setModifiedBy(getModifiedBy()); |
380 | 0 | i_xDocProps->setModificationDate(getModificationDate()); |
381 | 0 | i_xDocProps->setPrintedBy(getPrintedBy()); |
382 | 0 | i_xDocProps->setPrintDate(getPrintDate()); |
383 | 0 | i_xDocProps->setEditingCycles(getEditingCycles()); |
384 | 0 | i_xDocProps->setEditingDuration(getEditingDuration()); |
385 | 0 | i_xDocProps->setDescription(getDescription()); |
386 | 0 | i_xDocProps->setKeywords( |
387 | 0 | ::comphelper::string::convertCommaSeparated(getKeywords())); |
388 | |
|
389 | 0 | Reference<document::XDocumentProperties2> xDocProps2(i_xDocProps, UNO_QUERY); |
390 | 0 | xDocProps2->setContributor(::comphelper::string::convertCommaSeparated(getContributor())); |
391 | 0 | xDocProps2->setCoverage(getCoverage()); |
392 | 0 | xDocProps2->setIdentifier(getIdentifier()); |
393 | 0 | xDocProps2->setPublisher(::comphelper::string::convertCommaSeparated(getPublisher())); |
394 | 0 | xDocProps2->setRelation(::comphelper::string::convertCommaSeparated(getRelation())); |
395 | 0 | xDocProps2->setRights(getRights()); |
396 | 0 | xDocProps2->setSource(getSource()); |
397 | 0 | xDocProps2->setType(getType()); |
398 | 0 | xDocProps2->setSubject(getSubject()); |
399 | 0 | xDocProps2->setTitle(getTitle()); |
400 | | |
401 | | // this is necessary in case of replaying a recorded macro: |
402 | | // in this case, the macro may contain the 4 old user-defined DocumentInfo |
403 | | // fields, but not any of the DocumentInfo properties; |
404 | | // as a consequence, most of the UserDefined properties of the |
405 | | // DocumentProperties would be summarily deleted here, which does not |
406 | | // seem like a good idea. |
407 | 0 | if (i_bDoNotUpdateUserDefined) |
408 | 0 | return; |
409 | | |
410 | 0 | try |
411 | 0 | { |
412 | 0 | Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties(); |
413 | 0 | Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY ); |
414 | 0 | Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo(); |
415 | 0 | const Sequence< beans::Property > lProps = xSetInfo->getProperties(); |
416 | 0 | for ( const beans::Property& rProp : lProps ) |
417 | 0 | { |
418 | 0 | if (rProp.Attributes & css::beans::PropertyAttribute::REMOVABLE) |
419 | 0 | { |
420 | 0 | xContainer->removeProperty( rProp.Name ); |
421 | 0 | } |
422 | 0 | } |
423 | |
|
424 | 0 | for (auto const & pProp : m_aCustomProperties) |
425 | 0 | { |
426 | 0 | try |
427 | 0 | { |
428 | 0 | xContainer->addProperty( pProp->m_sName, |
429 | 0 | beans::PropertyAttribute::REMOVABLE, pProp->m_aValue ); |
430 | 0 | } |
431 | 0 | catch ( Exception const & ) |
432 | 0 | { |
433 | 0 | TOOLS_WARN_EXCEPTION( "sfx.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while adding custom properties" ); |
434 | 0 | } |
435 | 0 | } |
436 | 0 | } |
437 | 0 | catch ( Exception const & ) |
438 | 0 | { |
439 | 0 | TOOLS_WARN_EXCEPTION( "sfx.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while removing custom properties" ); |
440 | 0 | } |
441 | 0 | } |
442 | | |
443 | | |
444 | | void SfxDocumentInfoItem::SetDeleteUserData( bool bSet ) |
445 | 0 | { |
446 | 0 | m_bDeleteUserData = bSet; |
447 | 0 | } |
448 | | |
449 | | |
450 | | void SfxDocumentInfoItem::SetUseUserData( bool bSet ) |
451 | 0 | { |
452 | 0 | m_bUseUserData = bSet; |
453 | 0 | } |
454 | | |
455 | | void SfxDocumentInfoItem::SetUseThumbnailSave( bool bSet ) |
456 | 0 | { |
457 | 0 | m_bUseThumbnailSave = bSet; |
458 | 0 | } |
459 | | |
460 | | std::vector< std::unique_ptr<CustomProperty> > SfxDocumentInfoItem::GetCustomProperties() const |
461 | 0 | { |
462 | 0 | std::vector< std::unique_ptr<CustomProperty> > aRet; |
463 | 0 | for (auto const & pOtherProp : m_aCustomProperties) |
464 | 0 | { |
465 | 0 | std::unique_ptr<CustomProperty> pProp(new CustomProperty( pOtherProp->m_sName, |
466 | 0 | pOtherProp->m_aValue )); |
467 | 0 | aRet.push_back( std::move(pProp) ); |
468 | 0 | } |
469 | |
|
470 | 0 | return aRet; |
471 | 0 | } |
472 | | |
473 | | void SfxDocumentInfoItem::ClearCustomProperties() |
474 | 0 | { |
475 | 0 | m_aCustomProperties.clear(); |
476 | 0 | } |
477 | | |
478 | | void SfxDocumentInfoItem::AddCustomProperty( const OUString& sName, const Any& rValue ) |
479 | 0 | { |
480 | 0 | std::unique_ptr<CustomProperty> pProp(new CustomProperty( sName, rValue )); |
481 | 0 | m_aCustomProperties.push_back( std::move(pProp) ); |
482 | 0 | } |
483 | | |
484 | | |
485 | | void SfxDocumentInfoItem::SetCmisProperties( const Sequence< document::CmisProperty >& cmisProps) |
486 | 0 | { |
487 | 0 | m_aCmisProperties = cmisProps; |
488 | 0 | } |
489 | | |
490 | | bool SfxDocumentInfoItem::QueryValue( Any& rVal, sal_uInt8 nMemberId ) const |
491 | 0 | { |
492 | 0 | OUString aValue; |
493 | 0 | sal_Int32 nValue = 0; |
494 | 0 | bool bValue = false; |
495 | 0 | bool bIsInt = false; |
496 | 0 | bool bIsString = false; |
497 | 0 | nMemberId &= ~CONVERT_TWIPS; |
498 | 0 | switch ( nMemberId ) |
499 | 0 | { |
500 | 0 | case MID_DOCINFO_USEUSERDATA: |
501 | 0 | bValue = IsUseUserData(); |
502 | 0 | break; |
503 | 0 | case MID_DOCINFO_USETHUMBNAILSAVE: |
504 | 0 | bValue = IsUseThumbnailSave(); |
505 | 0 | break; |
506 | 0 | case MID_DOCINFO_DELETEUSERDATA: |
507 | 0 | bValue = m_bDeleteUserData; |
508 | 0 | break; |
509 | 0 | case MID_DOCINFO_AUTOLOADENABLED: |
510 | 0 | bValue = isAutoloadEnabled(); |
511 | 0 | break; |
512 | 0 | case MID_DOCINFO_AUTOLOADSECS: |
513 | 0 | bIsInt = true; |
514 | 0 | nValue = getAutoloadDelay(); |
515 | 0 | break; |
516 | 0 | case MID_DOCINFO_AUTOLOADURL: |
517 | 0 | bIsString = true; |
518 | 0 | aValue = getAutoloadURL(); |
519 | 0 | break; |
520 | 0 | case MID_DOCINFO_DEFAULTTARGET: |
521 | 0 | bIsString = true; |
522 | 0 | aValue = getDefaultTarget(); |
523 | 0 | break; |
524 | 0 | case MID_DOCINFO_DESCRIPTION: |
525 | 0 | bIsString = true; |
526 | 0 | aValue = getDescription(); |
527 | 0 | break; |
528 | 0 | case MID_DOCINFO_KEYWORDS: |
529 | 0 | bIsString = true; |
530 | 0 | aValue = getKeywords(); |
531 | 0 | break; |
532 | 0 | case MID_DOCINFO_SUBJECT: |
533 | 0 | bIsString = true; |
534 | 0 | aValue = getSubject(); |
535 | 0 | break; |
536 | 0 | case MID_DOCINFO_TITLE: |
537 | 0 | bIsString = true; |
538 | 0 | aValue = getTitle(); |
539 | 0 | break; |
540 | 0 | default: |
541 | 0 | OSL_FAIL("Wrong MemberId!"); |
542 | 0 | return false; |
543 | 0 | } |
544 | | |
545 | 0 | if ( bIsString ) |
546 | 0 | rVal <<= aValue; |
547 | 0 | else if ( bIsInt ) |
548 | 0 | rVal <<= nValue; |
549 | 0 | else |
550 | 0 | rVal <<= bValue; |
551 | 0 | return true; |
552 | 0 | } |
553 | | |
554 | | bool SfxDocumentInfoItem::PutValue( const Any& rVal, sal_uInt8 nMemberId ) |
555 | 0 | { |
556 | 0 | OUString aValue; |
557 | 0 | sal_Int32 nValue=0; |
558 | 0 | bool bValue = false; |
559 | 0 | bool bRet = false; |
560 | 0 | nMemberId &= ~CONVERT_TWIPS; |
561 | 0 | switch ( nMemberId ) |
562 | 0 | { |
563 | 0 | case MID_DOCINFO_USEUSERDATA: |
564 | 0 | bRet = (rVal >>= bValue); |
565 | 0 | if ( bRet ) |
566 | 0 | SetUseUserData( bValue ); |
567 | 0 | break; |
568 | 0 | case MID_DOCINFO_USETHUMBNAILSAVE: |
569 | 0 | bRet = (rVal >>=bValue); |
570 | 0 | if ( bRet ) |
571 | 0 | SetUseThumbnailSave( bValue ); |
572 | 0 | break; |
573 | 0 | case MID_DOCINFO_DELETEUSERDATA: |
574 | | // QUESTION: deleting user data was done here; seems to be superfluous! |
575 | 0 | bRet = (rVal >>= bValue); |
576 | 0 | if ( bRet ) |
577 | 0 | SetDeleteUserData( bValue ); |
578 | 0 | break; |
579 | 0 | case MID_DOCINFO_AUTOLOADENABLED: |
580 | 0 | bRet = (rVal >>= bValue); |
581 | 0 | if ( bRet ) |
582 | 0 | m_isAutoloadEnabled = bValue; |
583 | 0 | break; |
584 | 0 | case MID_DOCINFO_AUTOLOADSECS: |
585 | 0 | bRet = (rVal >>= nValue); |
586 | 0 | if ( bRet ) |
587 | 0 | m_AutoloadDelay = nValue; |
588 | 0 | break; |
589 | 0 | case MID_DOCINFO_AUTOLOADURL: |
590 | 0 | bRet = (rVal >>= aValue); |
591 | 0 | if ( bRet ) |
592 | 0 | m_AutoloadURL = aValue; |
593 | 0 | break; |
594 | 0 | case MID_DOCINFO_DEFAULTTARGET: |
595 | 0 | bRet = (rVal >>= aValue); |
596 | 0 | if ( bRet ) |
597 | 0 | m_DefaultTarget = aValue; |
598 | 0 | break; |
599 | 0 | case MID_DOCINFO_DESCRIPTION: |
600 | 0 | bRet = (rVal >>= aValue); |
601 | 0 | if ( bRet ) |
602 | 0 | setDescription(aValue); |
603 | 0 | break; |
604 | 0 | case MID_DOCINFO_KEYWORDS: |
605 | 0 | bRet = (rVal >>= aValue); |
606 | 0 | if ( bRet ) |
607 | 0 | setKeywords(aValue); |
608 | 0 | break; |
609 | 0 | case MID_DOCINFO_SUBJECT: |
610 | 0 | bRet = (rVal >>= aValue); |
611 | 0 | if ( bRet ) |
612 | 0 | setSubject(aValue); |
613 | 0 | break; |
614 | 0 | case MID_DOCINFO_TITLE: |
615 | 0 | bRet = (rVal >>= aValue); |
616 | 0 | if ( bRet ) |
617 | 0 | setTitle(aValue); |
618 | 0 | break; |
619 | 0 | default: |
620 | 0 | OSL_FAIL("Wrong MemberId!"); |
621 | 0 | return false; |
622 | 0 | } |
623 | | |
624 | 0 | return bRet; |
625 | 0 | } |
626 | | |
627 | | SfxDocumentDescPage::SfxDocumentDescPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rItemSet) |
628 | 0 | : SfxTabPage(pPage, pController, u"sfx/ui/descriptioninfopage.ui"_ustr, u"DescriptionInfoPage"_ustr, &rItemSet) |
629 | 0 | , m_pInfoItem(nullptr) |
630 | 0 | , m_xTitleEd(m_xBuilder->weld_entry(u"title"_ustr)) |
631 | 0 | , m_xThemaEd(m_xBuilder->weld_entry(u"subject"_ustr)) |
632 | 0 | , m_xKeywordsEd(m_xBuilder->weld_entry(u"keywords"_ustr)) |
633 | 0 | , m_xContributorEd(m_xBuilder->weld_entry(u"contributor"_ustr)) |
634 | 0 | , m_xCoverageEd(m_xBuilder->weld_entry(u"coverage"_ustr)) |
635 | 0 | , m_xIdentifierEd(m_xBuilder->weld_entry(u"identifier"_ustr)) |
636 | 0 | , m_xPublisherEd(m_xBuilder->weld_entry(u"publisher"_ustr)) |
637 | 0 | , m_xRelationEd(m_xBuilder->weld_entry(u"relation"_ustr)) |
638 | 0 | , m_xRightsEd(m_xBuilder->weld_entry(u"rights"_ustr)) |
639 | 0 | , m_xSourceEd(m_xBuilder->weld_entry(u"source"_ustr)) |
640 | 0 | , m_xTypeEd(m_xBuilder->weld_entry(u"type"_ustr)) |
641 | 0 | , m_xCommentEd(m_xBuilder->weld_text_view(u"comments"_ustr)) |
642 | 0 | { |
643 | 0 | m_xCommentEd->set_size_request(m_xKeywordsEd->get_preferred_size().Width(), |
644 | 0 | m_xCommentEd->get_height_rows(16)); |
645 | 0 | } |
646 | | |
647 | | SfxDocumentDescPage::~SfxDocumentDescPage() |
648 | 0 | { |
649 | 0 | } |
650 | | |
651 | | std::unique_ptr<SfxTabPage> SfxDocumentDescPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rItemSet) |
652 | 0 | { |
653 | 0 | return std::make_unique<SfxDocumentDescPage>(pPage, pController, *rItemSet); |
654 | 0 | } |
655 | | |
656 | | bool SfxDocumentDescPage::FillItemSet(SfxItemSet *rSet) |
657 | 0 | { |
658 | | // Test whether a change is present |
659 | 0 | const bool bTitleMod = m_xTitleEd->get_value_changed_from_saved(); |
660 | 0 | const bool bThemeMod = m_xThemaEd->get_value_changed_from_saved(); |
661 | 0 | const bool bKeywordsMod = m_xKeywordsEd->get_value_changed_from_saved(); |
662 | 0 | const bool bContributorMod = m_xContributorEd->get_value_changed_from_saved(); |
663 | 0 | const bool bCoverageMod = m_xCoverageEd->get_value_changed_from_saved(); |
664 | 0 | const bool bIdentifierMod = m_xIdentifierEd->get_value_changed_from_saved(); |
665 | 0 | const bool bPublisherMod = m_xPublisherEd->get_value_changed_from_saved(); |
666 | 0 | const bool bRelationMod = m_xRelationEd->get_value_changed_from_saved(); |
667 | 0 | const bool bRightsMod = m_xRightsEd->get_value_changed_from_saved(); |
668 | 0 | const bool bSourceMod = m_xSourceEd->get_value_changed_from_saved(); |
669 | 0 | const bool bTypeMod = m_xTypeEd->get_value_changed_from_saved(); |
670 | 0 | const bool bCommentMod = m_xCommentEd->get_value_changed_from_saved(); |
671 | 0 | if (!(bTitleMod || bThemeMod || bKeywordsMod |
672 | 0 | || bContributorMod || bCoverageMod || bIdentifierMod || bPublisherMod || bRelationMod |
673 | 0 | || bRightsMod || bSourceMod || bTypeMod || bCommentMod)) |
674 | 0 | { |
675 | 0 | return false; |
676 | 0 | } |
677 | | |
678 | | // Generating the output data |
679 | 0 | const SfxDocumentInfoItem* pItem = nullptr; |
680 | 0 | SfxDocumentInfoItem* pInfo = nullptr; |
681 | 0 | const SfxItemSet* pExSet = GetDialogExampleSet(); |
682 | |
|
683 | 0 | if ( pExSet && !(pItem = pExSet->GetItemIfSet( SID_DOCINFO )) ) |
684 | 0 | pInfo = m_pInfoItem; |
685 | 0 | else if ( pItem ) |
686 | 0 | pInfo = new SfxDocumentInfoItem( *pItem ); |
687 | |
|
688 | 0 | if ( !pInfo ) |
689 | 0 | { |
690 | 0 | SAL_WARN( "sfx.dialog", "SfxDocumentDescPage::FillItemSet(): no item found" ); |
691 | 0 | return false; |
692 | 0 | } |
693 | | |
694 | 0 | if ( bTitleMod ) |
695 | 0 | { |
696 | 0 | pInfo->setTitle( m_xTitleEd->get_text() ); |
697 | 0 | } |
698 | 0 | if ( bThemeMod ) |
699 | 0 | { |
700 | 0 | pInfo->setSubject( m_xThemaEd->get_text() ); |
701 | 0 | } |
702 | 0 | if ( bKeywordsMod ) |
703 | 0 | { |
704 | 0 | pInfo->setKeywords( m_xKeywordsEd->get_text() ); |
705 | 0 | } |
706 | 0 | if (bContributorMod) |
707 | 0 | { |
708 | 0 | pInfo->setContributor(m_xContributorEd->get_text()); |
709 | 0 | } |
710 | 0 | if (bCoverageMod) |
711 | 0 | { |
712 | 0 | pInfo->setCoverage(m_xCoverageEd->get_text()); |
713 | 0 | } |
714 | 0 | if (bIdentifierMod) |
715 | 0 | { |
716 | 0 | pInfo->setIdentifier(m_xIdentifierEd->get_text()); |
717 | 0 | } |
718 | 0 | if (bPublisherMod) |
719 | 0 | { |
720 | 0 | pInfo->setPublisher(m_xPublisherEd->get_text()); |
721 | 0 | } |
722 | 0 | if (bRelationMod) |
723 | 0 | { |
724 | 0 | pInfo->setRelation(m_xRelationEd->get_text()); |
725 | 0 | } |
726 | 0 | if (bRightsMod) |
727 | 0 | { |
728 | 0 | pInfo->setRights(m_xRightsEd->get_text()); |
729 | 0 | } |
730 | 0 | if (bSourceMod) |
731 | 0 | { |
732 | 0 | pInfo->setSource(m_xSourceEd->get_text()); |
733 | 0 | } |
734 | 0 | if (bTypeMod) |
735 | 0 | { |
736 | 0 | pInfo->setType(m_xTypeEd->get_text()); |
737 | 0 | } |
738 | 0 | if ( bCommentMod ) |
739 | 0 | { |
740 | 0 | pInfo->setDescription( m_xCommentEd->get_text() ); |
741 | 0 | } |
742 | 0 | rSet->Put( *pInfo ); |
743 | | // ptr compare OK, pInfo was created above as temporary data holder |
744 | 0 | if ( !areSfxPoolItemPtrsEqual(pInfo, m_pInfoItem) ) |
745 | 0 | { |
746 | 0 | delete pInfo; |
747 | 0 | } |
748 | |
|
749 | 0 | return true; |
750 | 0 | } |
751 | | |
752 | | void SfxDocumentDescPage::Reset(const SfxItemSet *rSet) |
753 | 0 | { |
754 | 0 | m_pInfoItem = const_cast<SfxDocumentInfoItem*>(&rSet->Get(SID_DOCINFO)); |
755 | |
|
756 | 0 | m_xTitleEd->set_text(m_pInfoItem->getTitle()); |
757 | 0 | m_xThemaEd->set_text(m_pInfoItem->getSubject()); |
758 | 0 | m_xKeywordsEd->set_text(m_pInfoItem->getKeywords()); |
759 | 0 | m_xContributorEd->set_text(m_pInfoItem->getContributor()); |
760 | 0 | m_xCoverageEd->set_text(m_pInfoItem->getCoverage()); |
761 | 0 | m_xIdentifierEd->set_text(m_pInfoItem->getIdentifier()); |
762 | 0 | m_xPublisherEd->set_text(m_pInfoItem->getPublisher()); |
763 | 0 | m_xRelationEd->set_text(m_pInfoItem->getRelation()); |
764 | 0 | m_xRightsEd->set_text(m_pInfoItem->getRights()); |
765 | 0 | m_xSourceEd->set_text(m_pInfoItem->getSource()); |
766 | 0 | m_xTypeEd->set_text(m_pInfoItem->getType()); |
767 | 0 | m_xCommentEd->set_text(m_pInfoItem->getDescription()); |
768 | |
|
769 | 0 | m_xTitleEd->save_value(); |
770 | 0 | m_xThemaEd->save_value(); |
771 | 0 | m_xKeywordsEd->save_value(); |
772 | 0 | m_xContributorEd->save_value(); |
773 | 0 | m_xCoverageEd->save_value(); |
774 | 0 | m_xIdentifierEd->save_value(); |
775 | 0 | m_xPublisherEd->save_value(); |
776 | 0 | m_xRelationEd->save_value(); |
777 | 0 | m_xRightsEd->save_value(); |
778 | 0 | m_xSourceEd->save_value(); |
779 | 0 | m_xTypeEd->save_value(); |
780 | 0 | m_xCommentEd->save_value(); |
781 | |
|
782 | 0 | const SfxBoolItem* pROItem = rSet->GetItem(SID_DOC_READONLY, false); |
783 | 0 | if (pROItem && pROItem->GetValue()) |
784 | 0 | { |
785 | 0 | m_xTitleEd->set_editable(false); |
786 | 0 | m_xThemaEd->set_editable(false); |
787 | 0 | m_xKeywordsEd->set_editable(false); |
788 | 0 | m_xContributorEd->set_editable(false); |
789 | 0 | m_xCoverageEd->set_editable(false); |
790 | 0 | m_xIdentifierEd->set_editable(false); |
791 | 0 | m_xPublisherEd->set_editable(false); |
792 | 0 | m_xRelationEd->set_editable(false); |
793 | 0 | m_xRightsEd->set_editable(false); |
794 | 0 | m_xSourceEd->set_editable(false); |
795 | 0 | m_xTypeEd->set_editable(false); |
796 | 0 | m_xCommentEd->set_editable(false); |
797 | 0 | } |
798 | 0 | } |
799 | | |
800 | | SfxDocumentPage::SfxDocumentPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rItemSet) |
801 | 0 | : SfxTabPage(pPage, pController, u"sfx/ui/documentinfopage.ui"_ustr, u"DocumentInfoPage"_ustr, &rItemSet) |
802 | 0 | , bEnableUseUserData( false ) |
803 | 0 | , bHandleDelete( false ) |
804 | 0 | , m_xBmp(m_xBuilder->weld_image(u"icon"_ustr)) |
805 | 0 | , m_xNameED(m_xBuilder->weld_label(u"nameed"_ustr)) |
806 | 0 | , m_xChangePassBtn(m_xBuilder->weld_button(u"changepass"_ustr)) |
807 | 0 | , m_xShowTypeFT(m_xBuilder->weld_label(u"showtype"_ustr)) |
808 | 0 | , m_xFileValEd(m_xBuilder->weld_label(u"showlocation"_ustr)) |
809 | 0 | , m_xFileValBtn(m_xBuilder->weld_button(u"btnShowLocation"_ustr)) |
810 | 0 | , m_xShowSizeFT(m_xBuilder->weld_label(u"showsize"_ustr)) |
811 | 0 | , m_xCreateValFt(m_xBuilder->weld_label(u"showcreate"_ustr)) |
812 | 0 | , m_xChangeValFt(m_xBuilder->weld_label(u"showmodify"_ustr)) |
813 | 0 | , m_xSignedValFt(m_xBuilder->weld_label(u"showsigned"_ustr)) |
814 | 0 | , m_xSignatureBtn(m_xBuilder->weld_button(u"signature"_ustr)) |
815 | 0 | , m_xPrintValFt(m_xBuilder->weld_label(u"showprint"_ustr)) |
816 | 0 | , m_xTimeLogValFt(m_xBuilder->weld_label(u"showedittime"_ustr)) |
817 | 0 | , m_xDocNoValFt(m_xBuilder->weld_label(u"showrevision"_ustr)) |
818 | 0 | , m_xUseUserDataCB(m_xBuilder->weld_check_button(u"userdatacb"_ustr)) |
819 | 0 | , m_xDeleteBtn(m_xBuilder->weld_button(u"reset"_ustr)) |
820 | 0 | , m_xUseThumbnailSaveCB(m_xBuilder->weld_check_button(u"thumbnailsavecb"_ustr)) |
821 | 0 | , m_xTemplFt(m_xBuilder->weld_label(u"templateft"_ustr)) |
822 | 0 | , m_xTemplValFt(m_xBuilder->weld_label(u"showtemplate"_ustr)) |
823 | 0 | , m_xImagePreferredDpiCheckButton(m_xBuilder->weld_check_button(u"image-preferred-dpi-checkbutton"_ustr)) |
824 | 0 | , m_xImagePreferredDpiComboBox(m_xBuilder->weld_combo_box(u"image-preferred-dpi-combobox"_ustr)) |
825 | 0 | { |
826 | 0 | m_xUseUserDataCB->set_accessible_description(SfxResId(STR_A11Y_DESC_USERDATA)); |
827 | |
|
828 | 0 | m_aUnknownSize = m_xShowSizeFT->get_label(); |
829 | 0 | m_xShowSizeFT->set_label(OUString()); |
830 | |
|
831 | 0 | m_aMultiSignedStr = m_xSignedValFt->get_label(); |
832 | 0 | m_xSignedValFt->set_label(OUString()); |
833 | 0 | m_xImagePreferredDpiComboBox->set_entry_width_chars(5); // "width in chars" in Glade not effective |
834 | |
|
835 | 0 | ImplUpdateSignatures(); |
836 | 0 | ImplCheckPasswordState(); |
837 | 0 | m_xChangePassBtn->connect_clicked( LINK( this, SfxDocumentPage, ChangePassHdl ) ); |
838 | 0 | m_xSignatureBtn->connect_clicked( LINK( this, SfxDocumentPage, SignatureHdl ) ); |
839 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
840 | 0 | m_xSignatureBtn->hide(); |
841 | 0 | m_xDeleteBtn->connect_clicked( LINK( this, SfxDocumentPage, DeleteHdl ) ); |
842 | 0 | m_xImagePreferredDpiCheckButton->connect_toggled(LINK(this, SfxDocumentPage, ImagePreferredDPICheckBoxClicked)); |
843 | | |
844 | | // [i96288] Check if the document signature command is enabled |
845 | | // on the main list enable/disable the pushbutton accordingly |
846 | 0 | SvtCommandOptions aCmdOptions; |
847 | 0 | if ( aCmdOptions.LookupDisabled( u"Signature"_ustr ) ) |
848 | 0 | m_xSignatureBtn->set_sensitive(false); |
849 | 0 | } |
850 | | |
851 | | SfxDocumentPage::~SfxDocumentPage() |
852 | 0 | { |
853 | 0 | if (m_xPasswordDialog) |
854 | 0 | { |
855 | 0 | m_xPasswordDialog->Response(RET_CANCEL); |
856 | 0 | m_xPasswordDialog.reset(); |
857 | 0 | } |
858 | 0 | } |
859 | | |
860 | | IMPL_LINK_NOARG(SfxDocumentPage, FileValHdl, weld::Button&, void) |
861 | 0 | { |
862 | 0 | sfx2::openUriExternally(m_sFileURL, false, GetFrameWeld()); |
863 | 0 | } |
864 | | |
865 | | IMPL_LINK_NOARG(SfxDocumentPage, DeleteHdl, weld::Button&, void) |
866 | 0 | { |
867 | 0 | OUString aName; |
868 | 0 | if (bEnableUseUserData && m_xUseUserDataCB->get_active()) |
869 | 0 | aName = SvtUserOptions().GetFullName(); |
870 | 0 | const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() ); |
871 | 0 | DateTime now( DateTime::SYSTEM ); |
872 | 0 | util::DateTime uDT( now.GetUNODateTime() ); |
873 | 0 | m_xCreateValFt->set_label( ConvertDateTime_Impl( aName, uDT, rLocaleWrapper ) ); |
874 | 0 | m_xChangeValFt->set_label( u""_ustr ); |
875 | 0 | m_xPrintValFt->set_label( u""_ustr ); |
876 | 0 | m_xTimeLogValFt->set_label( rLocaleWrapper.getDuration( tools::Duration() ) ); |
877 | 0 | m_xDocNoValFt->set_label(OUString('1')); |
878 | 0 | bHandleDelete = true; |
879 | 0 | } |
880 | | |
881 | | IMPL_LINK_NOARG(SfxDocumentPage, SignatureHdl, weld::Button&, void) |
882 | 0 | { |
883 | 0 | SfxObjectShell* pDoc = SfxObjectShell::Current(); |
884 | 0 | if( pDoc ) |
885 | 0 | { |
886 | 0 | pDoc->SignDocumentContent(GetFrameWeld(), [this] (bool /*bHaveWeSigned*/) { |
887 | 0 | ImplUpdateSignatures(); |
888 | 0 | }); |
889 | 0 | } |
890 | 0 | } |
891 | | |
892 | | IMPL_LINK_NOARG(SfxDocumentPage, ImagePreferredDPICheckBoxClicked, weld::Toggleable&, void) |
893 | 0 | { |
894 | 0 | bool bEnabled = m_xImagePreferredDpiCheckButton->get_state() == TRISTATE_TRUE; |
895 | 0 | m_xImagePreferredDpiComboBox->set_sensitive(bEnabled); |
896 | 0 | } |
897 | | |
898 | | IMPL_LINK_NOARG(SfxDocumentPage, ChangePassHdl, weld::Button&, void) |
899 | 0 | { |
900 | 0 | SfxObjectShell* pShell = SfxObjectShell::Current(); |
901 | 0 | do |
902 | 0 | { |
903 | 0 | if (!pShell) |
904 | 0 | break; |
905 | 0 | SfxItemSet& rMedSet = pShell->GetMedium()->GetItemSet(); |
906 | 0 | std::shared_ptr<const SfxFilter> pFilter = pShell->GetMedium()->GetFilter(); |
907 | 0 | if (!pFilter) |
908 | 0 | break; |
909 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
910 | 0 | { |
911 | | // MS Types support max len of 15 characters while OOXML is "unlimited" |
912 | 0 | const sal_uInt16 maxPwdLen = sfx2::IsMSType(pFilter) && !sfx2::IsOOXML(pFilter) ? 15 : 0; |
913 | | // handle the pwd dialog asynchronously |
914 | 0 | VclAbstractDialogFactory * pFact = VclAbstractDialogFactory::Create(); |
915 | 0 | m_xPasswordDialog = pFact->CreatePasswordToOpenModifyDialog(GetFrameWeld(), maxPwdLen, false); |
916 | 0 | m_xPasswordDialog->AllowEmpty(); // needed to remove password |
917 | 0 | m_xPasswordDialog->StartExecuteAsync([this, pFilter=std::move(pFilter), &rMedSet, pShell](sal_Int32 nResult) |
918 | 0 | { |
919 | 0 | if (nResult == RET_OK) |
920 | 0 | { |
921 | 0 | sfx2::SetPassword(pFilter, &rMedSet, m_xPasswordDialog->GetPasswordToOpen(), |
922 | 0 | m_xPasswordDialog->GetPasswordToOpen(), true); |
923 | 0 | tools::JsonWriter payloadJson; |
924 | 0 | payloadJson.put("password", m_xPasswordDialog->GetPasswordToOpen()); |
925 | 0 | payloadJson.put("isToModify", false); |
926 | |
|
927 | 0 | SfxViewShell *pViewShell = SfxViewShell::Current(); |
928 | 0 | if (pViewShell) |
929 | 0 | pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_PASSWORD_RESET, payloadJson.finishAndGetAsOString()); |
930 | |
|
931 | 0 | pShell->SetModified(); |
932 | 0 | } |
933 | 0 | m_xPasswordDialog->disposeOnce(); |
934 | 0 | }); |
935 | 0 | } else { |
936 | 0 | sfx2::RequestPassword(pFilter, OUString(), &rMedSet, GetFrameWeld()->GetXWindow()); |
937 | 0 | pShell->SetModified(); |
938 | 0 | } |
939 | 0 | } |
940 | 0 | while (false); |
941 | 0 | } |
942 | | |
943 | | void SfxDocumentPage::ImplUpdateSignatures() |
944 | 0 | { |
945 | 0 | SfxObjectShell* pDoc = SfxObjectShell::Current(); |
946 | 0 | if ( !pDoc ) |
947 | 0 | return; |
948 | | |
949 | 0 | SfxMedium* pMedium = pDoc->GetMedium(); |
950 | 0 | if ( !pMedium || pMedium->GetName().isEmpty() || !pMedium->GetStorage().is() ) |
951 | 0 | return; |
952 | | |
953 | 0 | Reference< security::XDocumentDigitalSignatures > xD; |
954 | 0 | try |
955 | 0 | { |
956 | 0 | xD = security::DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext()); |
957 | 0 | xD->setParentWindow(GetDialogController()->getDialog()->GetXWindow()); |
958 | 0 | } |
959 | 0 | catch ( const css::uno::DeploymentException& ) |
960 | 0 | { |
961 | 0 | } |
962 | 0 | OUString s; |
963 | 0 | Sequence< security::DocumentSignatureInformation > aInfos; |
964 | |
|
965 | 0 | if ( xD.is() ) |
966 | 0 | aInfos = xD->verifyDocumentContentSignatures( pMedium->GetZipStorageToSign_Impl(), |
967 | 0 | uno::Reference< io::XInputStream >() ); |
968 | 0 | if ( aInfos.getLength() > 1 ) |
969 | 0 | s = m_aMultiSignedStr; |
970 | 0 | else if ( aInfos.getLength() == 1 ) |
971 | 0 | { |
972 | 0 | const security::DocumentSignatureInformation& rInfo = aInfos[ 0 ]; |
973 | 0 | s = utl::GetDateTimeString( rInfo.SignatureDate, rInfo.SignatureTime ) + ", " + |
974 | 0 | comphelper::xmlsec::GetContentPart(rInfo.Signer->getSubjectName(), rInfo.Signer->getCertificateKind()); |
975 | 0 | } |
976 | 0 | m_xSignedValFt->set_label(s); |
977 | 0 | } |
978 | | |
979 | | void SfxDocumentPage::ImplCheckPasswordState() |
980 | 0 | { |
981 | 0 | SfxObjectShell* pShell = SfxObjectShell::Current(); |
982 | 0 | do |
983 | 0 | { |
984 | 0 | if (!pShell) |
985 | 0 | break; |
986 | 0 | const SfxUnoAnyItem* pEncryptionDataItem = pShell->GetMedium()->GetItemSet().GetItem(SID_ENCRYPTIONDATA, false); |
987 | 0 | uno::Sequence< beans::NamedValue > aEncryptionData; |
988 | 0 | if (pEncryptionDataItem) |
989 | 0 | pEncryptionDataItem->GetValue() >>= aEncryptionData; |
990 | 0 | else |
991 | 0 | break; |
992 | | |
993 | 0 | if (!aEncryptionData.hasElements()) |
994 | 0 | break; |
995 | 0 | m_xChangePassBtn->set_sensitive(true); |
996 | 0 | return; |
997 | 0 | } |
998 | 0 | while (false); |
999 | 0 | m_xChangePassBtn->set_sensitive(comphelper::LibreOfficeKit::isActive()); |
1000 | 0 | } |
1001 | | |
1002 | | std::unique_ptr<SfxTabPage> SfxDocumentPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rItemSet) |
1003 | 0 | { |
1004 | 0 | return std::make_unique<SfxDocumentPage>(pPage, pController, *rItemSet); |
1005 | 0 | } |
1006 | | |
1007 | | void SfxDocumentPage::EnableUseUserData() |
1008 | 0 | { |
1009 | 0 | bEnableUseUserData = true; |
1010 | 0 | m_xUseUserDataCB->show(); |
1011 | 0 | m_xDeleteBtn->show(); |
1012 | 0 | } |
1013 | | |
1014 | | bool SfxDocumentPage::FillItemSet( SfxItemSet* rSet ) |
1015 | 0 | { |
1016 | 0 | bool bRet = false; |
1017 | |
|
1018 | 0 | if ( !bHandleDelete && bEnableUseUserData && |
1019 | 0 | m_xUseUserDataCB->get_state_changed_from_saved() ) |
1020 | 0 | { |
1021 | 0 | const SfxItemSet* pExpSet = GetDialogExampleSet(); |
1022 | 0 | const SfxDocumentInfoItem* pInfoItem; |
1023 | |
|
1024 | 0 | if ( pExpSet && (pInfoItem = pExpSet->GetItemIfSet( SID_DOCINFO ) ) ) |
1025 | 0 | { |
1026 | 0 | bool bUseData = ( TRISTATE_TRUE == m_xUseUserDataCB->get_state() ); |
1027 | 0 | const_cast<SfxDocumentInfoItem*>(pInfoItem)->SetUseUserData( bUseData ); |
1028 | 0 | rSet->Put( *pInfoItem ); |
1029 | 0 | bRet = true; |
1030 | 0 | } |
1031 | 0 | } |
1032 | | |
1033 | | // tdf#116833 - don't overwrite deletion of document information |
1034 | 0 | if (m_xUseThumbnailSaveCB->get_state_changed_from_saved()) |
1035 | 0 | { |
1036 | 0 | const SfxItemSet* pExpSet = GetDialogExampleSet(); |
1037 | 0 | const SfxDocumentInfoItem* pInfoItem; |
1038 | |
|
1039 | 0 | if (pExpSet && (pInfoItem = pExpSet->GetItemIfSet(SID_DOCINFO))) |
1040 | 0 | { |
1041 | 0 | bool bUseThumbnail = (TRISTATE_TRUE == m_xUseThumbnailSaveCB->get_state()); |
1042 | 0 | const_cast<SfxDocumentInfoItem*>(pInfoItem)->SetUseThumbnailSave(bUseThumbnail); |
1043 | 0 | rSet->Put(*pInfoItem); |
1044 | 0 | bRet = true; |
1045 | 0 | } |
1046 | 0 | } |
1047 | |
|
1048 | 0 | if ( bHandleDelete ) |
1049 | 0 | { |
1050 | 0 | const SfxItemSet* pExpSet = GetDialogExampleSet(); |
1051 | 0 | const SfxDocumentInfoItem* pInfoItem; |
1052 | 0 | if ( pExpSet && (pInfoItem = pExpSet->GetItemIfSet( SID_DOCINFO )) ) |
1053 | 0 | { |
1054 | 0 | bool bUseAuthor = bEnableUseUserData && m_xUseUserDataCB->get_active(); |
1055 | 0 | SfxDocumentInfoItem newItem( *pInfoItem ); |
1056 | 0 | newItem.resetUserData( bUseAuthor |
1057 | 0 | ? SvtUserOptions().GetFullName() |
1058 | 0 | : OUString() ); |
1059 | 0 | const_cast<SfxDocumentInfoItem*>(pInfoItem)->SetUseUserData( TRISTATE_TRUE == m_xUseUserDataCB->get_state() ); |
1060 | 0 | newItem.SetUseUserData( TRISTATE_TRUE == m_xUseUserDataCB->get_state() ); |
1061 | |
|
1062 | 0 | newItem.SetDeleteUserData( true ); |
1063 | 0 | rSet->Put( newItem ); |
1064 | 0 | bRet = true; |
1065 | 0 | } |
1066 | 0 | } |
1067 | |
|
1068 | 0 | SfxObjectShell* pDocSh = SfxObjectShell::Current(); |
1069 | 0 | if (pDocSh) |
1070 | 0 | { |
1071 | 0 | uno::Reference<lang::XMultiServiceFactory> xFac(pDocSh->GetModel(), uno::UNO_QUERY); |
1072 | 0 | if (xFac.is()) |
1073 | 0 | { |
1074 | 0 | uno::Reference<beans::XPropertySet> xProps(xFac->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY); |
1075 | 0 | if (xProps.is()) |
1076 | 0 | { |
1077 | 0 | sal_Int32 nImagePreferredDPI = 0; |
1078 | 0 | if (m_xImagePreferredDpiCheckButton->get_state() == TRISTATE_TRUE) |
1079 | 0 | { |
1080 | 0 | OUString aImagePreferredDPIString = m_xImagePreferredDpiComboBox->get_active_text(); |
1081 | 0 | nImagePreferredDPI = aImagePreferredDPIString.toInt32(); |
1082 | 0 | } |
1083 | 0 | xProps->setPropertyValue(u"ImagePreferredDPI"_ustr, uno::Any(nImagePreferredDPI)); |
1084 | 0 | } |
1085 | 0 | } |
1086 | 0 | } |
1087 | |
|
1088 | 0 | return bRet; |
1089 | 0 | } |
1090 | | |
1091 | | void SfxDocumentPage::Reset( const SfxItemSet* rSet ) |
1092 | 0 | { |
1093 | | // Determine the document information |
1094 | 0 | const SfxDocumentInfoItem& rInfoItem = rSet->Get(SID_DOCINFO); |
1095 | | |
1096 | | // template data |
1097 | 0 | if (rInfoItem.HasTemplate()) |
1098 | 0 | { |
1099 | 0 | const OUString& rName = rInfoItem.getTemplateName(); |
1100 | 0 | if (rName.getLength() > SAL_MAX_INT16) // tdf#122780 pick some ~arbitrary max size |
1101 | 0 | m_xTemplValFt->set_label(rName.copy(0, SAL_MAX_INT16)); |
1102 | 0 | else |
1103 | 0 | m_xTemplValFt->set_label(rName); |
1104 | 0 | } |
1105 | 0 | else |
1106 | 0 | { |
1107 | 0 | m_xTemplFt->hide(); |
1108 | 0 | m_xTemplValFt->hide(); |
1109 | 0 | } |
1110 | | |
1111 | | // determine file name |
1112 | 0 | OUString aFile( rInfoItem.GetValue() ); |
1113 | 0 | OUString aFactory( aFile ); |
1114 | 0 | if ( aFile.getLength() > 2 && aFile[0] == '[' ) |
1115 | 0 | { |
1116 | 0 | sal_Int32 nPos = aFile.indexOf( ']' ); |
1117 | 0 | aFactory = aFile.copy( 1, nPos-1 ); |
1118 | 0 | aFile = aFile.copy( nPos+1 ); |
1119 | 0 | } |
1120 | | |
1121 | | // determine name |
1122 | 0 | INetURLObject aURL(aFile); |
1123 | 0 | OUString aName = aURL.GetLastName(INetURLObject::DecodeMechanism::WithCharset); |
1124 | 0 | if ( aName.isEmpty() || aURL.GetProtocol() == INetProtocol::PrivSoffice ) |
1125 | 0 | aName = SfxResId( STR_NONAME ); |
1126 | 0 | m_xNameED->set_label( aName ); |
1127 | | |
1128 | | // determine context symbol |
1129 | 0 | aURL.SetSmartProtocol( INetProtocol::File ); |
1130 | 0 | aURL.SetSmartURL( aFactory); |
1131 | 0 | const OUString aMainURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
1132 | 0 | OUString aImage = SvFileInformationManager::GetImageId( aURL, true ); |
1133 | 0 | m_xBmp->set_from_icon_name(aImage); |
1134 | | |
1135 | | // determine size and type |
1136 | 0 | OUString aSizeText( m_aUnknownSize ); |
1137 | | // we might already know the size as an optional argument passed to .uno:SetDocumentProperties |
1138 | 0 | sal_Int64 nSize = rInfoItem.getFileSize(); |
1139 | | // otherwise, for some protocols we can reliably query for it |
1140 | 0 | if (nSize == -1 && (aURL.GetProtocol() == INetProtocol::File || aURL.isAnyKnownWebDAVScheme())) |
1141 | 0 | nSize = SfxContentHelper::GetSize( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); |
1142 | 0 | if (nSize != -1) |
1143 | 0 | aSizeText = CreateSizeText( nSize ); |
1144 | 0 | m_xShowSizeFT->set_label( aSizeText ); |
1145 | |
|
1146 | 0 | OUString aDescription = SvFileInformationManager::GetDescription( INetURLObject(aMainURL) ); |
1147 | 0 | if ( aDescription.isEmpty() ) |
1148 | 0 | aDescription = SfxResId( STR_SFX_NEWOFFICEDOC ); |
1149 | 0 | m_xShowTypeFT->set_label( aDescription ); |
1150 | |
|
1151 | 0 | m_sFileURL.clear(); |
1152 | | // determine location |
1153 | | // online we don't know file location so we just set it as the name |
1154 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
1155 | 0 | { |
1156 | 0 | m_xFileValEd->set_label(aName); |
1157 | 0 | m_sFileURL = aName; |
1158 | | |
1159 | | // Disable setting/changing password on text files. |
1160 | | // Perhaps this needs to be done for both Online and Desktop. |
1161 | 0 | OUString sExtension(INetURLObject(aMainURL).getExtension()); |
1162 | 0 | if (!sExtension.isEmpty()) |
1163 | 0 | { |
1164 | 0 | sExtension = sExtension.toAsciiLowerCase(); |
1165 | 0 | if (sExtension == "txt" || sExtension == "csv") |
1166 | 0 | m_xChangePassBtn->set_sensitive(false); |
1167 | 0 | } |
1168 | 0 | } |
1169 | 0 | else |
1170 | 0 | { |
1171 | 0 | aURL.SetSmartURL( aFile); |
1172 | 0 | if ( aURL.GetProtocol() == INetProtocol::File ) |
1173 | 0 | { |
1174 | 0 | INetURLObject aPath(std::move(aURL)); |
1175 | 0 | aPath.setFinalSlash(); |
1176 | 0 | aPath.removeSegment(); |
1177 | | // we know it's a folder -> don't need the final slash, but it's better for WB_PATHELLIPSIS |
1178 | 0 | aPath.removeFinalSlash(); |
1179 | 0 | OUString aText( aPath.PathToFileName() ); //! (pb) MaxLen? |
1180 | 0 | m_xFileValEd->set_label(aText); |
1181 | 0 | OUString aURLStr; |
1182 | 0 | osl::FileBase::getFileURLFromSystemPath(aText, aURLStr); |
1183 | 0 | m_sFileURL = aURLStr; |
1184 | 0 | } |
1185 | 0 | else if (aURL.GetProtocol() != INetProtocol::PrivSoffice) |
1186 | 0 | { |
1187 | 0 | m_xFileValEd->set_label(aURL.GetPartBeforeLastName()); |
1188 | 0 | m_sFileURL = m_xFileValEd->get_label(); |
1189 | 0 | } |
1190 | 0 | } |
1191 | 0 | m_xFileValBtn->connect_clicked( LINK( this, SfxDocumentPage, FileValHdl ) ); |
1192 | 0 | if (m_sFileURL.isEmpty()) |
1193 | 0 | m_xFileValBtn->set_sensitive(false); |
1194 | | |
1195 | | // handle access data |
1196 | 0 | bool bUseUserData = rInfoItem.IsUseUserData(); |
1197 | 0 | const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() ); |
1198 | 0 | m_xCreateValFt->set_label( ConvertDateTime_Impl( rInfoItem.getAuthor(), |
1199 | 0 | rInfoItem.getCreationDate(), rLocaleWrapper ) ); |
1200 | 0 | util::DateTime aTime( rInfoItem.getModificationDate() ); |
1201 | 0 | if ( aTime.Month > 0 ) |
1202 | 0 | m_xChangeValFt->set_label( ConvertDateTime_Impl( |
1203 | 0 | rInfoItem.getModifiedBy(), aTime, rLocaleWrapper ) ); |
1204 | 0 | aTime = rInfoItem.getPrintDate(); |
1205 | 0 | if ( aTime.Month > 0 ) |
1206 | 0 | m_xPrintValFt->set_label( ConvertDateTime_Impl( rInfoItem.getPrintedBy(), |
1207 | 0 | aTime, rLocaleWrapper ) ); |
1208 | 0 | const tools::Long nTime = rInfoItem.getEditingDuration(); |
1209 | 0 | if ( bUseUserData ) |
1210 | 0 | { |
1211 | 0 | assert(SAL_MIN_INT32 <= nTime/86400 && nTime/86400 <= SAL_MAX_INT32); |
1212 | 0 | const tools::Duration aD( static_cast<sal_Int32>(nTime)/86400, |
1213 | 0 | (nTime%86400)/3600, (nTime%3600)/60, nTime%60, 0); |
1214 | 0 | m_xTimeLogValFt->set_label( rLocaleWrapper.getDuration( aD ) ); |
1215 | 0 | m_xDocNoValFt->set_label( OUString::number( |
1216 | 0 | rInfoItem.getEditingCycles() ) ); |
1217 | 0 | } |
1218 | |
|
1219 | 0 | bool bUseThumbnailSave = rInfoItem.IsUseThumbnailSave(); |
1220 | | |
1221 | | // Check for cmis properties where otherwise unavailable |
1222 | 0 | if ( rInfoItem.isCmisDocument( ) ) |
1223 | 0 | { |
1224 | 0 | const uno::Sequence< document::CmisProperty >& aCmisProps = rInfoItem.GetCmisProperties(); |
1225 | 0 | for ( const auto& rCmisProp : aCmisProps ) |
1226 | 0 | { |
1227 | 0 | if ( rCmisProp.Id == "cmis:contentStreamLength" && |
1228 | 0 | aSizeText == m_aUnknownSize ) |
1229 | 0 | { |
1230 | 0 | Sequence< sal_Int64 > seqValue; |
1231 | 0 | rCmisProp.Value >>= seqValue; |
1232 | 0 | SvNumberFormatter aNumberFormatter( ::comphelper::getProcessComponentContext(), |
1233 | 0 | Application::GetSettings().GetLanguageTag().getLanguageType() ); |
1234 | 0 | sal_uInt32 nIndex = aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM ); |
1235 | 0 | if ( seqValue.hasElements() ) |
1236 | 0 | { |
1237 | 0 | OUString sValue = aNumberFormatter.GetInputLineString( seqValue[0], nIndex ); |
1238 | 0 | m_xShowSizeFT->set_label( CreateSizeText( sValue.toInt64( ) ) ); |
1239 | 0 | } |
1240 | 0 | } |
1241 | |
|
1242 | 0 | util::DateTime uDT; |
1243 | 0 | OUString emptyDate = ConvertDateTime_Impl( u"", uDT, rLocaleWrapper ); |
1244 | 0 | if ( rCmisProp.Id == "cmis:creationDate" && |
1245 | 0 | (m_xCreateValFt->get_label() == emptyDate || |
1246 | 0 | m_xCreateValFt->get_label().isEmpty())) |
1247 | 0 | { |
1248 | 0 | Sequence< util::DateTime > seqValue; |
1249 | 0 | rCmisProp.Value >>= seqValue; |
1250 | 0 | if ( seqValue.hasElements() ) |
1251 | 0 | { |
1252 | 0 | m_xCreateValFt->set_label( ConvertDateTime_Impl( u"", seqValue[0], rLocaleWrapper ) ); |
1253 | 0 | } |
1254 | 0 | } |
1255 | 0 | if ( rCmisProp.Id == "cmis:lastModificationDate" && |
1256 | 0 | (m_xChangeValFt->get_label() == emptyDate || |
1257 | 0 | m_xChangeValFt->get_label().isEmpty())) |
1258 | 0 | { |
1259 | 0 | Sequence< util::DateTime > seqValue; |
1260 | 0 | rCmisProp.Value >>= seqValue; |
1261 | 0 | if ( seqValue.hasElements() ) |
1262 | 0 | { |
1263 | 0 | m_xChangeValFt->set_label( ConvertDateTime_Impl( u"", seqValue[0], rLocaleWrapper ) ); |
1264 | 0 | } |
1265 | 0 | } |
1266 | 0 | } |
1267 | 0 | } |
1268 | |
|
1269 | 0 | m_xUseUserDataCB->set_active(bUseUserData); |
1270 | 0 | m_xUseUserDataCB->save_state(); |
1271 | 0 | m_xUseUserDataCB->set_sensitive( bEnableUseUserData ); |
1272 | 0 | bHandleDelete = false; |
1273 | 0 | m_xDeleteBtn->set_sensitive( bEnableUseUserData ); |
1274 | 0 | m_xUseThumbnailSaveCB->set_active(bUseThumbnailSave); |
1275 | 0 | m_xUseThumbnailSaveCB->save_state(); |
1276 | |
|
1277 | 0 | SfxObjectShell* pDocSh = SfxObjectShell::Current(); |
1278 | 0 | sal_Int32 nImagePreferredDPI = 0; |
1279 | 0 | if (pDocSh) |
1280 | 0 | { |
1281 | 0 | try |
1282 | 0 | { |
1283 | 0 | uno::Reference< lang::XMultiServiceFactory > xFac( pDocSh->GetModel(), uno::UNO_QUERY ); |
1284 | 0 | if (xFac) |
1285 | 0 | { |
1286 | 0 | uno::Reference< beans::XPropertySet > xProps( xFac->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY ); |
1287 | 0 | if (xProps) |
1288 | 0 | xProps->getPropertyValue(u"ImagePreferredDPI"_ustr) >>= nImagePreferredDPI; |
1289 | 0 | } |
1290 | 0 | } |
1291 | 0 | catch( uno::Exception& ) |
1292 | 0 | { |
1293 | 0 | } |
1294 | 0 | } |
1295 | 0 | if (nImagePreferredDPI > 0) |
1296 | 0 | { |
1297 | 0 | m_xImagePreferredDpiCheckButton->set_state(TRISTATE_TRUE); |
1298 | 0 | m_xImagePreferredDpiComboBox->set_sensitive(true); |
1299 | 0 | m_xImagePreferredDpiComboBox->set_entry_text(OUString::number(nImagePreferredDPI)); |
1300 | 0 | } |
1301 | 0 | else |
1302 | 0 | { |
1303 | 0 | m_xImagePreferredDpiCheckButton->set_state(TRISTATE_FALSE); |
1304 | 0 | m_xImagePreferredDpiComboBox->set_sensitive(false); |
1305 | 0 | m_xImagePreferredDpiComboBox->set_entry_text(u""_ustr); |
1306 | 0 | } |
1307 | |
|
1308 | 0 | } |
1309 | | |
1310 | | SfxDocumentInfoDialog::SfxDocumentInfoDialog(weld::Window* pParent, const SfxItemSet& rItemSet) |
1311 | 0 | : SfxTabDialogController(pParent, u"sfx/ui/documentpropertiesdialog.ui"_ustr, |
1312 | 0 | u"DocumentPropertiesDialog"_ustr, &rItemSet) |
1313 | 0 | { |
1314 | 0 | const SfxDocumentInfoItem& rInfoItem = rItemSet.Get( SID_DOCINFO ); |
1315 | |
|
1316 | | #ifdef DBG_UTIL |
1317 | | const SfxStringItem* pURLItem = rItemSet.GetItem<SfxStringItem>(SID_BASEURL, false); |
1318 | | DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" ); |
1319 | | #endif |
1320 | | |
1321 | | // Determine the Titles |
1322 | 0 | OUString aTitle(m_xDialog->get_title()); |
1323 | 0 | const SfxStringItem* pItem = rItemSet.GetItemIfSet( SID_EXPLORER_PROPS_START, false ); |
1324 | 0 | if ( !pItem ) |
1325 | 0 | { |
1326 | | // File name |
1327 | 0 | const OUString& aFile( rInfoItem.GetValue() ); |
1328 | |
|
1329 | 0 | INetURLObject aURL; |
1330 | 0 | aURL.SetSmartProtocol( INetProtocol::File ); |
1331 | 0 | aURL.SetSmartURL( aFile); |
1332 | 0 | if ( INetProtocol::PrivSoffice != aURL.GetProtocol() ) |
1333 | 0 | { |
1334 | 0 | OUString aLastName( aURL.GetLastName() ); |
1335 | 0 | if ( !aLastName.isEmpty() ) |
1336 | 0 | aTitle = aTitle.replaceFirst("%1", aLastName); |
1337 | 0 | else |
1338 | 0 | aTitle = aTitle.replaceFirst("%1", aFile); |
1339 | 0 | } |
1340 | 0 | else |
1341 | 0 | aTitle = aTitle.replaceFirst("%1", SfxResId( STR_NONAME )); |
1342 | 0 | } |
1343 | 0 | else |
1344 | 0 | { |
1345 | 0 | aTitle = aTitle.replaceFirst("%1", pItem->GetValue()); |
1346 | 0 | } |
1347 | 0 | m_xDialog->set_title(aTitle); |
1348 | | |
1349 | | // Property Pages |
1350 | 0 | AddTabPage(u"general"_ustr, TabResId(RID_TAB_ORGANIZER.aLabel), SfxDocumentPage::Create, |
1351 | 0 | RID_L + RID_TAB_ORGANIZER.sIconName); |
1352 | 0 | AddTabPage(u"description"_ustr, TabResId(RID_TAB_DESCRIPTION.aLabel), SfxDocumentDescPage::Create, |
1353 | 0 | RID_L + RID_TAB_DESCRIPTION.sIconName); |
1354 | |
|
1355 | 0 | AddTabPage(u"customprops"_ustr, TabResId(RID_TAB_CUSTOM.aLabel), |
1356 | 0 | SfxCustomPropertiesPage::Create, RID_L + RID_TAB_CUSTOM.sIconName); |
1357 | |
|
1358 | 0 | if (rInfoItem.isCmisDocument()) |
1359 | 0 | AddTabPage(u"cmisprops"_ustr, TabResId(RID_TAB_CMIS.aLabel), |
1360 | 0 | SfxCmisPropertiesPage::Create, RID_L + RID_TAB_CMIS.sIconName); |
1361 | | // Disable security page for online as not fully asynced yet |
1362 | 0 | if (!comphelper::LibreOfficeKit::isActive()) |
1363 | 0 | AddTabPage(u"security"_ustr, TabResId(RID_TAB_SECURITY.aLabel), SfxSecurityPage::Create, |
1364 | 0 | RID_L + RID_TAB_SECURITY.sIconName); |
1365 | 0 | } |
1366 | | |
1367 | | void SfxDocumentInfoDialog::PageCreated(const OUString& rId, SfxTabPage &rPage) |
1368 | 0 | { |
1369 | 0 | if (rId == "general") |
1370 | 0 | static_cast<SfxDocumentPage&>(rPage).EnableUseUserData(); |
1371 | 0 | } |
1372 | | |
1373 | | void SfxDocumentInfoDialog::AddFontTabPage() |
1374 | 0 | { |
1375 | 0 | AddTabPage(u"font"_ustr, TabResId(RID_TAB_FONT.aLabel), |
1376 | 0 | SfxDocumentFontsPage::Create, RID_L + RID_TAB_FONT.sIconName); |
1377 | 0 | } |
1378 | | |
1379 | | // class CustomPropertiesYesNoButton ------------------------------------- |
1380 | | |
1381 | | CustomPropertiesYesNoButton::CustomPropertiesYesNoButton(std::unique_ptr<weld::Widget> xTopLevel, |
1382 | | std::unique_ptr<weld::RadioButton> xYesButton, |
1383 | | std::unique_ptr<weld::RadioButton> xNoButton) |
1384 | 0 | : m_xTopLevel(std::move(xTopLevel)) |
1385 | 0 | , m_xYesButton(std::move(xYesButton)) |
1386 | 0 | , m_xNoButton(std::move(xNoButton)) |
1387 | 0 | { |
1388 | 0 | CheckNo(); |
1389 | 0 | } |
1390 | | |
1391 | | CustomPropertiesYesNoButton::~CustomPropertiesYesNoButton() |
1392 | 0 | { |
1393 | 0 | } |
1394 | | |
1395 | | |
1396 | | DurationDialog_Impl::DurationDialog_Impl(weld::Widget* pParent, const util::Duration& rDuration) |
1397 | 0 | : GenericDialogController(pParent, u"sfx/ui/editdurationdialog.ui"_ustr, u"EditDurationDialog"_ustr) |
1398 | 0 | , m_xNegativeCB(m_xBuilder->weld_check_button(u"negative"_ustr)) |
1399 | 0 | , m_xYearNF(m_xBuilder->weld_spin_button(u"years"_ustr)) |
1400 | 0 | , m_xMonthNF(m_xBuilder->weld_spin_button(u"months"_ustr)) |
1401 | 0 | , m_xDayNF(m_xBuilder->weld_spin_button(u"days"_ustr)) |
1402 | 0 | , m_xHourNF(m_xBuilder->weld_spin_button(u"hours"_ustr)) |
1403 | 0 | , m_xMinuteNF(m_xBuilder->weld_spin_button(u"minutes"_ustr)) |
1404 | 0 | , m_xSecondNF(m_xBuilder->weld_spin_button(u"seconds"_ustr)) |
1405 | 0 | , m_xMSecondNF(m_xBuilder->weld_spin_button(u"milliseconds"_ustr)) |
1406 | 0 | { |
1407 | 0 | m_xNegativeCB->set_active(rDuration.Negative); |
1408 | 0 | m_xYearNF->set_value(rDuration.Years); |
1409 | 0 | m_xMonthNF->set_value(rDuration.Months); |
1410 | 0 | m_xDayNF->set_value(rDuration.Days); |
1411 | 0 | m_xHourNF->set_value(rDuration.Hours); |
1412 | 0 | m_xMinuteNF->set_value(rDuration.Minutes); |
1413 | 0 | m_xSecondNF->set_value(rDuration.Seconds); |
1414 | 0 | m_xMSecondNF->set_value(rDuration.NanoSeconds); |
1415 | 0 | } |
1416 | | |
1417 | | util::Duration DurationDialog_Impl::GetDuration() const |
1418 | 0 | { |
1419 | 0 | util::Duration aRet; |
1420 | 0 | aRet.Negative = m_xNegativeCB->get_active(); |
1421 | 0 | aRet.Years = m_xYearNF->get_value(); |
1422 | 0 | aRet.Months = m_xMonthNF->get_value(); |
1423 | 0 | aRet.Days = m_xDayNF->get_value(); |
1424 | 0 | aRet.Hours = m_xHourNF->get_value(); |
1425 | 0 | aRet.Minutes = m_xMinuteNF->get_value(); |
1426 | 0 | aRet.Seconds = m_xSecondNF->get_value(); |
1427 | 0 | aRet.NanoSeconds = m_xMSecondNF->get_value(); |
1428 | 0 | return aRet; |
1429 | 0 | } |
1430 | | |
1431 | | CustomPropertiesDurationField::CustomPropertiesDurationField(std::unique_ptr<weld::Entry> xEntry, |
1432 | | std::unique_ptr<weld::Button> xEditButton) |
1433 | 0 | : m_xEntry(std::move(xEntry)) |
1434 | 0 | , m_xEditButton(std::move(xEditButton)) |
1435 | 0 | { |
1436 | 0 | m_xEditButton->connect_clicked(LINK(this, CustomPropertiesDurationField, ClickHdl)); |
1437 | 0 | SetDuration( util::Duration(false, 0, 0, 0, 0, 0, 0, 0) ); |
1438 | 0 | } |
1439 | | |
1440 | | void CustomPropertiesDurationField::set_visible(bool bVisible) |
1441 | 0 | { |
1442 | 0 | m_xEntry->set_visible(bVisible); |
1443 | 0 | m_xEditButton->set_visible(bVisible); |
1444 | 0 | } |
1445 | | |
1446 | | void CustomPropertiesDurationField::SetDuration( const util::Duration& rDuration ) |
1447 | 0 | { |
1448 | 0 | m_aDuration = rDuration; |
1449 | 0 | OUString sText = (rDuration.Negative ? OUString('-') : OUString('+')) + |
1450 | 0 | SfxResId(SFX_ST_DURATION_FORMAT); |
1451 | 0 | sText = sText.replaceFirst( "%1", OUString::number( rDuration.Years ) ); |
1452 | 0 | sText = sText.replaceFirst( "%2", OUString::number( rDuration.Months ) ); |
1453 | 0 | sText = sText.replaceFirst( "%3", OUString::number( rDuration.Days ) ); |
1454 | 0 | sText = sText.replaceFirst( "%4", OUString::number( rDuration.Hours ) ); |
1455 | 0 | sText = sText.replaceFirst( "%5", OUString::number( rDuration.Minutes) ); |
1456 | 0 | sText = sText.replaceFirst( "%6", OUString::number( rDuration.Seconds) ); |
1457 | 0 | m_xEntry->set_text(sText); |
1458 | 0 | } |
1459 | | |
1460 | | IMPL_LINK(CustomPropertiesDurationField, ClickHdl, weld::Button&, rButton, void) |
1461 | 0 | { |
1462 | 0 | m_xDurationDialog = std::make_shared<DurationDialog_Impl>(&rButton, GetDuration()); |
1463 | 0 | weld::DialogController::runAsync(m_xDurationDialog, [&](sal_Int32 response) |
1464 | 0 | { |
1465 | 0 | if (response == RET_OK) |
1466 | 0 | { |
1467 | 0 | SetDuration(m_xDurationDialog->GetDuration()); |
1468 | 0 | } |
1469 | 0 | }); |
1470 | 0 | } |
1471 | | |
1472 | | CustomPropertiesDurationField::~CustomPropertiesDurationField() |
1473 | 0 | { |
1474 | 0 | if (m_xDurationDialog) |
1475 | 0 | m_xDurationDialog->response(RET_CANCEL); |
1476 | 0 | } |
1477 | | |
1478 | | namespace |
1479 | | { |
1480 | | void fillNameBox(weld::ComboBox& rNameBox) |
1481 | 0 | { |
1482 | 0 | for (const auto& rResId : SFX_CB_PROPERTY_STRINGARRAY) |
1483 | 0 | rNameBox.append_text(SfxResId(rResId)); |
1484 | 0 | Size aSize(rNameBox.get_preferred_size()); |
1485 | 0 | rNameBox.set_size_request(aSize.Width(), aSize.Height()); |
1486 | 0 | } |
1487 | | |
1488 | | void fillTypeBox(weld::ComboBox& rTypeBox) |
1489 | 0 | { |
1490 | 0 | for (const auto& [rResId, rProperty] : SFX_LB_PROPERTY_STRINGARRAY) |
1491 | 0 | { |
1492 | 0 | OUString sId(OUString::number(rProperty)); |
1493 | 0 | rTypeBox.append(sId, SfxResId(rResId)); |
1494 | 0 | } |
1495 | 0 | rTypeBox.set_active(0); |
1496 | 0 | Size aSize(rTypeBox.get_preferred_size()); |
1497 | 0 | rTypeBox.set_size_request(aSize.Width(), aSize.Height()); |
1498 | 0 | } |
1499 | | } |
1500 | | |
1501 | | // struct CustomPropertyLine --------------------------------------------- |
1502 | | CustomPropertyLine::CustomPropertyLine(CustomPropertiesWindow* pParent, weld::Widget* pContainer) |
1503 | 0 | : m_pParent(pParent) |
1504 | 0 | , m_xBuilder(Application::CreateBuilder(pContainer, u"sfx/ui/linefragment.ui"_ustr)) |
1505 | 0 | , m_xLine(m_xBuilder->weld_container(u"lineentry"_ustr)) |
1506 | 0 | , m_xNameBox(m_xBuilder->weld_combo_box(u"namebox"_ustr)) |
1507 | 0 | , m_xTypeBox(m_xBuilder->weld_combo_box(u"typebox"_ustr)) |
1508 | 0 | , m_xValueEdit(m_xBuilder->weld_entry(u"valueedit"_ustr)) |
1509 | 0 | , m_xDateTimeBox(m_xBuilder->weld_widget(u"datetimebox"_ustr)) |
1510 | 0 | , m_xDateField(new CustomPropertiesDateField(new SvtCalendarBox(m_xBuilder->weld_menu_button(u"date"_ustr)))) |
1511 | 0 | , m_xTimeField(new CustomPropertiesTimeField(m_xBuilder->weld_formatted_spin_button(u"time"_ustr))) |
1512 | 0 | , m_xDurationBox(m_xBuilder->weld_widget(u"durationbox"_ustr)) |
1513 | 0 | , m_xDurationField(new CustomPropertiesDurationField(m_xBuilder->weld_entry(u"duration"_ustr), |
1514 | 0 | m_xBuilder->weld_button(u"durationbutton"_ustr))) |
1515 | 0 | , m_xYesNoButton(new CustomPropertiesYesNoButton(m_xBuilder->weld_widget(u"yesno"_ustr), |
1516 | 0 | m_xBuilder->weld_radio_button(u"yes"_ustr), |
1517 | 0 | m_xBuilder->weld_radio_button(u"no"_ustr))) |
1518 | 0 | , m_xRemoveButton(m_xBuilder->weld_button(u"remove"_ustr)) |
1519 | 0 | , m_bTypeLostFocus( false ) |
1520 | 0 | { |
1521 | 0 | fillNameBox(*m_xNameBox); |
1522 | 0 | fillTypeBox(*m_xTypeBox); |
1523 | |
|
1524 | 0 | m_xTypeBox->connect_changed(LINK(this, CustomPropertyLine, TypeHdl)); |
1525 | 0 | m_xRemoveButton->connect_clicked(LINK(this, CustomPropertyLine, RemoveHdl)); |
1526 | 0 | m_xValueEdit->connect_focus_out(LINK(this, CustomPropertyLine, EditLoseFocusHdl)); |
1527 | | //add lose focus handlers of date/time fields |
1528 | 0 | m_xTypeBox->connect_focus_out(LINK(this, CustomPropertyLine, BoxLoseFocusHdl)); |
1529 | 0 | } |
1530 | | |
1531 | | void CustomPropertyLine::Clear() |
1532 | 0 | { |
1533 | 0 | m_xNameBox->set_active(-1); |
1534 | 0 | m_xValueEdit->set_text(OUString()); |
1535 | |
|
1536 | 0 | } |
1537 | | |
1538 | | void CustomPropertyLine::Hide() |
1539 | 0 | { |
1540 | 0 | m_xLine->hide(); |
1541 | 0 | } |
1542 | | |
1543 | | CustomPropertiesWindow::CustomPropertiesWindow(weld::Container& rParent, weld::Label& rHeaderAccName, |
1544 | | weld::Label& rHeaderAccType, weld::Label& rHeaderAccValue) |
1545 | 0 | : m_nHeight(0) |
1546 | 0 | , m_nLineHeight(0) |
1547 | 0 | , m_nScrollPos(0) |
1548 | 0 | , m_pCurrentLine(nullptr) |
1549 | 0 | , m_aNumberFormatter(::comphelper::getProcessComponentContext(), |
1550 | 0 | Application::GetSettings().GetLanguageTag().getLanguageType()) |
1551 | 0 | , m_aEditLoseFocusIdle("sfx2 CustomPropertiesWindow loseFocusIdle") |
1552 | 0 | , m_aBoxLoseFocusIdle("sfx2 CustomPropertiesWindow m_aBoxLoseFocusIdle") |
1553 | 0 | , m_rBody(rParent) |
1554 | 0 | , m_rHeaderAccName(rHeaderAccName) |
1555 | 0 | , m_rHeaderAccType(rHeaderAccType) |
1556 | 0 | , m_rHeaderAccValue(rHeaderAccValue) |
1557 | 0 | { |
1558 | 0 | m_aEditLoseFocusIdle.SetPriority( TaskPriority::LOWEST ); |
1559 | 0 | m_aEditLoseFocusIdle.SetInvokeHandler( LINK( this, CustomPropertiesWindow, EditTimeoutHdl ) ); |
1560 | 0 | m_aBoxLoseFocusIdle.SetPriority( TaskPriority::LOWEST ); |
1561 | 0 | m_aBoxLoseFocusIdle.SetInvokeHandler( LINK( this, CustomPropertiesWindow, BoxTimeoutHdl ) ); |
1562 | 0 | } |
1563 | | |
1564 | | CustomPropertiesWindow::~CustomPropertiesWindow() |
1565 | 0 | { |
1566 | 0 | m_aEditLoseFocusIdle.Stop(); |
1567 | 0 | m_aBoxLoseFocusIdle.Stop(); |
1568 | |
|
1569 | 0 | m_pCurrentLine = nullptr; |
1570 | 0 | } |
1571 | | |
1572 | | void CustomPropertyLine::DoTypeHdl(const weld::ComboBox& rBox) |
1573 | 0 | { |
1574 | 0 | auto nType = rBox.get_active_id().toInt32(); |
1575 | 0 | m_xValueEdit->set_visible( (Custom_Type_Text == nType) || (Custom_Type_Number == nType) ); |
1576 | 0 | m_xDateTimeBox->set_visible( (Custom_Type_Date == nType) || (Custom_Type_Datetime == nType) ); |
1577 | 0 | m_xDateField->set_visible( (Custom_Type_Date == nType) || (Custom_Type_Datetime == nType) ); |
1578 | 0 | m_xTimeField->set_visible( Custom_Type_Datetime == nType ); |
1579 | 0 | m_xDurationBox->set_visible( Custom_Type_Duration == nType ); |
1580 | 0 | m_xDurationField->set_visible( Custom_Type_Duration == nType ); |
1581 | 0 | m_xYesNoButton->set_visible( Custom_Type_Boolean == nType ); |
1582 | 0 | } |
1583 | | |
1584 | | IMPL_LINK(CustomPropertyLine, TypeHdl, weld::ComboBox&, rBox, void) |
1585 | 0 | { |
1586 | 0 | DoTypeHdl(rBox); |
1587 | 0 | } |
1588 | | |
1589 | | void CustomPropertiesWindow::Remove(const CustomPropertyLine* pLine) |
1590 | 0 | { |
1591 | 0 | StoreCustomProperties(); |
1592 | |
|
1593 | 0 | auto pFound = std::find_if( m_aCustomPropertiesLines.begin(), m_aCustomPropertiesLines.end(), |
1594 | 0 | [&] (const std::unique_ptr<CustomPropertyLine>& p) { return p.get() == pLine; }); |
1595 | 0 | if ( pFound != m_aCustomPropertiesLines.end() ) |
1596 | 0 | { |
1597 | 0 | sal_uInt32 nLineNumber = pFound - m_aCustomPropertiesLines.begin(); |
1598 | 0 | sal_uInt32 nDataModelIndex = GetCurrentDataModelPosition() + nLineNumber; |
1599 | 0 | m_aCustomProperties.erase(m_aCustomProperties.begin() + nDataModelIndex); |
1600 | |
|
1601 | 0 | ReloadLinesContent(); |
1602 | 0 | } |
1603 | |
|
1604 | 0 | m_aRemovedHdl.Call(nullptr); |
1605 | 0 | } |
1606 | | |
1607 | | IMPL_LINK_NOARG(CustomPropertyLine, RemoveHdl, weld::Button&, void) |
1608 | 0 | { |
1609 | 0 | m_pParent->Remove(this); |
1610 | 0 | } |
1611 | | |
1612 | | void CustomPropertiesWindow::EditLoseFocus(CustomPropertyLine* pLine) |
1613 | 0 | { |
1614 | 0 | m_pCurrentLine = pLine; |
1615 | 0 | m_aEditLoseFocusIdle.Start(); |
1616 | 0 | } |
1617 | | |
1618 | | IMPL_LINK_NOARG(CustomPropertyLine, EditLoseFocusHdl, weld::Widget&, void) |
1619 | 0 | { |
1620 | 0 | if (!m_bTypeLostFocus) |
1621 | 0 | m_pParent->EditLoseFocus(this); |
1622 | 0 | else |
1623 | 0 | m_bTypeLostFocus = false; |
1624 | 0 | } |
1625 | | |
1626 | | void CustomPropertiesWindow::BoxLoseFocus(CustomPropertyLine* pLine) |
1627 | 0 | { |
1628 | 0 | m_pCurrentLine = pLine; |
1629 | 0 | m_aBoxLoseFocusIdle.Start(); |
1630 | 0 | } |
1631 | | |
1632 | | IMPL_LINK_NOARG(CustomPropertyLine, BoxLoseFocusHdl, weld::Widget&, void) |
1633 | 0 | { |
1634 | 0 | m_pParent->BoxLoseFocus(this); |
1635 | 0 | } |
1636 | | |
1637 | | IMPL_LINK_NOARG(CustomPropertiesWindow, EditTimeoutHdl, Timer *, void) |
1638 | 0 | { |
1639 | 0 | ValidateLine( m_pCurrentLine, false ); |
1640 | 0 | } |
1641 | | |
1642 | | IMPL_LINK_NOARG(CustomPropertiesWindow, BoxTimeoutHdl, Timer *, void) |
1643 | 0 | { |
1644 | 0 | ValidateLine( m_pCurrentLine, true ); |
1645 | 0 | } |
1646 | | |
1647 | | bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine* pLine ) const |
1648 | 0 | { |
1649 | 0 | bool bIsValid = true; |
1650 | 0 | pLine->m_bTypeLostFocus = false; |
1651 | 0 | auto nType = pLine->m_xTypeBox->get_active_id().toInt32(); |
1652 | 0 | OUString sValue = pLine->m_xValueEdit->get_text(); |
1653 | 0 | if ( sValue.isEmpty() ) |
1654 | 0 | return true; |
1655 | | |
1656 | 0 | sal_uInt32 nIndex = NUMBERFORMAT_ENTRY_NOT_FOUND; |
1657 | 0 | if ( Custom_Type_Number == nType ) |
1658 | | // tdf#116214 Scientific format allows to use also standard numbers |
1659 | 0 | nIndex = const_cast< SvNumberFormatter& >( |
1660 | 0 | m_aNumberFormatter ).GetFormatIndex( NF_SCIENTIFIC_000E00 ); |
1661 | 0 | else if ( Custom_Type_Date == nType ) |
1662 | 0 | nIndex = const_cast< SvNumberFormatter& >( |
1663 | 0 | m_aNumberFormatter).GetFormatIndex( NF_DATE_SYS_DDMMYYYY ); |
1664 | |
|
1665 | 0 | if ( nIndex != NUMBERFORMAT_ENTRY_NOT_FOUND ) |
1666 | 0 | { |
1667 | 0 | sal_uInt32 nTemp = nIndex; |
1668 | 0 | double fDummy = 0.0; |
1669 | 0 | bIsValid = const_cast< SvNumberFormatter& >( |
1670 | 0 | m_aNumberFormatter ).IsNumberFormat( sValue, nIndex, fDummy ); |
1671 | 0 | if ( bIsValid && nTemp != nIndex ) |
1672 | | // sValue is a number but the format doesn't match the index |
1673 | 0 | bIsValid = false; |
1674 | 0 | } |
1675 | |
|
1676 | 0 | return bIsValid; |
1677 | 0 | } |
1678 | | |
1679 | | void CustomPropertiesWindow::ValidateLine( CustomPropertyLine* pLine, bool bIsFromTypeBox ) |
1680 | 0 | { |
1681 | 0 | if (pLine && !IsLineValid(pLine)) |
1682 | 0 | { |
1683 | 0 | if ( bIsFromTypeBox ) // LoseFocus of TypeBox |
1684 | 0 | pLine->m_bTypeLostFocus = true; |
1685 | 0 | std::unique_ptr<weld::MessageDialog> xMessageBox(Application::CreateMessageDialog(&m_rBody, |
1686 | 0 | VclMessageType::Question, VclButtonsType::OkCancel, SfxResId(STR_SFX_QUERY_WRONG_TYPE))); |
1687 | 0 | if (xMessageBox->run() == RET_OK) |
1688 | 0 | pLine->m_xTypeBox->set_active_id(OUString::number(Custom_Type_Text)); |
1689 | 0 | else |
1690 | 0 | pLine->m_xValueEdit->grab_focus(); |
1691 | 0 | } |
1692 | 0 | } |
1693 | | |
1694 | | void CustomPropertiesWindow::SetVisibleLineCount(sal_uInt32 nCount) |
1695 | 0 | { |
1696 | 0 | while (GetExistingLineCount() < nCount) |
1697 | 0 | { |
1698 | 0 | CreateNewLine(); |
1699 | 0 | } |
1700 | 0 | } |
1701 | | |
1702 | | void CustomPropertiesWindow::AddLine(const OUString& sName, Any const & rAny) |
1703 | 0 | { |
1704 | 0 | m_aCustomProperties.push_back(std::unique_ptr<CustomProperty>(new CustomProperty(sName, rAny))); |
1705 | 0 | ReloadLinesContent(); |
1706 | 0 | } |
1707 | | |
1708 | | void CustomPropertiesWindow::CreateNewLine() |
1709 | 0 | { |
1710 | 0 | CustomPropertyLine* pNewLine = new CustomPropertyLine(this, &m_rBody); |
1711 | 0 | pNewLine->m_xNameBox->set_accessible_name(m_rHeaderAccName.get_label()); |
1712 | 0 | pNewLine->m_xTypeBox->set_accessible_name(m_rHeaderAccType.get_label()); |
1713 | 0 | pNewLine->m_xValueEdit->set_accessible_name(m_rHeaderAccValue.get_label()); |
1714 | |
|
1715 | 0 | m_aCustomPropertiesLines.emplace_back( pNewLine ); |
1716 | | |
1717 | | // for ui-testing. Distinguish the elements in the lines |
1718 | 0 | sal_uInt16 nSize = m_aCustomPropertiesLines.size(); |
1719 | 0 | pNewLine->m_xNameBox->set_buildable_name(pNewLine->m_xNameBox->get_buildable_name() |
1720 | 0 | + OUString::number(nSize)); |
1721 | 0 | pNewLine->m_xTypeBox->set_buildable_name(pNewLine->m_xTypeBox->get_buildable_name() |
1722 | 0 | + OUString::number(nSize)); |
1723 | 0 | pNewLine->m_xValueEdit->set_buildable_name(pNewLine->m_xValueEdit->get_buildable_name() |
1724 | 0 | + OUString::number(nSize)); |
1725 | 0 | pNewLine->m_xRemoveButton->set_buildable_name(pNewLine->m_xRemoveButton->get_buildable_name() |
1726 | 0 | + OUString::number(nSize)); |
1727 | |
|
1728 | 0 | pNewLine->DoTypeHdl(*pNewLine->m_xTypeBox); |
1729 | 0 | } |
1730 | | |
1731 | | bool CustomPropertiesWindow::AreAllLinesValid() const |
1732 | 0 | { |
1733 | 0 | bool bRet = true; |
1734 | 0 | for ( std::unique_ptr<CustomPropertyLine> const & pLine : m_aCustomPropertiesLines ) |
1735 | 0 | { |
1736 | 0 | if ( !IsLineValid( pLine.get() ) ) |
1737 | 0 | { |
1738 | 0 | bRet = false; |
1739 | 0 | break; |
1740 | 0 | } |
1741 | 0 | } |
1742 | |
|
1743 | 0 | return bRet; |
1744 | 0 | } |
1745 | | |
1746 | | void CustomPropertiesWindow::ClearAllLines() |
1747 | 0 | { |
1748 | 0 | for (auto& pLine : m_aCustomPropertiesLines) |
1749 | 0 | { |
1750 | 0 | pLine->Clear(); |
1751 | 0 | } |
1752 | 0 | m_pCurrentLine = nullptr; |
1753 | 0 | m_aCustomProperties.clear(); |
1754 | 0 | m_nScrollPos = 0; |
1755 | 0 | } |
1756 | | |
1757 | | void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos ) |
1758 | 0 | { |
1759 | 0 | StoreCustomProperties(); |
1760 | 0 | m_nScrollPos += nNewPos; |
1761 | 0 | ReloadLinesContent(); |
1762 | 0 | } |
1763 | | |
1764 | | Sequence< beans::PropertyValue > CustomPropertiesWindow::GetCustomProperties() |
1765 | 0 | { |
1766 | 0 | StoreCustomProperties(); |
1767 | |
|
1768 | 0 | Sequence< beans::PropertyValue > aPropertiesSeq(GetTotalLineCount()); |
1769 | 0 | std::transform( |
1770 | 0 | m_aCustomProperties.begin(), m_aCustomProperties.end(), aPropertiesSeq.getArray(), |
1771 | 0 | [](const auto& el) { return comphelper::makePropertyValue(el->m_sName, el->m_aValue); }); |
1772 | |
|
1773 | 0 | return aPropertiesSeq; |
1774 | 0 | } |
1775 | | |
1776 | | CustomPropertiesTimeField::CustomPropertiesTimeField(std::unique_ptr<weld::FormattedSpinButton> xTimeField) |
1777 | 0 | : m_xTimeField(std::move(xTimeField)) |
1778 | 0 | , m_xFormatter(new weld::TimeFormatter(*m_xTimeField)) |
1779 | 0 | , m_isUTC(false) |
1780 | 0 | { |
1781 | 0 | m_xFormatter->SetExtFormat(ExtTimeFieldFormat::LongDuration); |
1782 | 0 | m_xFormatter->EnableEmptyField(false); |
1783 | 0 | } |
1784 | | |
1785 | | tools::Time CustomPropertiesTimeField::get_value() const |
1786 | 0 | { |
1787 | 0 | return m_xFormatter->GetTime(); |
1788 | 0 | } |
1789 | | |
1790 | | void CustomPropertiesTimeField::set_value(const tools::Time& rTime) |
1791 | 0 | { |
1792 | 0 | m_xFormatter->SetTime(rTime); |
1793 | 0 | } |
1794 | | |
1795 | | CustomPropertiesTimeField::~CustomPropertiesTimeField() |
1796 | 0 | { |
1797 | 0 | } |
1798 | | |
1799 | | CustomPropertiesDateField::CustomPropertiesDateField(SvtCalendarBox* pDateField) |
1800 | 0 | : m_xDateField(pDateField) |
1801 | 0 | { |
1802 | 0 | DateTime aDateTime(DateTime::SYSTEM); |
1803 | 0 | m_xDateField->set_date(aDateTime); |
1804 | 0 | } |
1805 | | |
1806 | | void CustomPropertiesDateField::set_visible(bool bVisible) |
1807 | 0 | { |
1808 | 0 | m_xDateField->set_visible(bVisible); |
1809 | 0 | } |
1810 | | |
1811 | | Date CustomPropertiesDateField::get_date() const |
1812 | 0 | { |
1813 | 0 | return m_xDateField->get_date(); |
1814 | 0 | } |
1815 | | |
1816 | | void CustomPropertiesDateField::set_date(const Date& rDate) |
1817 | 0 | { |
1818 | 0 | m_xDateField->set_date(rDate); |
1819 | 0 | } |
1820 | | |
1821 | | CustomPropertiesDateField::~CustomPropertiesDateField() |
1822 | 0 | { |
1823 | 0 | } |
1824 | | |
1825 | | void CustomPropertiesWindow::StoreCustomProperties() |
1826 | 0 | { |
1827 | 0 | sal_uInt32 nDataModelPos = GetCurrentDataModelPosition(); |
1828 | |
|
1829 | 0 | for (sal_uInt32 i = 0; nDataModelPos + i < GetTotalLineCount() && i < GetExistingLineCount(); i++) |
1830 | 0 | { |
1831 | 0 | CustomPropertyLine* pLine = m_aCustomPropertiesLines[i].get(); |
1832 | |
|
1833 | 0 | OUString sPropertyName = pLine->m_xNameBox->get_active_text(); |
1834 | 0 | if (!sPropertyName.isEmpty()) |
1835 | 0 | { |
1836 | 0 | m_aCustomProperties[nDataModelPos + i]->m_sName = sPropertyName; |
1837 | 0 | auto nType = pLine->m_xTypeBox->get_active_id().toInt32(); |
1838 | 0 | if (Custom_Type_Number == nType) |
1839 | 0 | { |
1840 | 0 | double nValue = 0; |
1841 | 0 | sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex(NF_NUMBER_SYSTEM); |
1842 | 0 | bool bIsNum = m_aNumberFormatter. |
1843 | 0 | IsNumberFormat(pLine->m_xValueEdit->get_text(), nIndex, nValue); |
1844 | 0 | if (bIsNum) |
1845 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= nValue; |
1846 | 0 | } |
1847 | 0 | else if (Custom_Type_Boolean == nType) |
1848 | 0 | { |
1849 | 0 | bool bValue = pLine->m_xYesNoButton->IsYesChecked(); |
1850 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= bValue; |
1851 | 0 | } |
1852 | 0 | else if (Custom_Type_Datetime == nType) |
1853 | 0 | { |
1854 | 0 | Date aTmpDate = pLine->m_xDateField->get_date(); |
1855 | 0 | tools::Time aTmpTime = pLine->m_xTimeField->get_value(); |
1856 | 0 | util::DateTime const aDateTime(aTmpTime.GetNanoSec(), |
1857 | 0 | aTmpTime.GetSec(), aTmpTime.GetMin(), aTmpTime.GetHour(), |
1858 | 0 | aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear(), |
1859 | 0 | pLine->m_xTimeField->m_isUTC); |
1860 | 0 | if (pLine->m_xDateField->m_TZ) |
1861 | 0 | { |
1862 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= util::DateTimeWithTimezone( |
1863 | 0 | aDateTime, *pLine->m_xDateField->m_TZ); |
1864 | 0 | } |
1865 | 0 | else |
1866 | 0 | { |
1867 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= aDateTime; |
1868 | 0 | } |
1869 | 0 | } |
1870 | 0 | else if (Custom_Type_Date == nType) |
1871 | 0 | { |
1872 | 0 | Date aTmpDate = pLine->m_xDateField->get_date(); |
1873 | 0 | util::Date const aDate(aTmpDate.GetDay(), aTmpDate.GetMonth(), |
1874 | 0 | aTmpDate.GetYear()); |
1875 | 0 | if (pLine->m_xDateField->m_TZ) |
1876 | 0 | { |
1877 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= util::DateWithTimezone( |
1878 | 0 | aDate, *pLine->m_xDateField->m_TZ); |
1879 | 0 | } |
1880 | 0 | else |
1881 | 0 | { |
1882 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= aDate; |
1883 | 0 | } |
1884 | 0 | } |
1885 | 0 | else if (Custom_Type_Duration == nType) |
1886 | 0 | { |
1887 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= pLine->m_xDurationField->GetDuration(); |
1888 | 0 | } |
1889 | 0 | else |
1890 | 0 | { |
1891 | 0 | OUString sValue(pLine->m_xValueEdit->get_text()); |
1892 | 0 | m_aCustomProperties[nDataModelPos + i]->m_aValue <<= sValue; |
1893 | 0 | } |
1894 | 0 | } |
1895 | 0 | } |
1896 | 0 | } |
1897 | | |
1898 | | void CustomPropertiesWindow::SetCustomProperties(std::vector< std::unique_ptr<CustomProperty> >&& rProperties) |
1899 | 0 | { |
1900 | 0 | m_aCustomProperties = std::move(rProperties); |
1901 | 0 | ReloadLinesContent(); |
1902 | 0 | } |
1903 | | |
1904 | | void CustomPropertiesWindow::ReloadLinesContent() |
1905 | 0 | { |
1906 | 0 | double nTmpValue = 0; |
1907 | 0 | bool bTmpValue = false; |
1908 | 0 | OUString sTmpValue; |
1909 | 0 | util::DateTime aTmpDateTime; |
1910 | 0 | util::Date aTmpDate; |
1911 | 0 | util::DateTimeWithTimezone aTmpDateTimeTZ; |
1912 | 0 | util::DateWithTimezone aTmpDateTZ; |
1913 | 0 | util::Duration aTmpDuration; |
1914 | 0 | SvtSysLocale aSysLocale; |
1915 | 0 | const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData(); |
1916 | 0 | CustomProperties nType = Custom_Type_Unknown; |
1917 | 0 | OUString sValue; |
1918 | |
|
1919 | 0 | sal_uInt32 nDataModelPos = GetCurrentDataModelPosition(); |
1920 | 0 | sal_uInt32 i = 0; |
1921 | |
|
1922 | 0 | for (; nDataModelPos + i < GetTotalLineCount() && i < GetExistingLineCount(); i++) |
1923 | 0 | { |
1924 | 0 | const OUString& rName = m_aCustomProperties[nDataModelPos + i]->m_sName; |
1925 | 0 | const css::uno::Any& rAny = m_aCustomProperties[nDataModelPos + i]->m_aValue; |
1926 | |
|
1927 | 0 | CustomPropertyLine* pLine = m_aCustomPropertiesLines[i].get(); |
1928 | 0 | pLine->Clear(); |
1929 | |
|
1930 | 0 | pLine->m_xNameBox->set_entry_text(rName); |
1931 | 0 | pLine->m_xLine->show(); |
1932 | |
|
1933 | 0 | if (!rAny.hasValue()) |
1934 | 0 | { |
1935 | 0 | pLine->m_xValueEdit->set_text(OUString()); |
1936 | 0 | } |
1937 | 0 | else if (rAny >>= nTmpValue) |
1938 | 0 | { |
1939 | 0 | sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex(NF_NUMBER_SYSTEM); |
1940 | 0 | sValue = m_aNumberFormatter.GetInputLineString(nTmpValue, nIndex); |
1941 | 0 | pLine->m_xValueEdit->set_text(sValue); |
1942 | 0 | nType = Custom_Type_Number; |
1943 | 0 | } |
1944 | 0 | else if (rAny >>= bTmpValue) |
1945 | 0 | { |
1946 | 0 | sValue = (bTmpValue ? rLocaleWrapper.getTrueWord() : rLocaleWrapper.getFalseWord()); |
1947 | 0 | nType = Custom_Type_Boolean; |
1948 | 0 | } |
1949 | 0 | else if (rAny >>= sTmpValue) |
1950 | 0 | { |
1951 | 0 | pLine->m_xValueEdit->set_text(sTmpValue); |
1952 | 0 | nType = Custom_Type_Text; |
1953 | 0 | } |
1954 | 0 | else if (rAny >>= aTmpDate) |
1955 | 0 | { |
1956 | 0 | pLine->m_xDateField->set_date(Date(aTmpDate)); |
1957 | 0 | nType = Custom_Type_Date; |
1958 | 0 | } |
1959 | 0 | else if (rAny >>= aTmpDateTime) |
1960 | 0 | { |
1961 | 0 | pLine->m_xDateField->set_date(Date(aTmpDateTime)); |
1962 | 0 | pLine->m_xTimeField->set_value(tools::Time(aTmpDateTime)); |
1963 | 0 | pLine->m_xTimeField->m_isUTC = aTmpDateTime.IsUTC; |
1964 | 0 | nType = Custom_Type_Datetime; |
1965 | 0 | } |
1966 | 0 | else if (rAny >>= aTmpDateTZ) |
1967 | 0 | { |
1968 | 0 | pLine->m_xDateField->set_date(Date(aTmpDateTZ.DateInTZ.Day, |
1969 | 0 | aTmpDateTZ.DateInTZ.Month, aTmpDateTZ.DateInTZ.Year)); |
1970 | 0 | pLine->m_xDateField->m_TZ = aTmpDateTZ.Timezone; |
1971 | 0 | nType = Custom_Type_Date; |
1972 | 0 | } |
1973 | | |
1974 | 0 | else if (rAny >>= aTmpDateTimeTZ) |
1975 | 0 | { |
1976 | 0 | util::DateTime const& rDT(aTmpDateTimeTZ.DateTimeInTZ); |
1977 | 0 | pLine->m_xDateField->set_date(Date(rDT)); |
1978 | 0 | pLine->m_xTimeField->set_value(tools::Time(rDT)); |
1979 | 0 | pLine->m_xTimeField->m_isUTC = rDT.IsUTC; |
1980 | 0 | pLine->m_xDateField->m_TZ = aTmpDateTimeTZ.Timezone; |
1981 | 0 | nType = Custom_Type_Datetime; |
1982 | 0 | } |
1983 | 0 | else if (rAny >>= aTmpDuration) |
1984 | 0 | { |
1985 | 0 | nType = Custom_Type_Duration; |
1986 | 0 | pLine->m_xDurationField->SetDuration(aTmpDuration); |
1987 | 0 | } |
1988 | |
|
1989 | 0 | if (Custom_Type_Boolean == nType) |
1990 | 0 | { |
1991 | 0 | if (bTmpValue) |
1992 | 0 | pLine->m_xYesNoButton->CheckYes(); |
1993 | 0 | else |
1994 | 0 | pLine->m_xYesNoButton->CheckNo(); |
1995 | 0 | } |
1996 | 0 | pLine->m_xTypeBox->set_active_id(OUString::number(nType)); |
1997 | |
|
1998 | 0 | pLine->DoTypeHdl(*pLine->m_xTypeBox); |
1999 | 0 | } |
2000 | | |
2001 | | // tdf#132667 - grab focus on the last inserted property |
2002 | 0 | if (i > 0 && m_aCustomProperties[nDataModelPos + i - 1]->m_sName.isEmpty()) |
2003 | 0 | { |
2004 | 0 | CustomPropertyLine* pLine = m_aCustomPropertiesLines[i - 1].get(); |
2005 | 0 | pLine->m_xNameBox->grab_focus(); |
2006 | 0 | } |
2007 | |
|
2008 | 0 | while (nDataModelPos + i >= GetTotalLineCount() && i < GetExistingLineCount()) |
2009 | 0 | { |
2010 | 0 | CustomPropertyLine* pLine = m_aCustomPropertiesLines[i].get(); |
2011 | 0 | pLine->Hide(); |
2012 | 0 | i++; |
2013 | 0 | } |
2014 | 0 | } |
2015 | | |
2016 | | CustomPropertiesControl::CustomPropertiesControl() |
2017 | 0 | : m_nThumbPos(0) |
2018 | 0 | { |
2019 | 0 | } |
2020 | | |
2021 | | void CustomPropertiesControl::Init(weld::Builder& rBuilder) |
2022 | 0 | { |
2023 | 0 | m_xBox = rBuilder.weld_widget(u"box"_ustr); |
2024 | 0 | m_xBody = rBuilder.weld_container(u"properties"_ustr); |
2025 | |
|
2026 | 0 | m_xName = rBuilder.weld_label(u"name"_ustr); |
2027 | 0 | m_xType = rBuilder.weld_label(u"type"_ustr); |
2028 | 0 | m_xValue = rBuilder.weld_label(u"value"_ustr); |
2029 | 0 | m_xVertScroll = rBuilder.weld_scrolled_window(u"scroll"_ustr, true); |
2030 | 0 | m_xPropertiesWin.reset(new CustomPropertiesWindow(*m_xBody, *m_xName, *m_xType, *m_xValue)); |
2031 | |
|
2032 | 0 | m_xBox->set_stack_background(); |
2033 | 0 | m_xVertScroll->show(); |
2034 | |
|
2035 | 0 | std::unique_ptr<CustomPropertyLine> xNewLine(new CustomPropertyLine(m_xPropertiesWin.get(), m_xBody.get())); |
2036 | 0 | Size aLineSize(xNewLine->m_xLine->get_preferred_size()); |
2037 | 0 | m_xPropertiesWin->SetLineHeight(aLineSize.Height() + 6); |
2038 | 0 | m_xBody->set_size_request(aLineSize.Width() + 6, -1); |
2039 | 0 | auto nHeight = aLineSize.Height() * 8; |
2040 | 0 | m_xVertScroll->set_size_request(-1, nHeight + 6); |
2041 | |
|
2042 | 0 | m_xPropertiesWin->SetHeight(nHeight); |
2043 | 0 | m_xVertScroll->connect_size_allocate(LINK(this, CustomPropertiesControl, ResizeHdl)); |
2044 | |
|
2045 | 0 | m_xName->set_size_request(xNewLine->m_xNameBox->get_preferred_size().Width(), -1); |
2046 | 0 | m_xType->set_size_request(xNewLine->m_xTypeBox->get_preferred_size().Width(), -1); |
2047 | 0 | m_xValue->set_size_request(xNewLine->m_xValueEdit->get_preferred_size().Width(), -1); |
2048 | |
|
2049 | 0 | m_xBody->move(xNewLine->m_xLine.get(), nullptr); |
2050 | 0 | xNewLine.reset(); |
2051 | |
|
2052 | 0 | m_xPropertiesWin->SetRemovedHdl( LINK( this, CustomPropertiesControl, RemovedHdl ) ); |
2053 | |
|
2054 | 0 | m_xVertScroll->vadjustment_set_upper(0); |
2055 | 0 | m_xVertScroll->vadjustment_set_page_size(0xFFFF); |
2056 | |
|
2057 | 0 | Link<weld::ScrolledWindow&,void> aScrollLink = LINK( this, CustomPropertiesControl, ScrollHdl ); |
2058 | 0 | m_xVertScroll->connect_vadjustment_value_changed(aScrollLink); |
2059 | |
|
2060 | 0 | ResizeHdl(Size(-1, nHeight)); |
2061 | 0 | } |
2062 | | |
2063 | | IMPL_LINK(CustomPropertiesControl, ResizeHdl, const Size&, rSize, void) |
2064 | 0 | { |
2065 | 0 | int nHeight = rSize.Height() - 6; |
2066 | 0 | if (nHeight == m_xPropertiesWin->GetHeight()) |
2067 | 0 | return; |
2068 | 0 | m_xPropertiesWin->SetHeight(nHeight); |
2069 | 0 | sal_Int32 nScrollOffset = m_xPropertiesWin->GetLineHeight(); |
2070 | 0 | sal_Int32 nVisibleEntries = nHeight / nScrollOffset; |
2071 | 0 | m_xPropertiesWin->SetVisibleLineCount( nVisibleEntries ); |
2072 | 0 | m_xVertScroll->vadjustment_set_page_increment( nVisibleEntries - 1 ); |
2073 | 0 | m_xVertScroll->vadjustment_set_page_size( nVisibleEntries ); |
2074 | 0 | m_xPropertiesWin->ReloadLinesContent(); |
2075 | 0 | } |
2076 | | |
2077 | | CustomPropertiesControl::~CustomPropertiesControl() |
2078 | 0 | { |
2079 | 0 | } |
2080 | | |
2081 | | IMPL_LINK( CustomPropertiesControl, ScrollHdl, weld::ScrolledWindow&, rScrollBar, void ) |
2082 | 0 | { |
2083 | 0 | sal_Int32 nOffset = m_xPropertiesWin->GetLineHeight(); |
2084 | 0 | int nThumbPos = rScrollBar.vadjustment_get_value(); |
2085 | 0 | nOffset *= ( m_nThumbPos - nThumbPos ); |
2086 | 0 | m_nThumbPos = nThumbPos; |
2087 | 0 | m_xPropertiesWin->DoScroll( nOffset ); |
2088 | 0 | } |
2089 | | |
2090 | | IMPL_LINK_NOARG(CustomPropertiesControl, RemovedHdl, void*, void) |
2091 | 0 | { |
2092 | 0 | auto nLineCount = m_xPropertiesWin->GetTotalLineCount(); |
2093 | 0 | m_xVertScroll->vadjustment_set_upper(nLineCount + 1); |
2094 | 0 | if (m_xPropertiesWin->GetTotalLineCount() > m_xPropertiesWin->GetExistingLineCount()) |
2095 | 0 | { |
2096 | 0 | m_xVertScroll->vadjustment_set_value(nLineCount - 1); |
2097 | 0 | ScrollHdl(*m_xVertScroll); |
2098 | 0 | } |
2099 | 0 | } |
2100 | | |
2101 | | void CustomPropertiesControl::AddLine( Any const & rAny ) |
2102 | 0 | { |
2103 | 0 | m_xPropertiesWin->AddLine( OUString(), rAny ); |
2104 | 0 | auto nLineCount = m_xPropertiesWin->GetTotalLineCount(); |
2105 | 0 | m_xVertScroll->vadjustment_set_upper(nLineCount + 1); |
2106 | 0 | if (m_xPropertiesWin->GetHeight() < nLineCount * m_xPropertiesWin->GetLineHeight()) |
2107 | 0 | { |
2108 | 0 | m_xVertScroll->vadjustment_set_value(nLineCount + 1); |
2109 | 0 | ScrollHdl(*m_xVertScroll); |
2110 | 0 | } |
2111 | 0 | } |
2112 | | |
2113 | | void CustomPropertiesControl::SetCustomProperties(std::vector< std::unique_ptr<CustomProperty> >&& rProperties) |
2114 | 0 | { |
2115 | 0 | m_xPropertiesWin->SetCustomProperties(std::move(rProperties)); |
2116 | 0 | auto nLineCount = m_xPropertiesWin->GetTotalLineCount(); |
2117 | 0 | m_xVertScroll->vadjustment_set_upper(nLineCount + 1); |
2118 | 0 | } |
2119 | | |
2120 | | // class SfxCustomPropertiesPage ----------------------------------------- |
2121 | | SfxCustomPropertiesPage::SfxCustomPropertiesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rItemSet ) |
2122 | 0 | : SfxTabPage(pPage, pController, u"sfx/ui/custominfopage.ui"_ustr, u"CustomInfoPage"_ustr, &rItemSet) |
2123 | 0 | , m_xPropertiesCtrl(new CustomPropertiesControl) |
2124 | 0 | , m_xAdd(m_xBuilder->weld_button(u"add"_ustr)) |
2125 | 0 | { |
2126 | 0 | m_xPropertiesCtrl->Init(*m_xBuilder); |
2127 | 0 | m_xAdd->connect_clicked(LINK(this, SfxCustomPropertiesPage, AddHdl)); |
2128 | 0 | } |
2129 | | |
2130 | | SfxCustomPropertiesPage::~SfxCustomPropertiesPage() |
2131 | 0 | { |
2132 | 0 | m_xPropertiesCtrl.reset(); |
2133 | 0 | } |
2134 | | |
2135 | | IMPL_LINK_NOARG(SfxCustomPropertiesPage, AddHdl, weld::Button&, void) |
2136 | 0 | { |
2137 | | // tdf#115853: reload current lines before adding a brand new one |
2138 | | // indeed the info are deleted by ClearCustomProperties |
2139 | | // each time SfxDocumentInfoItem destructor is called |
2140 | 0 | SfxDocumentInfoItem pInfo; |
2141 | 0 | const Sequence< beans::PropertyValue > aPropertySeq = m_xPropertiesCtrl->GetCustomProperties(); |
2142 | 0 | for ( const auto& rProperty : aPropertySeq ) |
2143 | 0 | { |
2144 | 0 | if ( !rProperty.Name.isEmpty() ) |
2145 | 0 | { |
2146 | 0 | pInfo.AddCustomProperty( rProperty.Name, rProperty.Value ); |
2147 | 0 | } |
2148 | 0 | } |
2149 | |
|
2150 | 0 | Any aAny; |
2151 | 0 | m_xPropertiesCtrl->AddLine(aAny); |
2152 | 0 | } |
2153 | | |
2154 | | bool SfxCustomPropertiesPage::FillItemSet( SfxItemSet* rSet ) |
2155 | 0 | { |
2156 | 0 | const SfxDocumentInfoItem* pItem = nullptr; |
2157 | 0 | SfxDocumentInfoItem* pInfo = nullptr; |
2158 | 0 | bool bMustDelete = false; |
2159 | |
|
2160 | 0 | if (const SfxItemSet* pItemSet = GetDialogExampleSet()) |
2161 | 0 | { |
2162 | 0 | pItem = pItemSet->GetItemIfSet(SID_DOCINFO); |
2163 | 0 | if (!pItem) |
2164 | 0 | pInfo = const_cast<SfxDocumentInfoItem*>(&rSet->Get( SID_DOCINFO )); |
2165 | 0 | else |
2166 | 0 | { |
2167 | 0 | bMustDelete = true; |
2168 | 0 | pInfo = new SfxDocumentInfoItem( *pItem ); |
2169 | 0 | } |
2170 | 0 | } |
2171 | |
|
2172 | 0 | if ( pInfo ) |
2173 | 0 | { |
2174 | | // If it's a CMIS document, we can't save custom properties |
2175 | 0 | if ( pInfo->isCmisDocument( ) ) |
2176 | 0 | { |
2177 | 0 | if ( bMustDelete ) |
2178 | 0 | delete pInfo; |
2179 | 0 | return false; |
2180 | 0 | } |
2181 | | |
2182 | 0 | pInfo->ClearCustomProperties(); |
2183 | 0 | const Sequence< beans::PropertyValue > aPropertySeq = m_xPropertiesCtrl->GetCustomProperties(); |
2184 | 0 | for ( const auto& rProperty : aPropertySeq ) |
2185 | 0 | { |
2186 | 0 | if ( !rProperty.Name.isEmpty() ) |
2187 | 0 | pInfo->AddCustomProperty( rProperty.Name, rProperty.Value ); |
2188 | 0 | } |
2189 | 0 | } |
2190 | | |
2191 | 0 | if (pInfo) |
2192 | 0 | { |
2193 | 0 | rSet->Put(*pInfo); |
2194 | 0 | if ( bMustDelete ) |
2195 | 0 | delete pInfo; |
2196 | 0 | } |
2197 | 0 | return true; |
2198 | 0 | } |
2199 | | |
2200 | | void SfxCustomPropertiesPage::Reset( const SfxItemSet* rItemSet ) |
2201 | 0 | { |
2202 | 0 | m_xPropertiesCtrl->ClearAllLines(); |
2203 | 0 | const SfxDocumentInfoItem& rInfoItem = rItemSet->Get(SID_DOCINFO); |
2204 | 0 | std::vector< std::unique_ptr<CustomProperty> > aCustomProps = rInfoItem.GetCustomProperties(); |
2205 | | // tdf#123919 - sort custom document properties |
2206 | 0 | auto const sort = comphelper::string::NaturalStringSorter( |
2207 | 0 | comphelper::getProcessComponentContext(), |
2208 | 0 | Application::GetSettings().GetLanguageTag().getLocale()); |
2209 | 0 | std::sort(aCustomProps.begin(), aCustomProps.end(), |
2210 | 0 | [&sort](const std::unique_ptr<CustomProperty>& rLHS, |
2211 | 0 | const std::unique_ptr<CustomProperty>& rRHS) { |
2212 | 0 | return sort.compare(rLHS->m_sName, rRHS->m_sName) < 0; |
2213 | 0 | }); |
2214 | 0 | m_xPropertiesCtrl->SetCustomProperties(std::move(aCustomProps)); |
2215 | 0 | } |
2216 | | |
2217 | | DeactivateRC SfxCustomPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ ) |
2218 | 0 | { |
2219 | 0 | DeactivateRC nRet = DeactivateRC::LeavePage; |
2220 | 0 | if ( !m_xPropertiesCtrl->AreAllLinesValid() ) |
2221 | 0 | nRet = DeactivateRC::KeepPage; |
2222 | 0 | return nRet; |
2223 | 0 | } |
2224 | | |
2225 | | std::unique_ptr<SfxTabPage> SfxCustomPropertiesPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rItemSet) |
2226 | 0 | { |
2227 | 0 | return std::make_unique<SfxCustomPropertiesPage>(pPage, pController, *rItemSet); |
2228 | 0 | } |
2229 | | |
2230 | | CmisValue::CmisValue(weld::Widget* pParent, const OUString& aStr) |
2231 | 0 | : m_xBuilder(Application::CreateBuilder(pParent, u"sfx/ui/cmisline.ui"_ustr)) |
2232 | 0 | , m_xFrame(m_xBuilder->weld_frame(u"CmisFrame"_ustr)) |
2233 | 0 | , m_xValueEdit(m_xBuilder->weld_entry(u"value"_ustr)) |
2234 | 0 | { |
2235 | 0 | m_xValueEdit->show(); |
2236 | 0 | m_xValueEdit->set_text(aStr); |
2237 | 0 | } |
2238 | | |
2239 | | CmisDateTime::CmisDateTime(weld::Widget* pParent, const util::DateTime& aDateTime) |
2240 | 0 | : m_xBuilder(Application::CreateBuilder(pParent, u"sfx/ui/cmisline.ui"_ustr)) |
2241 | 0 | , m_xFrame(m_xBuilder->weld_frame(u"CmisFrame"_ustr)) |
2242 | 0 | , m_xDateField(new SvtCalendarBox(m_xBuilder->weld_menu_button(u"date"_ustr))) |
2243 | 0 | , m_xTimeField(m_xBuilder->weld_formatted_spin_button(u"time"_ustr)) |
2244 | 0 | , m_xFormatter(new weld::TimeFormatter(*m_xTimeField)) |
2245 | 0 | { |
2246 | 0 | m_xFormatter->SetExtFormat(ExtTimeFieldFormat::LongDuration); |
2247 | 0 | m_xFormatter->EnableEmptyField(false); |
2248 | |
|
2249 | 0 | m_xDateField->show(); |
2250 | 0 | m_xTimeField->show(); |
2251 | 0 | m_xDateField->set_date(Date(aDateTime)); |
2252 | 0 | m_xFormatter->SetTime(tools::Time(aDateTime)); |
2253 | 0 | } |
2254 | | |
2255 | | CmisYesNo::CmisYesNo(weld::Widget* pParent, bool bValue) |
2256 | 0 | : m_xBuilder(Application::CreateBuilder(pParent, u"sfx/ui/cmisline.ui"_ustr)) |
2257 | 0 | , m_xFrame(m_xBuilder->weld_frame(u"CmisFrame"_ustr)) |
2258 | 0 | , m_xYesButton(m_xBuilder->weld_radio_button(u"yes"_ustr)) |
2259 | 0 | , m_xNoButton(m_xBuilder->weld_radio_button(u"no"_ustr)) |
2260 | 0 | { |
2261 | 0 | m_xYesButton->show(); |
2262 | 0 | m_xNoButton->show(); |
2263 | 0 | if (bValue) |
2264 | 0 | m_xYesButton->set_active(true); |
2265 | 0 | else |
2266 | 0 | m_xNoButton->set_active(true); |
2267 | 0 | } |
2268 | | |
2269 | | // struct CmisPropertyLine --------------------------------------------- |
2270 | | CmisPropertyLine::CmisPropertyLine(weld::Widget* pParent) |
2271 | 0 | : m_xBuilder(Application::CreateBuilder(pParent, u"sfx/ui/cmisline.ui"_ustr)) |
2272 | 0 | , m_sType(CMIS_TYPE_STRING) |
2273 | 0 | , m_bUpdatable(false) |
2274 | 0 | , m_bRequired(false) |
2275 | 0 | , m_bMultiValued(false) |
2276 | 0 | , m_bOpenChoice(false) |
2277 | 0 | , m_xFrame(m_xBuilder->weld_frame(u"CmisFrame"_ustr)) |
2278 | 0 | , m_xName(m_xBuilder->weld_label(u"name"_ustr)) |
2279 | 0 | , m_xType(m_xBuilder->weld_label(u"type"_ustr)) |
2280 | 0 | { |
2281 | 0 | m_xFrame->set_sensitive(true); |
2282 | 0 | } |
2283 | | |
2284 | | CmisPropertyLine::~CmisPropertyLine( ) |
2285 | 0 | { |
2286 | 0 | } |
2287 | | |
2288 | | // class CmisPropertiesWindow ----------------------------------------- |
2289 | | |
2290 | | CmisPropertiesWindow::CmisPropertiesWindow(std::unique_ptr<weld::Container> xParent) |
2291 | 0 | : m_xBox(std::move(xParent)) |
2292 | 0 | , m_aNumberFormatter(::comphelper::getProcessComponentContext(), |
2293 | 0 | Application::GetSettings().GetLanguageTag().getLanguageType()) |
2294 | 0 | { |
2295 | 0 | } |
2296 | | |
2297 | | CmisPropertiesWindow::~CmisPropertiesWindow() |
2298 | 0 | { |
2299 | 0 | } |
2300 | | |
2301 | | void CmisPropertiesWindow::ClearAllLines() |
2302 | 0 | { |
2303 | 0 | m_aCmisPropertiesLines.clear(); |
2304 | 0 | } |
2305 | | |
2306 | | void CmisPropertiesWindow::AddLine( const OUString& sId, const OUString& sName, |
2307 | | const OUString& sType, const bool bUpdatable, |
2308 | | const bool bRequired, const bool bMultiValued, |
2309 | | const bool bOpenChoice, Any& /*aChoices*/, Any const & rAny ) |
2310 | 0 | { |
2311 | 0 | std::unique_ptr<CmisPropertyLine> pNewLine(new CmisPropertyLine(m_xBox.get())); |
2312 | |
|
2313 | 0 | pNewLine->m_sId = sId; |
2314 | 0 | pNewLine->m_sType = sType; |
2315 | 0 | pNewLine->m_bUpdatable = bUpdatable; |
2316 | 0 | pNewLine->m_bRequired = bRequired; |
2317 | 0 | pNewLine->m_bMultiValued = bMultiValued; |
2318 | 0 | pNewLine->m_bOpenChoice = bOpenChoice; |
2319 | |
|
2320 | 0 | if ( sType == CMIS_TYPE_INTEGER ) |
2321 | 0 | { |
2322 | 0 | Sequence< sal_Int64 > seqValue; |
2323 | 0 | rAny >>= seqValue; |
2324 | 0 | sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM ); |
2325 | 0 | for (const auto& rValue : seqValue) |
2326 | 0 | { |
2327 | 0 | OUString sValue = m_aNumberFormatter.GetInputLineString( rValue, nIndex ); |
2328 | 0 | std::unique_ptr<CmisValue> pValue(new CmisValue(m_xBox.get(), sValue)); |
2329 | 0 | pValue->m_xValueEdit->set_editable(bUpdatable); |
2330 | 0 | pNewLine->m_aValues.push_back( std::move(pValue) ); |
2331 | 0 | } |
2332 | 0 | } |
2333 | 0 | else if ( sType == CMIS_TYPE_DECIMAL ) |
2334 | 0 | { |
2335 | 0 | Sequence< double > seqValue; |
2336 | 0 | rAny >>= seqValue; |
2337 | 0 | sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM ); |
2338 | 0 | for (const auto& rValue : seqValue) |
2339 | 0 | { |
2340 | 0 | OUString sValue = m_aNumberFormatter.GetInputLineString( rValue, nIndex ); |
2341 | 0 | std::unique_ptr<CmisValue> pValue(new CmisValue(m_xBox.get(), sValue)); |
2342 | 0 | pValue->m_xValueEdit->set_editable(bUpdatable); |
2343 | 0 | pNewLine->m_aValues.push_back( std::move(pValue) ); |
2344 | 0 | } |
2345 | |
|
2346 | 0 | } |
2347 | 0 | else if ( sType == CMIS_TYPE_BOOL ) |
2348 | 0 | { |
2349 | 0 | Sequence<sal_Bool> seqValue; |
2350 | 0 | rAny >>= seqValue; |
2351 | 0 | for (const auto& rValue : seqValue) |
2352 | 0 | { |
2353 | 0 | std::unique_ptr<CmisYesNo> pYesNo(new CmisYesNo(m_xBox.get(), rValue)); |
2354 | 0 | pYesNo->m_xYesButton->set_sensitive( bUpdatable ); |
2355 | 0 | pYesNo->m_xNoButton->set_sensitive( bUpdatable ); |
2356 | 0 | pNewLine->m_aYesNos.push_back( std::move(pYesNo) ); |
2357 | 0 | } |
2358 | 0 | } |
2359 | 0 | else if ( sType == CMIS_TYPE_STRING ) |
2360 | 0 | { |
2361 | 0 | Sequence< OUString > seqValue; |
2362 | 0 | rAny >>= seqValue; |
2363 | 0 | for (const auto& rValue : seqValue) |
2364 | 0 | { |
2365 | 0 | std::unique_ptr<CmisValue> pValue(new CmisValue(m_xBox.get(), rValue)); |
2366 | 0 | pValue->m_xValueEdit->set_editable(bUpdatable); |
2367 | 0 | pNewLine->m_aValues.push_back( std::move(pValue) ); |
2368 | 0 | } |
2369 | 0 | } |
2370 | 0 | else if ( sType == CMIS_TYPE_DATETIME ) |
2371 | 0 | { |
2372 | 0 | Sequence< util::DateTime > seqValue; |
2373 | 0 | rAny >>= seqValue; |
2374 | 0 | for (const auto& rValue : seqValue) |
2375 | 0 | { |
2376 | 0 | std::unique_ptr<CmisDateTime> pDateTime(new CmisDateTime(m_xBox.get(), rValue)); |
2377 | 0 | pDateTime->m_xDateField->set_sensitive(bUpdatable); |
2378 | 0 | pDateTime->m_xTimeField->set_sensitive(bUpdatable); |
2379 | 0 | pNewLine->m_aDateTimes.push_back( std::move(pDateTime) ); |
2380 | 0 | } |
2381 | 0 | } |
2382 | 0 | pNewLine->m_xName->set_label( sName ); |
2383 | 0 | pNewLine->m_xName->show(); |
2384 | 0 | pNewLine->m_xType->set_label( sType ); |
2385 | 0 | pNewLine->m_xType->show(); |
2386 | |
|
2387 | 0 | m_aCmisPropertiesLines.push_back( std::move(pNewLine) ); |
2388 | 0 | } |
2389 | | |
2390 | | Sequence< document::CmisProperty > CmisPropertiesWindow::GetCmisProperties() const |
2391 | 0 | { |
2392 | 0 | Sequence< document::CmisProperty > aPropertiesSeq( m_aCmisPropertiesLines.size() ); |
2393 | 0 | auto aPropertiesSeqRange = asNonConstRange(aPropertiesSeq); |
2394 | 0 | sal_Int32 i = 0; |
2395 | 0 | for ( auto& rxLine : m_aCmisPropertiesLines ) |
2396 | 0 | { |
2397 | 0 | CmisPropertyLine* pLine = rxLine.get(); |
2398 | |
|
2399 | 0 | aPropertiesSeqRange[i].Id = pLine->m_sId; |
2400 | 0 | aPropertiesSeqRange[i].Type = pLine->m_sType; |
2401 | 0 | aPropertiesSeqRange[i].Updatable = pLine->m_bUpdatable; |
2402 | 0 | aPropertiesSeqRange[i].Required = pLine->m_bRequired; |
2403 | 0 | aPropertiesSeqRange[i].OpenChoice = pLine->m_bOpenChoice; |
2404 | 0 | aPropertiesSeqRange[i].MultiValued = pLine->m_bMultiValued; |
2405 | |
|
2406 | 0 | OUString sPropertyName = pLine->m_xName->get_label(); |
2407 | 0 | if ( !sPropertyName.isEmpty() ) |
2408 | 0 | { |
2409 | 0 | aPropertiesSeqRange[i].Name = sPropertyName; |
2410 | 0 | OUString sType = pLine->m_xType->get_label(); |
2411 | 0 | if ( CMIS_TYPE_DECIMAL == sType ) |
2412 | 0 | { |
2413 | 0 | sal_uInt32 nIndex = const_cast< SvNumberFormatter& >( |
2414 | 0 | m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM ); |
2415 | 0 | Sequence< double > seqValue( pLine->m_aValues.size( ) ); |
2416 | 0 | auto seqValueRange = asNonConstRange(seqValue); |
2417 | 0 | sal_Int32 k = 0; |
2418 | 0 | for ( const auto& rxValue : pLine->m_aValues ) |
2419 | 0 | { |
2420 | 0 | double dValue = 0.0; |
2421 | 0 | OUString sValue( rxValue->m_xValueEdit->get_text() ); |
2422 | 0 | bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ). |
2423 | 0 | IsNumberFormat( sValue, nIndex, dValue ); |
2424 | 0 | if ( bIsNum ) |
2425 | 0 | seqValueRange[k] = dValue; |
2426 | 0 | ++k; |
2427 | 0 | } |
2428 | 0 | aPropertiesSeqRange[i].Value <<= seqValue; |
2429 | 0 | } |
2430 | 0 | else if ( CMIS_TYPE_INTEGER == sType ) |
2431 | 0 | { |
2432 | 0 | sal_uInt32 nIndex = const_cast< SvNumberFormatter& >( |
2433 | 0 | m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM ); |
2434 | 0 | Sequence< sal_Int64 > seqValue( pLine->m_aValues.size( ) ); |
2435 | 0 | auto seqValueRange = asNonConstRange(seqValue); |
2436 | 0 | sal_Int32 k = 0; |
2437 | 0 | for ( const auto& rxValue : pLine->m_aValues ) |
2438 | 0 | { |
2439 | 0 | double dValue = 0; |
2440 | 0 | OUString sValue( rxValue->m_xValueEdit->get_text() ); |
2441 | 0 | bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ). |
2442 | 0 | IsNumberFormat( sValue, nIndex, dValue ); |
2443 | 0 | if ( bIsNum ) |
2444 | 0 | seqValueRange[k] = static_cast<sal_Int64>(dValue); |
2445 | 0 | ++k; |
2446 | 0 | } |
2447 | 0 | aPropertiesSeqRange[i].Value <<= seqValue; |
2448 | 0 | } |
2449 | 0 | else if ( CMIS_TYPE_BOOL == sType ) |
2450 | 0 | { |
2451 | 0 | Sequence<sal_Bool> seqValue( pLine->m_aYesNos.size( ) ); |
2452 | 0 | sal_Bool* pseqValue = seqValue.getArray(); |
2453 | 0 | sal_Int32 k = 0; |
2454 | 0 | for ( const auto& rxYesNo : pLine->m_aYesNos ) |
2455 | 0 | { |
2456 | 0 | bool bValue = rxYesNo->m_xYesButton->get_active(); |
2457 | 0 | pseqValue[k] = bValue; |
2458 | 0 | ++k; |
2459 | 0 | } |
2460 | 0 | aPropertiesSeqRange[i].Value <<= seqValue; |
2461 | |
|
2462 | 0 | } |
2463 | 0 | else if ( CMIS_TYPE_DATETIME == sType ) |
2464 | 0 | { |
2465 | 0 | Sequence< util::DateTime > seqValue( pLine->m_aDateTimes.size( ) ); |
2466 | 0 | auto seqValueRange = asNonConstRange(seqValue); |
2467 | 0 | sal_Int32 k = 0; |
2468 | 0 | for ( const auto& rxDateTime : pLine->m_aDateTimes ) |
2469 | 0 | { |
2470 | 0 | Date aTmpDate = rxDateTime->m_xDateField->get_date(); |
2471 | 0 | tools::Time aTmpTime = rxDateTime->m_xFormatter->GetTime(); |
2472 | 0 | util::DateTime aDateTime( aTmpTime.GetNanoSec(), aTmpTime.GetSec(), |
2473 | 0 | aTmpTime.GetMin(), aTmpTime.GetHour(), |
2474 | 0 | aTmpDate.GetDay(), aTmpDate.GetMonth(), |
2475 | 0 | aTmpDate.GetYear(), true ); |
2476 | 0 | seqValueRange[k] = aDateTime; |
2477 | 0 | ++k; |
2478 | 0 | } |
2479 | 0 | aPropertiesSeqRange[i].Value <<= seqValue; |
2480 | 0 | } |
2481 | 0 | else |
2482 | 0 | { |
2483 | 0 | Sequence< OUString > seqValue( pLine->m_aValues.size( ) ); |
2484 | 0 | auto seqValueRange = asNonConstRange(seqValue); |
2485 | 0 | sal_Int32 k = 0; |
2486 | 0 | for ( const auto& rxValue : pLine->m_aValues ) |
2487 | 0 | { |
2488 | 0 | seqValueRange[k] = rxValue->m_xValueEdit->get_text(); |
2489 | 0 | ++k; |
2490 | 0 | } |
2491 | 0 | aPropertiesSeqRange[i].Value <<= seqValue; |
2492 | 0 | } |
2493 | 0 | } |
2494 | 0 | ++i; |
2495 | 0 | } |
2496 | |
|
2497 | 0 | return aPropertiesSeq; |
2498 | 0 | } |
2499 | | |
2500 | | CmisPropertiesControl::CmisPropertiesControl(weld::Builder& rBuilder) |
2501 | 0 | : m_aPropertiesWin(rBuilder.weld_container(u"CmisWindow"_ustr)) |
2502 | 0 | , m_xScrolledWindow(rBuilder.weld_scrolled_window(u"CmisScroll"_ustr)) |
2503 | 0 | { |
2504 | | // set height to something small and force it to take the size |
2505 | | // dictated by the other pages |
2506 | 0 | m_xScrolledWindow->set_size_request(-1, 42); |
2507 | 0 | } |
2508 | | |
2509 | | void CmisPropertiesControl::ClearAllLines() |
2510 | 0 | { |
2511 | 0 | m_aPropertiesWin.ClearAllLines(); |
2512 | 0 | } |
2513 | | |
2514 | | void CmisPropertiesControl::AddLine( const OUString& sId, const OUString& sName, |
2515 | | const OUString& sType, const bool bUpdatable, |
2516 | | const bool bRequired, const bool bMultiValued, |
2517 | | const bool bOpenChoice, Any& aChoices, Any const & rAny |
2518 | | ) |
2519 | 0 | { |
2520 | 0 | m_aPropertiesWin.AddLine( sId, sName, sType, bUpdatable, bRequired, bMultiValued, |
2521 | 0 | bOpenChoice, aChoices, rAny ); |
2522 | 0 | } |
2523 | | |
2524 | | // class SfxCmisPropertiesPage ----------------------------------------- |
2525 | | SfxCmisPropertiesPage::SfxCmisPropertiesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rItemSet) |
2526 | 0 | : SfxTabPage(pPage, pController, u"sfx/ui/cmisinfopage.ui"_ustr, u"CmisInfoPage"_ustr, &rItemSet) |
2527 | 0 | , m_xPropertiesCtrl(new CmisPropertiesControl(*m_xBuilder)) |
2528 | 0 | { |
2529 | 0 | } |
2530 | | |
2531 | | SfxCmisPropertiesPage::~SfxCmisPropertiesPage() |
2532 | 0 | { |
2533 | 0 | m_xPropertiesCtrl.reset(); |
2534 | 0 | } |
2535 | | |
2536 | | bool SfxCmisPropertiesPage::FillItemSet( SfxItemSet* rSet ) |
2537 | 0 | { |
2538 | 0 | const SfxDocumentInfoItem* pItem = nullptr; |
2539 | 0 | SfxDocumentInfoItem* pInfo = nullptr; |
2540 | 0 | bool bMustDelete = false; |
2541 | |
|
2542 | 0 | if (const SfxItemSet* pItemSet = GetDialogExampleSet()) |
2543 | 0 | { |
2544 | 0 | pItem = pItemSet->GetItemIfSet(SID_DOCINFO); |
2545 | 0 | if (!pItem) |
2546 | 0 | pInfo = const_cast<SfxDocumentInfoItem*>(&rSet->Get( SID_DOCINFO )); |
2547 | 0 | else |
2548 | 0 | { |
2549 | 0 | bMustDelete = true; |
2550 | 0 | pInfo = new SfxDocumentInfoItem( *pItem ); |
2551 | 0 | } |
2552 | 0 | } |
2553 | |
|
2554 | 0 | sal_Int32 modifiedNum = 0; |
2555 | 0 | if ( pInfo ) |
2556 | 0 | { |
2557 | 0 | Sequence< document::CmisProperty > aOldProps = pInfo->GetCmisProperties( ); |
2558 | 0 | Sequence< document::CmisProperty > aNewProps = m_xPropertiesCtrl->GetCmisProperties(); |
2559 | |
|
2560 | 0 | std::vector< document::CmisProperty > changedProps; |
2561 | 0 | for ( sal_Int32 i = 0; i< aNewProps.getLength( ); ++i ) |
2562 | 0 | { |
2563 | 0 | if ( aOldProps[i].Updatable && !aNewProps[i].Id.isEmpty( ) ) |
2564 | 0 | { |
2565 | 0 | if ( aOldProps[i].Type == CMIS_TYPE_DATETIME ) |
2566 | 0 | { |
2567 | 0 | Sequence< util::DateTime > oldValue; |
2568 | 0 | aOldProps[i].Value >>= oldValue; |
2569 | | // We only edit hours and minutes |
2570 | | // don't compare NanoSeconds and Seconds |
2571 | 0 | for ( auto& rDateTime : asNonConstRange(oldValue) ) |
2572 | 0 | { |
2573 | 0 | rDateTime.NanoSeconds = 0; |
2574 | 0 | rDateTime.Seconds = 0; |
2575 | 0 | } |
2576 | 0 | Sequence< util::DateTime > newValue; |
2577 | 0 | aNewProps[i].Value >>= newValue; |
2578 | 0 | if ( oldValue != newValue ) |
2579 | 0 | { |
2580 | 0 | modifiedNum++; |
2581 | 0 | changedProps.push_back( aNewProps[i] ); |
2582 | 0 | } |
2583 | 0 | } |
2584 | 0 | else if ( aOldProps[i].Value != aNewProps[i].Value ) |
2585 | 0 | { |
2586 | 0 | modifiedNum++; |
2587 | 0 | changedProps.push_back( aNewProps[i] ); |
2588 | 0 | } |
2589 | 0 | } |
2590 | 0 | } |
2591 | 0 | Sequence< document::CmisProperty> aModifiedProps( comphelper::containerToSequence(changedProps) ); |
2592 | 0 | pInfo->SetCmisProperties( aModifiedProps ); |
2593 | 0 | rSet->Put( *pInfo ); |
2594 | 0 | if ( bMustDelete ) |
2595 | 0 | delete pInfo; |
2596 | 0 | } |
2597 | |
|
2598 | 0 | return modifiedNum; |
2599 | 0 | } |
2600 | | |
2601 | | void SfxCmisPropertiesPage::Reset( const SfxItemSet* rItemSet ) |
2602 | 0 | { |
2603 | 0 | m_xPropertiesCtrl->ClearAllLines(); |
2604 | 0 | const SfxDocumentInfoItem& rInfoItem = rItemSet->Get(SID_DOCINFO); |
2605 | 0 | uno::Sequence< document::CmisProperty > aCmisProps = rInfoItem.GetCmisProperties(); |
2606 | 0 | for ( auto& rCmisProp : asNonConstRange(aCmisProps) ) |
2607 | 0 | { |
2608 | 0 | m_xPropertiesCtrl->AddLine(rCmisProp.Id, |
2609 | 0 | rCmisProp.Name, |
2610 | 0 | rCmisProp.Type, |
2611 | 0 | rCmisProp.Updatable, |
2612 | 0 | rCmisProp.Required, |
2613 | 0 | rCmisProp.MultiValued, |
2614 | 0 | rCmisProp.OpenChoice, |
2615 | 0 | rCmisProp.Choices, |
2616 | 0 | rCmisProp.Value); |
2617 | 0 | } |
2618 | 0 | } |
2619 | | |
2620 | | DeactivateRC SfxCmisPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ ) |
2621 | 0 | { |
2622 | 0 | return DeactivateRC::LeavePage; |
2623 | 0 | } |
2624 | | |
2625 | | std::unique_ptr<SfxTabPage> SfxCmisPropertiesPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rItemSet) |
2626 | 0 | { |
2627 | 0 | return std::make_unique<SfxCmisPropertiesPage>(pPage, pController, *rItemSet); |
2628 | 0 | } |
2629 | | |
2630 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |