ITEM: Refactor ItemType
[LibreOffice.git] / sw / source / ui / config / optcomp.cxx
blob30d698bf6ed61428902d6d49d988c7a39a206a5e
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 <optcomp.hxx>
22 #include <cmdid.h>
23 #include <docsh.hxx>
24 #include <strings.hrc>
25 #include <uiitems.hxx>
26 #include <view.hxx>
27 #include <wrtsh.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/weld.hxx>
31 #include <sfx2/docfilt.hxx>
32 #include <sfx2/fcontnr.hxx>
33 #include <IDocumentSettingAccess.hxx>
34 #include <vector>
35 #include <svtools/restartdialog.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <officecfg/Office/Compatibility.hxx>
38 #include <osl/diagnose.h>
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::document;
43 namespace
45 // Option ID, TranslateId
46 constexpr std::pair<OUString, TranslateId> options_list[]{
47 { u"AddSpacing"_ustr, STR_COMPAT_OPT_ADDSPACING },
48 { u"AddSpacingAtPages"_ustr, STR_COMPAT_OPT_ADDSPACINGATPAGES },
49 { u"UseOurTabStopFormat"_ustr, STR_COMPAT_OPT_USEOURTABSTOPFORMAT },
50 { u"NoExternalLeading"_ustr, STR_COMPAT_OPT_NOEXTERNALLEADING },
51 { u"UseLineSpacing"_ustr, STR_COMPAT_OPT_USELINESPACING },
52 { u"AddTableSpacing"_ustr, STR_COMPAT_OPT_ADDTABLESPACING },
53 { u"UseObjectPositioning"_ustr, STR_COMPAT_OPT_USEOBJECTPOSITIONING },
54 { u"UseOurTextWrapping"_ustr, STR_COMPAT_OPT_USEOURTEXTWRAPPING },
55 { u"ConsiderWrappingStyle"_ustr, STR_COMPAT_OPT_CONSIDERWRAPPINGSTYLE },
56 { u"ExpandWordSpace"_ustr, STR_COMPAT_OPT_EXPANDWORDSPACE },
57 { u"ProtectForm"_ustr, STR_COMPAT_OPT_PROTECTFORM },
58 { u"MsWordCompTrailingBlanks"_ustr, STR_COMPAT_OPT_MSWORDCOMPTRAILINGBLANKS },
59 { u"SubtractFlysAnchoredAtFlys"_ustr, STR_COMPAT_OPT_SUBTRACTFLYSANCHOREDATFLYS },
60 { u"EmptyDbFieldHidesPara"_ustr, STR_COMPAT_OPT_EMPTYDBFIELDHIDESPARA },
61 { u"UseVariableWidthNBSP"_ustr, STR_COMPAT_OPT_USEVARIABLEWIDTHNBSP },
62 { u"NoGapAfterNoteNumber"_ustr, STR_COMPAT_OPT_NOGAPAFTERNOTENUMBER },
63 { u"TabsRelativeToIndent"_ustr, STR_COMPAT_OPT_TABSRELATIVETOINDENT },
64 { u"TabOverMargin"_ustr, STR_COMPAT_OPT_TABOVERMARGIN },
65 { u"DoNotMirrorRtlDrawObjs"_ustr, STR_COMPAT_OPT_DO_NOT_MIRROR_RTL_DRAW_OBJS },
66 { u"ContinuousEndnotes"_ustr, STR_COMPAT_OPT_CONTINUOUS_ENDNOTES },
67 { u"MsWordCompGridMetrics"_ustr, STR_COMPAT_OPT_MSWORDCOMPGRIDMETRICS },
68 { u"IgnoreTabsAndBlanksForLineCalculation"_ustr, STR_COMPAT_OPT_IGNORETABSANDBLANKSFORLINECALCULATION },
71 // DocumentSettingId, negate?
72 std::pair<DocumentSettingId, bool> DocumentSettingForOption(const OUString& option)
74 static const std::map<OUString, std::pair<DocumentSettingId, bool>> map{
75 { u"AddSpacing"_ustr, { DocumentSettingId::PARA_SPACE_MAX, false } },
76 { u"AddSpacingAtPages"_ustr, { DocumentSettingId::PARA_SPACE_MAX_AT_PAGES, false } },
77 { u"UseOurTabStopFormat"_ustr, { DocumentSettingId::TAB_COMPAT, true } },
78 { u"NoExternalLeading"_ustr, { DocumentSettingId::ADD_EXT_LEADING, true } },
79 { u"UseLineSpacing"_ustr, { DocumentSettingId::OLD_LINE_SPACING, false } },
80 { u"AddTableSpacing"_ustr, { DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS, false } },
81 { u"UseObjectPositioning"_ustr, { DocumentSettingId::USE_FORMER_OBJECT_POS, false } },
82 { u"UseOurTextWrapping"_ustr, { DocumentSettingId::USE_FORMER_TEXT_WRAPPING, false } },
83 { u"ConsiderWrappingStyle"_ustr, { DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION, false } },
84 { u"ExpandWordSpace"_ustr, { DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, true } },
85 { u"ProtectForm"_ustr, { DocumentSettingId::PROTECT_FORM, false } },
86 { u"MsWordCompTrailingBlanks"_ustr, { DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, false } },
87 { u"SubtractFlysAnchoredAtFlys"_ustr, { DocumentSettingId::SUBTRACT_FLYS, false } },
88 { u"EmptyDbFieldHidesPara"_ustr, { DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA, false } },
89 { u"UseVariableWidthNBSP"_ustr, { DocumentSettingId::USE_VARIABLE_WIDTH_NBSP, false } },
90 { u"NoGapAfterNoteNumber"_ustr, { DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER, false } },
91 { u"TabsRelativeToIndent"_ustr, { DocumentSettingId::TABS_RELATIVE_TO_INDENT, false } },
92 { u"TabOverMargin"_ustr, { DocumentSettingId::TAB_OVER_MARGIN, false } },
93 { u"DoNotMirrorRtlDrawObjs"_ustr, { DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, false } },
94 { u"ContinuousEndnotes"_ustr, { DocumentSettingId::CONTINUOUS_ENDNOTES, false } },
95 // { u"AddTableLineSpacing"_ustr, { DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS, false } },
96 { u"MsWordCompGridMetrics"_ustr, { DocumentSettingId::MS_WORD_COMP_GRID_METRICS, false } },
97 { u"IgnoreTabsAndBlanksForLineCalculation"_ustr, { DocumentSettingId::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, false } },
99 return map.at(option);
103 SwCompatibilityOptPage::SwCompatibilityOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
104 : SfxTabPage(pPage, pController, u"modules/swriter/ui/optcompatpage.ui"_ustr, u"OptCompatPage"_ustr, &rSet)
105 , m_pWrtShell(nullptr)
106 , m_xMain(m_xBuilder->weld_frame(u"compatframe"_ustr))
107 , m_xOptionsLB(m_xBuilder->weld_tree_view(u"options"_ustr))
108 , m_xDefaultPB(m_xBuilder->weld_button(u"default"_ustr))
110 m_xOptionsLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
112 auto pos = m_xOptionsLB->make_iterator();
113 for (const auto& [compatId, translateId] : options_list)
115 m_xOptionsLB->append(pos.get());
116 m_xOptionsLB->set_id(*pos, compatId);
117 m_xOptionsLB->set_text(*pos, SwResId(translateId), 0);
120 InitControls( rSet );
122 // set handler
123 m_xDefaultPB->connect_clicked( LINK( this, SwCompatibilityOptPage, UseAsDefaultHdl ) );
126 SwCompatibilityOptPage::~SwCompatibilityOptPage()
130 void SwCompatibilityOptPage::InitControls( const SfxItemSet& rSet )
132 // init objectshell and detect document name
133 OUString sDocTitle;
134 SfxObjectShell* pObjShell = nullptr;
135 if ( const SwPtrItem* pItem = rSet.GetItemIfSet( FN_PARAM_WRTSHELL, false ) )
136 m_pWrtShell = static_cast<SwWrtShell*>(pItem->GetValue());
137 if ( m_pWrtShell )
139 pObjShell = m_pWrtShell->GetView().GetDocShell();
140 if ( pObjShell )
141 sDocTitle = pObjShell->GetTitle();
143 else
145 m_xMain->set_sensitive(false);
147 const OUString aText = m_xMain->get_label();
148 m_xMain->set_label(aText.replaceAll("%DOCNAME", sDocTitle));
151 IMPL_LINK_NOARG(SwCompatibilityOptPage, UseAsDefaultHdl, weld::Button&, void)
153 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), u"modules/swriter/ui/querydefaultcompatdialog.ui"_ustr));
154 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog(u"QueryDefaultCompatDialog"_ustr));
155 if (xQueryBox->run() != RET_YES)
156 return;
158 auto batch = comphelper::ConfigurationChanges::create();
159 SvtCompatibilityDefault defaultCompatOptions(batch);
161 const sal_Int32 nCount = m_xOptionsLB->n_children();
162 for ( sal_Int32 i = 0; i < nCount; ++i )
164 OUString option = m_xOptionsLB->get_id(i);
165 bool bChecked = m_xOptionsLB->get_toggle(i);
166 defaultCompatOptions.set(option, bChecked);
168 if (option == "AddTableSpacing")
170 bool const isLineSpacing = m_xOptionsLB->get_toggle(i) == TRISTATE_TRUE;
171 defaultCompatOptions.set(u"AddTableLineSpacing"_ustr, isLineSpacing);
173 else
175 assert(m_xOptionsLB->get_toggle(i) != TRISTATE_INDET);
179 batch->commit();
182 void SwCompatibilityOptPage::SetCurrentOptions()
184 bool hasReadOnly = false;
185 if (m_pWrtShell)
187 m_aSavedOptions.clear();
188 // get document options
189 const auto& rIDocumentSettingAccess = m_pWrtShell->getIDocumentSettingAccess();
190 auto batch = comphelper::ConfigurationChanges::create(); // needed to obtain RO status
191 const SvtCompatibilityDefault defaultCompatOptions(batch);
192 const sal_Int32 nCount = m_xOptionsLB->n_children();
193 for (sal_Int32 i = 0; i < nCount; ++i)
195 OUString option = m_xOptionsLB->get_id(i);
196 const bool bReadOnly = defaultCompatOptions.getPropertyReadOnly(option);
197 if (bReadOnly)
198 hasReadOnly = true;
199 const auto [docSettingId, shouldNegate] = DocumentSettingForOption(option);
200 bool bChecked = rIDocumentSettingAccess.get(docSettingId);
201 if (shouldNegate)
202 bChecked = !bChecked;
203 TriState value = bChecked ? TRISTATE_TRUE : TRISTATE_FALSE;
204 if (option == "AddTableSpacing")
205 { // hack: map 2 bools to 1 tristate
206 if (value == TRISTATE_TRUE)
208 if (!rIDocumentSettingAccess.get(
209 DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS))
210 value = TRISTATE_INDET; // 3 values possible here
213 m_xOptionsLB->set_toggle(i, value);
214 m_xOptionsLB->set_sensitive(i, !bReadOnly);
215 m_aSavedOptions[option] = value;
219 m_xDefaultPB->set_sensitive(!hasReadOnly);
222 std::unique_ptr<SfxTabPage> SwCompatibilityOptPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
224 return std::make_unique<SwCompatibilityOptPage>(pPage, pController, *rAttrSet);
227 OUString SwCompatibilityOptPage::GetAllStrings()
229 OUString sAllStrings;
231 if (const auto pString = m_xBuilder->weld_label(u"label11"_ustr))
232 sAllStrings += pString->get_label() + " ";
234 sAllStrings += m_xDefaultPB->get_label() + " ";
236 return sAllStrings.replaceAll("_", "");
239 bool SwCompatibilityOptPage::FillItemSet( SfxItemSet* )
241 bool bModified = false;
242 if ( m_pWrtShell )
244 const int nCount = m_xOptionsLB->n_children();
245 for (int i = 0; i < nCount; ++i)
247 OUString option = m_xOptionsLB->get_id(i);
248 TriState const current = m_xOptionsLB->get_toggle(i);
249 TriState saved = m_aSavedOptions[option];
250 if (current != saved)
252 bool const bChecked(current != TRISTATE_FALSE);
253 assert(current != TRISTATE_INDET); // can't *change* it to that
254 switch (DocumentSettingForOption(option).first)
256 case DocumentSettingId::PARA_SPACE_MAX:
257 m_pWrtShell->SetParaSpaceMax( bChecked );
258 break;
260 case DocumentSettingId::PARA_SPACE_MAX_AT_PAGES:
261 m_pWrtShell->SetParaSpaceMaxAtPages( bChecked );
262 break;
264 case DocumentSettingId::TAB_COMPAT:
265 m_pWrtShell->SetTabCompat( !bChecked );
266 break;
268 case DocumentSettingId::ADD_EXT_LEADING:
269 m_pWrtShell->SetAddExtLeading( !bChecked );
270 break;
272 case DocumentSettingId::OLD_LINE_SPACING:
273 m_pWrtShell->SetUseFormerLineSpacing( bChecked );
274 break;
276 case DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS:
277 m_pWrtShell->SetAddParaSpacingToTableCells( bChecked );
278 break;
280 case DocumentSettingId::USE_FORMER_OBJECT_POS:
281 m_pWrtShell->SetUseFormerObjectPositioning( bChecked );
282 break;
284 case DocumentSettingId::USE_FORMER_TEXT_WRAPPING:
285 m_pWrtShell->SetUseFormerTextWrapping( bChecked );
286 break;
288 case DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION:
289 m_pWrtShell->SetConsiderWrapOnObjPos( bChecked );
290 break;
292 case DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK:
293 m_pWrtShell->SetDoNotJustifyLinesWithManualBreak( !bChecked );
294 break;
296 case DocumentSettingId::PROTECT_FORM:
297 m_pWrtShell->SetProtectForm( bChecked );
298 break;
300 case DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS:
301 m_pWrtShell->SetMsWordCompTrailingBlanks( bChecked );
302 break;
304 case DocumentSettingId::SUBTRACT_FLYS:
305 m_pWrtShell->SetSubtractFlysAnchoredAtFlys(bChecked);
306 break;
308 case DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA:
309 m_pWrtShell->SetEmptyDbFieldHidesPara(bChecked);
310 break;
312 case DocumentSettingId::USE_VARIABLE_WIDTH_NBSP:
313 m_pWrtShell->GetDoc()->getIDocumentSettingAccess()
314 .set(DocumentSettingId::USE_VARIABLE_WIDTH_NBSP, bChecked);
315 break;
317 case DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER:
318 m_pWrtShell->SetNoGapAfterNoteNumber(bChecked);
319 break;
321 case DocumentSettingId::TABS_RELATIVE_TO_INDENT:
322 m_pWrtShell->SetTabsRelativeToIndent(bChecked);
323 break;
325 case DocumentSettingId::TAB_OVER_MARGIN:
326 m_pWrtShell->SetTabOverMargin(bChecked);
327 break;
329 case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS:
330 m_pWrtShell->SetDoNotMirrorRtlDrawObjs(bChecked);
331 break;
333 case DocumentSettingId::CONTINUOUS_ENDNOTES:
334 m_pWrtShell->SetContinuousEndnotes(bChecked);
335 break;
337 case DocumentSettingId::MS_WORD_COMP_GRID_METRICS:
338 m_pWrtShell->SetMsWordCompGridMetrics(bChecked);
339 break;
341 case DocumentSettingId::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION:
342 m_pWrtShell->SetIgnoreTabsAndBlanksForLineCalculation(bChecked);
343 break;
345 default:
346 break;
348 bModified = true;
353 return bModified;
356 void SwCompatibilityOptPage::Reset( const SfxItemSet* )
358 SetCurrentOptions();
361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */