File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 192, column 9 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <dbinsdlg.hxx> | |||
21 | ||||
22 | #include <float.h> | |||
23 | ||||
24 | #include <hintids.hxx> | |||
25 | #include <com/sun/star/container/XNameAccess.hpp> | |||
26 | #include <com/sun/star/sdbc/XDataSource.hpp> | |||
27 | #include <com/sun/star/sdbc/XRow.hpp> | |||
28 | #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> | |||
29 | #include <com/sun/star/sdbcx/XRowLocate.hpp> | |||
30 | #include <com/sun/star/sdb/XQueriesSupplier.hpp> | |||
31 | #include <com/sun/star/sdb/XColumn.hpp> | |||
32 | #include <com/sun/star/sdbc/DataType.hpp> | |||
33 | #include <com/sun/star/beans/XPropertySet.hpp> | |||
34 | #include <com/sun/star/util/NumberFormatter.hpp> | |||
35 | #include <com/sun/star/util/XNumberFormatTypes.hpp> | |||
36 | #include <comphelper/processfactory.hxx> | |||
37 | #include <comphelper/sequence.hxx> | |||
38 | #include <comphelper/types.hxx> | |||
39 | #include <svl/numuno.hxx> | |||
40 | #include <svl/stritem.hxx> | |||
41 | #include <tools/diagnose_ex.h> | |||
42 | #include <vcl/mnemonic.hxx> | |||
43 | #include <svl/style.hxx> | |||
44 | #include <svl/zformat.hxx> | |||
45 | #include <sfx2/htmlmode.hxx> | |||
46 | #include <svl/itemset.hxx> | |||
47 | #include <editeng/brushitem.hxx> | |||
48 | #include <editeng/boxitem.hxx> | |||
49 | #include <unotools/collatorwrapper.hxx> | |||
50 | #include <fmtclds.hxx> | |||
51 | #include <tabcol.hxx> | |||
52 | #include <uiitems.hxx> | |||
53 | #include <viewopt.hxx> | |||
54 | #include <wrtsh.hxx> | |||
55 | #include <view.hxx> | |||
56 | #include <docsh.hxx> | |||
57 | #include <dbmgr.hxx> | |||
58 | #include <tblafmt.hxx> | |||
59 | #include <cellatr.hxx> | |||
60 | #include <swtablerep.hxx> | |||
61 | #include <dbfld.hxx> | |||
62 | #include <fmtcol.hxx> | |||
63 | #include <swwait.hxx> | |||
64 | #include <modcfg.hxx> | |||
65 | #include <swmodule.hxx> | |||
66 | #include <poolfmt.hxx> | |||
67 | #include <connectivity/dbtools.hxx> | |||
68 | ||||
69 | #include <cmdid.h> | |||
70 | #include <SwStyleNameMapper.hxx> | |||
71 | #include <tabsh.hxx> | |||
72 | #include <swabstdlg.hxx> | |||
73 | #include <strings.hrc> | |||
74 | #include <IDocumentMarkAccess.hxx> | |||
75 | ||||
76 | #include <o3tl/any.hxx> | |||
77 | ||||
78 | #include <memory> | |||
79 | #include <swuiexp.hxx> | |||
80 | ||||
81 | using namespace ::dbtools; | |||
82 | using namespace ::com::sun::star; | |||
83 | using namespace ::com::sun::star::beans; | |||
84 | using namespace ::com::sun::star::container; | |||
85 | using namespace ::com::sun::star::lang; | |||
86 | using namespace ::com::sun::star::sdb; | |||
87 | using namespace ::com::sun::star::sdbc; | |||
88 | using namespace ::com::sun::star::sdbcx; | |||
89 | using namespace ::com::sun::star::uno; | |||
90 | ||||
91 | const char cDBFieldStart = '<'; | |||
92 | const char cDBFieldEnd = '>'; | |||
93 | ||||
94 | // Helper structure for adding database rows as fields or text | |||
95 | struct DB_Column | |||
96 | { | |||
97 | const enum class Type { FILLTEXT, COL_FIELD, COL_TEXT, SPLITPARA } eColType; | |||
98 | ||||
99 | union { | |||
100 | OUString* pText; | |||
101 | SwField* pField; | |||
102 | sal_uInt32 nFormat; | |||
103 | }; | |||
104 | const SwInsDBColumn* pColInfo; | |||
105 | ||||
106 | DB_Column() : eColType(Type::SPLITPARA), | |||
107 | pText(nullptr), | |||
108 | pColInfo(nullptr) | |||
109 | {} | |||
110 | ||||
111 | explicit DB_Column( const OUString& rText ) | |||
112 | : eColType(Type::FILLTEXT), | |||
113 | pText(new OUString(rText)), | |||
114 | pColInfo(nullptr) | |||
115 | {} | |||
116 | ||||
117 | DB_Column( const SwInsDBColumn& rInfo, sal_uInt32 nFormat_ ) | |||
118 | : eColType(Type::COL_TEXT), | |||
119 | nFormat(nFormat_), | |||
120 | pColInfo(&rInfo) | |||
121 | {} | |||
122 | ||||
123 | DB_Column( const SwInsDBColumn& rInfo, SwDBField& rField ) | |||
124 | : eColType(Type::COL_FIELD), | |||
125 | pField(&rField), | |||
126 | pColInfo(&rInfo) | |||
127 | {} | |||
128 | ||||
129 | ~DB_Column() | |||
130 | { | |||
131 | if( Type::COL_FIELD == eColType ) | |||
132 | delete pField; | |||
133 | else if( Type::FILLTEXT == eColType ) | |||
134 | delete pText; | |||
135 | } | |||
136 | }; | |||
137 | ||||
138 | namespace { | |||
139 | ||||
140 | struct DB_ColumnConfigData | |||
141 | { | |||
142 | SwInsDBColumns aDBColumns; | |||
143 | OUString sEdit; | |||
144 | OUString sTableList; | |||
145 | OUString sTmplNm; | |||
146 | OUString sTAutoFormatNm; | |||
147 | bool bIsTable : 1, | |||
148 | bIsField : 1, | |||
149 | bIsHeadlineOn : 1, | |||
150 | bIsEmptyHeadln : 1; | |||
151 | ||||
152 | DB_ColumnConfigData(DB_ColumnConfigData const&) = delete; | |||
153 | DB_ColumnConfigData& operator=(DB_ColumnConfigData const&) = delete; | |||
154 | ||||
155 | DB_ColumnConfigData() | |||
156 | { | |||
157 | bIsTable = bIsHeadlineOn = true; | |||
158 | bIsField = bIsEmptyHeadln = false; | |||
159 | } | |||
160 | }; | |||
161 | ||||
162 | } | |||
163 | ||||
164 | bool SwInsDBColumn::operator<( const SwInsDBColumn& rCmp ) const | |||
165 | { | |||
166 | return 0 > GetAppCollator().compareString( sColumn, rCmp.sColumn ); | |||
167 | } | |||
168 | ||||
169 | SwInsertDBColAutoPilot::SwInsertDBColAutoPilot( SwView& rView, | |||
170 | Reference<XDataSource> const & xDataSource, | |||
171 | Reference<sdbcx::XColumnsSupplier> const & xColSupp, | |||
172 | const SwDBData& rData ) | |||
173 | : SfxDialogController(rView.GetWindow()->GetFrameWeld(), "modules/swriter/ui/insertdbcolumnsdialog.ui", "InsertDbColumnsDialog") | |||
174 | , ConfigItem("Office.Writer/InsertData/DataSet", ConfigItemMode::NONE) | |||
175 | , aDBData(rData) | |||
176 | , sNoTmpl(SwResId(SW_STR_NONEreinterpret_cast<char const *>("SW_STR_NONE" "\004" u8"[None]" ))) | |||
177 | , pView(&rView) | |||
178 | , m_xRbAsTable(m_xBuilder->weld_radio_button("astable")) | |||
179 | , m_xRbAsField(m_xBuilder->weld_radio_button("asfields")) | |||
180 | , m_xRbAsText(m_xBuilder->weld_radio_button("astext")) | |||
181 | , m_xHeadFrame(m_xBuilder->weld_frame("dbframe")) | |||
182 | , m_xLbTableDbColumn(m_xBuilder->weld_tree_view("tabledbcols")) | |||
183 | , m_xLbTextDbColumn(m_xBuilder->weld_tree_view("tabletxtcols")) | |||
184 | , m_xFormatFrame(m_xBuilder->weld_frame("formatframe")) | |||
185 | , m_xRbDbFormatFromDb(m_xBuilder->weld_radio_button("fromdatabase")) | |||
186 | , m_xRbDbFormatFromUsr(m_xBuilder->weld_radio_button("userdefined")) | |||
187 | , m_xLbDbFormatFromUsr(new NumFormatListBox(m_xBuilder->weld_combo_box("numformat"))) | |||
188 | , m_xIbDbcolToEdit(m_xBuilder->weld_button("toedit")) | |||
189 | , m_xEdDbText(m_xBuilder->weld_text_view("textview")) | |||
190 | , m_xFtDbParaColl(m_xBuilder->weld_label("parastylelabel")) | |||
191 | , m_xLbDbParaColl(m_xBuilder->weld_combo_box("parastyle")) | |||
192 | , m_xIbDbcolAllTo(m_xBuilder->weld_button("oneright")) | |||
193 | , m_xIbDbcolOneTo(m_xBuilder->weld_button("allright")) | |||
194 | , m_xIbDbcolOneFrom(m_xBuilder->weld_button("oneleft")) | |||
195 | , m_xIbDbcolAllFrom(m_xBuilder->weld_button("allleft")) | |||
196 | , m_xFtTableCol(m_xBuilder->weld_label("tablecolft")) | |||
197 | , m_xLbTableCol(m_xBuilder->weld_tree_view("tablecols")) | |||
198 | , m_xCbTableHeadon(m_xBuilder->weld_check_button("tableheading")) | |||
199 | , m_xRbHeadlColnms(m_xBuilder->weld_radio_button("columnname")) | |||
200 | , m_xRbHeadlEmpty(m_xBuilder->weld_radio_button("rowonly")) | |||
201 | , m_xPbTableFormat(m_xBuilder->weld_button("tableformat")) | |||
202 | , m_xPbTableAutofmt(m_xBuilder->weld_button("autoformat")) | |||
203 | { | |||
204 | m_xEdDbText->set_size_request(m_xEdDbText->get_approximate_digit_width() * 40, -1); | |||
205 | m_xLbDbParaColl->make_sorted(); | |||
206 | ||||
207 | nGBFormatLen = m_xFormatFrame->get_label().getLength(); | |||
208 | ||||
209 | if (xColSupp.is()) | |||
210 | { | |||
211 | SwWrtShell& rSh = pView->GetWrtShell(); | |||
212 | SvNumberFormatter* pNumFormatr = rSh.GetNumberFormatter(); | |||
213 | SvNumberFormatsSupplierObj* pNumFormat = new SvNumberFormatsSupplierObj( pNumFormatr ); | |||
214 | Reference< util::XNumberFormatsSupplier > xDocNumFormatsSupplier = pNumFormat; | |||
215 | Reference< util::XNumberFormats > xDocNumberFormats = xDocNumFormatsSupplier->getNumberFormats(); | |||
216 | Reference< util::XNumberFormatTypes > xDocNumberFormatTypes(xDocNumberFormats, UNO_QUERY); | |||
217 | ||||
218 | Reference<XPropertySet> xSourceProps(xDataSource, UNO_QUERY); | |||
219 | Reference< util::XNumberFormats > xNumberFormats; | |||
220 | if(xSourceProps.is()) | |||
221 | { | |||
222 | Any aFormats = xSourceProps->getPropertyValue("NumberFormatsSupplier"); | |||
223 | if(aFormats.hasValue()) | |||
224 | { | |||
225 | Reference< util::XNumberFormatsSupplier> xSuppl; | |||
226 | aFormats >>= xSuppl; | |||
227 | if(xSuppl.is()) | |||
228 | { | |||
229 | xNumberFormats = xSuppl->getNumberFormats( ); | |||
230 | } | |||
231 | } | |||
232 | } | |||
233 | Reference <XNameAccess> xCols = xColSupp->getColumns(); | |||
234 | const Sequence<OUString> aColNames = xCols->getElementNames(); | |||
235 | for (const OUString& rColName : aColNames) | |||
236 | { | |||
237 | std::unique_ptr<SwInsDBColumn> pNew(new SwInsDBColumn( rColName )); | |||
238 | Any aCol = xCols->getByName(rColName); | |||
239 | Reference <XPropertySet> xCol; | |||
240 | aCol >>= xCol; | |||
241 | Any aType = xCol->getPropertyValue("Type"); | |||
242 | sal_Int32 eDataType = 0; | |||
243 | aType >>= eDataType; | |||
244 | switch(eDataType) | |||
245 | { | |||
246 | case DataType::BIT: | |||
247 | case DataType::BOOLEAN: | |||
248 | case DataType::TINYINT: | |||
249 | case DataType::SMALLINT: | |||
250 | case DataType::INTEGER: | |||
251 | case DataType::BIGINT: | |||
252 | case DataType::FLOAT: | |||
253 | case DataType::REAL: | |||
254 | case DataType::DOUBLE: | |||
255 | case DataType::NUMERIC: | |||
256 | case DataType::DECIMAL: | |||
257 | case DataType::DATE: | |||
258 | case DataType::TIME: | |||
259 | case DataType::TIMESTAMP: | |||
260 | { | |||
261 | pNew->bHasFormat = true; | |||
262 | Any aFormat = xCol->getPropertyValue("FormatKey"); | |||
263 | if(aFormat.hasValue()) | |||
264 | { | |||
265 | sal_Int32 nFormat = 0; | |||
266 | aFormat >>= nFormat; | |||
267 | if(xNumberFormats.is()) | |||
268 | { | |||
269 | try | |||
270 | { | |||
271 | Reference<XPropertySet> xNumProps = xNumberFormats->getByKey( nFormat ); | |||
272 | Any aFormatVal = xNumProps->getPropertyValue("FormatString"); | |||
273 | Any aLocale = xNumProps->getPropertyValue("Locale"); | |||
274 | OUString sFormat; | |||
275 | aFormatVal >>= sFormat; | |||
276 | lang::Locale aLoc; | |||
277 | aLocale >>= aLoc; | |||
278 | sal_Int32 nKey = xDocNumberFormats->queryKey( sFormat, aLoc, true); | |||
279 | if(nKey < 0) | |||
280 | { | |||
281 | nKey = xDocNumberFormats->addNew( sFormat, aLoc ); | |||
282 | } | |||
283 | pNew->nDBNumFormat = nKey; | |||
284 | } | |||
285 | catch (const Exception&) | |||
286 | { | |||
287 | OSL_FAIL("illegal number format key")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "287" ": "), "%s", "illegal number format key"); } } while (false); | |||
288 | } | |||
289 | } | |||
290 | } | |||
291 | else | |||
292 | { | |||
293 | pNew->nDBNumFormat = getDefaultNumberFormat(xCol, | |||
294 | xDocNumberFormatTypes, LanguageTag( rSh.GetCurLang() ).getLocale()); | |||
295 | } | |||
296 | ||||
297 | } | |||
298 | break; | |||
299 | } | |||
300 | if( !aDBColumns.insert( std::move(pNew) ).second ) | |||
301 | { | |||
302 | OSL_ENSURE( false, "Spaltenname mehrfach vergeben?" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "302" ": "), "%s", "Spaltenname mehrfach vergeben?"); } } while (false); | |||
303 | } | |||
304 | } | |||
305 | } | |||
306 | ||||
307 | // fill paragraph templates-ListBox | |||
308 | { | |||
309 | SfxStyleSheetBasePool* pPool = pView->GetDocShell()->GetStyleSheetPool(); | |||
310 | m_xLbDbParaColl->append_text( sNoTmpl ); | |||
311 | ||||
312 | const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Para); | |||
313 | while( pBase ) | |||
314 | { | |||
315 | m_xLbDbParaColl->append_text( pBase->GetName() ); | |||
316 | pBase = pPool->Next(); | |||
317 | } | |||
318 | m_xLbDbParaColl->set_active( 0 ); | |||
319 | } | |||
320 | ||||
321 | // when the cursor is inside of a table, table must NEVER be selectable | |||
322 | if( pView->GetWrtShell().GetTableFormat() ) | |||
323 | { | |||
324 | m_xRbAsTable->set_sensitive( false ); | |||
325 | m_xRbAsField->set_active(true); | |||
326 | m_xRbDbFormatFromDb->set_active(true); | |||
327 | } | |||
328 | else | |||
329 | { | |||
330 | m_xRbAsTable->set_active(true); | |||
331 | m_xRbDbFormatFromDb->set_active(true); | |||
332 | m_xIbDbcolOneFrom->set_sensitive( false ); | |||
333 | m_xIbDbcolAllFrom->set_sensitive( false ); | |||
334 | } | |||
335 | ||||
336 | // by default, select header button | |||
337 | m_xRbHeadlColnms->set_active(true); | |||
338 | m_xRbHeadlEmpty->set_active(false); | |||
339 | ||||
340 | m_xRbAsTable->connect_clicked( LINK(this, SwInsertDBColAutoPilot, PageHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubPageHdl)); | |||
341 | m_xRbAsField->connect_clicked( LINK(this, SwInsertDBColAutoPilot, PageHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubPageHdl)); | |||
342 | m_xRbAsText->connect_clicked( LINK(this, SwInsertDBColAutoPilot, PageHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubPageHdl)); | |||
343 | ||||
344 | m_xRbDbFormatFromDb->connect_clicked( LINK(this, SwInsertDBColAutoPilot, DBFormatHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubDBFormatHdl )); | |||
345 | m_xRbDbFormatFromUsr->connect_clicked( LINK(this, SwInsertDBColAutoPilot, DBFormatHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubDBFormatHdl )); | |||
346 | ||||
347 | m_xPbTableFormat->connect_clicked(LINK(this, SwInsertDBColAutoPilot, TableFormatHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTableFormatHdl )); | |||
348 | m_xPbTableAutofmt->connect_clicked(LINK(this, SwInsertDBColAutoPilot, AutoFormatHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubAutoFormatHdl )); | |||
349 | ||||
350 | m_xIbDbcolAllTo->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTableToFromHdl )); | |||
351 | m_xIbDbcolOneTo->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTableToFromHdl )); | |||
352 | m_xIbDbcolOneFrom->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTableToFromHdl )); | |||
353 | m_xIbDbcolAllFrom->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTableToFromHdl )); | |||
354 | m_xIbDbcolToEdit->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTableToFromHdl )); | |||
355 | ||||
356 | m_xCbTableHeadon->connect_clicked( LINK(this, SwInsertDBColAutoPilot, HeaderHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubHeaderHdl)); | |||
357 | m_xRbHeadlColnms->connect_clicked( LINK(this, SwInsertDBColAutoPilot, HeaderHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubHeaderHdl)); | |||
358 | m_xRbHeadlEmpty->connect_clicked( LINK(this, SwInsertDBColAutoPilot, HeaderHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubHeaderHdl)); | |||
359 | ||||
360 | m_xLbTextDbColumn->connect_changed( LINK( this, SwInsertDBColAutoPilot, TVSelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTVSelectHdl )); | |||
361 | m_xLbTableDbColumn->connect_changed( LINK( this, SwInsertDBColAutoPilot, TVSelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTVSelectHdl )); | |||
362 | m_xLbDbFormatFromUsr->connect_changed( LINK( this, SwInsertDBColAutoPilot, CBSelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubCBSelectHdl )); | |||
363 | m_xLbTableCol->connect_changed( LINK( this, SwInsertDBColAutoPilot, TVSelectHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubTVSelectHdl )); | |||
364 | ||||
365 | m_xLbTextDbColumn->connect_row_activated( LINK( this, SwInsertDBColAutoPilot, DblClickHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubDblClickHdl )); | |||
366 | m_xLbTableDbColumn->connect_row_activated( LINK( this, SwInsertDBColAutoPilot, DblClickHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubDblClickHdl )); | |||
367 | m_xLbTableCol->connect_row_activated( LINK( this, SwInsertDBColAutoPilot, DblClickHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwInsertDBColAutoPilot *>(this), &SwInsertDBColAutoPilot::LinkStubDblClickHdl )); | |||
368 | ||||
369 | for( size_t n = 0; n < aDBColumns.size(); ++n ) | |||
370 | { | |||
371 | const OUString& rS = aDBColumns[ n ]->sColumn; | |||
372 | m_xLbTableDbColumn->append_text(rS); | |||
373 | m_xLbTextDbColumn->append_text(rS); | |||
374 | } | |||
375 | m_xLbTextDbColumn->select(0); | |||
376 | m_xLbTableDbColumn->select(0); | |||
377 | ||||
378 | // read configuration | |||
379 | Load(); | |||
380 | ||||
381 | // lock size to widest config | |||
382 | m_xHeadFrame->set_size_request(m_xHeadFrame->get_preferred_size().Width(), -1); | |||
383 | // initialise Controls: | |||
384 | PageHdl(m_xRbAsTable->get_active() ? *m_xRbAsTable : *m_xRbAsField); | |||
385 | } | |||
386 | ||||
387 | SwInsertDBColAutoPilot::~SwInsertDBColAutoPilot() | |||
388 | { | |||
389 | } | |||
390 | ||||
391 | IMPL_LINK( SwInsertDBColAutoPilot, PageHdl, weld::Button&, rButton, void )void SwInsertDBColAutoPilot::LinkStubPageHdl(void * instance, weld::Button& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->PageHdl(data); } void SwInsertDBColAutoPilot ::PageHdl(weld::Button& rButton) | |||
392 | { | |||
393 | bool bShowTable = &rButton == m_xRbAsTable.get(); | |||
394 | ||||
395 | m_xHeadFrame->set_label(MnemonicGenerator::EraseAllMnemonicChars(rButton.get_label().replace('_', '~'))); | |||
396 | ||||
397 | m_xLbTextDbColumn->set_visible( !bShowTable ); | |||
398 | m_xIbDbcolToEdit->set_visible( !bShowTable ); | |||
399 | m_xEdDbText->set_visible( !bShowTable ); | |||
400 | m_xFtDbParaColl->set_visible( !bShowTable ); | |||
401 | m_xLbDbParaColl->set_visible( !bShowTable ); | |||
402 | ||||
403 | m_xLbTableDbColumn->set_visible( bShowTable ); | |||
404 | m_xIbDbcolAllTo->set_visible( bShowTable ); | |||
405 | m_xIbDbcolOneTo->set_visible( bShowTable ); | |||
406 | m_xIbDbcolOneFrom->set_visible( bShowTable ); | |||
407 | m_xIbDbcolAllFrom->set_visible( bShowTable ); | |||
408 | m_xFtTableCol->set_visible( bShowTable ); | |||
409 | m_xLbTableCol->set_visible( bShowTable ); | |||
410 | m_xCbTableHeadon->set_visible( bShowTable ); | |||
411 | m_xRbHeadlColnms->set_visible( bShowTable ); | |||
412 | m_xRbHeadlEmpty->set_visible( bShowTable ); | |||
413 | m_xPbTableFormat->set_visible( bShowTable ); | |||
414 | m_xPbTableAutofmt->set_visible( bShowTable ); | |||
415 | ||||
416 | if( bShowTable ) | |||
417 | m_xPbTableFormat->set_sensitive( 0 != m_xLbTableCol->n_children() ); | |||
418 | ||||
419 | TVSelectHdl( bShowTable ? *m_xLbTableDbColumn : *m_xLbTextDbColumn ); | |||
420 | } | |||
421 | ||||
422 | IMPL_LINK( SwInsertDBColAutoPilot, DBFormatHdl, weld::Button&, rButton, void )void SwInsertDBColAutoPilot::LinkStubDBFormatHdl(void * instance , weld::Button& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->DBFormatHdl(data); } void SwInsertDBColAutoPilot ::DBFormatHdl(weld::Button& rButton) | |||
423 | { | |||
424 | weld::TreeView& rBox = m_xRbAsTable->get_active() | |||
425 | ? ( m_xLbTableCol->get_id(0).isEmpty() | |||
426 | ? *m_xLbTableDbColumn | |||
427 | : *m_xLbTableCol ) | |||
428 | : *m_xLbTextDbColumn; | |||
429 | ||||
430 | SwInsDBColumn aSrch(rBox.get_selected_text()); | |||
431 | SwInsDBColumns::const_iterator it = aDBColumns.find( &aSrch ); | |||
432 | ||||
433 | bool bFromDB = m_xRbDbFormatFromDb.get() == &rButton; | |||
434 | (*it)->bIsDBFormat = bFromDB; | |||
435 | m_xLbDbFormatFromUsr->set_sensitive( !bFromDB ); | |||
436 | } | |||
437 | ||||
438 | IMPL_LINK( SwInsertDBColAutoPilot, TableToFromHdl, weld::Button&, rButton, void )void SwInsertDBColAutoPilot::LinkStubTableToFromHdl(void * instance , weld::Button& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->TableToFromHdl(data); } void SwInsertDBColAutoPilot ::TableToFromHdl(weld::Button& rButton) | |||
439 | { | |||
440 | bool bChgEnable = true, bEnableTo = true, bEnableFrom = true; | |||
441 | ||||
442 | if( &rButton == m_xIbDbcolAllTo.get() ) | |||
443 | { | |||
444 | bEnableTo = false; | |||
445 | ||||
446 | sal_Int32 n, nInsPos = m_xLbTableCol->get_selected_index(), | |||
447 | nCnt = m_xLbTableDbColumn->n_children(); | |||
448 | ||||
449 | m_xLbTableDbColumn->unselect_all(); | |||
450 | ||||
451 | m_xLbTableDbColumn->freeze(); | |||
452 | m_xLbTableCol->freeze(); | |||
453 | ||||
454 | if (nInsPos == -1) | |||
455 | for( n = 0; n < nCnt; ++n ) | |||
456 | m_xLbTableCol->append_text(m_xLbTableDbColumn->get_text(n)); | |||
457 | else | |||
458 | for( n = 0; n < nCnt; ++n, ++nInsPos ) | |||
459 | m_xLbTableCol->insert_text(nInsPos, m_xLbTableDbColumn->get_text(n)); | |||
460 | m_xLbTableDbColumn->clear(); | |||
461 | ||||
462 | m_xLbTableDbColumn->thaw(); | |||
463 | m_xLbTableCol->thaw(); | |||
464 | ||||
465 | m_xLbTableCol->select(nInsPos); | |||
466 | } | |||
467 | else if( &rButton == m_xIbDbcolOneTo.get() && | |||
468 | m_xLbTableDbColumn->get_selected_index() != -1 ) | |||
469 | { | |||
470 | sal_Int32 nInsPos = m_xLbTableCol->get_selected_index(), | |||
471 | nDelPos = m_xLbTableDbColumn->get_selected_index(); | |||
472 | m_xLbTableCol->insert_text(nInsPos, m_xLbTableDbColumn->get_text(nDelPos)); | |||
473 | m_xLbTableDbColumn->remove(nDelPos); | |||
474 | ||||
475 | m_xLbTableCol->select(nInsPos); | |||
476 | if (nDelPos >= m_xLbTableDbColumn->n_children()) | |||
477 | nDelPos = m_xLbTableDbColumn->n_children() - 1; | |||
478 | m_xLbTableDbColumn->select(nDelPos); | |||
479 | ||||
480 | bEnableTo = 0 != m_xLbTableDbColumn->n_children(); | |||
481 | } | |||
482 | else if( &rButton == m_xIbDbcolOneFrom.get() ) | |||
483 | { | |||
484 | if (m_xLbTableCol->get_selected_index() != -1) | |||
485 | { | |||
486 | sal_Int32 nInsPos, | |||
487 | nDelPos = m_xLbTableCol->get_selected_index(); | |||
488 | ||||
489 | // look for the right InsertPos!! | |||
490 | SwInsDBColumn aSrch(m_xLbTableCol->get_text(nDelPos)); | |||
491 | SwInsDBColumns::const_iterator it = aDBColumns.find( &aSrch ); | |||
492 | if( it == aDBColumns.begin() || (it+1) == aDBColumns.end() ) | |||
493 | nInsPos = it - aDBColumns.begin(); | |||
494 | else | |||
495 | { | |||
496 | nInsPos = -1; | |||
497 | while( ++it != aDBColumns.end() && | |||
498 | -1 == (nInsPos = m_xLbTableDbColumn-> | |||
499 | find_text( (*it)->sColumn )) ) | |||
500 | ; | |||
501 | } | |||
502 | ||||
503 | m_xLbTableDbColumn->insert_text(nInsPos, aSrch.sColumn); | |||
504 | m_xLbTableCol->remove( nDelPos ); | |||
505 | ||||
506 | if (nInsPos >= m_xLbTableDbColumn->n_children()) | |||
507 | nInsPos = m_xLbTableDbColumn->n_children() - 1; | |||
508 | m_xLbTableDbColumn->select(nInsPos); | |||
509 | ||||
510 | if (nDelPos >= m_xLbTableCol->n_children()) | |||
511 | nDelPos = m_xLbTableCol->n_children() - 1; | |||
512 | m_xLbTableCol->select(nDelPos); | |||
513 | } | |||
514 | else | |||
515 | bEnableTo = 0 != m_xLbTableDbColumn->n_children(); | |||
516 | ||||
517 | bEnableFrom = 0 != m_xLbTableCol->n_children(); | |||
518 | } | |||
519 | else if( &rButton == m_xIbDbcolAllFrom.get() ) | |||
520 | { | |||
521 | bEnableFrom = false; | |||
522 | ||||
523 | m_xLbTableDbColumn->freeze(); | |||
524 | m_xLbTableCol->freeze(); | |||
525 | ||||
526 | m_xLbTableDbColumn->clear(); | |||
527 | m_xLbTableCol->clear(); | |||
528 | for (size_t n = 0; n < aDBColumns.size(); ++n) | |||
529 | m_xLbTableDbColumn->append_text(aDBColumns[n]->sColumn); | |||
530 | ||||
531 | m_xLbTableDbColumn->thaw(); | |||
532 | m_xLbTableCol->thaw(); | |||
533 | ||||
534 | m_xLbTableDbColumn->select(0); | |||
535 | } | |||
536 | else if( &rButton == m_xIbDbcolToEdit.get() ) | |||
537 | { | |||
538 | bChgEnable = false; | |||
539 | // move data to Edit: | |||
540 | OUString aField(m_xLbTextDbColumn->get_selected_text()); | |||
541 | if( !aField.isEmpty() ) | |||
542 | { | |||
543 | OUString aStr( m_xEdDbText->get_text() ); | |||
544 | int nStartPos, nEndPos; | |||
545 | m_xEdDbText->get_selection_bounds(nStartPos, nEndPos); | |||
546 | sal_Int32 nPos = std::min(nStartPos, nEndPos); | |||
547 | sal_Int32 nMax = std::max(nStartPos, nEndPos); | |||
548 | const sal_Int32 nSel = nMax - nPos; | |||
549 | if( nSel ) | |||
550 | // first delete the existing selection | |||
551 | aStr = aStr.replaceAt( nPos, nSel, "" ); | |||
552 | ||||
553 | aField = OUStringChar(cDBFieldStart) + aField + OUStringChar(cDBFieldEnd); | |||
554 | if( !aStr.isEmpty() ) | |||
555 | { | |||
556 | if( nPos ) // one blank in front | |||
557 | { | |||
558 | sal_Unicode c = aStr[ nPos-1 ]; | |||
559 | if( '\n' != c && '\r' != c ) | |||
560 | aField = " " + aField; | |||
561 | } | |||
562 | if( nPos < aStr.getLength() ) // one blank behind | |||
563 | { | |||
564 | sal_Unicode c = aStr[ nPos ]; | |||
565 | if( '\n' != c && '\r' != c ) | |||
566 | aField += " "; | |||
567 | } | |||
568 | } | |||
569 | ||||
570 | m_xEdDbText->set_text( aStr.replaceAt( nPos, 0, aField ) ); | |||
571 | nPos += aField.getLength(); | |||
572 | m_xEdDbText->select_region(nPos, nPos); | |||
573 | } | |||
574 | } | |||
575 | ||||
576 | if( !bChgEnable ) | |||
577 | return; | |||
578 | ||||
579 | m_xIbDbcolOneTo->set_sensitive( bEnableTo ); | |||
580 | m_xIbDbcolAllTo->set_sensitive( bEnableTo ); | |||
581 | m_xIbDbcolOneFrom->set_sensitive( bEnableFrom ); | |||
582 | m_xIbDbcolAllFrom->set_sensitive( bEnableFrom ); | |||
583 | ||||
584 | m_xRbDbFormatFromDb->set_sensitive( false ); | |||
585 | m_xRbDbFormatFromUsr->set_sensitive( false ); | |||
586 | m_xLbDbFormatFromUsr->set_sensitive( false ); | |||
587 | ||||
588 | m_xPbTableFormat->set_sensitive( bEnableFrom ); | |||
589 | } | |||
590 | ||||
591 | IMPL_LINK(SwInsertDBColAutoPilot, DblClickHdl, weld::TreeView&, rBox, bool)bool SwInsertDBColAutoPilot::LinkStubDblClickHdl(void * instance , weld::TreeView& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->DblClickHdl(data); } bool SwInsertDBColAutoPilot ::DblClickHdl(weld::TreeView& rBox) | |||
592 | { | |||
593 | weld::Button* pButton = nullptr; | |||
594 | if( &rBox == m_xLbTextDbColumn.get() ) | |||
595 | pButton = m_xIbDbcolToEdit.get(); | |||
596 | else if( &rBox == m_xLbTableDbColumn.get() && m_xIbDbcolOneTo->get_sensitive() ) | |||
597 | pButton = m_xIbDbcolOneTo.get(); | |||
598 | else if( &rBox == m_xLbTableCol.get() && m_xIbDbcolOneFrom->get_sensitive() ) | |||
599 | pButton = m_xIbDbcolOneFrom.get(); | |||
600 | ||||
601 | if (pButton) | |||
602 | TableToFromHdl(*pButton); | |||
603 | ||||
604 | return true; | |||
605 | } | |||
606 | ||||
607 | IMPL_LINK_NOARG(SwInsertDBColAutoPilot, TableFormatHdl, weld::Button&, void)void SwInsertDBColAutoPilot::LinkStubTableFormatHdl(void * instance , weld::Button& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->TableFormatHdl(data); } void SwInsertDBColAutoPilot ::TableFormatHdl(__attribute__ ((unused)) weld::Button&) | |||
608 | { | |||
609 | SwWrtShell& rSh = pView->GetWrtShell(); | |||
610 | bool bNewSet = false; | |||
611 | if( !pTableSet ) | |||
612 | { | |||
613 | bNewSet = true; | |||
614 | pTableSet.reset(new SfxItemSet( rSh.GetAttrPool(), SwuiGetUITableAttrRange() )); | |||
615 | ||||
616 | // At first acquire the simple attributes | |||
617 | pTableSet->Put( SfxStringItem( FN_PARAM_TABLE_NAME((20000 + 1100)+44), rSh.GetUniqueTableName() )); | |||
618 | pTableSet->Put( SfxUInt16Item( FN_PARAM_TABLE_HEADLINE((20000 + 1100)+50), 1 ) ); | |||
619 | ||||
620 | pTableSet->Put( SfxUInt16Item( SID_BACKGRND_DESTINATION( 10000 + 404 ), | |||
621 | rSh.GetViewOptions()->GetTableDest() )); | |||
622 | ||||
623 | SvxBrushItem aBrush( RES_BACKGROUND ); | |||
624 | pTableSet->Put( aBrush ); | |||
625 | aBrush.SetWhich(SID_ATTR_BRUSH_ROW( 10000 + 368 )); | |||
626 | pTableSet->Put( aBrush ); | |||
627 | aBrush.SetWhich(SID_ATTR_BRUSH_TABLE( 10000 + 453 )); | |||
628 | pTableSet->Put( aBrush ); | |||
629 | ||||
630 | SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNERTypedWhichId<SvxBoxInfoItem>( 10000 + 23 ) ); | |||
631 | // table variant, when multiple table cells are selected | |||
632 | aBoxInfo.SetTable( true ); | |||
633 | // always show gap field | |||
634 | aBoxInfo.SetDist( true); | |||
635 | // set minimum size in tables and paragraphs | |||
636 | aBoxInfo.SetMinDist( false ); | |||
637 | // always set default-gap | |||
638 | aBoxInfo.SetDefDist( MIN_BORDER_DIST28 ); | |||
639 | // Single lines can have DontCare-status only in tables | |||
640 | aBoxInfo.SetValid( SvxBoxInfoItemValidFlags::DISABLE ); | |||
641 | pTableSet->Put( aBoxInfo ); | |||
642 | ||||
643 | SwGetCurColNumPara aPara; | |||
644 | const sal_uInt16 nNum = rSh.GetCurColNum( &aPara ); | |||
645 | long nWidth; | |||
646 | ||||
647 | if( nNum ) | |||
648 | { | |||
649 | nWidth = aPara.pPrtRect->Width(); | |||
650 | const SwFormatCol& rCol = aPara.pFrameFormat->GetCol(); | |||
651 | const SwColumns& rCols = rCol.GetColumns(); | |||
652 | ||||
653 | // initialise nStart and nEnd for nNum == 0 | |||
654 | long nWidth1 = 0, | |||
655 | nStart1 = 0, | |||
656 | nEnd1 = nWidth; | |||
657 | for( sal_uInt16 i = 0; i < nNum; ++i ) | |||
658 | { | |||
659 | const SwColumn* pCol = &rCols[i]; | |||
660 | nStart1 = pCol->GetLeft() + nWidth1; | |||
661 | nWidth1 += static_cast<long>(rCol.CalcColWidth( i, static_cast<sal_uInt16>(nWidth) )); | |||
662 | nEnd1 = nWidth1 - pCol->GetRight(); | |||
663 | } | |||
664 | if(nStart1 || nEnd1 != nWidth) | |||
665 | nWidth = nEnd1 - nStart1; | |||
666 | } | |||
667 | else | |||
668 | nWidth = rSh.GetAnyCurRect( | |||
669 | (FrameTypeFlags::FLY_ANY & rSh.GetFrameType( nullptr, true )) | |||
670 | ? CurRectType::FlyEmbeddedPrt | |||
671 | : CurRectType::PagePrt ).Width(); | |||
672 | ||||
673 | SwTabCols aTabCols; | |||
674 | aTabCols.SetRight( nWidth ); | |||
675 | aTabCols.SetRightMax( nWidth ); | |||
676 | pRep.reset(new SwTableRep( aTabCols )); | |||
677 | pRep->SetAlign( text::HoriOrientation::NONE ); | |||
678 | pRep->SetSpace( nWidth ); | |||
679 | pRep->SetWidth( nWidth ); | |||
680 | pRep->SetWidthPercent( 100 ); | |||
681 | pTableSet->Put( SwPtrItem( FN_TABLE_REP((20000 + 400) + 99), pRep.get() )); | |||
682 | ||||
683 | pTableSet->Put( SfxUInt16Item( SID_HTML_MODE(10000 + 414), | |||
684 | ::GetHtmlMode( pView->GetDocShell() ))); | |||
685 | } | |||
686 | ||||
687 | sal_Int32 nCols = m_xLbTableCol->n_children(); | |||
688 | if (nCols != pRep->GetAllColCount() && nCols > 0) | |||
689 | { | |||
690 | // Number of columns has changed: then the TabCols have to be adjusted | |||
691 | long nWidth = pRep->GetWidth(); | |||
692 | --nCols; | |||
693 | SwTabCols aTabCols( nCols ); | |||
694 | aTabCols.SetRight( nWidth ); | |||
695 | aTabCols.SetRightMax( nWidth ); | |||
696 | if( nCols ) | |||
697 | { | |||
698 | const sal_Int32 nStep = nWidth / (nCols+1); | |||
699 | for( sal_Int32 n = 0; n < nCols; ++n ) | |||
700 | { | |||
701 | aTabCols.Insert( nStep*(n+1), false, n ); | |||
702 | } | |||
703 | } | |||
704 | pRep.reset(new SwTableRep( aTabCols )); | |||
705 | pRep->SetAlign( text::HoriOrientation::NONE ); | |||
706 | pRep->SetSpace( nWidth ); | |||
707 | pRep->SetWidth( nWidth ); | |||
708 | pRep->SetWidthPercent( 100 ); | |||
709 | pTableSet->Put( SwPtrItem( FN_TABLE_REP((20000 + 400) + 99), pRep.get() )); | |||
710 | } | |||
711 | ||||
712 | SwAbstractDialogFactory& rFact = swui::GetFactory(); | |||
713 | ||||
714 | ScopedVclPtr<SfxAbstractTabDialog> pDlg(rFact.CreateSwTableTabDlg(m_xDialog.get(), pTableSet.get(), &rSh)); | |||
715 | if( RET_OK == pDlg->Execute() ) | |||
716 | pTableSet->Put( *pDlg->GetOutputItemSet() ); | |||
717 | else if( bNewSet ) | |||
718 | { | |||
719 | pTableSet.reset(); | |||
720 | pRep.reset(); | |||
721 | } | |||
722 | } | |||
723 | ||||
724 | IMPL_LINK_NOARG(SwInsertDBColAutoPilot, AutoFormatHdl, weld::Button&, void)void SwInsertDBColAutoPilot::LinkStubAutoFormatHdl(void * instance , weld::Button& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->AutoFormatHdl(data); } void SwInsertDBColAutoPilot ::AutoFormatHdl(__attribute__ ((unused)) weld::Button&) | |||
| ||||
725 | { | |||
726 | SwAbstractDialogFactory& rFact = swui::GetFactory(); | |||
727 | ||||
728 | ScopedVclPtr<AbstractSwAutoFormatDlg> pDlg(rFact.CreateSwAutoFormatDlg(m_xDialog.get(), pView->GetWrtShellPtr(), false, m_xTAutoFormat.get())); | |||
729 | if( RET_OK == pDlg->Execute()) | |||
730 | m_xTAutoFormat = pDlg->FillAutoFormatOfIndex(); | |||
731 | } | |||
732 | ||||
733 | IMPL_LINK(SwInsertDBColAutoPilot, TVSelectHdl, weld::TreeView&, rBox, void)void SwInsertDBColAutoPilot::LinkStubTVSelectHdl(void * instance , weld::TreeView& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->TVSelectHdl(data); } void SwInsertDBColAutoPilot ::TVSelectHdl(weld::TreeView& rBox) | |||
734 | { | |||
735 | weld::TreeView* pGetBox = &rBox; | |||
736 | ||||
737 | SwInsDBColumn aSrch(pGetBox->get_selected_text()); | |||
738 | SwInsDBColumns::const_iterator it = aDBColumns.find( &aSrch ); | |||
739 | ||||
740 | // set the selected FieldName at the FormatGroupBox, so that | |||
741 | // it's clear what field is configured by the format! | |||
742 | OUString sText( m_xFormatFrame->get_label().copy( 0, nGBFormatLen )); | |||
743 | if( aSrch.sColumn.isEmpty() ) | |||
744 | { | |||
745 | m_xRbDbFormatFromDb->set_sensitive( false ); | |||
746 | m_xRbDbFormatFromUsr->set_sensitive( false ); | |||
747 | m_xLbDbFormatFromUsr->set_sensitive( false ); | |||
748 | } | |||
749 | else | |||
750 | { | |||
751 | bool bEnableFormat = (*it)->bHasFormat; | |||
752 | m_xRbDbFormatFromDb->set_sensitive( bEnableFormat ); | |||
753 | m_xRbDbFormatFromUsr->set_sensitive( bEnableFormat ); | |||
754 | ||||
755 | if( bEnableFormat ) | |||
756 | { | |||
757 | sText += " (" + aSrch.sColumn + ")"; | |||
758 | } | |||
759 | ||||
760 | bool bIsDBFormat = (*it)->bIsDBFormat; | |||
761 | m_xRbDbFormatFromDb->set_active( bIsDBFormat ); | |||
762 | m_xRbDbFormatFromUsr->set_active( !bIsDBFormat ); | |||
763 | m_xLbDbFormatFromUsr->set_sensitive( !bIsDBFormat ); | |||
764 | if( !bIsDBFormat ) | |||
765 | m_xLbDbFormatFromUsr->SetDefFormat( (*it)->nUsrNumFormat ); | |||
766 | } | |||
767 | ||||
768 | m_xFormatFrame->set_label(sText); | |||
769 | ||||
770 | if (m_xLbTableCol->n_children()) | |||
771 | { | |||
772 | // to know later on, what ListBox was the "active", a Flag | |||
773 | // is remembered in the 1st entry | |||
774 | if (&rBox == m_xLbTableCol.get()) | |||
775 | m_xLbTableCol->set_id(0, "tablecols"); | |||
776 | else | |||
777 | m_xLbTableCol->set_id(0, OUString()); | |||
778 | } | |||
779 | } | |||
780 | ||||
781 | IMPL_LINK_NOARG(SwInsertDBColAutoPilot, CBSelectHdl, weld::ComboBox&, void)void SwInsertDBColAutoPilot::LinkStubCBSelectHdl(void * instance , weld::ComboBox& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->CBSelectHdl(data); } void SwInsertDBColAutoPilot ::CBSelectHdl(__attribute__ ((unused)) weld::ComboBox&) | |||
782 | { | |||
783 | weld::TreeView* pGetBox = m_xRbAsTable->get_active() | |||
784 | ? ( m_xLbTableCol->get_id(0).isEmpty() | |||
785 | ? m_xLbTableDbColumn.get() | |||
786 | : m_xLbTableCol.get() ) | |||
787 | : m_xLbTextDbColumn.get(); | |||
788 | ||||
789 | SwInsDBColumn aSrch(pGetBox->get_selected_text()); | |||
790 | SwInsDBColumns::const_iterator it = aDBColumns.find( &aSrch ); | |||
791 | ||||
792 | if( !aSrch.sColumn.isEmpty() ) | |||
793 | { | |||
794 | m_xLbDbFormatFromUsr->CallSelectHdl(); | |||
795 | (*it)->nUsrNumFormat = m_xLbDbFormatFromUsr->GetFormat(); | |||
796 | } | |||
797 | } | |||
798 | ||||
799 | IMPL_LINK( SwInsertDBColAutoPilot, HeaderHdl, weld::Button&, rButton, void )void SwInsertDBColAutoPilot::LinkStubHeaderHdl(void * instance , weld::Button& data) { return static_cast<SwInsertDBColAutoPilot *>(instance)->HeaderHdl(data); } void SwInsertDBColAutoPilot ::HeaderHdl(weld::Button& rButton) | |||
800 | { | |||
801 | if (&rButton == m_xCbTableHeadon.get()) | |||
802 | { | |||
803 | bool bEnable = m_xCbTableHeadon->get_active(); | |||
804 | ||||
805 | m_xRbHeadlColnms->set_sensitive( bEnable ); | |||
806 | m_xRbHeadlEmpty->set_sensitive( bEnable ); | |||
807 | } | |||
808 | } | |||
809 | ||||
810 | static void lcl_InsTextInArr( const OUString& rText, DB_Columns& rColArr ) | |||
811 | { | |||
812 | sal_Int32 nSttPos = 0, nFndPos; | |||
813 | while( -1 != ( nFndPos = rText.indexOf( '\x0A', nSttPos )) ) | |||
814 | { | |||
815 | if( 1 < nFndPos ) | |||
816 | { | |||
817 | rColArr.push_back(std::make_unique<DB_Column>(rText.copy(nSttPos, nFndPos -1))); | |||
818 | } | |||
819 | rColArr.push_back(std::make_unique<DB_Column>()); | |||
820 | nSttPos = nFndPos + 1; | |||
821 | } | |||
822 | if( nSttPos < rText.getLength() ) | |||
823 | { | |||
824 | rColArr.push_back(std::make_unique<DB_Column>(rText.copy(nSttPos))); | |||
825 | } | |||
826 | } | |||
827 | ||||
828 | bool SwInsertDBColAutoPilot::SplitTextToColArr( const OUString& rText, | |||
829 | DB_Columns& rColArr, | |||
830 | bool bInsField ) | |||
831 | { | |||
832 | // create each of the database columns from the text again | |||
833 | // and then save in an array | |||
834 | // database columns are in <> and must be present in the columns' array: | |||
835 | OUString sText( rText ); | |||
836 | sal_Int32 nFndPos, nEndPos, nSttPos = 0; | |||
837 | ||||
838 | while( -1 != ( nFndPos = sText.indexOf( cDBFieldStart, nSttPos ))) | |||
839 | { | |||
840 | nSttPos = nFndPos + 1; | |||
841 | nEndPos = sText.indexOf( cDBFieldEnd, nSttPos+1 ); | |||
842 | if( -1 != nEndPos ) | |||
843 | { | |||
844 | // Text in <> brackets found: what is it: | |||
845 | SwInsDBColumn aSrch( sText.copy( nSttPos, nEndPos - nSttPos )); | |||
846 | SwInsDBColumns::const_iterator it = aDBColumns.find( &aSrch ); | |||
847 | if( it != aDBColumns.end() ) | |||
848 | { | |||
849 | // that is a valid field | |||
850 | // so surely the text "before": | |||
851 | const SwInsDBColumn& rFndCol = **it; | |||
852 | ||||
853 | DB_Column* pNew; | |||
854 | ||||
855 | if( 1 < nSttPos ) | |||
856 | { | |||
857 | ::lcl_InsTextInArr( sText.copy( 0, nSttPos-1 ), rColArr ); | |||
858 | sText = sText.copy( nSttPos-1 ); | |||
859 | } | |||
860 | ||||
861 | sText = sText.copy( rFndCol.sColumn.getLength() + 2 ); | |||
862 | nSttPos = 0; | |||
863 | ||||
864 | sal_uInt16 nSubType = 0; | |||
865 | sal_uInt32 nFormat; | |||
866 | if( rFndCol.bHasFormat ) | |||
867 | { | |||
868 | if( rFndCol.bIsDBFormat ) | |||
869 | nFormat = static_cast<sal_uInt32>(rFndCol.nDBNumFormat); | |||
870 | else | |||
871 | { | |||
872 | nFormat = rFndCol.nUsrNumFormat; | |||
873 | nSubType = nsSwExtendedSubType::SUB_OWN_FMT; | |||
874 | } | |||
875 | } | |||
876 | else | |||
877 | nFormat = 0; | |||
878 | ||||
879 | if( bInsField ) | |||
880 | { | |||
881 | SwWrtShell& rSh = pView->GetWrtShell(); | |||
882 | SwDBFieldType aFieldType( rSh.GetDoc(), aSrch.sColumn, | |||
883 | aDBData ); | |||
884 | pNew = new DB_Column( rFndCol, *new SwDBField( | |||
885 | static_cast<SwDBFieldType*>(rSh.InsertFieldType( aFieldType )), | |||
886 | nFormat ) ); | |||
887 | if( nSubType ) | |||
888 | pNew->pField->SetSubType( nSubType ); | |||
889 | } | |||
890 | else | |||
891 | pNew = new DB_Column( rFndCol, nFormat ); | |||
892 | ||||
893 | rColArr.push_back( std::unique_ptr<DB_Column>(pNew) ); | |||
894 | } | |||
895 | } | |||
896 | } | |||
897 | ||||
898 | // don't forget the last text | |||
899 | if( !sText.isEmpty() ) | |||
900 | ::lcl_InsTextInArr( sText, rColArr ); | |||
901 | ||||
902 | return !rColArr.empty(); | |||
903 | } | |||
904 | ||||
905 | void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection, | |||
906 | Reference< XDataSource> const & xSource, | |||
907 | Reference< XConnection> const & xConnection, | |||
908 | Reference< sdbc::XResultSet > const & xResultSet_in ) | |||
909 | { | |||
910 | auto xResultSet = xResultSet_in; | |||
911 | ||||
912 | const Any* pSelection = rSelection.hasElements() ? rSelection.getConstArray() : nullptr; | |||
913 | SwWrtShell& rSh = pView->GetWrtShell(); | |||
914 | ||||
915 | //with the drag and drop interface no result set is initially available | |||
916 | bool bDisposeResultSet = false; | |||
917 | // we don't have a cursor, so we have to create our own RowSet | |||
918 | if ( !xResultSet.is() ) | |||
919 | { | |||
920 | xResultSet = SwDBManager::createCursor(aDBData.sDataSource,aDBData.sCommand,aDBData.nCommandType,xConnection,pView); | |||
921 | bDisposeResultSet = xResultSet.is(); | |||
922 | } | |||
923 | ||||
924 | Reference< sdbc::XRow > xRow(xResultSet, UNO_QUERY); | |||
925 | if ( !xRow.is() ) | |||
926 | return; | |||
927 | ||||
928 | rSh.StartAllAction(); | |||
929 | bool bUndo = rSh.DoesUndo(); | |||
930 | if( bUndo ) | |||
931 | rSh.StartUndo(); | |||
932 | ||||
933 | bool bAsTable = m_xRbAsTable->get_active(); | |||
934 | SvNumberFormatter& rNumFormatr = *rSh.GetNumberFormatter(); | |||
935 | ||||
936 | if( rSh.HasSelection() ) | |||
937 | rSh.DelRight(); | |||
938 | ||||
939 | std::unique_ptr<SwWait> pWait; | |||
940 | ||||
941 | Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY ); | |||
942 | Reference <XNameAccess> xCols = xColsSupp->getColumns(); | |||
943 | ||||
944 | uno::Reference<sdbcx::XRowLocate> xRowLocate(xResultSet, uno::UNO_QUERY_THROW); | |||
945 | ||||
946 | do{ // middle checked loop!! | |||
947 | if( bAsTable ) // fill in data as table | |||
948 | { | |||
949 | rSh.DoUndo( false ); | |||
950 | ||||
951 | sal_Int32 nCols = m_xLbTableCol->n_children(); | |||
952 | sal_Int32 nRows = 0; | |||
953 | if( m_xCbTableHeadon->get_active() ) | |||
954 | nRows++; | |||
955 | ||||
956 | if( pSelection ) | |||
957 | nRows += rSelection.getLength(); | |||
958 | else | |||
959 | ++nRows; | |||
960 | ||||
961 | // prepare the array for the selected columns | |||
962 | std::vector<SwInsDBColumn*> aColFields; | |||
963 | for( sal_Int32 n = 0; n < nCols; ++n ) | |||
964 | { | |||
965 | SwInsDBColumn aSrch(m_xLbTableCol->get_text(n)); | |||
966 | SwInsDBColumns::const_iterator it = aDBColumns.find( &aSrch ); | |||
967 | if (it != aDBColumns.end()) | |||
968 | aColFields.push_back(it->get()); | |||
969 | else { | |||
970 | OSL_ENSURE( false, "database column not found" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "970" ": "), "%s", "database column not found"); } } while (false); | |||
971 | } | |||
972 | } | |||
973 | ||||
974 | if( static_cast<size_t>(nCols) != aColFields.size() ) | |||
975 | { | |||
976 | OSL_ENSURE( false, "not all database columns found" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "976" ": "), "%s", "not all database columns found"); } } while (false); | |||
977 | nCols = static_cast<sal_Int32>(aColFields.size()); | |||
978 | } | |||
979 | ||||
980 | if(!nRows || !nCols) | |||
981 | { | |||
982 | OSL_ENSURE( false, "wrong parameters" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "982" ": "), "%s", "wrong parameters"); } } while (false ); | |||
983 | break; | |||
984 | } | |||
985 | ||||
986 | const SwModuleOptions* pModOpt = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetModuleConfig(); | |||
987 | ||||
988 | bool bHTML = 0 != (::GetHtmlMode( pView->GetDocShell() ) & HTMLMODE_ON); | |||
989 | rSh.InsertTable( | |||
990 | pModOpt->GetInsTableFlags(bHTML), | |||
991 | nRows, nCols, (pSelection ? m_xTAutoFormat.get(): nullptr) ); | |||
992 | rSh.MoveTable( GotoPrevTable, fnTableStart ); | |||
993 | ||||
994 | if( pSelection && pTableSet ) | |||
995 | SetTabSet(); | |||
996 | ||||
997 | SfxItemSet aTableSet( rSh.GetAttrPool(), svl::Items<RES_BOXATR_FORMAT, | |||
998 | RES_BOXATR_VALUE>{} ); | |||
999 | bool bIsAutoUpdateCells = rSh.IsAutoUpdateCells(); | |||
1000 | rSh.SetAutoUpdateCells( false ); | |||
1001 | ||||
1002 | if( m_xCbTableHeadon->get_active() ) | |||
1003 | { | |||
1004 | for( sal_Int32 n = 0; n < nCols; ++n ) | |||
1005 | { | |||
1006 | if( m_xRbHeadlColnms->get_active() ) | |||
1007 | { | |||
1008 | rSh.SwEditShell::Insert2( aColFields[ n ]->sColumn ); | |||
1009 | } | |||
1010 | rSh.GoNextCell(); | |||
1011 | } | |||
1012 | } | |||
1013 | else | |||
1014 | rSh.SetRowsToRepeat( 0 ); | |||
1015 | ||||
1016 | for( sal_Int32 i = 0 ; ; ++i ) | |||
1017 | { | |||
1018 | bool bBreak = false; | |||
1019 | try | |||
1020 | { | |||
1021 | if(pSelection) | |||
1022 | { | |||
1023 | bBreak = !xRowLocate->moveToBookmark(pSelection[i]); | |||
1024 | } | |||
1025 | else if(!i) | |||
1026 | bBreak = !xResultSet->first(); | |||
1027 | } | |||
1028 | catch (const Exception&) | |||
1029 | { | |||
1030 | bBreak = true; | |||
1031 | } | |||
1032 | if(bBreak) | |||
1033 | break; | |||
1034 | ||||
1035 | for( sal_Int32 n = 0; n < nCols; ++n ) | |||
1036 | { | |||
1037 | // at the very first time, NO GoNextCell, because we're | |||
1038 | // already in it. Also no GoNextCell after the Insert, | |||
1039 | // because an empty line is added at the end. | |||
1040 | if( i || n ) | |||
1041 | rSh.GoNextCell(); | |||
1042 | ||||
1043 | const SwInsDBColumn* pEntry = aColFields[ n ]; | |||
1044 | ||||
1045 | Reference< XColumn > xColumn; | |||
1046 | xCols->getByName(pEntry->sColumn) >>= xColumn; | |||
1047 | Reference< XPropertySet > xColumnProps( xColumn, UNO_QUERY ); | |||
1048 | sal_Int32 eDataType = 0; | |||
1049 | if( xColumnProps.is() ) | |||
1050 | { | |||
1051 | Any aType = xColumnProps->getPropertyValue("Type"); | |||
1052 | aType >>= eDataType; | |||
1053 | } | |||
1054 | try | |||
1055 | { | |||
1056 | if( pEntry->bHasFormat ) | |||
1057 | { | |||
1058 | SwTableBoxNumFormat aNumFormat( | |||
1059 | pEntry->bIsDBFormat ? static_cast<sal_uInt32>(pEntry->nDBNumFormat) | |||
1060 | : pEntry->nUsrNumFormat ); | |||
1061 | aTableSet.Put(aNumFormat); | |||
1062 | if( xColumn.is() ) | |||
1063 | { | |||
1064 | double fVal = xColumn->getDouble(); | |||
1065 | if( xColumn->wasNull() ) | |||
1066 | aTableSet.ClearItem( RES_BOXATR_VALUE ); | |||
1067 | else | |||
1068 | { | |||
1069 | if(rNumFormatr.GetType(aNumFormat.GetValue()) & SvNumFormatType::DATE) | |||
1070 | { | |||
1071 | ::Date aStandard(1,1,1900); | |||
1072 | if (rNumFormatr.GetNullDate() != aStandard) | |||
1073 | fVal += (aStandard - rNumFormatr.GetNullDate()); | |||
1074 | } | |||
1075 | aTableSet.Put( SwTableBoxValue( fVal )); | |||
1076 | } | |||
1077 | } | |||
1078 | else | |||
1079 | aTableSet.ClearItem( RES_BOXATR_VALUE ); | |||
1080 | rSh.SetTableBoxFormulaAttrs( aTableSet ); | |||
1081 | } | |||
1082 | //#i60207# don't insert binary data as string - creates a loop | |||
1083 | else if( DataType::BINARY == eDataType || | |||
1084 | DataType::VARBINARY == eDataType || | |||
1085 | DataType::LONGVARBINARY== eDataType || | |||
1086 | DataType::SQLNULL == eDataType || | |||
1087 | DataType::OTHER == eDataType || | |||
1088 | DataType::OBJECT == eDataType || | |||
1089 | DataType::DISTINCT == eDataType || | |||
1090 | DataType::STRUCT == eDataType || | |||
1091 | DataType::ARRAY == eDataType || | |||
1092 | DataType::BLOB == eDataType || | |||
1093 | DataType::CLOB == eDataType || | |||
1094 | DataType::REF == eDataType | |||
1095 | ) | |||
1096 | { | |||
1097 | // do nothing | |||
1098 | } | |||
1099 | else | |||
1100 | { | |||
1101 | const OUString sVal = xColumn->getString(); | |||
1102 | if(!xColumn->wasNull()) | |||
1103 | { | |||
1104 | rSh.SwEditShell::Insert2( sVal ); | |||
1105 | } | |||
1106 | } | |||
1107 | } | |||
1108 | catch (const Exception&) | |||
1109 | { | |||
1110 | TOOLS_WARN_EXCEPTION("sw", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException () ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "" << " " << exceptionToString(tools_warn_exception )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ( "sw"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "1110" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "" << " " << exceptionToString (tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "1110" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "" << " " << exceptionToString(tools_warn_exception )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ( "sw"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "1110" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "" << " " << exceptionToString (tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/dbinsdlg.cxx" ":" "1110" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); } while (false); | |||
1111 | } | |||
1112 | } | |||
1113 | ||||
1114 | if( !pSelection ) | |||
1115 | { | |||
1116 | if ( !xResultSet->next() ) | |||
1117 | break; | |||
1118 | } | |||
1119 | else if( i+1 >= rSelection.getLength() ) | |||
1120 | break; | |||
1121 | ||||
1122 | if( 10 == i ) | |||
1123 | pWait.reset(new SwWait( *pView->GetDocShell(), true )); | |||
1124 | } | |||
1125 | ||||
1126 | rSh.MoveTable( GotoCurrTable, fnTableStart ); | |||
1127 | if( !pSelection && ( pTableSet || m_xTAutoFormat )) | |||
1128 | { | |||
1129 | if( pTableSet ) | |||
1130 | SetTabSet(); | |||
1131 | ||||
1132 | if (m_xTAutoFormat) | |||
1133 | rSh.SetTableStyle(*m_xTAutoFormat); | |||
1134 | } | |||
1135 | rSh.SetAutoUpdateCells( bIsAutoUpdateCells ); | |||
1136 | } | |||
1137 | else // add data as fields/text | |||
1138 | { | |||
1139 | DB_Columns aColArr; | |||
1140 | if( SplitTextToColArr( m_xEdDbText->get_text(), aColArr, m_xRbAsField->get_active() ) ) | |||
1141 | { | |||
1142 | // now for each data set, we can iterate over the array | |||
1143 | // and add the data | |||
1144 | ||||
1145 | if( !rSh.IsSttPara() ) | |||
1146 | rSh.SwEditShell::SplitNode(); | |||
1147 | if( !rSh.IsEndPara() ) | |||
1148 | { | |||
1149 | rSh.SwEditShell::SplitNode(); | |||
1150 | rSh.SwCursorShell::Left(1,CRSR_SKIP_CHARS); | |||
1151 | } | |||
1152 | ||||
1153 | rSh.DoUndo( false ); | |||
1154 | ||||
1155 | SwTextFormatColl* pColl = nullptr; | |||
1156 | { | |||
1157 | const OUString sTmplNm(m_xLbDbParaColl->get_active_text()); | |||
1158 | if( sNoTmpl != sTmplNm ) | |||
1159 | { | |||
1160 | pColl = rSh.FindTextFormatCollByName( sTmplNm ); | |||
1161 | if( !pColl ) | |||
1162 | { | |||
1163 | const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( | |||
1164 | sTmplNm, SwGetPoolIdFromName::TxtColl ); | |||
1165 | if( USHRT_MAX(32767 *2 +1) != nId ) | |||
1166 | pColl = rSh.GetTextCollFromPool( nId ); | |||
1167 | else | |||
1168 | pColl = rSh.MakeTextFormatColl( sTmplNm ); | |||
1169 | } | |||
1170 | rSh.SetTextFormatColl( pColl ); | |||
1171 | } | |||
1172 | } | |||
1173 | ||||
1174 | // for adding as fields -> insert a "NextField" after | |||
1175 | // every data set | |||
1176 | SwDBFormatData aDBFormatData; | |||
1177 | Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); | |||
1178 | aDBFormatData.xFormatter.set(util::NumberFormatter::create(xContext), UNO_QUERY_THROW) ; | |||
1179 | ||||
1180 | Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY); | |||
1181 | if(xSourceProps.is()) | |||
1182 | { | |||
1183 | Any aFormats = xSourceProps->getPropertyValue("NumberFormatsSupplier"); | |||
1184 | if(aFormats.hasValue()) | |||
1185 | { | |||
1186 | Reference< util::XNumberFormatsSupplier> xSuppl; | |||
1187 | aFormats >>= xSuppl; | |||
1188 | if(xSuppl.is()) | |||
1189 | { | |||
1190 | Reference< XPropertySet > xSettings = xSuppl->getNumberFormatSettings(); | |||
1191 | Any aNull = xSettings->getPropertyValue("NullDate"); | |||
1192 | aNull >>= aDBFormatData.aNullDate; | |||
1193 | if(aDBFormatData.xFormatter.is()) | |||
1194 | aDBFormatData.xFormatter->attachNumberFormatsSupplier(xSuppl); | |||
1195 | } | |||
1196 | } | |||
1197 | } | |||
1198 | aDBFormatData.aLocale = LanguageTag( rSh.GetCurLang() ).getLocale(); | |||
1199 | SwDBNextSetField aNxtDBField( static_cast<SwDBNextSetFieldType*>(rSh. | |||
1200 | GetFieldType( 0, SwFieldIds::DbNextSet )), | |||
1201 | "1", aDBData ); | |||
1202 | ||||
1203 | bool bSetCursor = true; | |||
1204 | const size_t nCols = aColArr.size(); | |||
1205 | ::sw::mark::IMark* pMark = nullptr; | |||
1206 | for( sal_Int32 i = 0 ; ; ++i ) | |||
1207 | { | |||
1208 | bool bBreak = false; | |||
1209 | try | |||
1210 | { | |||
1211 | if(pSelection) | |||
1212 | { | |||
1213 | bBreak = !xRowLocate->moveToBookmark(pSelection[i]); | |||
1214 | } | |||
1215 | else if(!i) | |||
1216 | bBreak = !xResultSet->first(); | |||
1217 | } | |||
1218 | catch (const Exception&) | |||
1219 | { | |||
1220 | bBreak = true; | |||
1221 | } | |||
1222 | ||||
1223 | if(bBreak) | |||
1224 | break; | |||
1225 | ||||
1226 | for( size_t n = 0; n < nCols; ++n ) | |||
1227 | { | |||
1228 | DB_Column* pDBCol = aColArr[ n ].get(); | |||
1229 | OUString sIns; | |||
1230 | switch( pDBCol->eColType ) | |||
1231 | { | |||
1232 | case DB_Column::Type::FILLTEXT: | |||
1233 | sIns = *pDBCol->pText; | |||
1234 | break; | |||
1235 | ||||
1236 | case DB_Column::Type::SPLITPARA: | |||
1237 | rSh.SplitNode(); | |||
1238 | // when the template is not the same as the follow template, | |||
1239 | // the selected has to be set newly | |||
1240 | if( pColl && &pColl->GetNextTextFormatColl() != pColl ) | |||
1241 | rSh.SetTextFormatColl( pColl ); | |||
1242 | break; | |||
1243 | ||||
1244 | case DB_Column::Type::COL_FIELD: | |||
1245 | { | |||
1246 | std::unique_ptr<SwDBField> pField(static_cast<SwDBField *>( | |||
1247 | pDBCol->pField->CopyField().release())); | |||
1248 | double nValue = DBL_MAX1.7976931348623157e+308; | |||
1249 | ||||
1250 | Reference< XPropertySet > xColumnProps; | |||
1251 | xCols->getByName(pDBCol->pColInfo->sColumn) >>= xColumnProps; | |||
1252 | ||||
1253 | pField->SetExpansion( SwDBManager::GetDBField( | |||
1254 | xColumnProps, | |||
1255 | aDBFormatData, | |||
1256 | &nValue ) ); | |||
1257 | if( DBL_MAX1.7976931348623157e+308 != nValue ) | |||
1258 | { | |||
1259 | Any aType = xColumnProps->getPropertyValue("Type"); | |||
1260 | sal_Int32 eDataType = 0; | |||
1261 | aType >>= eDataType; | |||
1262 | if( DataType::DATE == eDataType || DataType::TIME == eDataType || | |||
1263 | DataType::TIMESTAMP == eDataType) | |||
1264 | ||||
1265 | { | |||
1266 | ::Date aStandard(1,1,1900); | |||
1267 | ::Date aCompare(aDBFormatData.aNullDate.Day , | |||
1268 | aDBFormatData.aNullDate.Month, | |||
1269 | aDBFormatData.aNullDate.Year); | |||
1270 | if(aStandard != aCompare) | |||
1271 | nValue += (aStandard - aCompare); | |||
1272 | } | |||
1273 | pField->ChgValue( nValue, true ); | |||
1274 | } | |||
1275 | pField->SetInitialized(); | |||
1276 | ||||
1277 | rSh.Insert( *pField ); | |||
1278 | } | |||
1279 | break; | |||
1280 | ||||
1281 | case DB_Column::Type::COL_TEXT: | |||
1282 | { | |||
1283 | double nValue = DBL_MAX1.7976931348623157e+308; | |||
1284 | Reference< XPropertySet > xColumnProps; | |||
1285 | xCols->getByName(pDBCol->pColInfo->sColumn) >>= xColumnProps; | |||
1286 | sIns = SwDBManager::GetDBField( | |||
1287 | xColumnProps, | |||
1288 | aDBFormatData, | |||
1289 | &nValue ); | |||
1290 | if( pDBCol->nFormat && | |||
1291 | DBL_MAX1.7976931348623157e+308 != nValue ) | |||
1292 | { | |||
1293 | const Color* pCol; | |||
1294 | if(rNumFormatr.GetType(pDBCol->nFormat) & SvNumFormatType::DATE) | |||
1295 | { | |||
1296 | ::Date aStandard(1,1,1900); | |||
1297 | if (rNumFormatr.GetNullDate() != aStandard) | |||
1298 | nValue += (aStandard - rNumFormatr.GetNullDate()); | |||
1299 | } | |||
1300 | rNumFormatr.GetOutputString( nValue, | |||
1301 | pDBCol->nFormat, | |||
1302 | sIns, &pCol ); | |||
1303 | } | |||
1304 | } | |||
1305 | break; | |||
1306 | } | |||
1307 | ||||
1308 | if( !sIns.isEmpty() ) | |||
1309 | { | |||
1310 | rSh.Insert( sIns ); | |||
1311 | ||||
1312 | if( bSetCursor) | |||
1313 | { | |||
1314 | // to the beginning and set a mark, so that | |||
1315 | // the cursor can be set to the initial position | |||
1316 | // at the end. | |||
1317 | ||||
1318 | rSh.SwCursorShell::MovePara( | |||
1319 | GoCurrPara, fnParaStart ); | |||
1320 | pMark = rSh.SetBookmark( | |||
1321 | vcl::KeyCode(), | |||
1322 | OUString(), | |||
1323 | IDocumentMarkAccess::MarkType::UNO_BOOKMARK ); | |||
1324 | rSh.SwCursorShell::MovePara( | |||
1325 | GoCurrPara, fnParaEnd ); | |||
1326 | bSetCursor = false; | |||
1327 | } | |||
1328 | } | |||
1329 | } | |||
1330 | ||||
1331 | if( !pSelection ) | |||
1332 | { | |||
1333 | bool bNext = xResultSet->next(); | |||
1334 | if(!bNext) | |||
1335 | break; | |||
1336 | } | |||
1337 | else if( i+1 >= rSelection.getLength() ) | |||
1338 | break; | |||
1339 | ||||
1340 | if( m_xRbAsField->get_active() ) | |||
1341 | rSh.Insert( aNxtDBField ); | |||
1342 | ||||
1343 | if( !rSh.IsSttPara() ) | |||
1344 | rSh.SwEditShell::SplitNode(); | |||
1345 | ||||
1346 | if( 10 == i ) | |||
1347 | pWait.reset(new SwWait( *pView->GetDocShell(), true )); | |||
1348 | } | |||
1349 | ||||
1350 | if( !bSetCursor && pMark != nullptr) | |||
1351 | { | |||
1352 | rSh.SetMark(); | |||
1353 | rSh.GotoMark( pMark ); | |||
1354 | rSh.getIDocumentMarkAccess()->deleteMark( pMark ); | |||
1355 | break; | |||
1356 | } | |||
1357 | } | |||
1358 | } | |||
1359 | // write configuration | |||
1360 | Commit(); | |||
1361 | }while( false ); // middle checked loop | |||
1362 | ||||
1363 | if( bUndo ) | |||
1364 | { | |||
1365 | rSh.DoUndo(); | |||
1366 | rSh.AppendUndoForInsertFromDB( bAsTable ); | |||
1367 | rSh.EndUndo(); | |||
1368 | } | |||
1369 | rSh.ClearMark(); | |||
1370 | rSh.EndAllAction(); | |||
1371 | ||||
1372 | if ( bDisposeResultSet ) | |||
1373 | ::comphelper::disposeComponent(xResultSet); | |||
1374 | } | |||
1375 | ||||
1376 | void SwInsertDBColAutoPilot::SetTabSet() | |||
1377 | { | |||
1378 | SwWrtShell& rSh = pView->GetWrtShell(); | |||
1379 | const SfxPoolItem* pItem; | |||
1380 | ||||
1381 | if (m_xTAutoFormat) | |||
1382 | { | |||
1383 | if (m_xTAutoFormat->IsFrame()) | |||
1384 | { | |||
1385 | // border is from AutoFormat | |||
1386 | pTableSet->ClearItem( RES_BOX ); | |||
1387 | pTableSet->ClearItem( SID_ATTR_BORDER_INNERTypedWhichId<SvxBoxInfoItem>( 10000 + 23 ) ); | |||
1388 | } | |||
1389 | if (m_xTAutoFormat->IsBackground()) | |||
1390 | { | |||
1391 | pTableSet->ClearItem( RES_BACKGROUND ); | |||
1392 | pTableSet->ClearItem( SID_ATTR_BRUSH_ROW( 10000 + 368 ) ); | |||
1393 | pTableSet->ClearItem( SID_ATTR_BRUSH_TABLE( 10000 + 453 ) ); | |||
1394 | } | |||
1395 | } | |||
1396 | else | |||
1397 | { | |||
1398 | // remove the defaults again, it makes no sense to set them | |||
1399 | SvxBrushItem aBrush( RES_BACKGROUND ); | |||
1400 | static const sal_uInt16 aIds[3] = | |||
1401 | { RES_BACKGROUND, SID_ATTR_BRUSH_ROW( 10000 + 368 ), SID_ATTR_BRUSH_TABLE( 10000 + 453 ) }; | |||
1402 | for(sal_uInt16 i : aIds) | |||
1403 | if( SfxItemState::SET == pTableSet->GetItemState( i, | |||
1404 | false, &pItem ) && *pItem == aBrush ) | |||
1405 | pTableSet->ClearItem( i ); | |||
1406 | } | |||
1407 | ||||
1408 | if( SfxItemState::SET == pTableSet->GetItemState( FN_PARAM_TABLE_NAME((20000 + 1100)+44), false, | |||
1409 | &pItem ) && static_cast<const SfxStringItem*>(pItem)->GetValue() == | |||
1410 | rSh.GetTableFormat()->GetName() ) | |||
1411 | pTableSet->ClearItem( FN_PARAM_TABLE_NAME((20000 + 1100)+44) ); | |||
1412 | ||||
1413 | rSh.MoveTable( GotoCurrTable, fnTableStart ); | |||
1414 | rSh.SetMark(); | |||
1415 | rSh.MoveTable( GotoCurrTable, fnTableEnd ); | |||
1416 | ||||
1417 | ItemSetToTableParam( *pTableSet, rSh ); | |||
1418 | ||||
1419 | rSh.ClearMark(); | |||
1420 | rSh.MoveTable( GotoCurrTable, fnTableStart ); | |||
1421 | } | |||
1422 | ||||
1423 | static Sequence<OUString> lcl_createSourceNames(const OUString& rNodeName) | |||
1424 | { | |||
1425 | Sequence<OUString> aSourceNames(11); | |||
1426 | OUString* pNames = aSourceNames.getArray(); | |||
1427 | pNames[0] = rNodeName + "/DataSource"; | |||
1428 | pNames[1] = rNodeName + "/Command"; | |||
1429 | pNames[2] = rNodeName + "/CommandType"; | |||
1430 | pNames[3] = rNodeName + "/ColumnsToText"; | |||
1431 | pNames[4] = rNodeName + "/ColumnsToTable"; | |||
1432 | pNames[5] = rNodeName + "/ParaStyle"; | |||
1433 | pNames[6] = rNodeName + "/TableAutoFormat"; | |||
1434 | pNames[7] = rNodeName + "/IsTable"; | |||
1435 | pNames[8] = rNodeName + "/IsField"; | |||
1436 | pNames[9] = rNodeName + "/IsHeadlineOn"; | |||
1437 | pNames[10] = rNodeName + "/IsEmptyHeadline"; | |||
1438 | return aSourceNames; | |||
1439 | } | |||
1440 | ||||
1441 | static Sequence<OUString> lcl_CreateSubNames(const OUString& rSubNodeName) | |||
1442 | { | |||
1443 | Sequence<OUString> aSubSourceNames(6); | |||
1444 | OUString* pNames = aSubSourceNames.getArray(); | |||
1445 | pNames[0] = rSubNodeName + "/ColumnName"; | |||
1446 | pNames[1] = rSubNodeName + "/ColumnIndex"; | |||
1447 | pNames[2] = rSubNodeName + "/IsNumberFormat"; | |||
1448 | pNames[3] = rSubNodeName + "/IsNumberFormatFromDataBase"; | |||
1449 | pNames[4] = rSubNodeName + "/NumberFormat"; | |||
1450 | pNames[5] = rSubNodeName + "/NumberFormatLocale"; | |||
1451 | return aSubSourceNames; | |||
1452 | } | |||
1453 | ||||
1454 | static OUString lcl_CreateUniqueName(const Sequence<OUString>& aNames) | |||
1455 | { | |||
1456 | sal_Int32 nIdx = aNames.getLength(); | |||
1457 | while(true) | |||
1458 | { | |||
1459 | const OUString sRet = "_" + OUString::number(nIdx++); | |||
1460 | if ( comphelper::findValue(aNames, sRet) == -1 ) | |||
1461 | return sRet; // No match found, return unique name | |||
1462 | } | |||
1463 | } | |||
1464 | ||||
1465 | void SwInsertDBColAutoPilot::Notify( const css::uno::Sequence< OUString >& ) {} | |||
1466 | ||||
1467 | void SwInsertDBColAutoPilot::ImplCommit() | |||
1468 | { | |||
1469 | Sequence <OUString> aNames = GetNodeNames(OUString()); | |||
1470 | //remove entries that contain this data source + table at first | |||
1471 | for(OUString const & nodeName : std::as_const(aNames)) | |||
1472 | { | |||
1473 | Sequence<OUString> aSourceNames(2); | |||
1474 | OUString* pSourceNames = aSourceNames.getArray(); | |||
1475 | pSourceNames[0] = nodeName + "/DataSource"; | |||
1476 | pSourceNames[1] = nodeName + "/Command"; | |||
1477 | Sequence<Any> aSourceProperties = GetProperties(aSourceNames); | |||
1478 | const Any* pSourceProps = aSourceProperties.getArray(); | |||
1479 | OUString sSource, sCommand; | |||
1480 | pSourceProps[0] >>= sSource; | |||
1481 | pSourceProps[1] >>= sCommand; | |||
1482 | if(sSource==aDBData.sDataSource && sCommand==aDBData.sCommand) | |||
1483 | { | |||
1484 | Sequence<OUString> aElements { nodeName }; | |||
1485 | ClearNodeElements(OUString(), aElements); | |||
1486 | } | |||
1487 | } | |||
1488 | ||||
1489 | aNames = GetNodeNames(OUString()); | |||
1490 | OUString sNewNode = lcl_CreateUniqueName(aNames); | |||
1491 | Sequence<OUString> aNodeNames = lcl_createSourceNames(sNewNode); | |||
1492 | Sequence<PropertyValue> aValues(aNodeNames.getLength()); | |||
1493 | PropertyValue* pValues = aValues.getArray(); | |||
1494 | const OUString* pNodeNames = aNodeNames.getConstArray(); | |||
1495 | for(sal_Int32 i = 0; i < aNodeNames.getLength(); i++) | |||
1496 | { | |||
1497 | pValues[i].Name = "/" + pNodeNames[i]; | |||
1498 | } | |||
1499 | ||||
1500 | pValues[0].Value <<= aDBData.sDataSource; | |||
1501 | pValues[1].Value <<= aDBData.sCommand; | |||
1502 | pValues[2].Value <<= aDBData.nCommandType; | |||
1503 | pValues[3].Value <<= m_xEdDbText->get_text(); | |||
1504 | ||||
1505 | OUString sTmp; | |||
1506 | const sal_Int32 nCnt = m_xLbTableCol->n_children(); | |||
1507 | for( sal_Int32 n = 0; n < nCnt; ++n ) | |||
1508 | sTmp += m_xLbTableCol->get_text(n) + "\x0a"; | |||
1509 | ||||
1510 | if (!sTmp.isEmpty()) | |||
1511 | pValues[4].Value <<= sTmp; | |||
1512 | ||||
1513 | if( sNoTmpl != (sTmp = m_xLbDbParaColl->get_active_text()) ) | |||
1514 | pValues[5].Value <<= sTmp; | |||
1515 | ||||
1516 | if (m_xTAutoFormat) | |||
1517 | pValues[6].Value <<= m_xTAutoFormat->GetName(); | |||
1518 | ||||
1519 | pValues[7].Value <<= m_xRbAsTable->get_active(); | |||
1520 | pValues[8].Value <<= m_xRbAsField->get_active(); | |||
1521 | pValues[9].Value <<= m_xCbTableHeadon->get_active(); | |||
1522 | pValues[10].Value <<= m_xRbHeadlEmpty->get_active(); | |||
1523 | ||||
1524 | SetSetProperties(OUString(), aValues); | |||
1525 | ||||
1526 | sNewNode += "/ColumnSet"; | |||
1527 | ||||
1528 | LanguageType ePrevLang(0xffff); | |||
1529 | ||||
1530 | SvNumberFormatter& rNFormatr = *pView->GetWrtShell().GetNumberFormatter(); | |||
1531 | for(size_t nCol = 0; nCol < aDBColumns.size(); nCol++) | |||
1532 | { | |||
1533 | SwInsDBColumn* pColumn = aDBColumns[nCol].get(); | |||
1534 | OUString sColumnInsertNode(sNewNode + "/__"); | |||
1535 | if( nCol < 10 ) | |||
1536 | sColumnInsertNode += "00"; | |||
1537 | else if( nCol < 100 ) | |||
1538 | sColumnInsertNode += "0"; | |||
1539 | sColumnInsertNode += OUString::number( nCol ); | |||
1540 | ||||
1541 | const Sequence <OUString> aSubNodeNames = lcl_CreateSubNames(sColumnInsertNode); | |||
1542 | Sequence<PropertyValue> aSubValues(aSubNodeNames.getLength()); | |||
1543 | PropertyValue* pSubValues = aSubValues.getArray(); | |||
1544 | sal_Int32 i = 0; | |||
1545 | ||||
1546 | for( const OUString& rSubNodeName : aSubNodeNames) | |||
1547 | pSubValues[i++].Name = rSubNodeName; | |||
1548 | pSubValues[0].Value <<= pColumn->sColumn; | |||
1549 | pSubValues[1].Value <<= i; | |||
1550 | pSubValues[2].Value <<= pColumn->bHasFormat; | |||
1551 | pSubValues[3].Value <<= pColumn->bIsDBFormat; | |||
1552 | ||||
1553 | SwStyleNameMapper::FillUIName( RES_POOLCOLL_STANDARD, sTmp ); | |||
1554 | const SvNumberformat* pNF = rNFormatr.GetEntry( pColumn->nUsrNumFormat ); | |||
1555 | LanguageType eLang; | |||
1556 | if( pNF ) | |||
1557 | { | |||
1558 | pSubValues[4].Value <<= pNF->GetFormatstring(); | |||
1559 | eLang = pNF->GetLanguage(); | |||
1560 | } | |||
1561 | else | |||
1562 | { | |||
1563 | pSubValues[4].Value <<= sTmp; | |||
1564 | eLang = GetAppLanguage(); | |||
1565 | } | |||
1566 | ||||
1567 | OUString sPrevLang; | |||
1568 | if( eLang != ePrevLang ) | |||
1569 | { | |||
1570 | sPrevLang = LanguageTag::convertToBcp47( eLang ); | |||
1571 | ePrevLang = eLang; | |||
1572 | } | |||
1573 | ||||
1574 | pSubValues[5].Value <<= sPrevLang; | |||
1575 | SetSetProperties(sNewNode, aSubValues); | |||
1576 | } | |||
1577 | } | |||
1578 | ||||
1579 | void SwInsertDBColAutoPilot::Load() | |||
1580 | { | |||
1581 | const Sequence<OUString> aNames = GetNodeNames(OUString()); | |||
1582 | SvNumberFormatter& rNFormatr = *pView->GetWrtShell().GetNumberFormatter(); | |||
1583 | for(OUString const & nodeName : aNames) | |||
1584 | { | |||
1585 | //search for entries with the appropriate data source and table | |||
1586 | Sequence<OUString> aSourceNames = lcl_createSourceNames(nodeName); | |||
1587 | ||||
1588 | Sequence< Any> aDataSourceProps = GetProperties(aSourceNames); | |||
1589 | const Any* pDataSourceProps = aDataSourceProps.getConstArray(); | |||
1590 | OUString sSource, sCommand; | |||
1591 | sal_Int16 nCommandType; | |||
1592 | pDataSourceProps[0] >>= sSource; | |||
1593 | pDataSourceProps[1] >>= sCommand; | |||
1594 | pDataSourceProps[2] >>= nCommandType; | |||
1595 | if(sSource == aDBData.sDataSource && sCommand == aDBData.sCommand) | |||
1596 | { | |||
1597 | std::unique_ptr<DB_ColumnConfigData> pNewData(new DB_ColumnConfigData); | |||
1598 | ||||
1599 | pDataSourceProps[3] >>= pNewData->sEdit; | |||
1600 | pDataSourceProps[4] >>= pNewData->sTableList; | |||
1601 | pDataSourceProps[5] >>= pNewData->sTmplNm; | |||
1602 | pDataSourceProps[6] >>= pNewData->sTAutoFormatNm; | |||
1603 | if(pDataSourceProps[7].hasValue()) | |||
1604 | pNewData->bIsTable = *o3tl::doAccess<bool>(pDataSourceProps[7]); | |||
1605 | if(pDataSourceProps[8].hasValue()) | |||
1606 | pNewData->bIsField = *o3tl::doAccess<bool>(pDataSourceProps[8]); | |||
1607 | if(pDataSourceProps[9].hasValue()) | |||
1608 | pNewData->bIsHeadlineOn = *o3tl::doAccess<bool>(pDataSourceProps[9]); | |||
1609 | if(pDataSourceProps[10].hasValue()) | |||
1610 | pNewData->bIsEmptyHeadln = *o3tl::doAccess<bool>(pDataSourceProps[10]); | |||
1611 | ||||
1612 | const OUString sSubNodeName(nodeName + "/ColumnSet/"); | |||
1613 | const Sequence <OUString> aSubNames = GetNodeNames(sSubNodeName); | |||
1614 | for(const OUString& rSubName : aSubNames) | |||
1615 | { | |||
1616 | Sequence <OUString> aSubNodeNames = | |||
1617 | lcl_CreateSubNames(sSubNodeName + rSubName); | |||
1618 | Sequence< Any> aSubProps = GetProperties(aSubNodeNames); | |||
1619 | const Any* pSubProps = aSubProps.getConstArray(); | |||
1620 | ||||
1621 | OUString sColumn; | |||
1622 | pSubProps[0] >>= sColumn; | |||
1623 | // check for existence of the loaded column name | |||
1624 | bool bFound = false; | |||
1625 | for(size_t nRealColumn = 0; nRealColumn < aDBColumns.size(); ++nRealColumn) | |||
1626 | { | |||
1627 | if(aDBColumns[nRealColumn]->sColumn == sColumn) | |||
1628 | { | |||
1629 | bFound = true; | |||
1630 | break; | |||
1631 | } | |||
1632 | } | |||
1633 | if(!bFound) | |||
1634 | continue; | |||
1635 | sal_Int16 nIndex = 0; | |||
1636 | pSubProps[1] >>= nIndex; | |||
1637 | std::unique_ptr<SwInsDBColumn> pInsDBColumn(new SwInsDBColumn(sColumn)); | |||
1638 | if(pSubProps[2].hasValue()) | |||
1639 | pInsDBColumn->bHasFormat = *o3tl::doAccess<bool>(pSubProps[2]); | |||
1640 | if(pSubProps[3].hasValue()) | |||
1641 | pInsDBColumn->bIsDBFormat = *o3tl::doAccess<bool>(pSubProps[3]); | |||
1642 | ||||
1643 | pSubProps[4] >>= pInsDBColumn->sUsrNumFormat; | |||
1644 | OUString sNumberFormatLocale; | |||
1645 | pSubProps[5] >>= sNumberFormatLocale; | |||
1646 | ||||
1647 | /* XXX Earlier versions wrote a Country-Language string in | |||
1648 | * SwInsertDBColAutoPilot::Commit() that here was read as | |||
1649 | * Language-Country with 2 characters copied to language, | |||
1650 | * 1 character separator and unconditionally 2 characters read | |||
1651 | * as country. So for 'DE-de' and locales that have similar | |||
1652 | * case-insensitive equal language/country combos that may have | |||
1653 | * worked, for all others not. FIXME if you need to read old | |||
1654 | * data that you were never able to read before. */ | |||
1655 | pInsDBColumn->eUsrNumFormatLng = LanguageTag::convertToLanguageType( sNumberFormatLocale ); | |||
1656 | ||||
1657 | pInsDBColumn->nUsrNumFormat = rNFormatr.GetEntryKey( pInsDBColumn->sUsrNumFormat, | |||
1658 | pInsDBColumn->eUsrNumFormatLng ); | |||
1659 | ||||
1660 | pNewData->aDBColumns.insert(std::move(pInsDBColumn)); | |||
1661 | } | |||
1662 | OUString sTmp( pNewData->sTableList ); | |||
1663 | if( !sTmp.isEmpty() ) | |||
1664 | { | |||
1665 | sal_Int32 n = 0; | |||
1666 | do { | |||
1667 | const OUString sEntry( sTmp.getToken( 0, '\x0a', n ) ); | |||
1668 | //preselect column - if they still exist! | |||
1669 | if (m_xLbTableDbColumn->find_text(sEntry) != -1) | |||
1670 | { | |||
1671 | m_xLbTableCol->append_text(sEntry); | |||
1672 | m_xLbTableDbColumn->remove_text(sEntry); | |||
1673 | } | |||
1674 | } while( n>=0 ); | |||
1675 | ||||
1676 | if (!m_xLbTableDbColumn->n_children()) | |||
1677 | { | |||
1678 | m_xIbDbcolAllTo->set_sensitive( false ); | |||
1679 | m_xIbDbcolOneTo->set_sensitive( false ); | |||
1680 | } | |||
1681 | m_xIbDbcolOneFrom->set_sensitive(true); | |||
1682 | m_xIbDbcolAllFrom->set_sensitive(true); | |||
1683 | } | |||
1684 | m_xEdDbText->set_text( pNewData->sEdit ); | |||
1685 | ||||
1686 | sTmp = pNewData->sTmplNm; | |||
1687 | if( !sTmp.isEmpty() ) | |||
1688 | m_xLbDbParaColl->set_active_text(sTmp); | |||
1689 | else | |||
1690 | m_xLbDbParaColl->set_active(0); | |||
1691 | ||||
1692 | m_xTAutoFormat.reset(); | |||
1693 | sTmp = pNewData->sTAutoFormatNm; | |||
1694 | if( !sTmp.isEmpty() ) | |||
1695 | { | |||
1696 | // then load the AutoFormat file and look for Autoformat first | |||
1697 | SwTableAutoFormatTable aAutoFormatTable; | |||
1698 | aAutoFormatTable.Load(); | |||
1699 | for( size_t nAutoFormat = aAutoFormatTable.size(); nAutoFormat; ) | |||
1700 | if( sTmp == aAutoFormatTable[ --nAutoFormat ].GetName() ) | |||
1701 | { | |||
1702 | m_xTAutoFormat.reset(new SwTableAutoFormat(aAutoFormatTable[nAutoFormat])); | |||
1703 | break; | |||
1704 | } | |||
1705 | } | |||
1706 | ||||
1707 | m_xRbAsTable->set_active( pNewData->bIsTable ); | |||
1708 | m_xRbAsField->set_active( pNewData->bIsField ); | |||
1709 | m_xRbAsText->set_active( !pNewData->bIsTable && !pNewData->bIsField ); | |||
1710 | ||||
1711 | m_xCbTableHeadon->set_active( pNewData->bIsHeadlineOn ); | |||
1712 | m_xRbHeadlColnms->set_active( !pNewData->bIsEmptyHeadln ); | |||
1713 | m_xRbHeadlEmpty->set_active( pNewData->bIsEmptyHeadln ); | |||
1714 | HeaderHdl(*m_xCbTableHeadon); | |||
1715 | ||||
1716 | // now copy the user defined Numberformat strings to the | |||
1717 | // Shell. Then only these are available as ID | |||
1718 | for( size_t n = 0; n < aDBColumns.size() ; ++n ) | |||
1719 | { | |||
1720 | SwInsDBColumn& rSet = *aDBColumns[ n ]; | |||
1721 | for( size_t m = 0; m < pNewData->aDBColumns.size() ; ++m ) | |||
1722 | { | |||
1723 | SwInsDBColumn& rGet = *pNewData->aDBColumns[ m ]; | |||
1724 | if(rGet.sColumn == rSet.sColumn) | |||
1725 | { | |||
1726 | if( rGet.bHasFormat && !rGet.bIsDBFormat ) | |||
1727 | { | |||
1728 | rSet.bIsDBFormat = false; | |||
1729 | rSet.nUsrNumFormat = rNFormatr.GetEntryKey( rGet.sUsrNumFormat, | |||
1730 | rGet.eUsrNumFormatLng ); | |||
1731 | if( NUMBERFORMAT_ENTRY_NOT_FOUND == rSet.nUsrNumFormat ) | |||
1732 | { | |||
1733 | sal_Int32 nCheckPos; | |||
1734 | SvNumFormatType nType; | |||
1735 | rNFormatr.PutEntry( rGet.sUsrNumFormat, nCheckPos, nType, | |||
1736 | rSet.nUsrNumFormat, rGet.eUsrNumFormatLng ); | |||
1737 | } | |||
1738 | } | |||
1739 | break; | |||
1740 | } | |||
1741 | } | |||
1742 | } | |||
1743 | ||||
1744 | // when the cursor is inside of a table, table must NEVER be selectable | |||
1745 | if( !m_xRbAsTable->get_sensitive() && m_xRbAsTable->get_active() ) | |||
1746 | m_xRbAsField->set_active(true); | |||
1747 | break; | |||
1748 | } | |||
1749 | } | |||
1750 | } | |||
1751 | ||||
1752 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_VCL_PTR_HXX |
21 | #define INCLUDED_VCL_PTR_HXX |
22 | |
23 | #include <sal/config.h> |
24 | |
25 | #include <rtl/ref.hxx> |
26 | |
27 | #include <utility> |
28 | #include <type_traits> |
29 | |
30 | #ifdef DBG_UTIL |
31 | #ifndef _WIN32 |
32 | #include <vcl/vclmain.hxx> |
33 | #endif |
34 | #endif |
35 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase( |
44 | int (*)[sizeof(T)]) |
45 | { return std::is_base_of<VclReferenceBase, T>::value; } |
46 | |
47 | } // namespace vcl::detail |
48 | |
49 | /** |
50 | * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses. |
51 | * |
52 | * For more details on the design please see vcl/README.lifecycle |
53 | * |
54 | * @param reference_type must be a subclass of vcl::Window |
55 | */ |
56 | template <class reference_type> |
57 | class VclPtr |
58 | { |
59 | static_assert( |
60 | vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>( |
61 | nullptr), |
62 | "template argument type must be derived from VclReferenceBase"); |
63 | |
64 | ::rtl::Reference<reference_type> m_rInnerRef; |
65 | |
66 | public: |
67 | /** Constructor... |
68 | */ |
69 | VclPtr() |
70 | : m_rInnerRef() |
71 | {} |
72 | |
73 | /** Constructor... |
74 | */ |
75 | VclPtr (reference_type * pBody) |
76 | : m_rInnerRef(pBody) |
77 | {} |
78 | |
79 | /** Constructor... that doesn't take a ref. |
80 | */ |
81 | VclPtr (reference_type * pBody, __sal_NoAcquire) |
82 | : m_rInnerRef(pBody, SAL_NO_ACQUIRE) |
83 | {} |
84 | |
85 | /** Up-casting conversion constructor: Copies interface reference. |
86 | |
87 | Does not work for up-casts to ambiguous bases. For the special case of |
88 | up-casting to Reference< XInterface >, see the corresponding conversion |
89 | operator. |
90 | |
91 | @param rRef another reference |
92 | */ |
93 | template< class derived_type > |
94 | VclPtr( |
95 | const VclPtr< derived_type > & rRef, |
96 | typename std::enable_if< |
97 | std::is_base_of<reference_type, derived_type>::value, int>::type |
98 | = 0 ) |
99 | : m_rInnerRef( static_cast<reference_type*>(rRef) ) |
100 | { |
101 | } |
102 | |
103 | #if defined(DBG_UTIL) && !defined(_WIN32) |
104 | virtual ~VclPtr() |
105 | { |
106 | assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain ::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 106, __extension__ __PRETTY_FUNCTION__)); |
107 | // We can be one of the intermediate counts, but if we are the last |
108 | // VclPtr keeping this object alive, then something forgot to call dispose(). |
109 | assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)) |
110 | && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)); |
111 | } |
112 | VclPtr(VclPtr const &) = default; |
113 | VclPtr(VclPtr &&) = default; |
114 | VclPtr & operator =(VclPtr const &) = default; |
115 | VclPtr & operator =(VclPtr &&) = default; |
116 | #endif |
117 | |
118 | /** |
119 | * A construction helper for VclPtr. Since VclPtr types are created |
120 | * with a reference-count of one - to help fit into the existing |
121 | * code-flow; this helps us to construct them easily. |
122 | * |
123 | * For more details on the design please see vcl/README.lifecycle |
124 | * |
125 | * @tparam reference_type must be a subclass of vcl::Window |
126 | */ |
127 | template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg) |
128 | { |
129 | return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ); |
130 | } |
131 | |
132 | /** Probably most common used: handle->someBodyOp(). |
133 | */ |
134 | reference_type * operator->() const |
135 | { |
136 | return m_rInnerRef.get(); |
137 | } |
138 | |
139 | /** Get the body. Can be used instead of operator->(). |
140 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
141 | are the same. |
142 | */ |
143 | reference_type * get() const |
144 | { |
145 | return m_rInnerRef.get(); |
146 | } |
147 | |
148 | void set(reference_type *pBody) |
149 | { |
150 | m_rInnerRef.set(pBody); |
151 | } |
152 | |
153 | void reset(reference_type *pBody) |
154 | { |
155 | m_rInnerRef.set(pBody); |
156 | } |
157 | |
158 | /** Up-casting copy assignment operator. |
159 | |
160 | Does not work for up-casts to ambiguous bases. |
161 | |
162 | @param rRef another reference |
163 | */ |
164 | template<typename derived_type> |
165 | typename std::enable_if< |
166 | std::is_base_of<reference_type, derived_type>::value, |
167 | VclPtr &>::type |
168 | operator =(VclPtr<derived_type> const & rRef) |
169 | { |
170 | m_rInnerRef.set(rRef.get()); |
171 | return *this; |
172 | } |
173 | |
174 | VclPtr & operator =(reference_type * pBody) |
175 | { |
176 | m_rInnerRef.set(pBody); |
177 | return *this; |
178 | } |
179 | |
180 | operator reference_type * () const |
181 | { |
182 | return m_rInnerRef.get(); |
183 | } |
184 | |
185 | explicit operator bool () const |
186 | { |
187 | return m_rInnerRef.get() != nullptr; |
188 | } |
189 | |
190 | void clear() |
191 | { |
192 | m_rInnerRef.clear(); |
193 | } |
194 | |
195 | void reset() |
196 | { |
197 | m_rInnerRef.clear(); |
198 | } |
199 | |
200 | void disposeAndClear() |
201 | { |
202 | // hold it alive for the lifetime of this method |
203 | ::rtl::Reference<reference_type> aTmp(m_rInnerRef); |
204 | m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-) |
205 | if (aTmp.get()) { |
206 | aTmp->disposeOnce(); |
207 | } |
208 | } |
209 | |
210 | /** Needed to place VclPtr's into STL collection. |
211 | */ |
212 | bool operator< (const VclPtr<reference_type> & handle) const |
213 | { |
214 | return (m_rInnerRef < handle.m_rInnerRef); |
215 | } |
216 | }; // class VclPtr |
217 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) { |
261 | return !(p1 == p2); |
262 | } |
263 | |
264 | /** |
265 | * A construction helper for a temporary VclPtr. Since VclPtr types |
266 | * are created with a reference-count of one - to help fit into |
267 | * the existing code-flow; this helps us to construct them easily. |
268 | * see also VclPtr::Create and ScopedVclPtr |
269 | * |
270 | * For more details on the design please see vcl/README.lifecycle |
271 | * |
272 | * @param reference_type must be a subclass of vcl::Window |
273 | */ |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
278 | template<typename... Arg> VclPtrInstance(Arg &&... arg) |
279 | : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
280 | { |
281 | } |
282 | |
283 | /** |
284 | * Override and disallow this, to prevent people accidentally calling it and actually |
285 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
286 | */ |
287 | template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete; |
288 | }; |
289 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
294 | /** Constructor... |
295 | */ |
296 | ScopedVclPtr() |
297 | : VclPtr<reference_type>() |
298 | {} |
299 | |
300 | /** Constructor |
301 | */ |
302 | ScopedVclPtr (reference_type * pBody) |
303 | : VclPtr<reference_type>(pBody) |
304 | {} |
305 | |
306 | /** Copy constructor... |
307 | */ |
308 | ScopedVclPtr (const VclPtr<reference_type> & handle) |
309 | : VclPtr<reference_type>(handle) |
310 | {} |
311 | |
312 | /** |
313 | Assignment that releases the last reference. |
314 | */ |
315 | void disposeAndReset(reference_type *pBody) |
316 | { |
317 | if (pBody != this->get()) { |
318 | VclPtr<reference_type>::disposeAndClear(); |
319 | VclPtr<reference_type>::set(pBody); |
320 | } |
321 | } |
322 | |
323 | /** |
324 | Assignment that releases the last reference. |
325 | */ |
326 | ScopedVclPtr<reference_type>& operator = (reference_type * pBody) |
327 | { |
328 | disposeAndReset(pBody); |
329 | return *this; |
330 | } |
331 | |
332 | /** Up-casting conversion constructor: Copies interface reference. |
333 | |
334 | Does not work for up-casts to ambiguous bases. For the special case of |
335 | up-casting to Reference< XInterface >, see the corresponding conversion |
336 | operator. |
337 | |
338 | @param rRef another reference |
339 | */ |
340 | template< class derived_type > |
341 | ScopedVclPtr( |
342 | const VclPtr< derived_type > & rRef, |
343 | typename std::enable_if< |
344 | std::is_base_of<reference_type, derived_type>::value, int>::type |
345 | = 0 ) |
346 | : VclPtr<reference_type>( rRef ) |
347 | { |
348 | } |
349 | |
350 | /** Up-casting assignment operator. |
351 | |
352 | Does not work for up-casts to ambiguous bases. |
353 | |
354 | @param rRef another VclPtr |
355 | */ |
356 | template<typename derived_type> |
357 | typename std::enable_if< |
358 | std::is_base_of<reference_type, derived_type>::value, |
359 | ScopedVclPtr &>::type |
360 | operator =(VclPtr<derived_type> const & rRef) |
361 | { |
362 | disposeAndReset(rRef.get()); |
363 | return *this; |
364 | } |
365 | |
366 | /** |
367 | * Override and disallow this, to prevent people accidentally calling it and actually |
368 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
369 | */ |
370 | template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete; |
371 | |
372 | ~ScopedVclPtr() |
373 | { |
374 | VclPtr<reference_type>::disposeAndClear(); |
375 | assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get( ) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 375, __extension__ __PRETTY_FUNCTION__)); // make sure there are no lingering references |
376 | } |
377 | |
378 | private: |
379 | // Most likely we don't want this default copy-constructor. |
380 | ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete; |
381 | // And certainly we don't want a default assignment operator. |
382 | ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete; |
383 | // And disallow reset as that doesn't call disposeAndClear on the original reference |
384 | void reset() = delete; |
385 | void reset(reference_type *pBody) = delete; |
386 | |
387 | protected: |
388 | ScopedVclPtr (reference_type * pBody, __sal_NoAcquire) |
389 | : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE) |
390 | {} |
391 | }; |
392 | |
393 | /** |
394 | * A construction helper for ScopedVclPtr. Since VclPtr types are created |
395 | * with a reference-count of one - to help fit into the existing |
396 | * code-flow; this helps us to construct them easily. |
397 | * |
398 | * For more details on the design please see vcl/README.lifecycle |
399 | * |
400 | * @param reference_type must be a subclass of vcl::Window |
401 | */ |
402 | #if defined _MSC_VER |
403 | #pragma warning(push) |
404 | #pragma warning(disable: 4521) // " multiple copy constructors specified" |
405 | #endif |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
410 | template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg) |
411 | : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
412 | { |
413 | } |
414 | |
415 | /** |
416 | * Override and disallow this, to prevent people accidentally calling it and actually |
417 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
418 | */ |
419 | template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete; |
420 | |
421 | private: |
422 | // Prevent the above perfect forwarding ctor from hijacking (accidental) |
423 | // attempts at ScopedVclPtrInstance copy construction (where the hijacking |
424 | // would typically lead to somewhat obscure error messages); both non-const |
425 | // and const variants are needed here, as the ScopedVclPtr base class has a |
426 | // const--variant copy ctor, so the implicitly declared copy ctor for |
427 | // ScopedVclPtrInstance would also be the const variant, so non-const copy |
428 | // construction attempts would be hijacked by the perfect forwarding ctor; |
429 | // but if we only declared a non-const variant here, the const variant would |
430 | // no longer be implicitly declared (as there would already be an explicitly |
431 | // declared copy ctor), so const copy construction attempts would then be |
432 | // hijacked by the perfect forwarding ctor: |
433 | ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete; |
434 | ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete; |
435 | }; |
436 | #if defined _MSC_VER |
437 | #pragma warning(pop) |
438 | #endif |
439 | |
440 | #endif // INCLUDED_VCL_PTR_HXX |
441 | |
442 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_RTL_REF_HXX | ||||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||||
22 | |||||||||
23 | #include "sal/config.h" | ||||||||
24 | |||||||||
25 | #include <cassert> | ||||||||
26 | #include <cstddef> | ||||||||
27 | #include <functional> | ||||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
29 | #include <type_traits> | ||||||||
30 | #endif | ||||||||
31 | |||||||||
32 | #include "sal/types.h" | ||||||||
33 | |||||||||
34 | namespace rtl | ||||||||
35 | { | ||||||||
36 | |||||||||
37 | /** Template reference class for reference type. | ||||||||
38 | */ | ||||||||
39 | template <class reference_type> | ||||||||
40 | class Reference | ||||||||
41 | { | ||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||
43 | */ | ||||||||
44 | reference_type * m_pBody; | ||||||||
45 | |||||||||
46 | |||||||||
47 | public: | ||||||||
48 | /** Constructor... | ||||||||
49 | */ | ||||||||
50 | Reference() | ||||||||
51 | : m_pBody (NULL__null) | ||||||||
52 | {} | ||||||||
53 | |||||||||
54 | |||||||||
55 | /** Constructor... | ||||||||
56 | */ | ||||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||||
58 | : m_pBody (pBody) | ||||||||
59 | { | ||||||||
60 | } | ||||||||
61 | |||||||||
62 | /** Constructor... | ||||||||
63 | */ | ||||||||
64 | Reference (reference_type * pBody) | ||||||||
65 | : m_pBody (pBody) | ||||||||
66 | { | ||||||||
67 | if (m_pBody) | ||||||||
68 | m_pBody->acquire(); | ||||||||
69 | } | ||||||||
70 | |||||||||
71 | /** Copy constructor... | ||||||||
72 | */ | ||||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||||
74 | : m_pBody (handle.m_pBody) | ||||||||
75 | { | ||||||||
76 | if (m_pBody) | ||||||||
77 | m_pBody->acquire(); | ||||||||
78 | } | ||||||||
79 | |||||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
81 | /** Move constructor... | ||||||||
82 | */ | ||||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||||
84 | : m_pBody (handle.m_pBody) | ||||||||
85 | { | ||||||||
86 | handle.m_pBody = nullptr; | ||||||||
87 | } | ||||||||
88 | #endif | ||||||||
89 | |||||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||||
92 | |||||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||||
94 | |||||||||
95 | @param rRef another reference | ||||||||
96 | */ | ||||||||
97 | template< class derived_type > | ||||||||
98 | inline Reference( | ||||||||
99 | const Reference< derived_type > & rRef, | ||||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||||
101 | : m_pBody (rRef.get()) | ||||||||
102 | { | ||||||||
103 | if (m_pBody) | ||||||||
104 | m_pBody->acquire(); | ||||||||
105 | } | ||||||||
106 | #endif | ||||||||
107 | |||||||||
108 | /** Destructor... | ||||||||
109 | */ | ||||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||||
111 | { | ||||||||
112 | if (m_pBody
| ||||||||
113 | m_pBody->release(); | ||||||||
114 | } | ||||||||
115 | |||||||||
116 | /** Set... | ||||||||
117 | Similar to assignment. | ||||||||
118 | */ | ||||||||
119 | Reference<reference_type> & | ||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||
121 | { | ||||||||
122 | if (pBody) | ||||||||
123 | pBody->acquire(); | ||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||
125 | m_pBody = pBody; | ||||||||
126 | if (pOld) | ||||||||
127 | pOld->release(); | ||||||||
128 | return *this; | ||||||||
129 | } | ||||||||
130 | |||||||||
131 | /** Assignment. | ||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||
133 | bind it to the body represented by the handle. | ||||||||
134 | */ | ||||||||
135 | Reference<reference_type> & | ||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||
137 | { | ||||||||
138 | return set( handle.m_pBody ); | ||||||||
139 | } | ||||||||
140 | |||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
142 | /** Assignment. | ||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||
144 | * bind it to the body represented by the handle, and | ||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||
146 | */ | ||||||||
147 | Reference<reference_type> & | ||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||
149 | { | ||||||||
150 | // self-movement guts ourself | ||||||||
151 | if (m_pBody) | ||||||||
152 | m_pBody->release(); | ||||||||
153 | m_pBody = handle.m_pBody; | ||||||||
154 | handle.m_pBody = nullptr; | ||||||||
155 | return *this; | ||||||||
156 | } | ||||||||
157 | #endif | ||||||||
158 | |||||||||
159 | /** Assignment... | ||||||||
160 | */ | ||||||||
161 | Reference<reference_type> & | ||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||
163 | { | ||||||||
164 | return set( pBody ); | ||||||||
165 | } | ||||||||
166 | |||||||||
167 | /** Unbind the body from this handle. | ||||||||
168 | Note that for a handle representing a large body, | ||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||
171 | since in the second case two large objects exist in memory | ||||||||
172 | (the old body and the new body). | ||||||||
173 | */ | ||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||
175 | { | ||||||||
176 | if (m_pBody) | ||||||||
177 | { | ||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||
179 | m_pBody = NULL__null; | ||||||||
180 | pOld->release(); | ||||||||
181 | } | ||||||||
182 | return *this; | ||||||||
183 | } | ||||||||
184 | |||||||||
185 | |||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||
188 | are the same. | ||||||||
189 | */ | ||||||||
190 | reference_type * SAL_CALL get() const | ||||||||
191 | { | ||||||||
192 | return m_pBody; | ||||||||
| |||||||||
193 | } | ||||||||
194 | |||||||||
195 | |||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||
197 | */ | ||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||
199 | { | ||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||
201 | return m_pBody; | ||||||||
202 | } | ||||||||
203 | |||||||||
204 | |||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||
206 | */ | ||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||
208 | { | ||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||
210 | return *m_pBody; | ||||||||
211 | } | ||||||||
212 | |||||||||
213 | |||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||
215 | */ | ||||||||
216 | bool SAL_CALL is() const | ||||||||
217 | { | ||||||||
218 | return (m_pBody != NULL__null); | ||||||||
219 | } | ||||||||
220 | |||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||
223 | */ | ||||||||
224 | explicit operator bool() const | ||||||||
225 | { | ||||||||
226 | return is(); | ||||||||
227 | } | ||||||||
228 | #endif | ||||||||
229 | |||||||||
230 | /** Returns True if this points to pBody. | ||||||||
231 | */ | ||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||
233 | { | ||||||||
234 | return (m_pBody == pBody); | ||||||||
235 | } | ||||||||
236 | |||||||||
237 | |||||||||
238 | /** Returns True if handle points to the same body. | ||||||||
239 | */ | ||||||||
240 | bool | ||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||
242 | { | ||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||
244 | } | ||||||||
245 | |||||||||
246 | |||||||||
247 | /** Needed to place References into STL collection. | ||||||||
248 | */ | ||||||||
249 | bool | ||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||
251 | { | ||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||
253 | } | ||||||||
254 | |||||||||
255 | |||||||||
256 | /** Needed to place References into STL collection. | ||||||||
257 | */ | ||||||||
258 | bool | ||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||
260 | { | ||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||
262 | } | ||||||||
263 | |||||||||
264 | |||||||||
265 | /** Needed to place References into STL collection. | ||||||||
266 | */ | ||||||||
267 | bool | ||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||
269 | { | ||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||
271 | } | ||||||||
272 | }; | ||||||||
273 | |||||||||
274 | } // namespace rtl | ||||||||
275 | |||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
277 | namespace std | ||||||||
278 | { | ||||||||
279 | |||||||||
280 | /// @cond INTERNAL | ||||||||
281 | /** | ||||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||||
283 | |||||||||
284 | @since LibreOffice 6.3 | ||||||||
285 | */ | ||||||||
286 | template<typename T> | ||||||||
287 | struct hash<::rtl::Reference<T>> | ||||||||
288 | { | ||||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||||
290 | { return std::size_t(s.get()); } | ||||||||
291 | }; | ||||||||
292 | /// @endcond | ||||||||
293 | |||||||||
294 | } | ||||||||
295 | |||||||||
296 | #endif | ||||||||
297 | |||||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||||
299 | |||||||||
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |