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 .
21 #include <docufld.hxx>
22 #include <strings.hrc>
25 #include <swmodule.hxx>
27 #include <svl/numformat.hxx>
28 #include <svl/zformat.hxx>
29 #include <o3tl/string_view.hxx>
31 #define USER_DATA_VERSION_1 "1"
32 #define USER_DATA_VERSION USER_DATA_VERSION_1
34 SwFieldDokPage::SwFieldDokPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
*const pCoreSet
)
35 : SwFieldPage(pPage
, pController
, "modules/swriter/ui/flddocumentpage.ui",
36 "FieldDocumentPage", pCoreSet
)
39 , m_xTypeLB(m_xBuilder
->weld_tree_view("type"))
40 , m_xSelection(m_xBuilder
->weld_widget("selectframe"))
41 , m_xSelectionLB(m_xBuilder
->weld_tree_view("select"))
42 , m_xValueFT(m_xBuilder
->weld_label("valueft"))
43 , m_xValueED(m_xBuilder
->weld_entry("value"))
44 , m_xLevelFT(m_xBuilder
->weld_label("levelft"))
45 , m_xLevelED(m_xBuilder
->weld_spin_button("level"))
46 , m_xDateFT(m_xBuilder
->weld_label("daysft"))
47 , m_xTimeFT(m_xBuilder
->weld_label("minutesft"))
48 , m_xDateOffsetED(m_xBuilder
->weld_spin_button("offset"))
49 , m_xFormat(m_xBuilder
->weld_widget("formatframe"))
50 , m_xFormatLB(m_xBuilder
->weld_tree_view("format"))
51 , m_xNumFormatLB(new SwNumFormatTreeView(m_xBuilder
->weld_tree_view("numformat")))
52 , m_xFixedCB(m_xBuilder
->weld_check_button("fixed"))
54 m_xTypeLB
->make_sorted();
55 m_xFormatLB
->make_sorted();
57 auto nWidth
= m_xTypeLB
->get_approximate_digit_width() * FIELD_COLUMN_WIDTH
;
58 auto nHeight
= m_xTypeLB
->get_height_rows(10);
60 m_xTypeLB
->set_size_request(nWidth
, nHeight
);
61 m_xSelectionLB
->set_size_request(nWidth
, nHeight
);
62 m_xFormatLB
->set_size_request(nWidth
* 2, nHeight
);
64 m_xSelectionLB
->connect_row_activated(LINK(this, SwFieldDokPage
, TreeViewInsertHdl
));
65 m_xFormatLB
->connect_row_activated(LINK(this, SwFieldDokPage
, TreeViewInsertHdl
));
66 m_xNumFormatLB
->connect_row_activated(LINK(this, SwFieldDokPage
, NumFormatHdl
));
68 m_xLevelED
->set_max(MAXLEVEL
);
69 m_xDateOffsetED
->set_range(INT_MIN
, INT_MAX
);
70 //enable 'active' language selection
71 m_xNumFormatLB
->SetShowLanguageControl(true);
74 m_xTypeLB
->set_buildable_name(m_xTypeLB
->get_buildable_name() + "-doc");
75 m_xValueED
->set_buildable_name(m_xValueED
->get_buildable_name() + "-doc");
76 m_xNumFormatLB
->set_buildable_name(m_xNumFormatLB
->get_buildable_name() + "-doc");
77 m_xSelectionLB
->set_buildable_name(m_xSelectionLB
->get_buildable_name() + "-doc");
78 m_xFormatLB
->set_buildable_name(m_xFormatLB
->get_buildable_name() + "-doc");
81 SwFieldDokPage::~SwFieldDokPage()
85 void SwFieldDokPage::Reset(const SfxItemSet
* )
88 Init(); // general initialisation
90 // initialise TypeListBox
91 const SwFieldGroupRgn
& rRg
= SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
100 for(sal_uInt16 i
= rRg
.nStart
; i
< rRg
.nEnd
; ++i
)
102 const SwFieldTypesEnum nTypeId
= SwFieldMgr::GetTypeId(i
);
106 case SwFieldTypesEnum::PreviousPage
:
107 case SwFieldTypesEnum::NextPage
:
108 case SwFieldTypesEnum::PageNumber
:
111 m_xTypeLB
->append(OUString::number(USHRT_MAX
), SwResId(FMT_REF_PAGE
));
117 m_xTypeLB
->append(OUString::number(static_cast<sal_uInt16
>(nTypeId
)), SwFieldMgr::GetTypeStr(i
));
124 const SwField
* pCurField
= GetCurField();
125 SwFieldTypesEnum nTypeId
= pCurField
->GetTypeId();
126 if (nTypeId
== SwFieldTypesEnum::FixedDate
)
127 nTypeId
= SwFieldTypesEnum::Date
;
128 if (nTypeId
== SwFieldTypesEnum::FixedTime
)
129 nTypeId
= SwFieldTypesEnum::Time
;
130 m_xTypeLB
->append(OUString::number(static_cast<sal_uInt16
>(nTypeId
)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId
)));
131 m_xNumFormatLB
->SetAutomaticLanguage(pCurField
->IsAutomaticLanguage());
132 SwWrtShell
*pSh
= GetWrtShell();
134 pSh
= ::GetActiveWrtShell();
137 const SvNumberformat
* pFormat
= pSh
->GetNumberFormatter()->GetEntry(pCurField
->GetFormat());
139 m_xNumFormatLB
->SetLanguage(pFormat
->GetLanguage());
147 RestorePos(*m_xTypeLB
);
149 m_xTypeLB
->connect_row_activated(LINK(this, SwFieldDokPage
, TreeViewInsertHdl
));
150 m_xTypeLB
->connect_changed(LINK(this, SwFieldDokPage
, TypeHdl
));
151 m_xFormatLB
->connect_changed(LINK(this, SwFieldDokPage
, FormatHdl
));
155 const OUString sUserData
= GetUserData();
157 if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData
, 0, ';', nIdx
), u
"" USER_DATA_VERSION_1
))
159 const sal_uInt16 nVal
= static_cast< sal_uInt16
>(o3tl::toInt32(o3tl::getToken(sUserData
, 0, ';', nIdx
)));
160 if(nVal
!= USHRT_MAX
)
162 for (int i
= 0, nEntryCount
= m_xTypeLB
->n_children(); i
< nEntryCount
; i
++)
164 if (nVal
== m_xTypeLB
->get_id(i
).toUInt32())
166 m_xTypeLB
->select(i
);
177 m_nOldSel
= m_xSelectionLB
->get_selected_index();
178 m_nOldFormat
= GetCurField()->GetFormat();
179 m_xFixedCB
->save_state();
180 m_xValueED
->save_value();
181 m_xLevelED
->save_value();
182 m_xDateOffsetED
->save_value();
186 IMPL_LINK_NOARG(SwFieldDokPage
, TypeHdl
, weld::TreeView
&, void)
188 // save old ListBoxPos
189 const sal_Int32 nOld
= GetTypeSel();
191 // current ListBoxPos
192 SetTypeSel(m_xTypeLB
->get_selected_index());
194 if(GetTypeSel() == -1)
197 m_xTypeLB
->select(0);
200 if (nOld
== GetTypeSel())
208 SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xTypeLB
->get_id(GetTypeSel()).toUInt32());
210 // fill Selection-Listbox
211 m_xSelectionLB
->clear();
213 if (nTypeId
!= SwFieldTypesEnum::Unknown
)
215 std::vector
<OUString
> aLst
;
216 GetFieldMgr().GetSubTypes(nTypeId
, aLst
);
218 if (nTypeId
!= SwFieldTypesEnum::Author
)
219 nCount
= aLst
.size();
221 nCount
= GetFieldMgr().GetFormatCount(nTypeId
, IsFieldDlgHtmlMode());
223 for (size_t i
= 0; i
< nCount
; ++i
)
227 OUString
sId(OUString::number(i
));
228 if (nTypeId
!= SwFieldTypesEnum::Author
)
229 m_xSelectionLB
->append(sId
, aLst
[i
]);
231 m_xSelectionLB
->append(sId
, GetFieldMgr().GetFormatStr(nTypeId
, i
));
235 bool bInsert
= false;
237 OUString
sId(OUString::number(i
));
241 case SwFieldTypesEnum::Date
:
242 case SwFieldTypesEnum::Time
:
243 m_xSelectionLB
->append(sId
, aLst
[i
]);
244 if (static_cast<SwDateTimeField
*>(GetCurField())->IsFixed() && !i
)
245 m_xSelectionLB
->select_id(sId
);
246 if (!static_cast<SwDateTimeField
*>(GetCurField())->IsFixed() && i
)
247 m_xSelectionLB
->select_id(sId
);
249 case SwFieldTypesEnum::ExtendedUser
:
250 case SwFieldTypesEnum::DocumentStatistics
:
251 m_xSelectionLB
->append(sId
, aLst
[i
]);
252 if (GetCurField()->GetSubType() == i
)
253 m_xSelectionLB
->select_id(sId
);
256 case SwFieldTypesEnum::Author
:
258 const OUString
sFormat(GetFieldMgr().GetFormatStr(nTypeId
, i
));
259 m_xSelectionLB
->append(sId
, sFormat
);
260 m_xSelectionLB
->select_text(GetFieldMgr().GetFormatStr(nTypeId
, GetCurField()->GetFormat()));
265 if (aLst
[i
] == GetCurField()->GetPar1())
271 m_xSelectionLB
->append(sId
, aLst
[i
]);
276 m_xSelectionLB
->connect_changed(Link
<weld::TreeView
&,void>());
280 AddSubType(SwFieldTypesEnum::PageNumber
);
281 AddSubType(SwFieldTypesEnum::PreviousPage
);
282 AddSubType(SwFieldTypesEnum::NextPage
);
283 nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(0).toUInt32());
285 m_xSelectionLB
->connect_changed(LINK(this, SwFieldDokPage
, SubTypeHdl
));
288 bool bEnable
= nCount
!= 0;
290 if (bEnable
&& m_xSelectionLB
->get_selected_index() == -1)
291 m_xSelectionLB
->select(0);
293 m_xSelection
->set_sensitive( bEnable
);
295 // fill Format-Listbox
296 sal_Int32 nSize
= FillFormatLB(nTypeId
);
298 bool bValue
= false, bLevel
= false, bNumFormat
= false, bOffset
= false;
299 bool bFormat
= nSize
!= 0;
300 bool bOneArea
= false;
302 SvNumFormatType nFormatType
= SvNumFormatType::ALL
;
306 case SwFieldTypesEnum::Date
:
307 bFormat
= bNumFormat
= bOneArea
= bOffset
= true;
309 nFormatType
= SvNumFormatType::DATE
;
313 m_xDateOffsetED
->set_range(INT_MIN
, INT_MAX
); // no limit
316 m_xDateOffsetED
->set_value( static_cast<SwDateTimeField
*>(GetCurField())->GetOffset() / 24 / 60);
319 case SwFieldTypesEnum::Time
:
320 bFormat
= bNumFormat
= bOneArea
= bOffset
= true;
322 nFormatType
= SvNumFormatType::TIME
;
326 m_xDateOffsetED
->set_range(-1440, 1440); // one day
329 m_xDateOffsetED
->set_value( static_cast<SwDateTimeField
*>(GetCurField())->GetOffset() );
332 case SwFieldTypesEnum::PreviousPage
:
333 case SwFieldTypesEnum::NextPage
:
336 const sal_uInt16 nTmp
= m_xFormatLB
->get_selected_id().toUInt32();
338 if(SVX_NUM_CHAR_SPECIAL
!= nTmp
)
340 sal_Int32 nOff
= GetCurField()->GetPar2().toInt32();
341 if( SwFieldTypesEnum::NextPage
== nTypeId
&& 1 != nOff
)
342 m_xValueED
->set_text(
343 OUString::number(nOff
- 1) );
344 else if( SwFieldTypesEnum::PreviousPage
== nTypeId
&& -1 != nOff
)
345 m_xValueED
->set_text(
346 OUString::number(nOff
+ 1) );
348 m_xValueED
->set_text(OUString());
351 m_xValueED
->set_text(static_cast<SwPageNumberField
*>(GetCurField())->GetUserString());
356 case SwFieldTypesEnum::Chapter
:
357 m_xValueFT
->set_label(SwResId(STR_LEVEL
));
359 m_xLevelED
->set_text(OUString::number(static_cast<SwChapterField
*>(GetCurField())->GetLevel(GetWrtShell()->GetLayout()) + 1));
363 case SwFieldTypesEnum::PageNumber
:
364 m_xValueFT
->set_label( SwResId( STR_OFFSET
));
366 m_xValueED
->set_text(GetCurField()->GetPar2());
370 case SwFieldTypesEnum::ExtendedUser
:
371 case SwFieldTypesEnum::Author
:
372 case SwFieldTypesEnum::Filename
:
384 m_xNumFormatLB
->SetDefFormat(GetCurField()->GetFormat());
386 if (m_xNumFormatLB
->GetFormatType() == (SvNumFormatType::DATE
|SvNumFormatType::TIME
))
388 // always set Format-Type because otherwise when date/time formats are combined,
389 // both formats would be displayed at the same time
390 m_xNumFormatLB
->SetFormatType(SvNumFormatType::ALL
);
391 m_xNumFormatLB
->SetFormatType(nFormatType
);
392 // set correct format once again
393 m_xNumFormatLB
->SetDefFormat(GetCurField()->GetFormat());
397 m_xNumFormatLB
->SetFormatType(nFormatType
);
399 m_xNumFormatLB
->SetOneArea(bOneArea
);
402 m_xFormatLB
->set_visible(!bNumFormat
);
403 m_xNumFormatLB
->set_visible(bNumFormat
);
405 m_xValueFT
->set_visible(bValue
);
406 m_xValueED
->set_visible(bValue
);
407 m_xLevelFT
->set_visible(bLevel
);
408 m_xLevelED
->set_visible(bLevel
);
409 m_xDateOffsetED
->set_visible(bOffset
);
410 m_xFixedCB
->set_visible(!bValue
&& !bLevel
&& !bOffset
);
412 m_xFormat
->set_sensitive(bFormat
);
413 m_xFixedCB
->set_sensitive(bFixed
);
416 m_xFixedCB
->set_active((GetCurField()->GetFormat() & AF_FIXED
) != 0 && bFixed
);
418 if (m_xNumFormatLB
->get_selected_index() == -1)
419 m_xNumFormatLB
->select(0);
420 m_xValueFT
->set_sensitive(bValue
|| bLevel
|| bOffset
);
421 m_xValueED
->set_sensitive(bValue
);
424 void SwFieldDokPage::AddSubType(SwFieldTypesEnum nTypeId
)
426 m_xSelectionLB
->append(OUString::number(static_cast<sal_uInt16
>(nTypeId
)), SwFieldType::GetTypeStr(nTypeId
));
429 IMPL_LINK_NOARG(SwFieldDokPage
, SubTypeHdl
, weld::TreeView
&, void)
431 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
435 const SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(nPos
).toUInt32());
436 FillFormatLB(nTypeId
);
438 TranslateId pTextRes
;
441 case SwFieldTypesEnum::Chapter
:
442 pTextRes
= STR_LEVEL
;
445 case SwFieldTypesEnum::PreviousPage
:
446 case SwFieldTypesEnum::NextPage
:
447 pTextRes
= SVX_NUM_CHAR_SPECIAL
== m_xFormatLB
->get_selected_id().toUInt32()
448 ? STR_VALUE
: STR_OFFSET
;
451 case SwFieldTypesEnum::PageNumber
:
452 pTextRes
= STR_OFFSET
;
458 m_xValueFT
->set_label(SwResId(pTextRes
));
461 sal_Int32
SwFieldDokPage::FillFormatLB(SwFieldTypesEnum nTypeId
)
463 // fill Format-Listbox
464 m_xFormatLB
->clear();
466 if (nTypeId
== SwFieldTypesEnum::Author
)
467 return m_xFormatLB
->n_children();
469 const sal_uInt16 nSize
= GetFieldMgr().GetFormatCount(nTypeId
, IsFieldDlgHtmlMode());
471 for( sal_uInt16 i
= 0; i
< nSize
; ++i
)
473 const sal_uInt16 nFormatId
= GetFieldMgr().GetFormatId( nTypeId
, i
);
474 OUString
sId(OUString::number(nFormatId
));
475 m_xFormatLB
->append(sId
, GetFieldMgr().GetFormatStr(nTypeId
, i
));
480 m_xFormatLB
->select_id(OUString::number(GetCurField()->GetFormat() & ~AF_FIXED
));
484 // Select default selected value for "Insert" dialog
487 case SwFieldTypesEnum::PageNumber
:
488 case SwFieldTypesEnum::DocumentStatistics
:
489 m_xFormatLB
->select_text(SwResId(FMT_NUM_PAGEDESC
));
492 m_xFormatLB
->select(0);
496 FormatHdl(*m_xFormatLB
);
501 IMPL_LINK_NOARG(SwFieldDokPage
, FormatHdl
, weld::TreeView
&, void)
503 SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xTypeLB
->get_id(GetTypeSel()).toUInt32());
505 if (nTypeId
== SwFieldTypesEnum::Unknown
)
507 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
511 nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(nPos
).toUInt32());
514 if (nTypeId
!= SwFieldTypesEnum::NextPage
&& nTypeId
!= SwFieldTypesEnum::PreviousPage
)
517 // Prev/Next - PageNumFields special treatment:
518 sal_uInt16 nTmp
= m_xFormatLB
->get_selected_id().toUInt32();
519 const OUString
sOldText( m_xValueFT
->get_label() );
520 const OUString
sNewText( SwResId( SVX_NUM_CHAR_SPECIAL
== nTmp
? STR_VALUE
523 if (sOldText
!= sNewText
)
524 m_xValueFT
->set_label(sNewText
);
526 if (sOldText
!= m_xValueFT
->get_label())
527 m_xValueED
->set_text(OUString());
530 bool SwFieldDokPage::FillItemSet(SfxItemSet
* )
532 SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xTypeLB
->get_id(GetTypeSel()).toUInt32());
534 if (nTypeId
== SwFieldTypesEnum::Unknown
)
536 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
539 nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(nPos
).toUInt32());
542 OUString
aVal(m_xValueED
->get_text());
543 sal_uInt32 nFormat
= 0;
544 sal_uInt16 nSubType
= 0;
546 if (m_xFormatLB
->get_sensitive())
548 sal_Int32 nPos
= m_xFormatLB
->get_selected_index();
550 nFormat
= m_xFormatLB
->get_id(nPos
).toUInt32();
553 if (m_xSelectionLB
->get_sensitive())
555 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
557 nSubType
= m_xSelectionLB
->get_id(nPos
).toUInt32();
562 case SwFieldTypesEnum::Author
:
566 case SwFieldTypesEnum::ExtendedUser
:
567 nFormat
|= m_xFixedCB
->get_active() ? AF_FIXED
: 0;
570 case SwFieldTypesEnum::Filename
:
571 nFormat
|= m_xFixedCB
->get_active() ? FF_FIXED
: 0;
574 case SwFieldTypesEnum::Date
:
575 case SwFieldTypesEnum::Time
:
577 nFormat
= m_xNumFormatLB
->GetFormat();
578 tools::Long nVal
= static_cast< tools::Long
>(m_xDateOffsetED
->get_value());
579 if (nTypeId
== SwFieldTypesEnum::Date
)
580 aVal
= OUString::number(nVal
* 60 * 24);
582 aVal
= OUString::number(nVal
);
586 case SwFieldTypesEnum::NextPage
:
587 case SwFieldTypesEnum::PreviousPage
:
588 case SwFieldTypesEnum::PageNumber
:
589 case SwFieldTypesEnum::GetRefPage
:
591 if( SVX_NUM_CHAR_SPECIAL
!= nFormat
&&
592 (SwFieldTypesEnum::PreviousPage
== nTypeId
|| SwFieldTypesEnum::NextPage
== nTypeId
))
594 sal_Int32 nVal
= m_xValueED
->get_text().toInt32();
595 aVal
= OUString::number(nVal
);
600 case SwFieldTypesEnum::Chapter
:
601 aVal
= m_xLevelED
->get_text();
608 if (!IsFieldEdit() ||
609 m_nOldSel
!= m_xSelectionLB
->get_selected_index() ||
610 m_nOldFormat
!= nFormat
||
611 m_xFixedCB
->get_state_changed_from_saved() ||
612 m_xValueED
->get_value_changed_from_saved() ||
613 m_xLevelED
->get_value_changed_from_saved() ||
614 m_xDateOffsetED
->get_value_changed_from_saved())
616 InsertField(nTypeId
, nSubType
, OUString(), aVal
, nFormat
, ' ', m_xNumFormatLB
->IsAutomaticLanguage());
622 std::unique_ptr
<SfxTabPage
> SwFieldDokPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
,
623 const SfxItemSet
*const pAttrSet
)
625 return std::make_unique
<SwFieldDokPage
>(pPage
, pController
, pAttrSet
);
628 sal_uInt16
SwFieldDokPage::GetGroup()
633 void SwFieldDokPage::FillUserData()
635 const sal_Int32 nEntryPos
= m_xTypeLB
->get_selected_index();
636 const sal_uInt16 nTypeSel
= ( -1 == nEntryPos
)
637 ? USHRT_MAX
: m_xTypeLB
->get_id(nEntryPos
).toUInt32();
638 SetUserData(USER_DATA_VERSION
";" + OUString::number( nTypeSel
));
641 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */