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
, u
"modules/swriter/ui/flddocumentpage.ui"_ustr
,
36 u
"FieldDocumentPage"_ustr
, pCoreSet
)
39 , m_xTypeLB(m_xBuilder
->weld_tree_view(u
"type"_ustr
))
40 , m_xSelection(m_xBuilder
->weld_widget(u
"selectframe"_ustr
))
41 , m_xSelectionLB(m_xBuilder
->weld_tree_view(u
"select"_ustr
))
42 , m_xValueFT(m_xBuilder
->weld_label(u
"valueft"_ustr
))
43 , m_xValueED(m_xBuilder
->weld_entry(u
"value"_ustr
))
44 , m_xLevelFT(m_xBuilder
->weld_label(u
"levelft"_ustr
))
45 , m_xLevelED(m_xBuilder
->weld_combo_box(u
"level"_ustr
))
46 , m_xDateFT(m_xBuilder
->weld_label(u
"daysft"_ustr
))
47 , m_xTimeFT(m_xBuilder
->weld_label(u
"minutesft"_ustr
))
48 , m_xDateOffsetED(m_xBuilder
->weld_spin_button(u
"offset"_ustr
))
49 , m_xFormat(m_xBuilder
->weld_widget(u
"formatframe"_ustr
))
50 , m_xFormatLB(m_xBuilder
->weld_tree_view(u
"format"_ustr
))
51 , m_xNumFormatLB(new SwNumFormatTreeView(m_xBuilder
->weld_tree_view(u
"numformat"_ustr
)))
52 , m_xFixedCB(m_xBuilder
->weld_check_button(u
"fixed"_ustr
))
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 for (sal_uInt16 i
= 1; i
<= MAXLEVEL
; i
++)
69 m_xLevelED
->append_text(OUString::number(i
));
71 m_xLevelED
->set_active(0);
72 m_xDateOffsetED
->set_range(INT_MIN
, INT_MAX
);
73 //enable 'active' language selection
74 m_xNumFormatLB
->SetShowLanguageControl(true);
77 m_xTypeLB
->set_buildable_name(m_xTypeLB
->get_buildable_name() + "-doc");
78 m_xValueED
->set_buildable_name(m_xValueED
->get_buildable_name() + "-doc");
79 m_xNumFormatLB
->set_buildable_name(m_xNumFormatLB
->get_buildable_name() + "-doc");
80 m_xSelectionLB
->set_buildable_name(m_xSelectionLB
->get_buildable_name() + "-doc");
81 m_xFormatLB
->set_buildable_name(m_xFormatLB
->get_buildable_name() + "-doc");
84 SwFieldDokPage::~SwFieldDokPage()
88 void SwFieldDokPage::Reset(const SfxItemSet
* )
91 Init(); // general initialisation
93 // initialise TypeListBox
94 const SwFieldGroupRgn
& rRg
= SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
103 for(sal_uInt16 i
= rRg
.nStart
; i
< rRg
.nEnd
; ++i
)
105 const SwFieldTypesEnum nTypeId
= SwFieldMgr::GetTypeId(i
);
109 case SwFieldTypesEnum::PreviousPage
:
110 case SwFieldTypesEnum::NextPage
:
111 case SwFieldTypesEnum::PageNumber
:
114 m_xTypeLB
->append(OUString::number(USHRT_MAX
), SwResId(FMT_REF_PAGE
));
120 m_xTypeLB
->append(OUString::number(static_cast<sal_uInt16
>(nTypeId
)), SwFieldMgr::GetTypeStr(i
));
127 const SwField
* pCurField
= GetCurField();
128 SwFieldTypesEnum nTypeId
= pCurField
->GetTypeId();
129 if (nTypeId
== SwFieldTypesEnum::FixedDate
)
130 nTypeId
= SwFieldTypesEnum::Date
;
131 if (nTypeId
== SwFieldTypesEnum::FixedTime
)
132 nTypeId
= SwFieldTypesEnum::Time
;
133 m_xTypeLB
->append(OUString::number(static_cast<sal_uInt16
>(nTypeId
)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId
)));
134 m_xNumFormatLB
->SetAutomaticLanguage(pCurField
->IsAutomaticLanguage());
135 SwWrtShell
*pSh
= GetWrtShell();
137 pSh
= ::GetActiveWrtShell();
140 const SvNumberformat
* pFormat
= pSh
->GetNumberFormatter()->GetEntry(pCurField
->GetFormat());
142 m_xNumFormatLB
->SetLanguage(pFormat
->GetLanguage());
150 RestorePos(*m_xTypeLB
);
152 m_xTypeLB
->connect_row_activated(LINK(this, SwFieldDokPage
, TreeViewInsertHdl
));
153 m_xTypeLB
->connect_selection_changed(LINK(this, SwFieldDokPage
, TypeHdl
));
154 m_xFormatLB
->connect_selection_changed(LINK(this, SwFieldDokPage
, FormatHdl
));
158 const OUString sUserData
= GetUserData();
160 if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData
, 0, ';', nIdx
), u
"" USER_DATA_VERSION_1
))
162 const sal_uInt16 nVal
= static_cast< sal_uInt16
>(o3tl::toInt32(o3tl::getToken(sUserData
, 0, ';', nIdx
)));
163 if(nVal
!= USHRT_MAX
)
165 for (int i
= 0, nEntryCount
= m_xTypeLB
->n_children(); i
< nEntryCount
; i
++)
167 if (nVal
== m_xTypeLB
->get_id(i
).toUInt32())
169 m_xTypeLB
->select(i
);
180 m_nOldSel
= m_xSelectionLB
->get_selected_index();
181 m_nOldFormat
= GetCurField()->GetFormat();
182 m_xFixedCB
->save_state();
183 m_xValueED
->save_value();
184 m_xLevelED
->save_value();
185 m_xDateOffsetED
->save_value();
189 IMPL_LINK_NOARG(SwFieldDokPage
, TypeHdl
, weld::TreeView
&, void)
191 // save old ListBoxPos
192 const sal_Int32 nOld
= GetTypeSel();
194 // current ListBoxPos
195 SetTypeSel(m_xTypeLB
->get_selected_index());
197 if(GetTypeSel() == -1)
200 m_xTypeLB
->select(0);
203 if (nOld
== GetTypeSel())
211 SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xTypeLB
->get_id(GetTypeSel()).toUInt32());
213 // fill Selection-Listbox
214 m_xSelectionLB
->clear();
216 if (nTypeId
!= SwFieldTypesEnum::Unknown
)
218 std::vector
<OUString
> aLst
;
219 GetFieldMgr().GetSubTypes(nTypeId
, aLst
);
221 if (nTypeId
!= SwFieldTypesEnum::Author
)
222 nCount
= aLst
.size();
224 nCount
= GetFieldMgr().GetFormatCount(nTypeId
, IsFieldDlgHtmlMode());
226 for (size_t i
= 0; i
< nCount
; ++i
)
230 OUString
sId(OUString::number(i
));
231 if (nTypeId
!= SwFieldTypesEnum::Author
)
232 m_xSelectionLB
->append(sId
, aLst
[i
]);
234 m_xSelectionLB
->append(sId
, GetFieldMgr().GetFormatStr(nTypeId
, i
));
238 bool bInsert
= false;
240 OUString
sId(OUString::number(i
));
244 case SwFieldTypesEnum::Date
:
245 case SwFieldTypesEnum::Time
:
246 m_xSelectionLB
->append(sId
, aLst
[i
]);
247 if (static_cast<SwDateTimeField
*>(GetCurField())->IsFixed() && !i
)
248 m_xSelectionLB
->select_id(sId
);
249 if (!static_cast<SwDateTimeField
*>(GetCurField())->IsFixed() && i
)
250 m_xSelectionLB
->select_id(sId
);
252 case SwFieldTypesEnum::ExtendedUser
:
253 case SwFieldTypesEnum::DocumentStatistics
:
254 m_xSelectionLB
->append(sId
, aLst
[i
]);
255 if (GetCurField()->GetSubType() == i
)
256 m_xSelectionLB
->select_id(sId
);
259 case SwFieldTypesEnum::Author
:
261 const OUString
sFormat(GetFieldMgr().GetFormatStr(nTypeId
, i
));
262 m_xSelectionLB
->append(sId
, sFormat
);
263 m_xSelectionLB
->select_text(GetFieldMgr().GetFormatStr(nTypeId
, GetCurField()->GetFormat()));
268 if (aLst
[i
] == GetCurField()->GetPar1())
274 m_xSelectionLB
->append(sId
, aLst
[i
]);
279 m_xSelectionLB
->connect_selection_changed(Link
<weld::TreeView
&, void>());
283 AddSubType(SwFieldTypesEnum::PageNumber
);
284 AddSubType(SwFieldTypesEnum::PreviousPage
);
285 AddSubType(SwFieldTypesEnum::NextPage
);
286 nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(0).toUInt32());
288 m_xSelectionLB
->connect_selection_changed(LINK(this, SwFieldDokPage
, SubTypeHdl
));
291 bool bEnable
= nCount
!= 0;
293 if (bEnable
&& m_xSelectionLB
->get_selected_index() == -1)
294 m_xSelectionLB
->select(0);
296 m_xSelection
->set_sensitive( bEnable
);
298 // fill Format-Listbox
299 sal_Int32 nSize
= FillFormatLB(nTypeId
);
301 bool bValue
= false, bLevel
= false, bNumFormat
= false, bOffset
= false;
302 bool bFormat
= nSize
!= 0;
303 bool bOneArea
= false;
305 SvNumFormatType nFormatType
= SvNumFormatType::ALL
;
309 case SwFieldTypesEnum::Date
:
310 bFormat
= bNumFormat
= bOneArea
= bOffset
= true;
312 nFormatType
= SvNumFormatType::DATE
;
316 m_xDateOffsetED
->set_range(INT_MIN
, INT_MAX
); // no limit
319 m_xDateOffsetED
->set_value( static_cast<SwDateTimeField
*>(GetCurField())->GetOffset() / 24 / 60);
322 case SwFieldTypesEnum::Time
:
323 bFormat
= bNumFormat
= bOneArea
= bOffset
= true;
325 nFormatType
= SvNumFormatType::TIME
;
329 m_xDateOffsetED
->set_range(-1440, 1440); // one day
332 m_xDateOffsetED
->set_value( static_cast<SwDateTimeField
*>(GetCurField())->GetOffset() );
335 case SwFieldTypesEnum::PreviousPage
:
336 case SwFieldTypesEnum::NextPage
:
339 const sal_uInt16 nTmp
= m_xFormatLB
->get_selected_id().toUInt32();
341 if(SVX_NUM_CHAR_SPECIAL
!= nTmp
)
343 sal_Int32 nOff
= GetCurField()->GetPar2().toInt32();
344 if( SwFieldTypesEnum::NextPage
== nTypeId
&& 1 != nOff
)
345 m_xValueED
->set_text(
346 OUString::number(nOff
- 1) );
347 else if( SwFieldTypesEnum::PreviousPage
== nTypeId
&& -1 != nOff
)
348 m_xValueED
->set_text(
349 OUString::number(nOff
+ 1) );
351 m_xValueED
->set_text(OUString());
354 m_xValueED
->set_text(static_cast<SwPageNumberField
*>(GetCurField())->GetUserString());
359 case SwFieldTypesEnum::Chapter
:
360 m_xValueFT
->set_label(SwResId(STR_LEVEL
));
362 m_xLevelED
->set_active(static_cast<SwChapterField
*>(GetCurField())->GetLevel(GetWrtShell()->GetLayout()));
366 case SwFieldTypesEnum::PageNumber
:
367 m_xValueFT
->set_label( SwResId( STR_OFFSET
));
369 m_xValueED
->set_text(GetCurField()->GetPar2());
373 case SwFieldTypesEnum::ExtendedUser
:
374 case SwFieldTypesEnum::Author
:
375 case SwFieldTypesEnum::Filename
:
387 m_xNumFormatLB
->SetDefFormat(GetCurField()->GetFormat());
389 if (m_xNumFormatLB
->GetFormatType() == (SvNumFormatType::DATE
|SvNumFormatType::TIME
))
391 // always set Format-Type because otherwise when date/time formats are combined,
392 // both formats would be displayed at the same time
393 m_xNumFormatLB
->SetFormatType(SvNumFormatType::ALL
);
394 m_xNumFormatLB
->SetFormatType(nFormatType
);
395 // set correct format once again
396 m_xNumFormatLB
->SetDefFormat(GetCurField()->GetFormat());
400 m_xNumFormatLB
->SetFormatType(nFormatType
);
402 m_xNumFormatLB
->SetOneArea(bOneArea
);
405 m_xFormatLB
->set_visible(!bNumFormat
);
406 m_xNumFormatLB
->set_visible(bNumFormat
);
408 m_xValueFT
->set_visible(bValue
);
409 m_xValueED
->set_visible(bValue
);
410 m_xLevelFT
->set_visible(bLevel
);
411 m_xLevelED
->set_visible(bLevel
);
412 m_xDateOffsetED
->set_visible(bOffset
);
413 m_xFixedCB
->set_visible(!bValue
&& !bLevel
&& !bOffset
);
415 m_xFormat
->set_sensitive(bFormat
);
416 m_xFixedCB
->set_sensitive(bFixed
);
419 m_xFixedCB
->set_active((GetCurField()->GetFormat() & AF_FIXED
) != 0 && bFixed
);
421 if (m_xNumFormatLB
->get_selected_index() == -1)
422 m_xNumFormatLB
->select(0);
423 m_xValueFT
->set_sensitive(bValue
|| bLevel
|| bOffset
);
424 m_xValueED
->set_sensitive(bValue
);
427 void SwFieldDokPage::AddSubType(SwFieldTypesEnum nTypeId
)
429 m_xSelectionLB
->append(OUString::number(static_cast<sal_uInt16
>(nTypeId
)), SwFieldType::GetTypeStr(nTypeId
));
432 IMPL_LINK_NOARG(SwFieldDokPage
, SubTypeHdl
, weld::TreeView
&, void)
434 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
438 const SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(nPos
).toUInt32());
439 FillFormatLB(nTypeId
);
441 TranslateId pTextRes
;
444 case SwFieldTypesEnum::Chapter
:
445 pTextRes
= STR_LEVEL
;
448 case SwFieldTypesEnum::PreviousPage
:
449 case SwFieldTypesEnum::NextPage
:
450 pTextRes
= SVX_NUM_CHAR_SPECIAL
== m_xFormatLB
->get_selected_id().toUInt32()
451 ? STR_VALUE
: STR_OFFSET
;
454 case SwFieldTypesEnum::PageNumber
:
455 pTextRes
= STR_OFFSET
;
461 m_xValueFT
->set_label(SwResId(pTextRes
));
464 sal_Int32
SwFieldDokPage::FillFormatLB(SwFieldTypesEnum nTypeId
)
466 // fill Format-Listbox
467 m_xFormatLB
->clear();
469 if (nTypeId
== SwFieldTypesEnum::Author
)
470 return m_xFormatLB
->n_children();
472 const sal_uInt16 nSize
= GetFieldMgr().GetFormatCount(nTypeId
, IsFieldDlgHtmlMode());
474 for( sal_uInt16 i
= 0; i
< nSize
; ++i
)
476 const sal_uInt16 nFormatId
= GetFieldMgr().GetFormatId( nTypeId
, i
);
477 OUString
sId(OUString::number(nFormatId
));
478 m_xFormatLB
->append(sId
, GetFieldMgr().GetFormatStr(nTypeId
, i
));
483 m_xFormatLB
->select_id(OUString::number(GetCurField()->GetFormat() & ~AF_FIXED
));
487 // Select default selected value for "Insert" dialog
490 case SwFieldTypesEnum::PageNumber
:
491 case SwFieldTypesEnum::DocumentStatistics
:
492 m_xFormatLB
->select_text(SwResId(FMT_NUM_PAGEDESC
));
495 m_xFormatLB
->select(0);
499 FormatHdl(*m_xFormatLB
);
504 IMPL_LINK_NOARG(SwFieldDokPage
, FormatHdl
, weld::TreeView
&, void)
506 SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xTypeLB
->get_id(GetTypeSel()).toUInt32());
508 if (nTypeId
== SwFieldTypesEnum::Unknown
)
510 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
514 nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(nPos
).toUInt32());
517 if (nTypeId
!= SwFieldTypesEnum::NextPage
&& nTypeId
!= SwFieldTypesEnum::PreviousPage
)
520 // Prev/Next - PageNumFields special treatment:
521 sal_uInt16 nTmp
= m_xFormatLB
->get_selected_id().toUInt32();
522 const OUString
sOldText( m_xValueFT
->get_label() );
523 const OUString
sNewText( SwResId( SVX_NUM_CHAR_SPECIAL
== nTmp
? STR_VALUE
526 if (sOldText
!= sNewText
)
527 m_xValueFT
->set_label(sNewText
);
529 if (sOldText
!= m_xValueFT
->get_label())
530 m_xValueED
->set_text(OUString());
533 bool SwFieldDokPage::FillItemSet(SfxItemSet
* )
535 SwFieldTypesEnum nTypeId
= static_cast<SwFieldTypesEnum
>(m_xTypeLB
->get_id(GetTypeSel()).toUInt32());
537 if (nTypeId
== SwFieldTypesEnum::Unknown
)
539 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
542 nTypeId
= static_cast<SwFieldTypesEnum
>(m_xSelectionLB
->get_id(nPos
).toUInt32());
545 OUString
aVal(m_xValueED
->get_text());
546 sal_uInt32 nFormat
= 0;
547 sal_uInt16 nSubType
= 0;
549 if (m_xFormatLB
->get_sensitive())
551 sal_Int32 nPos
= m_xFormatLB
->get_selected_index();
553 nFormat
= m_xFormatLB
->get_id(nPos
).toUInt32();
556 if (m_xSelectionLB
->get_sensitive())
558 sal_Int32 nPos
= m_xSelectionLB
->get_selected_index();
560 nSubType
= m_xSelectionLB
->get_id(nPos
).toUInt32();
565 case SwFieldTypesEnum::Author
:
569 case SwFieldTypesEnum::ExtendedUser
:
570 nFormat
|= m_xFixedCB
->get_active() ? AF_FIXED
: 0;
573 case SwFieldTypesEnum::Filename
:
574 nFormat
|= m_xFixedCB
->get_active() ? FF_FIXED
: 0;
577 case SwFieldTypesEnum::Date
:
578 case SwFieldTypesEnum::Time
:
580 nFormat
= m_xNumFormatLB
->GetFormat();
581 tools::Long nVal
= static_cast< tools::Long
>(m_xDateOffsetED
->get_value());
582 if (nTypeId
== SwFieldTypesEnum::Date
)
583 aVal
= OUString::number(nVal
* 60 * 24);
585 aVal
= OUString::number(nVal
);
589 case SwFieldTypesEnum::NextPage
:
590 case SwFieldTypesEnum::PreviousPage
:
591 case SwFieldTypesEnum::PageNumber
:
592 case SwFieldTypesEnum::GetRefPage
:
594 if( SVX_NUM_CHAR_SPECIAL
!= nFormat
&&
595 (SwFieldTypesEnum::PreviousPage
== nTypeId
|| SwFieldTypesEnum::NextPage
== nTypeId
))
597 sal_Int32 nVal
= m_xValueED
->get_text().toInt32();
598 aVal
= OUString::number(nVal
);
603 case SwFieldTypesEnum::Chapter
:
604 aVal
= m_xLevelED
->get_active_text();
611 if (!IsFieldEdit() ||
612 m_nOldSel
!= m_xSelectionLB
->get_selected_index() ||
613 m_nOldFormat
!= nFormat
||
614 m_xFixedCB
->get_state_changed_from_saved() ||
615 m_xValueED
->get_value_changed_from_saved() ||
616 m_xLevelED
->get_value_changed_from_saved() ||
617 m_xDateOffsetED
->get_value_changed_from_saved())
619 InsertField(nTypeId
, nSubType
, OUString(), aVal
, nFormat
, ' ', m_xNumFormatLB
->IsAutomaticLanguage());
625 std::unique_ptr
<SfxTabPage
> SwFieldDokPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
,
626 const SfxItemSet
*const pAttrSet
)
628 return std::make_unique
<SwFieldDokPage
>(pPage
, pController
, pAttrSet
);
631 sal_uInt16
SwFieldDokPage::GetGroup()
636 void SwFieldDokPage::FillUserData()
638 const sal_Int32 nEntryPos
= m_xTypeLB
->get_selected_index();
639 const sal_uInt16 nTypeSel
= ( -1 == nEntryPos
)
640 ? USHRT_MAX
: m_xTypeLB
->get_id(nEntryPos
).toUInt32();
641 SetUserData(USER_DATA_VERSION
";" + OUString::number( nTypeSel
));
644 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */