1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <dbinsdlg.hxx>
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>
52 #include <uiitems.hxx>
53 #include <viewopt.hxx>
58 #include <tblafmt.hxx>
59 #include <cellatr.hxx>
60 #include <swtablerep.hxx>
65 #include <swmodule.hxx>
66 #include <poolfmt.hxx>
67 #include <connectivity/dbtools.hxx>
70 #include <SwStyleNameMapper.hxx>
72 #include <swabstdlg.hxx>
73 #include <strings.hrc>
74 #include <IDocumentMarkAccess.hxx>
76 #include <o3tl/any.hxx>
79 #include <swuiexp.hxx>
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
;
91 const char cDBFieldStart
= '<';
92 const char cDBFieldEnd
= '>';
94 // Helper structure for adding database rows as fields or text
97 const enum class Type
{ FILLTEXT
, COL_FIELD
, COL_TEXT
, SPLITPARA
} eColType
;
104 const SwInsDBColumn
* pColInfo
;
106 DB_Column() : eColType(Type::SPLITPARA
),
111 explicit DB_Column( const OUString
& rText
)
112 : eColType(Type::FILLTEXT
),
113 pText(new OUString(rText
)),
117 DB_Column( const SwInsDBColumn
& rInfo
, sal_uInt32 nFormat_
)
118 : eColType(Type::COL_TEXT
),
123 DB_Column( const SwInsDBColumn
& rInfo
, SwDBField
& rField
)
124 : eColType(Type::COL_FIELD
),
131 if( Type::COL_FIELD
== eColType
)
133 else if( Type::FILLTEXT
== eColType
)
140 struct DB_ColumnConfigData
142 SwInsDBColumns aDBColumns
;
146 OUString sTAutoFormatNm
;
152 DB_ColumnConfigData(DB_ColumnConfigData
const&) = delete;
153 DB_ColumnConfigData
& operator=(DB_ColumnConfigData
const&) = delete;
155 DB_ColumnConfigData()
157 bIsTable
= bIsHeadlineOn
= true;
158 bIsField
= bIsEmptyHeadln
= false;
164 bool SwInsDBColumn::operator<( const SwInsDBColumn
& rCmp
) const
166 return 0 > GetAppCollator().compareString( sColumn
, rCmp
.sColumn
);
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
)
176 , sNoTmpl(SwResId(SW_STR_NONE
))
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"))
204 m_xEdDbText
->set_size_request(m_xEdDbText
->get_approximate_digit_width() * 40, -1);
205 m_xLbDbParaColl
->make_sorted();
207 nGBFormatLen
= m_xFormatFrame
->get_label().getLength();
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
);
218 Reference
<XPropertySet
> xSourceProps(xDataSource
, UNO_QUERY
);
219 Reference
< util::XNumberFormats
> xNumberFormats
;
220 if(xSourceProps
.is())
222 Any aFormats
= xSourceProps
->getPropertyValue("NumberFormatsSupplier");
223 if(aFormats
.hasValue())
225 Reference
< util::XNumberFormatsSupplier
> xSuppl
;
229 xNumberFormats
= xSuppl
->getNumberFormats( );
233 Reference
<XNameAccess
> xCols
= xColSupp
->getColumns();
234 const Sequence
<OUString
> aColNames
= xCols
->getElementNames();
235 for (const OUString
& rColName
: aColNames
)
237 std::unique_ptr
<SwInsDBColumn
> pNew(new SwInsDBColumn( rColName
));
238 Any aCol
= xCols
->getByName(rColName
);
239 Reference
<XPropertySet
> xCol
;
241 Any aType
= xCol
->getPropertyValue("Type");
242 sal_Int32 eDataType
= 0;
247 case DataType::BOOLEAN
:
248 case DataType::TINYINT
:
249 case DataType::SMALLINT
:
250 case DataType::INTEGER
:
251 case DataType::BIGINT
:
252 case DataType::FLOAT
:
254 case DataType::DOUBLE
:
255 case DataType::NUMERIC
:
256 case DataType::DECIMAL
:
259 case DataType::TIMESTAMP
:
261 pNew
->bHasFormat
= true;
262 Any aFormat
= xCol
->getPropertyValue("FormatKey");
263 if(aFormat
.hasValue())
265 sal_Int32 nFormat
= 0;
267 if(xNumberFormats
.is())
271 Reference
<XPropertySet
> xNumProps
= xNumberFormats
->getByKey( nFormat
);
272 Any aFormatVal
= xNumProps
->getPropertyValue("FormatString");
273 Any aLocale
= xNumProps
->getPropertyValue("Locale");
275 aFormatVal
>>= sFormat
;
278 sal_Int32 nKey
= xDocNumberFormats
->queryKey( sFormat
, aLoc
, true);
281 nKey
= xDocNumberFormats
->addNew( sFormat
, aLoc
);
283 pNew
->nDBNumFormat
= nKey
;
285 catch (const Exception
&)
287 OSL_FAIL("illegal number format key");
293 pNew
->nDBNumFormat
= getDefaultNumberFormat(xCol
,
294 xDocNumberFormatTypes
, LanguageTag( rSh
.GetCurLang() ).getLocale());
300 if( !aDBColumns
.insert( std::move(pNew
) ).second
)
302 OSL_ENSURE( false, "Spaltenname mehrfach vergeben?" );
307 // fill paragraph templates-ListBox
309 SfxStyleSheetBasePool
* pPool
= pView
->GetDocShell()->GetStyleSheetPool();
310 m_xLbDbParaColl
->append_text( sNoTmpl
);
312 const SfxStyleSheetBase
* pBase
= pPool
->First(SfxStyleFamily::Para
);
315 m_xLbDbParaColl
->append_text( pBase
->GetName() );
316 pBase
= pPool
->Next();
318 m_xLbDbParaColl
->set_active( 0 );
321 // when the cursor is inside of a table, table must NEVER be selectable
322 if( pView
->GetWrtShell().GetTableFormat() )
324 m_xRbAsTable
->set_sensitive( false );
325 m_xRbAsField
->set_active(true);
326 m_xRbDbFormatFromDb
->set_active(true);
330 m_xRbAsTable
->set_active(true);
331 m_xRbDbFormatFromDb
->set_active(true);
332 m_xIbDbcolOneFrom
->set_sensitive( false );
333 m_xIbDbcolAllFrom
->set_sensitive( false );
336 // by default, select header button
337 m_xRbHeadlColnms
->set_active(true);
338 m_xRbHeadlEmpty
->set_active(false);
340 m_xRbAsTable
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, PageHdl
));
341 m_xRbAsField
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, PageHdl
));
342 m_xRbAsText
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, PageHdl
));
344 m_xRbDbFormatFromDb
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, DBFormatHdl
));
345 m_xRbDbFormatFromUsr
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, DBFormatHdl
));
347 m_xPbTableFormat
->connect_clicked(LINK(this, SwInsertDBColAutoPilot
, TableFormatHdl
));
348 m_xPbTableAutofmt
->connect_clicked(LINK(this, SwInsertDBColAutoPilot
, AutoFormatHdl
));
350 m_xIbDbcolAllTo
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, TableToFromHdl
));
351 m_xIbDbcolOneTo
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, TableToFromHdl
));
352 m_xIbDbcolOneFrom
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, TableToFromHdl
));
353 m_xIbDbcolAllFrom
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, TableToFromHdl
));
354 m_xIbDbcolToEdit
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, TableToFromHdl
));
356 m_xCbTableHeadon
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, HeaderHdl
));
357 m_xRbHeadlColnms
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, HeaderHdl
));
358 m_xRbHeadlEmpty
->connect_clicked( LINK(this, SwInsertDBColAutoPilot
, HeaderHdl
));
360 m_xLbTextDbColumn
->connect_changed( LINK( this, SwInsertDBColAutoPilot
, TVSelectHdl
));
361 m_xLbTableDbColumn
->connect_changed( LINK( this, SwInsertDBColAutoPilot
, TVSelectHdl
));
362 m_xLbDbFormatFromUsr
->connect_changed( LINK( this, SwInsertDBColAutoPilot
, CBSelectHdl
));
363 m_xLbTableCol
->connect_changed( LINK( this, SwInsertDBColAutoPilot
, TVSelectHdl
));
365 m_xLbTextDbColumn
->connect_row_activated( LINK( this, SwInsertDBColAutoPilot
, DblClickHdl
));
366 m_xLbTableDbColumn
->connect_row_activated( LINK( this, SwInsertDBColAutoPilot
, DblClickHdl
));
367 m_xLbTableCol
->connect_row_activated( LINK( this, SwInsertDBColAutoPilot
, DblClickHdl
));
369 for( size_t n
= 0; n
< aDBColumns
.size(); ++n
)
371 const OUString
& rS
= aDBColumns
[ n
]->sColumn
;
372 m_xLbTableDbColumn
->append_text(rS
);
373 m_xLbTextDbColumn
->append_text(rS
);
375 m_xLbTextDbColumn
->select(0);
376 m_xLbTableDbColumn
->select(0);
378 // read configuration
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
);
387 SwInsertDBColAutoPilot::~SwInsertDBColAutoPilot()
391 IMPL_LINK( SwInsertDBColAutoPilot
, PageHdl
, weld::Button
&, rButton
, void )
393 bool bShowTable
= &rButton
== m_xRbAsTable
.get();
395 m_xHeadFrame
->set_label(MnemonicGenerator::EraseAllMnemonicChars(rButton
.get_label().replace('_', '~')));
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
);
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
);
417 m_xPbTableFormat
->set_sensitive( 0 != m_xLbTableCol
->n_children() );
419 TVSelectHdl( bShowTable
? *m_xLbTableDbColumn
: *m_xLbTextDbColumn
);
422 IMPL_LINK( SwInsertDBColAutoPilot
, DBFormatHdl
, weld::Button
&, rButton
, void )
424 weld::TreeView
& rBox
= m_xRbAsTable
->get_active()
425 ? ( m_xLbTableCol
->get_id(0).isEmpty()
426 ? *m_xLbTableDbColumn
428 : *m_xLbTextDbColumn
;
430 SwInsDBColumn
aSrch(rBox
.get_selected_text());
431 SwInsDBColumns::const_iterator it
= aDBColumns
.find( &aSrch
);
433 bool bFromDB
= m_xRbDbFormatFromDb
.get() == &rButton
;
434 (*it
)->bIsDBFormat
= bFromDB
;
435 m_xLbDbFormatFromUsr
->set_sensitive( !bFromDB
);
438 IMPL_LINK( SwInsertDBColAutoPilot
, TableToFromHdl
, weld::Button
&, rButton
, void )
440 bool bChgEnable
= true, bEnableTo
= true, bEnableFrom
= true;
442 if( &rButton
== m_xIbDbcolAllTo
.get() )
446 sal_Int32 n
, nInsPos
= m_xLbTableCol
->get_selected_index(),
447 nCnt
= m_xLbTableDbColumn
->n_children();
449 m_xLbTableDbColumn
->unselect_all();
451 m_xLbTableDbColumn
->freeze();
452 m_xLbTableCol
->freeze();
455 for( n
= 0; n
< nCnt
; ++n
)
456 m_xLbTableCol
->append_text(m_xLbTableDbColumn
->get_text(n
));
458 for( n
= 0; n
< nCnt
; ++n
, ++nInsPos
)
459 m_xLbTableCol
->insert_text(nInsPos
, m_xLbTableDbColumn
->get_text(n
));
460 m_xLbTableDbColumn
->clear();
462 m_xLbTableDbColumn
->thaw();
463 m_xLbTableCol
->thaw();
465 m_xLbTableCol
->select(nInsPos
);
467 else if( &rButton
== m_xIbDbcolOneTo
.get() &&
468 m_xLbTableDbColumn
->get_selected_index() != -1 )
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
);
475 m_xLbTableCol
->select(nInsPos
);
476 if (nDelPos
>= m_xLbTableDbColumn
->n_children())
477 nDelPos
= m_xLbTableDbColumn
->n_children() - 1;
478 m_xLbTableDbColumn
->select(nDelPos
);
480 bEnableTo
= 0 != m_xLbTableDbColumn
->n_children();
482 else if( &rButton
== m_xIbDbcolOneFrom
.get() )
484 if (m_xLbTableCol
->get_selected_index() != -1)
487 nDelPos
= m_xLbTableCol
->get_selected_index();
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();
497 while( ++it
!= aDBColumns
.end() &&
498 -1 == (nInsPos
= m_xLbTableDbColumn
->
499 find_text( (*it
)->sColumn
)) )
503 m_xLbTableDbColumn
->insert_text(nInsPos
, aSrch
.sColumn
);
504 m_xLbTableCol
->remove( nDelPos
);
506 if (nInsPos
>= m_xLbTableDbColumn
->n_children())
507 nInsPos
= m_xLbTableDbColumn
->n_children() - 1;
508 m_xLbTableDbColumn
->select(nInsPos
);
510 if (nDelPos
>= m_xLbTableCol
->n_children())
511 nDelPos
= m_xLbTableCol
->n_children() - 1;
512 m_xLbTableCol
->select(nDelPos
);
515 bEnableTo
= 0 != m_xLbTableDbColumn
->n_children();
517 bEnableFrom
= 0 != m_xLbTableCol
->n_children();
519 else if( &rButton
== m_xIbDbcolAllFrom
.get() )
523 m_xLbTableDbColumn
->freeze();
524 m_xLbTableCol
->freeze();
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
);
531 m_xLbTableDbColumn
->thaw();
532 m_xLbTableCol
->thaw();
534 m_xLbTableDbColumn
->select(0);
536 else if( &rButton
== m_xIbDbcolToEdit
.get() )
539 // move data to Edit:
540 OUString
aField(m_xLbTextDbColumn
->get_selected_text());
541 if( !aField
.isEmpty() )
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
;
550 // first delete the existing selection
551 aStr
= aStr
.replaceAt( nPos
, nSel
, "" );
553 aField
= OUStringChar(cDBFieldStart
) + aField
+ OUStringChar(cDBFieldEnd
);
554 if( !aStr
.isEmpty() )
556 if( nPos
) // one blank in front
558 sal_Unicode c
= aStr
[ nPos
-1 ];
559 if( '\n' != c
&& '\r' != c
)
560 aField
= " " + aField
;
562 if( nPos
< aStr
.getLength() ) // one blank behind
564 sal_Unicode c
= aStr
[ nPos
];
565 if( '\n' != c
&& '\r' != c
)
570 m_xEdDbText
->set_text( aStr
.replaceAt( nPos
, 0, aField
) );
571 nPos
+= aField
.getLength();
572 m_xEdDbText
->select_region(nPos
, nPos
);
579 m_xIbDbcolOneTo
->set_sensitive( bEnableTo
);
580 m_xIbDbcolAllTo
->set_sensitive( bEnableTo
);
581 m_xIbDbcolOneFrom
->set_sensitive( bEnableFrom
);
582 m_xIbDbcolAllFrom
->set_sensitive( bEnableFrom
);
584 m_xRbDbFormatFromDb
->set_sensitive( false );
585 m_xRbDbFormatFromUsr
->set_sensitive( false );
586 m_xLbDbFormatFromUsr
->set_sensitive( false );
588 m_xPbTableFormat
->set_sensitive( bEnableFrom
);
591 IMPL_LINK(SwInsertDBColAutoPilot
, DblClickHdl
, weld::TreeView
&, rBox
, bool)
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();
602 TableToFromHdl(*pButton
);
607 IMPL_LINK_NOARG(SwInsertDBColAutoPilot
, TableFormatHdl
, weld::Button
&, void)
609 SwWrtShell
& rSh
= pView
->GetWrtShell();
610 bool bNewSet
= false;
614 pTableSet
.reset(new SfxItemSet( rSh
.GetAttrPool(), SwuiGetUITableAttrRange() ));
616 // At first acquire the simple attributes
617 pTableSet
->Put( SfxStringItem( FN_PARAM_TABLE_NAME
, rSh
.GetUniqueTableName() ));
618 pTableSet
->Put( SfxUInt16Item( FN_PARAM_TABLE_HEADLINE
, 1 ) );
620 pTableSet
->Put( SfxUInt16Item( SID_BACKGRND_DESTINATION
,
621 rSh
.GetViewOptions()->GetTableDest() ));
623 SvxBrushItem
aBrush( RES_BACKGROUND
);
624 pTableSet
->Put( aBrush
);
625 aBrush
.SetWhich(SID_ATTR_BRUSH_ROW
);
626 pTableSet
->Put( aBrush
);
627 aBrush
.SetWhich(SID_ATTR_BRUSH_TABLE
);
628 pTableSet
->Put( aBrush
);
630 SvxBoxInfoItem
aBoxInfo( SID_ATTR_BORDER_INNER
);
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_DIST
);
639 // Single lines can have DontCare-status only in tables
640 aBoxInfo
.SetValid( SvxBoxInfoItemValidFlags::DISABLE
);
641 pTableSet
->Put( aBoxInfo
);
643 SwGetCurColNumPara aPara
;
644 const sal_uInt16 nNum
= rSh
.GetCurColNum( &aPara
);
649 nWidth
= aPara
.pPrtRect
->Width();
650 const SwFormatCol
& rCol
= aPara
.pFrameFormat
->GetCol();
651 const SwColumns
& rCols
= rCol
.GetColumns();
653 // initialise nStart and nEnd for nNum == 0
654 tools::Long nWidth1
= 0,
657 for( sal_uInt16 i
= 0; i
< nNum
; ++i
)
659 const SwColumn
* pCol
= &rCols
[i
];
660 nStart1
= pCol
->GetLeft() + nWidth1
;
661 nWidth1
+= static_cast<tools::Long
>(rCol
.CalcColWidth( i
, static_cast<sal_uInt16
>(nWidth
) ));
662 nEnd1
= nWidth1
- pCol
->GetRight();
664 if(nStart1
|| nEnd1
!= nWidth
)
665 nWidth
= nEnd1
- nStart1
;
668 nWidth
= rSh
.GetAnyCurRect(
669 (FrameTypeFlags::FLY_ANY
& rSh
.GetFrameType( nullptr, true ))
670 ? CurRectType::FlyEmbeddedPrt
671 : CurRectType::PagePrt
).Width();
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
, pRep
.get() ));
683 pTableSet
->Put( SfxUInt16Item( SID_HTML_MODE
,
684 ::GetHtmlMode( pView
->GetDocShell() )));
687 sal_Int32 nCols
= m_xLbTableCol
->n_children();
688 if (nCols
!= pRep
->GetAllColCount() && nCols
> 0)
690 // Number of columns has changed: then the TabCols have to be adjusted
691 tools::Long nWidth
= pRep
->GetWidth();
693 SwTabCols
aTabCols( nCols
);
694 aTabCols
.SetRight( nWidth
);
695 aTabCols
.SetRightMax( nWidth
);
698 const sal_Int32 nStep
= nWidth
/ (nCols
+1);
699 for( sal_Int32 n
= 0; n
< nCols
; ++n
)
701 aTabCols
.Insert( nStep
*(n
+1), false, n
);
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
, pRep
.get() ));
712 SwAbstractDialogFactory
& rFact
= swui::GetFactory();
714 ScopedVclPtr
<SfxAbstractTabDialog
> pDlg(rFact
.CreateSwTableTabDlg(m_xDialog
.get(), pTableSet
.get(), &rSh
));
715 if( RET_OK
== pDlg
->Execute() )
716 pTableSet
->Put( *pDlg
->GetOutputItemSet() );
724 IMPL_LINK_NOARG(SwInsertDBColAutoPilot
, AutoFormatHdl
, weld::Button
&, void)
726 SwAbstractDialogFactory
& rFact
= swui::GetFactory();
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();
733 IMPL_LINK(SwInsertDBColAutoPilot
, TVSelectHdl
, weld::TreeView
&, rBox
, void)
735 weld::TreeView
* pGetBox
= &rBox
;
737 SwInsDBColumn
aSrch(pGetBox
->get_selected_text());
738 SwInsDBColumns::const_iterator it
= aDBColumns
.find( &aSrch
);
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() )
745 m_xRbDbFormatFromDb
->set_sensitive( false );
746 m_xRbDbFormatFromUsr
->set_sensitive( false );
747 m_xLbDbFormatFromUsr
->set_sensitive( false );
751 bool bEnableFormat
= (*it
)->bHasFormat
;
752 m_xRbDbFormatFromDb
->set_sensitive( bEnableFormat
);
753 m_xRbDbFormatFromUsr
->set_sensitive( bEnableFormat
);
757 sText
+= " (" + aSrch
.sColumn
+ ")";
760 bool bIsDBFormat
= (*it
)->bIsDBFormat
;
761 m_xRbDbFormatFromDb
->set_active( bIsDBFormat
);
762 m_xRbDbFormatFromUsr
->set_active( !bIsDBFormat
);
763 m_xLbDbFormatFromUsr
->set_sensitive( !bIsDBFormat
);
765 m_xLbDbFormatFromUsr
->SetDefFormat( (*it
)->nUsrNumFormat
);
768 m_xFormatFrame
->set_label(sText
);
770 if (m_xLbTableCol
->n_children())
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");
777 m_xLbTableCol
->set_id(0, OUString());
781 IMPL_LINK_NOARG(SwInsertDBColAutoPilot
, CBSelectHdl
, weld::ComboBox
&, void)
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();
789 SwInsDBColumn
aSrch(pGetBox
->get_selected_text());
790 SwInsDBColumns::const_iterator it
= aDBColumns
.find( &aSrch
);
792 if( !aSrch
.sColumn
.isEmpty() )
794 m_xLbDbFormatFromUsr
->CallSelectHdl();
795 (*it
)->nUsrNumFormat
= m_xLbDbFormatFromUsr
->GetFormat();
799 IMPL_LINK( SwInsertDBColAutoPilot
, HeaderHdl
, weld::Button
&, rButton
, void )
801 if (&rButton
== m_xCbTableHeadon
.get())
803 bool bEnable
= m_xCbTableHeadon
->get_active();
805 m_xRbHeadlColnms
->set_sensitive( bEnable
);
806 m_xRbHeadlEmpty
->set_sensitive( bEnable
);
810 static void lcl_InsTextInArr( const OUString
& rText
, DB_Columns
& rColArr
)
812 sal_Int32 nSttPos
= 0, nFndPos
;
813 while( -1 != ( nFndPos
= rText
.indexOf( '\x0A', nSttPos
)) )
817 rColArr
.push_back(std::make_unique
<DB_Column
>(rText
.copy(nSttPos
, nFndPos
-1)));
819 rColArr
.push_back(std::make_unique
<DB_Column
>());
820 nSttPos
= nFndPos
+ 1;
822 if( nSttPos
< rText
.getLength() )
824 rColArr
.push_back(std::make_unique
<DB_Column
>(rText
.copy(nSttPos
)));
828 bool SwInsertDBColAutoPilot::SplitTextToColArr( const OUString
& rText
,
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;
838 while( -1 != ( nFndPos
= sText
.indexOf( cDBFieldStart
, nSttPos
)))
840 nSttPos
= nFndPos
+ 1;
841 nEndPos
= sText
.indexOf( cDBFieldEnd
, nSttPos
+1 );
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() )
849 // that is a valid field
850 // so surely the text "before":
851 const SwInsDBColumn
& rFndCol
= **it
;
857 ::lcl_InsTextInArr( sText
.copy( 0, nSttPos
-1 ), rColArr
);
858 sText
= sText
.copy( nSttPos
-1 );
861 sText
= sText
.copy( rFndCol
.sColumn
.getLength() + 2 );
864 sal_uInt16 nSubType
= 0;
866 if( rFndCol
.bHasFormat
)
868 if( rFndCol
.bIsDBFormat
)
869 nFormat
= static_cast<sal_uInt32
>(rFndCol
.nDBNumFormat
);
872 nFormat
= rFndCol
.nUsrNumFormat
;
873 nSubType
= nsSwExtendedSubType::SUB_OWN_FMT
;
881 SwWrtShell
& rSh
= pView
->GetWrtShell();
882 SwDBFieldType
aFieldType( rSh
.GetDoc(), aSrch
.sColumn
,
884 pNew
= new DB_Column( rFndCol
, *new SwDBField(
885 static_cast<SwDBFieldType
*>(rSh
.InsertFieldType( aFieldType
)),
888 pNew
->pField
->SetSubType( nSubType
);
891 pNew
= new DB_Column( rFndCol
, nFormat
);
893 rColArr
.push_back( std::unique_ptr
<DB_Column
>(pNew
) );
898 // don't forget the last text
899 if( !sText
.isEmpty() )
900 ::lcl_InsTextInArr( sText
, rColArr
);
902 return !rColArr
.empty();
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
)
910 auto xResultSet
= xResultSet_in
;
912 const Any
* pSelection
= rSelection
.hasElements() ? rSelection
.getConstArray() : nullptr;
913 SwWrtShell
& rSh
= pView
->GetWrtShell();
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() )
920 xResultSet
= SwDBManager::createCursor(aDBData
.sDataSource
,aDBData
.sCommand
,aDBData
.nCommandType
,xConnection
,pView
);
921 bDisposeResultSet
= xResultSet
.is();
924 Reference
< sdbc::XRow
> xRow(xResultSet
, UNO_QUERY
);
928 rSh
.StartAllAction();
929 bool bUndo
= rSh
.DoesUndo();
933 bool bAsTable
= m_xRbAsTable
->get_active();
934 SvNumberFormatter
& rNumFormatr
= *rSh
.GetNumberFormatter();
936 if( rSh
.HasSelection() )
939 std::unique_ptr
<SwWait
> pWait
;
941 Reference
< XColumnsSupplier
> xColsSupp( xResultSet
, UNO_QUERY
);
942 Reference
<XNameAccess
> xCols
= xColsSupp
->getColumns();
944 uno::Reference
<sdbcx::XRowLocate
> xRowLocate(xResultSet
, uno::UNO_QUERY_THROW
);
946 do{ // middle checked loop!!
947 if( bAsTable
) // fill in data as table
951 sal_Int32 nCols
= m_xLbTableCol
->n_children();
953 if( m_xCbTableHeadon
->get_active() )
957 nRows
+= rSelection
.getLength();
961 // prepare the array for the selected columns
962 std::vector
<SwInsDBColumn
*> aColFields
;
963 for( sal_Int32 n
= 0; n
< nCols
; ++n
)
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());
970 OSL_ENSURE( false, "database column not found" );
974 if( static_cast<size_t>(nCols
) != aColFields
.size() )
976 OSL_ENSURE( false, "not all database columns found" );
977 nCols
= static_cast<sal_Int32
>(aColFields
.size());
982 OSL_ENSURE( false, "wrong parameters" );
986 const SwModuleOptions
* pModOpt
= SW_MOD()->GetModuleConfig();
988 bool bHTML
= 0 != (::GetHtmlMode( pView
->GetDocShell() ) & HTMLMODE_ON
);
990 pModOpt
->GetInsTableFlags(bHTML
),
991 nRows
, nCols
, (pSelection
? m_xTAutoFormat
.get(): nullptr) );
992 rSh
.MoveTable( GotoPrevTable
, fnTableStart
);
994 if( pSelection
&& pTableSet
)
997 SfxItemSet
aTableSet( rSh
.GetAttrPool(), svl::Items
<RES_BOXATR_FORMAT
,
998 RES_BOXATR_VALUE
>{} );
999 bool bIsAutoUpdateCells
= rSh
.IsAutoUpdateCells();
1000 rSh
.SetAutoUpdateCells( false );
1002 if( m_xCbTableHeadon
->get_active() )
1004 for( sal_Int32 n
= 0; n
< nCols
; ++n
)
1006 if( m_xRbHeadlColnms
->get_active() )
1008 rSh
.SwEditShell::Insert2( aColFields
[ n
]->sColumn
);
1014 rSh
.SetRowsToRepeat( 0 );
1016 for( sal_Int32 i
= 0 ; ; ++i
)
1018 bool bBreak
= false;
1023 bBreak
= !xRowLocate
->moveToBookmark(pSelection
[i
]);
1026 bBreak
= !xResultSet
->first();
1028 catch (const Exception
&)
1035 for( sal_Int32 n
= 0; n
< nCols
; ++n
)
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.
1043 const SwInsDBColumn
* pEntry
= aColFields
[ n
];
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() )
1051 Any aType
= xColumnProps
->getPropertyValue("Type");
1052 aType
>>= eDataType
;
1056 if( pEntry
->bHasFormat
)
1058 SwTableBoxNumFormat
aNumFormat(
1059 pEntry
->bIsDBFormat
? static_cast<sal_uInt32
>(pEntry
->nDBNumFormat
)
1060 : pEntry
->nUsrNumFormat
);
1061 aTableSet
.Put(aNumFormat
);
1064 double fVal
= xColumn
->getDouble();
1065 if( xColumn
->wasNull() )
1066 aTableSet
.ClearItem( RES_BOXATR_VALUE
);
1069 if(rNumFormatr
.GetType(aNumFormat
.GetValue()) & SvNumFormatType::DATE
)
1071 ::Date
aStandard(1,1,1900);
1072 if (rNumFormatr
.GetNullDate() != aStandard
)
1073 fVal
+= (aStandard
- rNumFormatr
.GetNullDate());
1075 aTableSet
.Put( SwTableBoxValue( fVal
));
1079 aTableSet
.ClearItem( RES_BOXATR_VALUE
);
1080 rSh
.SetTableBoxFormulaAttrs( aTableSet
);
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
1101 const OUString sVal
= xColumn
->getString();
1102 if(!xColumn
->wasNull())
1104 rSh
.SwEditShell::Insert2( sVal
);
1108 catch (const Exception
&)
1110 TOOLS_WARN_EXCEPTION("sw", "");
1116 if ( !xResultSet
->next() )
1119 else if( i
+1 >= rSelection
.getLength() )
1123 pWait
.reset(new SwWait( *pView
->GetDocShell(), true ));
1126 rSh
.MoveTable( GotoCurrTable
, fnTableStart
);
1127 if( !pSelection
&& ( pTableSet
|| m_xTAutoFormat
))
1133 rSh
.SetTableStyle(*m_xTAutoFormat
);
1135 rSh
.SetAutoUpdateCells( bIsAutoUpdateCells
);
1137 else // add data as fields/text
1140 if( SplitTextToColArr( m_xEdDbText
->get_text(), aColArr
, m_xRbAsField
->get_active() ) )
1142 // now for each data set, we can iterate over the array
1145 if( !rSh
.IsSttPara() )
1146 rSh
.SwEditShell::SplitNode();
1147 if( !rSh
.IsEndPara() )
1149 rSh
.SwEditShell::SplitNode();
1150 rSh
.SwCursorShell::Left(1,CRSR_SKIP_CHARS
);
1153 rSh
.DoUndo( false );
1155 SwTextFormatColl
* pColl
= nullptr;
1157 const OUString
sTmplNm(m_xLbDbParaColl
->get_active_text());
1158 if( sNoTmpl
!= sTmplNm
)
1160 pColl
= rSh
.FindTextFormatCollByName( sTmplNm
);
1163 const sal_uInt16 nId
= SwStyleNameMapper::GetPoolIdFromUIName(
1164 sTmplNm
, SwGetPoolIdFromName::TxtColl
);
1165 if( USHRT_MAX
!= nId
)
1166 pColl
= rSh
.GetTextCollFromPool( nId
);
1168 pColl
= rSh
.MakeTextFormatColl( sTmplNm
);
1170 rSh
.SetTextFormatColl( pColl
);
1174 // for adding as fields -> insert a "NextField" after
1176 SwDBFormatData aDBFormatData
;
1177 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
1178 aDBFormatData
.xFormatter
.set(util::NumberFormatter::create(xContext
), UNO_QUERY_THROW
) ;
1180 Reference
<XPropertySet
> xSourceProps(xSource
, UNO_QUERY
);
1181 if(xSourceProps
.is())
1183 Any aFormats
= xSourceProps
->getPropertyValue("NumberFormatsSupplier");
1184 if(aFormats
.hasValue())
1186 Reference
< util::XNumberFormatsSupplier
> xSuppl
;
1187 aFormats
>>= xSuppl
;
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
);
1198 aDBFormatData
.aLocale
= LanguageTag( rSh
.GetCurLang() ).getLocale();
1199 SwDBNextSetField
aNxtDBField( static_cast<SwDBNextSetFieldType
*>(rSh
.
1200 GetFieldType( 0, SwFieldIds::DbNextSet
)),
1203 bool bSetCursor
= true;
1204 const size_t nCols
= aColArr
.size();
1205 ::sw::mark::IMark
* pMark
= nullptr;
1206 for( sal_Int32 i
= 0 ; ; ++i
)
1208 bool bBreak
= false;
1213 bBreak
= !xRowLocate
->moveToBookmark(pSelection
[i
]);
1216 bBreak
= !xResultSet
->first();
1218 catch (const Exception
&)
1226 for( size_t n
= 0; n
< nCols
; ++n
)
1228 DB_Column
* pDBCol
= aColArr
[ n
].get();
1230 switch( pDBCol
->eColType
)
1232 case DB_Column::Type::FILLTEXT
:
1233 sIns
= *pDBCol
->pText
;
1236 case DB_Column::Type::SPLITPARA
:
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
);
1244 case DB_Column::Type::COL_FIELD
:
1246 std::unique_ptr
<SwDBField
> pField(static_cast<SwDBField
*>(
1247 pDBCol
->pField
->CopyField().release()));
1248 double nValue
= DBL_MAX
;
1250 Reference
< XPropertySet
> xColumnProps
;
1251 xCols
->getByName(pDBCol
->pColInfo
->sColumn
) >>= xColumnProps
;
1253 pField
->SetExpansion( SwDBManager::GetDBField(
1257 if( DBL_MAX
!= nValue
)
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
)
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
);
1273 pField
->ChgValue( nValue
, true );
1275 pField
->SetInitialized();
1277 rSh
.Insert( *pField
);
1281 case DB_Column::Type::COL_TEXT
:
1283 double nValue
= DBL_MAX
;
1284 Reference
< XPropertySet
> xColumnProps
;
1285 xCols
->getByName(pDBCol
->pColInfo
->sColumn
) >>= xColumnProps
;
1286 sIns
= SwDBManager::GetDBField(
1290 if( pDBCol
->nFormat
&&
1294 if(rNumFormatr
.GetType(pDBCol
->nFormat
) & SvNumFormatType::DATE
)
1296 ::Date
aStandard(1,1,1900);
1297 if (rNumFormatr
.GetNullDate() != aStandard
)
1298 nValue
+= (aStandard
- rNumFormatr
.GetNullDate());
1300 rNumFormatr
.GetOutputString( nValue
,
1308 if( !sIns
.isEmpty() )
1314 // to the beginning and set a mark, so that
1315 // the cursor can be set to the initial position
1318 rSh
.SwCursorShell::MovePara(
1319 GoCurrPara
, fnParaStart
);
1320 pMark
= rSh
.SetBookmark(
1323 IDocumentMarkAccess::MarkType::UNO_BOOKMARK
);
1324 rSh
.SwCursorShell::MovePara(
1325 GoCurrPara
, fnParaEnd
);
1333 bool bNext
= xResultSet
->next();
1337 else if( i
+1 >= rSelection
.getLength() )
1340 if( m_xRbAsField
->get_active() )
1341 rSh
.Insert( aNxtDBField
);
1343 if( !rSh
.IsSttPara() )
1344 rSh
.SwEditShell::SplitNode();
1347 pWait
.reset(new SwWait( *pView
->GetDocShell(), true ));
1350 if( !bSetCursor
&& pMark
!= nullptr)
1353 rSh
.GotoMark( pMark
);
1354 rSh
.getIDocumentMarkAccess()->deleteMark( pMark
);
1359 // write configuration
1361 }while( false ); // middle checked loop
1366 rSh
.AppendUndoForInsertFromDB( bAsTable
);
1372 if ( bDisposeResultSet
)
1373 ::comphelper::disposeComponent(xResultSet
);
1376 void SwInsertDBColAutoPilot::SetTabSet()
1378 SwWrtShell
& rSh
= pView
->GetWrtShell();
1379 const SfxPoolItem
* pItem
;
1383 if (m_xTAutoFormat
->IsFrame())
1385 // border is from AutoFormat
1386 pTableSet
->ClearItem( RES_BOX
);
1387 pTableSet
->ClearItem( SID_ATTR_BORDER_INNER
);
1389 if (m_xTAutoFormat
->IsBackground())
1391 pTableSet
->ClearItem( RES_BACKGROUND
);
1392 pTableSet
->ClearItem( SID_ATTR_BRUSH_ROW
);
1393 pTableSet
->ClearItem( SID_ATTR_BRUSH_TABLE
);
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
, SID_ATTR_BRUSH_TABLE
};
1402 for(sal_uInt16 i
: aIds
)
1403 if( SfxItemState::SET
== pTableSet
->GetItemState( i
,
1404 false, &pItem
) && *pItem
== aBrush
)
1405 pTableSet
->ClearItem( i
);
1408 if( SfxItemState::SET
== pTableSet
->GetItemState( FN_PARAM_TABLE_NAME
, false,
1409 &pItem
) && static_cast<const SfxStringItem
*>(pItem
)->GetValue() ==
1410 rSh
.GetTableFormat()->GetName() )
1411 pTableSet
->ClearItem( FN_PARAM_TABLE_NAME
);
1413 rSh
.MoveTable( GotoCurrTable
, fnTableStart
);
1415 rSh
.MoveTable( GotoCurrTable
, fnTableEnd
);
1417 ItemSetToTableParam( *pTableSet
, rSh
);
1420 rSh
.MoveTable( GotoCurrTable
, fnTableStart
);
1423 static Sequence
<OUString
> lcl_createSourceNames(const OUString
& rNodeName
)
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
;
1441 static Sequence
<OUString
> lcl_CreateSubNames(const OUString
& rSubNodeName
)
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
;
1454 static OUString
lcl_CreateUniqueName(const Sequence
<OUString
>& aNames
)
1456 sal_Int32 nIdx
= aNames
.getLength();
1459 const OUString sRet
= "_" + OUString::number(nIdx
++);
1460 if ( comphelper::findValue(aNames
, sRet
) == -1 )
1461 return sRet
; // No match found, return unique name
1465 void SwInsertDBColAutoPilot::Notify( const css::uno::Sequence
< OUString
>& ) {}
1467 void SwInsertDBColAutoPilot::ImplCommit()
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
))
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
)
1484 Sequence
<OUString
> aElements
{ nodeName
};
1485 ClearNodeElements(OUString(), aElements
);
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
++)
1497 pValues
[i
].Name
= "/" + pNodeNames
[i
];
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();
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";
1510 if (!sTmp
.isEmpty())
1511 pValues
[4].Value
<<= sTmp
;
1513 if( sNoTmpl
!= (sTmp
= m_xLbDbParaColl
->get_active_text()) )
1514 pValues
[5].Value
<<= sTmp
;
1517 pValues
[6].Value
<<= m_xTAutoFormat
->GetName();
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();
1524 SetSetProperties(OUString(), aValues
);
1526 sNewNode
+= "/ColumnSet";
1528 LanguageType
ePrevLang(0xffff);
1530 SvNumberFormatter
& rNFormatr
= *pView
->GetWrtShell().GetNumberFormatter();
1531 for(size_t nCol
= 0; nCol
< aDBColumns
.size(); nCol
++)
1533 SwInsDBColumn
* pColumn
= aDBColumns
[nCol
].get();
1534 OUString
sColumnInsertNode(sNewNode
+ "/__");
1536 sColumnInsertNode
+= "00";
1537 else if( nCol
< 100 )
1538 sColumnInsertNode
+= "0";
1539 sColumnInsertNode
+= OUString::number( nCol
);
1541 const Sequence
<OUString
> aSubNodeNames
= lcl_CreateSubNames(sColumnInsertNode
);
1542 Sequence
<PropertyValue
> aSubValues(aSubNodeNames
.getLength());
1543 PropertyValue
* pSubValues
= aSubValues
.getArray();
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
;
1553 SwStyleNameMapper::FillUIName( RES_POOLCOLL_STANDARD
, sTmp
);
1554 const SvNumberformat
* pNF
= rNFormatr
.GetEntry( pColumn
->nUsrNumFormat
);
1558 pSubValues
[4].Value
<<= pNF
->GetFormatstring();
1559 eLang
= pNF
->GetLanguage();
1563 pSubValues
[4].Value
<<= sTmp
;
1564 eLang
= GetAppLanguage();
1568 if( eLang
!= ePrevLang
)
1570 sPrevLang
= LanguageTag::convertToBcp47( eLang
);
1574 pSubValues
[5].Value
<<= sPrevLang
;
1575 SetSetProperties(sNewNode
, aSubValues
);
1579 void SwInsertDBColAutoPilot::Load()
1581 const Sequence
<OUString
> aNames
= GetNodeNames(OUString());
1582 SvNumberFormatter
& rNFormatr
= *pView
->GetWrtShell().GetNumberFormatter();
1583 for(OUString
const & nodeName
: aNames
)
1585 //search for entries with the appropriate data source and table
1586 Sequence
<OUString
> aSourceNames
= lcl_createSourceNames(nodeName
);
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
)
1597 std::unique_ptr
<DB_ColumnConfigData
> pNewData(new DB_ColumnConfigData
);
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]);
1612 const OUString
sSubNodeName(nodeName
+ "/ColumnSet/");
1613 const Sequence
<OUString
> aSubNames
= GetNodeNames(sSubNodeName
);
1614 for(const OUString
& rSubName
: aSubNames
)
1616 Sequence
<OUString
> aSubNodeNames
=
1617 lcl_CreateSubNames(sSubNodeName
+ rSubName
);
1618 Sequence
< Any
> aSubProps
= GetProperties(aSubNodeNames
);
1619 const Any
* pSubProps
= aSubProps
.getConstArray();
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
)
1627 if(aDBColumns
[nRealColumn
]->sColumn
== sColumn
)
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]);
1643 pSubProps
[4] >>= pInsDBColumn
->sUsrNumFormat
;
1644 OUString sNumberFormatLocale
;
1645 pSubProps
[5] >>= sNumberFormatLocale
;
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
);
1657 pInsDBColumn
->nUsrNumFormat
= rNFormatr
.GetEntryKey( pInsDBColumn
->sUsrNumFormat
,
1658 pInsDBColumn
->eUsrNumFormatLng
);
1660 pNewData
->aDBColumns
.insert(std::move(pInsDBColumn
));
1662 OUString
sTmp( pNewData
->sTableList
);
1663 if( !sTmp
.isEmpty() )
1667 const OUString
sEntry( sTmp
.getToken( 0, '\x0a', n
) );
1668 //preselect column - if they still exist!
1669 if (m_xLbTableDbColumn
->find_text(sEntry
) != -1)
1671 m_xLbTableCol
->append_text(sEntry
);
1672 m_xLbTableDbColumn
->remove_text(sEntry
);
1676 if (!m_xLbTableDbColumn
->n_children())
1678 m_xIbDbcolAllTo
->set_sensitive( false );
1679 m_xIbDbcolOneTo
->set_sensitive( false );
1681 m_xIbDbcolOneFrom
->set_sensitive(true);
1682 m_xIbDbcolAllFrom
->set_sensitive(true);
1684 m_xEdDbText
->set_text( pNewData
->sEdit
);
1686 sTmp
= pNewData
->sTmplNm
;
1687 if( !sTmp
.isEmpty() )
1688 m_xLbDbParaColl
->set_active_text(sTmp
);
1690 m_xLbDbParaColl
->set_active(0);
1692 m_xTAutoFormat
.reset();
1693 sTmp
= pNewData
->sTAutoFormatNm
;
1694 if( !sTmp
.isEmpty() )
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() )
1702 m_xTAutoFormat
.reset(new SwTableAutoFormat(aAutoFormatTable
[nAutoFormat
]));
1707 m_xRbAsTable
->set_active( pNewData
->bIsTable
);
1708 m_xRbAsField
->set_active( pNewData
->bIsField
);
1709 m_xRbAsText
->set_active( !pNewData
->bIsTable
&& !pNewData
->bIsField
);
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
);
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
)
1720 SwInsDBColumn
& rSet
= *aDBColumns
[ n
];
1721 for( size_t m
= 0; m
< pNewData
->aDBColumns
.size() ; ++m
)
1723 SwInsDBColumn
& rGet
= *pNewData
->aDBColumns
[ m
];
1724 if(rGet
.sColumn
== rSet
.sColumn
)
1726 if( rGet
.bHasFormat
&& !rGet
.bIsDBFormat
)
1728 rSet
.bIsDBFormat
= false;
1729 rSet
.nUsrNumFormat
= rNFormatr
.GetEntryKey( rGet
.sUsrNumFormat
,
1730 rGet
.eUsrNumFormatLng
);
1731 if( NUMBERFORMAT_ENTRY_NOT_FOUND
== rSet
.nUsrNumFormat
)
1733 sal_Int32 nCheckPos
;
1734 SvNumFormatType nType
;
1735 rNFormatr
.PutEntry( rGet
.sUsrNumFormat
, nCheckPos
, nType
,
1736 rSet
.nUsrNumFormat
, rGet
.eUsrNumFormatLng
);
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);
1752 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */