Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / ui / fldui / fldvar.cxx
blob13265523ba1767e11d8375ff091e3aed2393b7dd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <swtypes.hxx>
21 #include <sfx2/linkmgr.hxx>
22 #include <IDocumentFieldsAccess.hxx>
23 #include <usrfld.hxx>
24 #include <docufld.hxx>
25 #include <expfld.hxx>
26 #include <ddefld.hxx>
27 #include <wrtsh.hxx>
28 #include <doc.hxx>
29 #include <docary.hxx>
30 #include <swmodule.hxx>
31 #include "fldvar.hxx"
32 #include "flddinf.hxx"
33 #include <calc.hxx>
34 #include <svl/numformat.hxx>
35 #include <svl/zformat.hxx>
36 #include <o3tl/string_view.hxx>
37 #include <strings.hrc>
39 #define USER_DATA_VERSION_1 "1"
40 #define USER_DATA_VERSION USER_DATA_VERSION_1
42 SwFieldVarPage::SwFieldVarPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet )
43 : SwFieldPage(pPage, pController, "modules/swriter/ui/fldvarpage.ui", "FieldVarPage", pCoreSet)
44 , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
45 , m_xSelection(m_xBuilder->weld_widget("selectframe"))
46 , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
47 , m_xNameFT(m_xBuilder->weld_label("nameft"))
48 , m_xNameED(m_xBuilder->weld_entry("name"))
49 , m_xValueFT(m_xBuilder->weld_label("valueft"))
50 , m_xValueED(new ConditionEdit(m_xBuilder->weld_entry("value")))
51 , m_xFormat(m_xBuilder->weld_widget("formatframe"))
52 , m_xNumFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("numformat")))
53 , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
54 , m_xChapterFrame(m_xBuilder->weld_widget("chapterframe"))
55 , m_xChapterLevelLB(m_xBuilder->weld_combo_box("level"))
56 , m_xInvisibleCB(m_xBuilder->weld_check_button("invisible"))
57 , m_xSeparatorFT(m_xBuilder->weld_label("separatorft"))
58 , m_xSeparatorED(m_xBuilder->weld_entry("separator"))
59 , m_xNewPB(m_xBuilder->weld_button("apply"))
60 , m_xDelPB(m_xBuilder->weld_button("delete"))
61 , m_nOldFormat(0)
62 , m_bInit(true)
64 FillFieldSelect(*m_xTypeLB);
65 m_xSelectionLB->make_sorted();
66 FillFieldSelect(*m_xFormatLB);
68 auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
69 auto nHeight = m_xTypeLB->get_height_rows(10);
70 m_xTypeLB->set_size_request(nWidth, nHeight);
71 m_xSelectionLB->set_size_request(nWidth, nHeight);
72 m_xFormatLB->set_size_request(nWidth, nHeight/2);
74 m_sOldValueFT = m_xValueFT->get_label();
75 m_sOldNameFT = m_xNameFT->get_label();
77 for (sal_uInt16 i = 1; i <= MAXLEVEL; i++)
78 m_xChapterLevelLB->append_text(OUString::number(i));
80 m_xChapterLevelLB->set_active(0);
81 //enable 'active' language selection
82 m_xNumFormatLB->SetShowLanguageControl(true);
84 // uitests
85 m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-var");
86 m_xNameED->set_buildable_name(m_xNameED->get_buildable_name() + "-var");
87 m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-var");
88 m_xNumFormatLB->set_buildable_name(m_xNumFormatLB->get_buildable_name() + "-var");
89 m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-var");
90 m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-var");
93 SwFieldVarPage::~SwFieldVarPage()
97 void SwFieldVarPage::Reset(const SfxItemSet* )
99 SavePos(*m_xTypeLB);
101 Init(); // general initialisation
103 m_xTypeLB->freeze();
104 m_xTypeLB->clear();
106 SwFieldTypesEnum nTypeId;
108 if (!IsFieldEdit())
110 // initialise TypeListBox
111 const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
113 for (short i = rRg.nStart; i < rRg.nEnd; ++i)
115 nTypeId = SwFieldMgr::GetTypeId(i);
116 m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
119 else
121 const SwField* pCurField = GetCurField();
122 assert(pCurField && "<SwFieldVarPage::Reset(..)> - <SwField> instance missing!");
123 nTypeId = pCurField->GetTypeId();
124 if (nTypeId == SwFieldTypesEnum::SetInput)
125 nTypeId = SwFieldTypesEnum::Input;
126 m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
127 m_xNumFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
128 SwWrtShell *pSh = GetWrtShell();
129 if(!pSh)
130 pSh = ::GetActiveWrtShell();
131 if(pSh)
133 const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
134 if(pFormat)
135 m_xNumFormatLB->SetLanguage(pFormat->GetLanguage());
139 m_xTypeLB->thaw();
141 // select old Pos
142 RestorePos(*m_xTypeLB);
144 m_xTypeLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
145 m_xTypeLB->connect_changed(LINK(this, SwFieldVarPage, TypeHdl));
146 m_xSelectionLB->connect_changed(LINK(this, SwFieldVarPage, SubTypeListBoxHdl));
147 m_xSelectionLB->connect_row_activated(LINK(this, SwFieldVarPage, SubTypeInsertHdl));
148 m_xFormatLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
149 m_xNumFormatLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
150 m_xNameED->connect_changed(LINK(this, SwFieldVarPage, ModifyHdl));
151 m_xValueED->connect_changed(LINK(this, SwFieldVarPage, ModifyHdl));
152 m_xNewPB->connect_clicked(LINK(this, SwFieldVarPage, TBClickHdl));
153 m_xDelPB->connect_clicked(LINK(this, SwFieldVarPage, TBClickHdl));
154 m_xChapterLevelLB->connect_changed(LINK(this, SwFieldVarPage, ChapterHdl));
155 m_xSeparatorED->connect_changed(LINK(this, SwFieldVarPage, SeparatorHdl));
157 if( !IsRefresh() )
159 OUString sUserData = GetUserData();
160 sal_Int32 nIdx{ 0 };
161 if(!IsRefresh() && o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
163 std::u16string_view sVal = o3tl::getToken(sUserData, 0, ';', nIdx);
164 sal_uInt16 nVal = o3tl::narrowing<sal_uInt16>(o3tl::toInt32(sVal));
165 if (USHRT_MAX != nVal)
167 for (sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; i++)
169 if (nVal == m_xTypeLB->get_id(i).toUInt32())
171 m_xTypeLB->select(i);
172 break;
178 TypeHdl(*m_xTypeLB);
180 if (IsFieldEdit())
182 m_xSelectionLB->save_value();
183 m_xFormatLB->save_value();
184 m_nOldFormat = m_xNumFormatLB->GetFormat();
185 m_xNameED->save_value();
186 m_xValueED->save_value();
187 m_xInvisibleCB->save_state();
188 m_xChapterLevelLB->save_value();
189 m_xSeparatorED->save_value();
193 IMPL_LINK_NOARG(SwFieldVarPage, TypeHdl, weld::TreeView&, void)
195 // save old ListBoxPos
196 const sal_Int32 nOld = GetTypeSel();
198 // current ListBoxPos
199 SetTypeSel(m_xTypeLB->get_selected_index());
201 if(GetTypeSel() == -1)
203 SetTypeSel(0);
204 m_xTypeLB->select(0);
207 if (nOld != GetTypeSel() || nOld == -1)
209 m_bInit = true;
210 if (nOld != -1)
212 m_xNameED->set_text(OUString());
213 m_xValueED->set_text(OUString());
216 m_xValueED->SetDropEnable(false);
217 UpdateSubType(); // initialise selection-listboxes
220 m_bInit = false;
223 IMPL_LINK( SwFieldVarPage, SubTypeListBoxHdl, weld::TreeView&, rBox, void )
225 SubTypeHdl(&rBox);
228 static inline sal_uInt32 lcl_getUsedNumFormat( const SwNumFormatTreeView& rNumFormatLB, bool& rbText )
230 sal_uInt32 nNumberFormat = 0;
231 const sal_Int32 nNumFormatPos = rNumFormatLB.get_selected_index();
232 if (nNumFormatPos != -1)
234 nNumberFormat = rNumFormatLB.GetFormat();
235 if ((rbText = (nNumFormatPos == 0 && nNumberFormat == SAL_MAX_UINT32)))
236 nNumberFormat = 0;
238 return nNumberFormat;
241 void SwFieldVarPage::SubTypeHdl(const weld::TreeView* pBox)
243 SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
244 sal_Int32 nSelPos = m_xSelectionLB->get_selected_index();
245 size_t nSelData = SIZE_MAX;
247 if (nSelPos != -1)
248 nSelData = m_xSelectionLB->get_id(nSelPos).toUInt32();
250 if (IsFieldEdit() && (!pBox || m_bInit))
252 if (nTypeId != SwFieldTypesEnum::Formel)
253 m_xNameED->set_text(GetFieldMgr().GetCurFieldPar1());
255 m_xValueED->set_text(GetFieldMgr().GetCurFieldPar2());
258 if (m_xNameFT->get_label() != m_sOldNameFT)
259 m_xNameFT->set_label(m_sOldNameFT);
260 if (m_xValueFT->get_label() != m_sOldValueFT)
261 m_xValueFT->set_label(m_sOldValueFT);
263 FillFormatLB(nTypeId);
265 sal_Int32 nSize = m_xFormatLB->n_children();
267 bool bValue = false, bName = false, bNumFormat = false,
268 bInvisible = false, bShowChapterFrame = false;
269 bool bFormat = nSize != 0;
271 switch (nTypeId)
273 case SwFieldTypesEnum::User:
275 // change or create user type
276 SwUserFieldType* pType = static_cast<SwUserFieldType*>(
277 GetFieldMgr().GetFieldType(SwFieldIds::User, nSelData));
279 if (pType)
281 if (!IsFieldEdit())
283 if (pBox || (m_bInit && !IsRefresh())) // only when interacting via mouse
285 m_xNameED->set_text(pType->GetName());
287 if (pType->GetType() == UF_STRING)
289 m_xValueED->set_text(pType->GetContent());
290 m_xNumFormatLB->select(0);
292 else
294 bool bText = false;
295 const sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
296 m_xValueED->set_text(pType->GetInputOrDateTime(nNumberFormat));
300 else
302 bool bText = false;
303 const sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
304 m_xValueED->set_text(pType->GetInputOrDateTime(nNumberFormat));
307 else
309 if (pBox) // only when interacting via mouse
311 m_xNameED->set_text(OUString());
312 m_xValueED->set_text(OUString());
315 bValue = bName = bNumFormat = bInvisible = true;
317 m_xValueED->SetDropEnable(true);
318 break;
321 case SwFieldTypesEnum::Set:
322 bValue = true;
324 bNumFormat = bInvisible = true;
326 if (!IsFieldDlgHtmlMode())
327 bName = true;
328 else
330 m_xNumFormatLB->clear();
331 m_xNumFormatLB->append(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND), SwResId(FMT_SETVAR_TEXT));
332 m_xNumFormatLB->select(0);
334 // is there a corresponding SetField
335 if (IsFieldEdit() || pBox) // only when interacting via mouse
337 if (nSelPos != -1)
339 OUString sName(m_xSelectionLB->get_selected_text());
340 m_xNameED->set_text(sName);
342 if (!IsFieldDlgHtmlMode())
344 SwWrtShell *pSh = GetWrtShell();
345 if(!pSh)
346 pSh = ::GetActiveWrtShell();
347 if(pSh)
349 SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
350 pSh->GetFieldType(SwFieldIds::SetExp, sName));
352 if (pSetTyp && pSetTyp->GetType() == nsSwGetSetExpType::GSE_STRING)
353 m_xNumFormatLB->select(0); // textual
358 if (GetCurField() != nullptr && IsFieldEdit())
360 m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetInputOrDateTime());
362 m_xValueED->SetDropEnable(true);
363 break;
365 case SwFieldTypesEnum::Formel:
367 bValue = true;
368 bNumFormat = true;
369 m_xValueFT->set_label(SwResId(STR_FORMULA));
370 m_xValueED->SetDropEnable(true);
372 break;
374 case SwFieldTypesEnum::Get:
376 if (!IsFieldEdit())
378 m_xNameED->set_text(OUString());
379 m_xValueED->set_text(OUString());
382 if (nSelPos != -1)
384 OUString sName(m_xSelectionLB->get_selected_text());
385 if (!IsFieldEdit())
386 m_xNameED->set_text(sName);
388 // is there a corresponding SetField
389 SwWrtShell *pSh = GetWrtShell();
390 if(!pSh)
391 pSh = ::GetActiveWrtShell();
392 if(pSh)
394 SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
395 pSh->GetFieldType(SwFieldIds::SetExp, sName));
397 if(pSetTyp)
399 if (pSetTyp->GetType() & nsSwGetSetExpType::GSE_STRING) // textual?
400 bFormat = true;
401 else // numeric
402 bNumFormat = true;
406 else
407 bFormat = false;
409 EnableInsert(bFormat || bNumFormat);
411 break;
413 case SwFieldTypesEnum::Input:
414 m_xValueFT->set_label(SwResId(STR_PROMPT));
416 if (nSelPos != -1)
418 bValue = bNumFormat = true;
420 OUString sName = m_xSelectionLB->get_selected_text();
421 m_xNameED->set_text( sName );
423 // User- or SetField ?
424 if (!GetFieldMgr().GetFieldType(SwFieldIds::User, sName)) // SetExp
426 // is there a corresponding SetField
427 SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
428 GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName));
430 if(pSetTyp)
432 if (pSetTyp->GetType() == nsSwGetSetExpType::GSE_STRING) // textual?
434 m_xNumFormatLB->clear();
435 m_xNumFormatLB->append(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND), SwResId(FMT_USERVAR_TEXT));
436 m_xNumFormatLB->select(0);
439 if (GetCurField() && IsFieldEdit() && (!pBox || m_bInit) )
440 m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetPromptText());
442 else // USERFLD
443 bFormat = bNumFormat = false;
445 break;
447 case SwFieldTypesEnum::DDE:
448 m_xValueFT->set_label(SwResId(STR_DDE_CMD));
450 if (IsFieldEdit() || pBox) // only when interacting via mouse
452 if (nSelPos != -1)
454 SwDDEFieldType* pType =
455 static_cast<SwDDEFieldType*>( GetFieldMgr().GetFieldType(SwFieldIds::Dde, nSelData) );
457 if(pType)
459 m_xNameED->set_text(pType->GetName());
461 //JP 28.08.95: DDE-Topics/-Items can have blanks in their names!
462 // That's not considered here yet
463 OUString sCmd( pType->GetCmd() );
464 sal_Int32 nTmpPos = 0;
465 sCmd = sCmd.replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &nTmpPos );
466 sCmd = sCmd.replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &nTmpPos );
468 m_xValueED->set_text( sCmd );
469 m_xFormatLB->select(static_cast<int>(pType->GetType()));
473 bName = bValue = true;
474 break;
476 case SwFieldTypesEnum::Sequence:
478 bName = bValue = bShowChapterFrame = true;
480 SwFieldType* pFieldTyp;
481 if( GetCurField() && IsFieldEdit() )
482 pFieldTyp = GetCurField()->GetTyp();
483 else
485 OUString sFieldTypeName(m_xSelectionLB->get_text(nSelPos));
486 if( !sFieldTypeName.isEmpty() )
487 pFieldTyp = GetFieldMgr().GetFieldType( SwFieldIds::SetExp,
488 sFieldTypeName );
489 else
490 pFieldTyp = nullptr;
493 if( GetCurField() && IsFieldEdit() )
494 m_xValueED->set_text( static_cast<SwSetExpField*>(GetCurField())->
495 GetFormula() );
497 if( IsFieldEdit() || pBox ) // only when interacting via mouse
498 m_xNameED->set_text( m_xSelectionLB->get_selected_text() );
500 if( pFieldTyp )
502 sal_uInt8 nLevel = static_cast<SwSetExpFieldType*>(pFieldTyp)->GetOutlineLvl();
503 if( 0x7f == nLevel )
504 m_xChapterLevelLB->set_active(0);
505 else
506 m_xChapterLevelLB->set_active(nLevel + 1);
507 OUString sDelim = static_cast<SwSetExpFieldType*>(pFieldTyp)->GetDelimiter();
508 m_xSeparatorED->set_text( sDelim );
509 ChapterHdl(*m_xChapterLevelLB);
512 break;
514 case SwFieldTypesEnum::SetRefPage:
516 bValue = false;
517 m_xValueFT->set_label( SwResId( STR_OFFSET ));
519 if (IsFieldEdit() || pBox) // only when interacting via mouse
520 m_xNameED->set_text(OUString());
522 if (nSelData != 0 && nSelData != SIZE_MAX)
524 bValue = true; // SubType OFF - knows no Offset
525 if (GetCurField() && IsFieldEdit())
526 m_xValueED->set_text(OUString::number(static_cast<SwRefPageSetField*>(GetCurField())->GetOffset()));
529 break;
531 case SwFieldTypesEnum::GetRefPage:
532 m_xNameED->set_text(OUString());
533 m_xValueED->set_text(OUString());
534 break;
536 default: break;
539 m_xNumFormatLB->set_visible(bNumFormat);
540 m_xFormatLB->set_visible(!bNumFormat);
542 if (IsFieldEdit())
543 bName = false;
545 m_xFormat->set_sensitive(bFormat || bNumFormat);
546 m_xNameFT->set_sensitive(bName);
547 m_xNameED->set_sensitive(bName);
548 m_xValueFT->set_sensitive(bValue);
549 m_xValueED->set_sensitive(bValue);
551 m_xInvisibleCB->set_visible(!bShowChapterFrame);
552 m_xChapterFrame->set_visible(bShowChapterFrame);
553 m_xInvisibleCB->set_sensitive(bInvisible);
555 ModifyHdl(*m_xNameED); // apply/insert/delete status update
558 IMPL_LINK(SwFieldVarPage, SubTypeInsertHdl, weld::TreeView&, rBox, bool)
560 if (!m_bInit)
562 SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
563 if (nTypeId == SwFieldTypesEnum::Formel)
565 auto nSelPos = m_xSelectionLB->get_selected_index();
566 if (nSelPos != -1)
568 m_xValueED->replace_selection(m_xSelectionLB->get_text(nSelPos));
569 ModifyHdl(*m_xNameED);
570 return true;
574 TreeViewInsertHdl(rBox);
575 return true;
578 // renew types in SelectionBox
579 void SwFieldVarPage::UpdateSubType()
581 SetSelectionSel(m_xSelectionLB->get_selected_index());
583 OUString sOldSel;
584 if (GetSelectionSel() != -1)
585 sOldSel = m_xSelectionLB->get_text(GetSelectionSel());
587 // fill Selection-Listbox
588 m_xSelectionLB->freeze();
589 m_xSelectionLB->clear();
591 const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
592 std::vector<OUString> aList;
593 GetFieldMgr().GetSubTypes(nTypeId, aList);
594 const size_t nCount = aList.size();
595 for (size_t i = 0; i < nCount; ++i)
597 if (nTypeId != SwFieldTypesEnum::Input || i)
599 if (!IsFieldEdit())
601 m_xSelectionLB->append(OUString::number(i), aList[i]);
603 else
605 bool bInsert = false;
607 switch (nTypeId)
609 case SwFieldTypesEnum::Input:
610 if (GetCurField() && aList[i] == GetCurField()->GetPar1())
611 bInsert = true;
612 break;
614 case SwFieldTypesEnum::Formel:
615 bInsert = true;
616 break;
618 case SwFieldTypesEnum::Get:
619 if (GetCurField() && aList[i] == static_cast<const SwFormulaField*>(GetCurField())->GetFormula())
620 bInsert = true;
621 break;
623 case SwFieldTypesEnum::Set:
624 case SwFieldTypesEnum::User:
625 if (GetCurField() && aList[i] == GetCurField()->GetTyp()->GetName())
627 bInsert = true;
628 if (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE)
629 m_xInvisibleCB->set_active(true);
631 break;
633 case SwFieldTypesEnum::SetRefPage:
635 if (GetCurField() != nullptr
636 && ((static_cast<SwRefPageSetField*>(GetCurField())->IsOn()
637 && i) || (!static_cast<SwRefPageSetField*>(GetCurField())
638 ->IsOn() && !i)))
640 sOldSel = aList[i];
643 // allow all entries for selection:
644 m_xSelectionLB->append(OUString::number(i), aList[i]);
645 break;
647 default:
648 if (GetCurField() && aList[i] == GetCurField()->GetPar1())
649 bInsert = true;
650 break;
653 if (bInsert)
655 m_xSelectionLB->append(OUString::number(i), aList[i]);
656 if (nTypeId != SwFieldTypesEnum::Formel)
657 break;
663 m_xSelectionLB->thaw();
665 const bool bEnable = m_xSelectionLB->n_children() != 0;
666 weld::TreeView* pLB = nullptr;
668 if (bEnable)
670 int nIndex = m_xSelectionLB->find_text(sOldSel);
671 if (nIndex != -1)
672 m_xSelectionLB->select(nIndex);
673 else
675 m_xSelectionLB->select(0);
676 pLB = m_xSelectionLB.get(); // newly initialise all controls
680 m_xSelection->set_sensitive(bEnable);
682 SubTypeHdl(pLB);
685 void SwFieldVarPage::FillFormatLB(SwFieldTypesEnum nTypeId)
687 OUString sOldSel;
688 const sal_Int32 nFormatSel = m_xFormatLB->get_selected_index();
689 if (nFormatSel != -1)
690 sOldSel = m_xFormatLB->get_text(nFormatSel);
692 weld::TreeView& rWidget = dynamic_cast<weld::TreeView&>(m_xNumFormatLB->get_widget());
694 OUString sOldNumSel;
695 sal_uInt32 nOldNumFormat = 0;
696 sal_Int32 nNumFormatSel = rWidget.get_selected_index();
697 if (nNumFormatSel != -1)
699 sOldNumSel = rWidget.get_text(nNumFormatSel);
700 nOldNumFormat = m_xNumFormatLB->GetFormat();
703 // fill Format-Listbox
704 m_xFormatLB->freeze();
705 m_xFormatLB->clear();
706 m_xNumFormatLB->clear(); // flags list as dirty and needing refilling with stock entries
707 bool bSpecialFormat = false;
709 if( SwFieldTypesEnum::GetRefPage != nTypeId )
711 if (GetCurField() != nullptr && IsFieldEdit())
713 bSpecialFormat = GetCurField()->GetFormat() == NUMBERFORMAT_ENTRY_NOT_FOUND;
715 if (!bSpecialFormat)
717 m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
718 sOldNumSel.clear();
720 else if (nTypeId == SwFieldTypesEnum::Get || nTypeId == SwFieldTypesEnum::Formel)
722 m_xNumFormatLB->SetFormatType(SvNumFormatType::NUMBER);
725 else
727 if (nOldNumFormat && nOldNumFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
728 m_xNumFormatLB->SetDefFormat(nOldNumFormat);
729 else
730 m_xNumFormatLB->SetFormatType(SvNumFormatType::NUMBER);
734 switch (nTypeId)
736 case SwFieldTypesEnum::User:
738 if (!IsFieldEdit() || bSpecialFormat)
740 OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
741 int nOldIndex = rWidget.get_selected_index();
742 rWidget.insert(0, SwResId(FMT_MARK_TEXT), &sId, nullptr, nullptr);
743 rWidget.insert(1, SwResId(FMT_USERVAR_CMD), &sId, nullptr, nullptr);
744 if (nOldIndex != -1)
745 rWidget.select(nOldIndex + 2);
748 break;
750 case SwFieldTypesEnum::Set:
752 if (!IsFieldEdit() || bSpecialFormat)
754 OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
755 int nOldIndex = rWidget.get_selected_index();
756 rWidget.insert(0, SwResId(FMT_SETVAR_TEXT), &sId, nullptr, nullptr);
757 if (nOldIndex != -1)
758 rWidget.select(nOldIndex + 1);
761 break;
763 case SwFieldTypesEnum::Formel:
765 OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
766 int nOldIndex = rWidget.get_selected_index();
767 rWidget.insert(0, SwResId(FMT_GETVAR_NAME), &sId, nullptr, nullptr);
768 if (nOldIndex != -1)
769 rWidget.select(nOldIndex + 1);
771 break;
773 case SwFieldTypesEnum::Get:
775 OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
776 int nOldIndex = rWidget.get_selected_index();
777 rWidget.insert(0, SwResId(FMT_GETVAR_NAME), &sId, nullptr, nullptr);
778 if (nOldIndex != -1)
779 rWidget.select(nOldIndex + 1);
781 break;
783 default: break;
786 if (IsFieldEdit() && bSpecialFormat)
788 if (nTypeId == SwFieldTypesEnum::User && (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_CMD))
789 rWidget.select(1);
790 else
791 rWidget.select(0);
793 else
795 if (!nOldNumFormat && (nNumFormatSel = rWidget.find_text(sOldNumSel)) != -1)
796 rWidget.select(nNumFormatSel);
797 else if (nOldNumFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
798 rWidget.select_text(sOldSel);
801 const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
803 OUString sSelectId;
805 for (sal_uInt16 i = 0; i < nSize; i++)
807 const sal_uInt16 nFieldId = GetFieldMgr().GetFormatId( nTypeId, i );
808 OUString sId(OUString::number(nFieldId));
809 m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
810 if (IsFieldEdit() && GetCurField() && nFieldId == GetCurField()->GetFormat())
811 sSelectId = sId;
814 m_xFormatLB->thaw();
815 if (!sSelectId.isEmpty())
816 m_xFormatLB->select_id(sSelectId);
818 if (nSize && (!IsFieldEdit() || m_xFormatLB->get_selected_index() == -1))
820 int nIndex = m_xFormatLB->find_text(sOldSel);
821 if (nIndex == -1)
822 nIndex = m_xFormatLB->find_text(SwResId(FMT_NUM_PAGEDESC));
823 if (nIndex == -1)
824 nIndex = m_xFormatLB->find_text(SwResId(FMT_NUM_ARABIC));
825 if (nIndex == -1)
826 nIndex = 0;
827 m_xFormatLB->select(nIndex);
831 // Modify
832 IMPL_LINK_NOARG(SwFieldVarPage, ModifyHdl, weld::Entry&, void)
834 OUString sValue(m_xValueED->get_text());
835 bool bHasValue = !sValue.isEmpty();
836 const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
837 bool bInsert = false, bApply = false, bDelete = false;
839 OUString sName( m_xNameED->get_text() );
840 sal_Int32 nLen = sName.getLength();
842 switch( nTypeId )
844 case SwFieldTypesEnum::DDE:
845 case SwFieldTypesEnum::User:
846 case SwFieldTypesEnum::Set:
847 case SwFieldTypesEnum::Sequence:
848 SwCalc::IsValidVarName( sName, &sName );
849 if ( sName.getLength() != nLen )
851 nLen = sName.getLength();
852 int nStartPos, nEndPos;
853 m_xNameED->get_selection_bounds(nStartPos, nEndPos);
854 m_xNameED->set_text( sName );
855 m_xNameED->select_region(nStartPos, nEndPos); // restore Cursorpos
857 break;
858 default: break;
861 // check buttons
862 switch (nTypeId)
864 case SwFieldTypesEnum::DDE:
865 if( nLen )
867 // is there already a corresponding type
868 bInsert = bApply = true;
870 SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::Dde, sName);
872 SwWrtShell *pSh = GetWrtShell();
873 if(!pSh)
874 pSh = ::GetActiveWrtShell();
875 if(pSh && pType)
876 bDelete = !pSh->IsUsed( *pType );
878 break;
880 case SwFieldTypesEnum::User:
881 if( nLen )
883 // is there already a corresponding type
884 SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::User, sName);
886 SwWrtShell *pSh = GetWrtShell();
887 if(!pSh)
888 pSh = ::GetActiveWrtShell();
889 if(pSh && pType)
890 bDelete = !pSh->IsUsed( *pType );
892 pType = GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName);
893 if (!pType) // no name conflict with variables
895 // user fields can also be inserted without content!
896 // Bug #56845
897 bInsert = bApply = true;
900 break;
902 default:
903 bInsert = true;
905 if (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Sequence)
907 SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(
908 GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName));
910 if (pFieldType)
913 SwWrtShell *pSh = GetWrtShell();
914 if(!pSh)
915 pSh = ::GetActiveWrtShell();
916 if(pSh)
918 const SwFieldTypes* p = pSh->GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
919 sal_uInt16 i;
921 for (i = 0; i < INIT_FLDTYPES; i++)
923 SwFieldType* pType = (*p)[ i ].get();
924 if (pType == pFieldType)
925 break;
928 if (i >= INIT_FLDTYPES && !pSh->IsUsed(*pFieldType))
929 bDelete = true;
931 if (nTypeId == SwFieldTypesEnum::Sequence && !(pFieldType->GetType() & nsSwGetSetExpType::GSE_SEQ))
932 bInsert = false;
934 if (nTypeId == SwFieldTypesEnum::Set && (pFieldType->GetType() & nsSwGetSetExpType::GSE_SEQ))
935 bInsert = false;
938 if (GetFieldMgr().GetFieldType(SwFieldIds::User, sName))
939 bInsert = false;
942 if (!nLen && (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Input ||
943 (!IsFieldEdit() && nTypeId == SwFieldTypesEnum::Get ) ) )
944 bInsert = false;
946 if( (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Formel) &&
947 !bHasValue )
948 bInsert = false;
949 break;
952 m_xNewPB->set_sensitive(bApply);
953 m_xDelPB->set_sensitive(bDelete);
954 EnableInsert(bInsert);
957 IMPL_LINK(SwFieldVarPage, TBClickHdl, weld::Button&, rBox, void)
959 const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
961 if (&rBox == m_xDelPB.get())
963 if( nTypeId == SwFieldTypesEnum::User )
964 GetFieldMgr().RemoveFieldType(SwFieldIds::User, m_xSelectionLB->get_selected_text());
965 else
967 SwFieldIds nWhich;
969 switch(nTypeId)
971 case SwFieldTypesEnum::Set:
972 case SwFieldTypesEnum::Sequence:
973 nWhich = SwFieldIds::SetExp;
974 break;
975 default:
976 nWhich = SwFieldIds::Dde;
977 break;
980 GetFieldMgr().RemoveFieldType(nWhich, m_xSelectionLB->get_selected_text());
983 UpdateSubType();
984 SwWrtShell *pSh = GetWrtShell();
985 if(!pSh)
986 pSh = ::GetActiveWrtShell();
987 if(pSh)
989 pSh->SetModified();
992 else if (&rBox == m_xNewPB.get())
994 OUString sName(m_xNameED->get_text()), sValue(m_xValueED->get_text());
995 SwFieldType* pType = nullptr;
996 SwFieldIds nId = SwFieldIds::Database;
997 sal_Int32 nNumFormatPos = m_xNumFormatLB->get_selected_index();
999 switch (nTypeId)
1001 case SwFieldTypesEnum::User: nId = SwFieldIds::User; break;
1002 case SwFieldTypesEnum::DDE: nId = SwFieldIds::Dde; break;
1003 case SwFieldTypesEnum::Set: nId = SwFieldIds::SetExp;break;
1004 default: break;
1006 pType = GetFieldMgr().GetFieldType(nId, sName);
1008 int nFormat = m_xFormatLB->get_selected_index();
1009 if (nFormat != -1)
1010 nFormat = m_xFormatLB->get_id(nFormat).toUInt32();
1012 if (pType) // change
1014 SwWrtShell *pSh = GetWrtShell();
1015 if(!pSh)
1016 pSh = ::GetActiveWrtShell();
1017 if(pSh)
1019 pSh->StartAllAction();
1021 if (nTypeId == SwFieldTypesEnum::User)
1023 if (nNumFormatPos != -1)
1025 // The first listbox entry is Text and second is
1026 // Formula and both are SAL_MAX_UINT32 :-/ but only if
1027 // not another yet unlisted of Additional Formats was
1028 // selected that may claim the top position :-/
1029 bool bText = false;
1030 sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
1031 if (nNumberFormat && nNumberFormat != SAL_MAX_UINT32)
1032 { // Switch language to office-language because calculator expects
1033 // String in office format and it should be fed into dialog like
1034 // that
1035 nNumberFormat = SwValueField::GetSystemFormat(pSh->GetNumberFormatter(), nNumberFormat);
1037 static_cast<SwUserFieldType*>(pType)->SetContent(m_xValueED->get_text(), nNumberFormat);
1038 static_cast<SwUserFieldType*>(pType)->SetType(
1039 bText ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR );
1042 else
1044 if (nFormat != -1)
1046 // DDE-Topics/-Items can have blanks in their names!
1047 // That's not being considered here yet.
1048 sal_Int32 nTmpPos = 0;
1049 sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
1050 sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
1051 static_cast<SwDDEFieldType*>(pType)->SetCmd(sValue);
1052 static_cast<SwDDEFieldType*>(pType)->SetType(static_cast<SfxLinkUpdateMode>(nFormat));
1055 pType->UpdateFields();
1057 pSh->EndAllAction();
1060 else // new
1062 if(nTypeId == SwFieldTypesEnum::User)
1064 SwWrtShell *pSh = GetWrtShell();
1065 if(!pSh)
1066 pSh = ::GetActiveWrtShell();
1067 if(pSh)
1069 SwUserFieldType aType( pSh->GetDoc(), sName );
1071 if (nNumFormatPos != -1)
1073 // The first listbox entry is Text and second is
1074 // Formula and both are SAL_MAX_UINT32 :-/ but only if
1075 // not another yet unlisted of Additional Formats was
1076 // selected that may claim the top position :-/
1077 bool bText = false;
1078 sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
1079 aType.SetType(bText ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR);
1080 aType.SetContent( sValue, nNumberFormat );
1081 m_xSelectionLB->append_text(sName);
1082 m_xSelectionLB->select_text(sName);
1083 GetFieldMgr().InsertFieldType( aType ); // Userfld new
1087 else
1089 if (nFormat != -1)
1091 // DDE-Topics/-Items can have blanks in their names!
1092 // That's not being considered here yet.
1093 sal_Int32 nTmpPos = 0;
1094 sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
1095 sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
1097 SwDDEFieldType aType(sName, sValue, static_cast<SfxLinkUpdateMode>(nFormat));
1098 m_xSelectionLB->append_text(sName);
1099 m_xSelectionLB->select_text(sName);
1100 GetFieldMgr().InsertFieldType(aType); // DDE-Field new
1104 if (IsFieldEdit())
1105 GetFieldMgr().GetCurField(); // update FieldManager
1107 UpdateSubType();
1111 IMPL_LINK_NOARG(SwFieldVarPage, ChapterHdl, weld::ComboBox&, void)
1113 bool bEnable = m_xChapterLevelLB->get_active() != 0;
1115 m_xSeparatorED->set_sensitive(bEnable);
1116 m_xSeparatorFT->set_sensitive(bEnable);
1117 SeparatorHdl(*m_xSeparatorED);
1120 IMPL_LINK_NOARG(SwFieldVarPage, SeparatorHdl, weld::Entry&, void)
1122 bool bEnable = !m_xSeparatorED->get_text().isEmpty() ||
1123 m_xChapterLevelLB->get_active() == 0;
1124 EnableInsert(bEnable);
1127 bool SwFieldVarPage::FillItemSet(SfxItemSet* )
1129 const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
1131 OUString aVal(m_xValueED->get_text());
1132 OUString aName(m_xNameED->get_text());
1134 const sal_Int32 nSubPos = m_xSelectionLB->get_selected_index();
1135 sal_uInt16 nSubType = (nSubPos == -1) ? 0 : m_xSelectionLB->get_id(nSubPos).toUInt32();
1137 sal_uInt32 nFormat;
1139 if (!m_xNumFormatLB->get_visible())
1141 sal_Int32 nFormatPos = m_xFormatLB->get_selected_index();
1143 if(nFormatPos == -1)
1144 nFormat = 0;
1145 else
1146 nFormat = m_xFormatLB->get_id(nFormatPos).toUInt32();
1148 else
1150 nFormat = m_xNumFormatLB->GetFormat();
1152 if (nFormat && nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND && m_xNumFormatLB->IsAutomaticLanguage())
1154 // Switch language to office language because calculator expects
1155 // String in office format and it should be fed into the dialog
1156 // like that
1157 SwWrtShell *pSh = GetWrtShell();
1158 if(!pSh)
1159 pSh = ::GetActiveWrtShell();
1160 if(pSh)
1162 nFormat = SwValueField::GetSystemFormat(pSh->GetNumberFormatter(), nFormat);
1166 sal_Unicode cSeparator = ' ';
1167 switch (nTypeId)
1169 case SwFieldTypesEnum::User:
1171 nSubType = (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR;
1173 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND && m_xNumFormatLB->get_selected_text() == SwResId(FMT_USERVAR_CMD))
1174 nSubType |= nsSwExtendedSubType::SUB_CMD;
1176 if (m_xInvisibleCB->get_active())
1177 nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
1178 break;
1180 case SwFieldTypesEnum::Formel:
1182 nSubType = nsSwGetSetExpType::GSE_FORMULA;
1183 if (m_xNumFormatLB->get_visible() && nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
1184 nSubType |= nsSwExtendedSubType::SUB_CMD;
1185 break;
1187 case SwFieldTypesEnum::Get:
1189 nSubType &= 0xff00;
1190 if (m_xNumFormatLB->get_visible() && nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
1191 nSubType |= nsSwExtendedSubType::SUB_CMD;
1192 break;
1194 case SwFieldTypesEnum::Input:
1196 SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::User, aName);
1197 nSubType = static_cast< sal_uInt16 >((nSubType & 0xff00) | (pType ? INP_USR : INP_VAR));
1198 break;
1201 case SwFieldTypesEnum::Set:
1203 if (IsFieldDlgHtmlMode())
1205 nSubType = 0x0100;
1206 nSubType = (nSubType & 0xff00) | nsSwGetSetExpType::GSE_STRING;
1208 else
1209 nSubType = (nSubType & 0xff00) | ((nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR);
1211 if (m_xInvisibleCB->get_active())
1212 nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
1213 break;
1215 case SwFieldTypesEnum::Sequence:
1217 nSubType = static_cast< sal_uInt16 >(m_xChapterLevelLB->get_active());
1218 if (nSubType == 0)
1219 nSubType = 0x7f;
1220 else
1222 nSubType--;
1223 OUString sSeparator(m_xSeparatorED->get_text()[0]);
1224 cSeparator = !sSeparator.isEmpty() ? sSeparator[0] : ' ';
1226 break;
1228 case SwFieldTypesEnum::GetRefPage:
1229 if( SVX_NUM_CHAR_SPECIAL == nFormat )
1230 aVal = m_xValueED->get_text();
1231 break;
1232 default: break;
1235 if (!IsFieldEdit() ||
1236 m_xNameED->get_value_changed_from_saved() ||
1237 m_xValueED->get_value_changed_from_saved() ||
1238 m_xSelectionLB->get_value_changed_from_saved() ||
1239 m_xFormatLB->get_value_changed_from_saved() ||
1240 m_nOldFormat != m_xNumFormatLB->GetFormat() ||
1241 m_xInvisibleCB->get_state_changed_from_saved() ||
1242 m_xChapterLevelLB->get_value_changed_from_saved() ||
1243 m_xSeparatorED->get_value_changed_from_saved())
1245 InsertField( nTypeId, nSubType, aName, aVal, nFormat,
1246 cSeparator, m_xNumFormatLB->IsAutomaticLanguage() );
1249 UpdateSubType();
1251 return false;
1254 std::unique_ptr<SfxTabPage> SwFieldVarPage::Create( weld::Container* pPage, weld::DialogController* pController,
1255 const SfxItemSet *const pAttrSet)
1257 return std::make_unique<SwFieldVarPage>( pPage, pController, pAttrSet );
1260 sal_uInt16 SwFieldVarPage::GetGroup()
1262 return GRP_VAR;
1265 void SwFieldVarPage::FillUserData()
1267 OUString sData = USER_DATA_VERSION ";";
1268 sal_Int32 nTypeSel = m_xTypeLB->get_selected_index();
1269 if( -1 == nTypeSel )
1270 nTypeSel = USHRT_MAX;
1271 else
1272 nTypeSel = m_xTypeLB->get_id(nTypeSel).toUInt32();
1273 sData += OUString::number( nTypeSel );
1274 SetUserData(sData);
1277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */