android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / ui / config / optcomp.cxx
blob8d0c503630c569de9b58982f8eee9f213d24ba22
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 <uiitems.hxx>
25 #include <view.hxx>
26 #include <wrtsh.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/weld.hxx>
30 #include <sfx2/docfilt.hxx>
31 #include <sfx2/fcontnr.hxx>
32 #include <IDocumentSettingAccess.hxx>
33 #include <vector>
34 #include <svtools/restartdialog.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <officecfg/Office/Compatibility.hxx>
37 #include <osl/diagnose.h>
39 using namespace ::com::sun::star::beans;
40 using namespace ::com::sun::star::document;
41 using namespace ::com::sun::star::uno;
43 struct SwCompatibilityOptPage_Impl
45 std::vector< SvtCompatibilityEntry > m_aList;
48 SwCompatibilityOptPage::SwCompatibilityOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
49 : SfxTabPage(pPage, pController, "modules/swriter/ui/optcompatpage.ui", "OptCompatPage", &rSet)
50 , m_pWrtShell(nullptr)
51 , m_pImpl(new SwCompatibilityOptPage_Impl)
52 , m_nSavedOptions(0)
53 , m_bSavedMSFormsMenuOption(false)
54 , m_xMain(m_xBuilder->weld_frame("compatframe"))
55 , m_xGlobalOptionsFrame(m_xBuilder->weld_frame("globalcompatframe"))
56 , m_xFormattingLB(m_xBuilder->weld_combo_box("format"))
57 , m_xGlobalOptionsLB(m_xBuilder->weld_combo_box("globaloptions"))
58 , m_xOptionsLB(m_xBuilder->weld_tree_view("options"))
59 , m_xGlobalOptionsCLB(m_xBuilder->weld_tree_view("globaloptioncheckbox"))
60 , m_xDefaultPB(m_xBuilder->weld_button("default"))
62 m_xOptionsLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
63 m_xGlobalOptionsCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
65 int nPos = 0;
66 for (int i = static_cast<int>(SvtCompatibilityEntry::Index::Module) + 1;
67 i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID) - 1; // omit AddTableLineSpacing
68 ++i)
70 int nCoptIdx = i - 2; /* Do not consider "Name" & "Module" indexes */
72 const OUString sEntry = m_xFormattingLB->get_text(nCoptIdx);
73 m_xOptionsLB->append();
74 m_xOptionsLB->set_toggle(nPos, TRISTATE_FALSE);
75 m_xOptionsLB->set_text(nPos, sEntry, 0);
76 ++nPos;
79 m_sUserEntry = m_xFormattingLB->get_text(m_xFormattingLB->get_count() - 1);
81 m_xFormattingLB->clear();
83 // Set MSOCompatibleFormsMenu entry attributes
84 const bool bReadOnly = officecfg::Office::Compatibility::View::MSCompatibleFormsMenu::isReadOnly();
85 m_xGlobalOptionsCLB->set_sensitive(!bReadOnly);
87 m_xGlobalOptionsCLB->append();
88 const bool bChecked = officecfg::Office::Compatibility::View::MSCompatibleFormsMenu::get();
89 m_xGlobalOptionsCLB->set_toggle(0, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
90 m_xGlobalOptionsCLB->set_text(0, m_xGlobalOptionsLB->get_text(0), 0);
92 m_xGlobalOptionsLB->clear();
94 // tdf#125799, we let only the doc options grow/shrink but give this one more than its bare
95 // min request height because there's only one row in it and that looks somewhat abrupt
96 m_xGlobalOptionsCLB->set_size_request(-1, m_xGlobalOptionsCLB->get_preferred_size().Height() * 2);
98 InitControls( rSet );
100 // set handler
101 m_xFormattingLB->connect_changed( LINK( this, SwCompatibilityOptPage, SelectHdl ) );
102 m_xDefaultPB->connect_clicked( LINK( this, SwCompatibilityOptPage, UseAsDefaultHdl ) );
105 SwCompatibilityOptPage::~SwCompatibilityOptPage()
109 static sal_uInt32 convertBools2Ulong_Impl
111 bool _bAddSpacing,
112 bool _bAddSpacingAtPages,
113 bool _bUseOurTabStops,
114 bool _bNoExtLeading,
115 bool _bUseLineSpacing,
116 bool _bAddTableSpacing,
117 bool _bAddTableLineSpacing,
118 bool _bUseObjPos,
119 bool _bUseOurTextWrapping,
120 bool _bConsiderWrappingStyle,
121 bool _bExpandWordSpace,
122 bool _bProtectForm,
123 bool _bMsWordCompTrailingBlanks,
124 bool bSubtractFlysAnchoredAtFlys,
125 bool bEmptyDbFieldHidesPara
128 sal_uInt32 nRet = 0;
129 sal_uInt32 nSetBit = 1;
131 if ( _bAddSpacing )
132 nRet |= nSetBit;
133 nSetBit = nSetBit << 1;
134 if ( _bAddSpacingAtPages )
135 nRet |= nSetBit;
136 nSetBit = nSetBit << 1;
137 if ( _bUseOurTabStops )
138 nRet |= nSetBit;
139 nSetBit = nSetBit << 1;
140 if ( _bNoExtLeading )
141 nRet |= nSetBit;
142 nSetBit = nSetBit << 1;
143 if ( _bUseLineSpacing )
144 nRet |= nSetBit;
145 nSetBit = nSetBit << 1;
146 if ( _bAddTableSpacing )
147 nRet |= nSetBit;
148 nSetBit = nSetBit << 1;
149 if (_bAddTableLineSpacing)
150 nRet |= nSetBit;
151 nSetBit = nSetBit << 1;
152 if ( _bUseObjPos )
153 nRet |= nSetBit;
154 nSetBit = nSetBit << 1;
155 if ( _bUseOurTextWrapping )
156 nRet |= nSetBit;
157 nSetBit = nSetBit << 1;
158 if ( _bConsiderWrappingStyle )
159 nRet |= nSetBit;
160 nSetBit = nSetBit << 1;
161 if ( _bExpandWordSpace )
162 nRet |= nSetBit;
163 nSetBit = nSetBit << 1;
164 if ( _bProtectForm )
165 nRet |= nSetBit;
166 nSetBit = nSetBit << 1;
167 if ( _bMsWordCompTrailingBlanks )
168 nRet |= nSetBit;
169 nSetBit = nSetBit << 1;
170 if (bSubtractFlysAnchoredAtFlys)
171 nRet |= nSetBit;
172 nSetBit = nSetBit << 1;
173 if (bEmptyDbFieldHidesPara)
174 nRet |= nSetBit;
176 return nRet;
179 void SwCompatibilityOptPage::InitControls( const SfxItemSet& rSet )
181 // init objectshell and detect document name
182 OUString sDocTitle;
183 SfxObjectShell* pObjShell = nullptr;
184 if ( const SwPtrItem* pItem = rSet.GetItemIfSet( FN_PARAM_WRTSHELL, false ) )
185 m_pWrtShell = static_cast<SwWrtShell*>(pItem->GetValue());
186 if ( m_pWrtShell )
188 pObjShell = m_pWrtShell->GetView().GetDocShell();
189 if ( pObjShell )
190 sDocTitle = pObjShell->GetTitle();
192 else
194 m_xMain->set_sensitive(false);
195 m_xGlobalOptionsFrame->set_sensitive(false);
197 const OUString& rText = m_xMain->get_label();
198 m_xMain->set_label(rText.replaceAll("%DOCNAME", sDocTitle));
200 // loading file formats
201 const std::vector< SvtCompatibilityEntry > aList = m_aConfigItem.GetList();
203 for ( const SvtCompatibilityEntry& rEntry : aList )
205 const OUString sEntryName = rEntry.getValue<OUString>( SvtCompatibilityEntry::Index::Name );
206 const bool bIsUserEntry = ( sEntryName == SvtCompatibilityEntry::USER_ENTRY_NAME );
207 const bool bIsDefaultEntry = ( sEntryName == SvtCompatibilityEntry::DEFAULT_ENTRY_NAME );
209 m_pImpl->m_aList.push_back( rEntry );
211 if ( bIsDefaultEntry )
212 continue;
214 OUString sNewEntry;
215 if ( bIsUserEntry )
216 sNewEntry = m_sUserEntry;
218 else if ( pObjShell && !sEntryName.isEmpty() )
220 SfxFilterContainer* pFacCont = pObjShell->GetFactory().GetFilterContainer();
221 std::shared_ptr<const SfxFilter> pFilter = pFacCont->GetFilter4FilterName( sEntryName );
222 if ( pFilter )
223 sNewEntry = pFilter->GetUIName();
226 if ( sNewEntry.isEmpty() )
227 sNewEntry = sEntryName;
229 sal_uInt32 nOptions = convertBools2Ulong_Impl(
230 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddSpacing ),
231 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddSpacingAtPages ),
232 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseOurTabStops ),
233 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::NoExtLeading ),
234 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseLineSpacing ),
235 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddTableSpacing ),
236 rEntry.getValue<bool>(SvtCompatibilityEntry::Index::AddTableLineSpacing),
237 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseObjectPositioning ),
238 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseOurTextWrapping ),
239 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::ConsiderWrappingStyle ),
240 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::ExpandWordSpace ),
241 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::ProtectForm ),
242 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::MsWordTrailingBlanks ),
243 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys ),
244 rEntry.getValue<bool>( SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara ));
245 m_xFormattingLB->append(OUString::number(nOptions), sNewEntry);
249 IMPL_LINK_NOARG(SwCompatibilityOptPage, SelectHdl, weld::ComboBox&, void)
251 sal_uInt32 nOptions = m_xFormattingLB->get_active_id().toUInt32();
252 SetCurrentOptions(nOptions);
255 IMPL_LINK_NOARG(SwCompatibilityOptPage, UseAsDefaultHdl, weld::Button&, void)
257 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/querydefaultcompatdialog.ui"));
258 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("QueryDefaultCompatDialog"));
259 if (xQueryBox->run() != RET_YES)
260 return;
262 auto pItem = std::find_if(m_pImpl->m_aList.begin(), m_pImpl->m_aList.end(),
263 [](const SvtCompatibilityEntry& rItem)
265 const OUString sEntryName = rItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name );
266 const bool bIsDefaultEntry = ( sEntryName == SvtCompatibilityEntry::DEFAULT_ENTRY_NAME );
267 return bIsDefaultEntry;
269 if (pItem != m_pImpl->m_aList.end())
271 const sal_Int32 nCount = m_xOptionsLB->n_children();
272 for ( sal_Int32 i = 0; i < nCount; ++i )
274 bool bChecked = m_xOptionsLB->get_toggle(i);
276 int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
277 pItem->setValue<bool>( SvtCompatibilityEntry::Index(nCoptIdx), bChecked );
278 if (nCoptIdx == int(SvtCompatibilityEntry::Index::AddTableSpacing))
280 bool const isLineSpacing = m_xOptionsLB->get_toggle(i) == TRISTATE_TRUE;
281 pItem->setValue<bool>(SvtCompatibilityEntry::Index::AddTableLineSpacing, isLineSpacing);
283 else
285 assert(m_xOptionsLB->get_toggle(i) != TRISTATE_INDET);
290 WriteOptions();
293 void SwCompatibilityOptPage::SetCurrentOptions( sal_uInt32 nOptions )
295 const int nCount = m_xOptionsLB->n_children();
296 OSL_ENSURE( nCount <= 32, "SwCompatibilityOptPage::Reset(): entry overflow" );
297 for (int i = 0; i < nCount; ++i)
299 bool bChecked = ( ( nOptions & 0x00000001 ) == 0x00000001 );
300 TriState value = bChecked ? TRISTATE_TRUE : TRISTATE_FALSE;
301 if (i == int(SvtCompatibilityEntry::Index::AddTableSpacing) - 2)
302 { // hack: map 2 bools to 1 tristate
303 nOptions = nOptions >> 1;
304 if (value == TRISTATE_TRUE
305 && (nOptions & 0x00000001) != 0x00000001) // ADD_PARA_LINE_SPACING_TO_TABLE_CELLS
307 value = TRISTATE_INDET; // 3 values possible here
310 m_xOptionsLB->set_toggle(i, value);
311 nOptions = nOptions >> 1;
315 sal_uInt32 SwCompatibilityOptPage::GetDocumentOptions() const
317 sal_uInt32 nRet = 0;
318 if ( m_pWrtShell )
320 const IDocumentSettingAccess& rIDocumentSettingAccess = m_pWrtShell->getIDocumentSettingAccess();
321 nRet = convertBools2Ulong_Impl(
322 rIDocumentSettingAccess.get( DocumentSettingId::PARA_SPACE_MAX ),
323 rIDocumentSettingAccess.get( DocumentSettingId::PARA_SPACE_MAX_AT_PAGES ),
324 !rIDocumentSettingAccess.get( DocumentSettingId::TAB_COMPAT ),
325 !rIDocumentSettingAccess.get( DocumentSettingId::ADD_EXT_LEADING ),
326 rIDocumentSettingAccess.get( DocumentSettingId::OLD_LINE_SPACING ),
327 rIDocumentSettingAccess.get( DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS ),
328 rIDocumentSettingAccess.get( DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS ),
329 rIDocumentSettingAccess.get( DocumentSettingId::USE_FORMER_OBJECT_POS ),
330 rIDocumentSettingAccess.get( DocumentSettingId::USE_FORMER_TEXT_WRAPPING ),
331 rIDocumentSettingAccess.get( DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION ),
332 !rIDocumentSettingAccess.get( DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK ),
333 rIDocumentSettingAccess.get( DocumentSettingId::PROTECT_FORM ),
334 rIDocumentSettingAccess.get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ),
335 rIDocumentSettingAccess.get( DocumentSettingId::SUBTRACT_FLYS ),
336 rIDocumentSettingAccess.get( DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA ) );
338 return nRet;
341 void SwCompatibilityOptPage::WriteOptions()
343 m_aConfigItem.Clear();
344 for ( const auto& rItem : m_pImpl->m_aList )
345 m_aConfigItem.AppendItem(rItem);
348 std::unique_ptr<SfxTabPage> SwCompatibilityOptPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
350 return std::make_unique<SwCompatibilityOptPage>(pPage, pController, *rAttrSet);
353 bool SwCompatibilityOptPage::FillItemSet( SfxItemSet* )
355 bool bModified = false;
356 if ( m_pWrtShell )
358 sal_uInt32 nSavedOptions = m_nSavedOptions;
359 const int nCount = m_xOptionsLB->n_children();
360 OSL_ENSURE( nCount <= 32, "SwCompatibilityOptPage::Reset(): entry overflow" );
362 for (int i = 0; i < nCount; ++i)
364 TriState const current = m_xOptionsLB->get_toggle(i);
365 TriState saved = ((nSavedOptions & 0x00000001) == 0x00000001) ? TRISTATE_TRUE : TRISTATE_FALSE;
366 if (i == int(SvtCompatibilityEntry::Index::AddTableSpacing) - 2)
367 { // hack: map 2 bools to 1 tristate
368 nSavedOptions = nSavedOptions >> 1;
369 if (saved == TRISTATE_TRUE
370 && ((nSavedOptions & 0x00000001) != 0x00000001))
372 saved = TRISTATE_INDET;
375 if (current != saved)
377 bool const bChecked(current != TRISTATE_FALSE);
378 assert(current != TRISTATE_INDET); // can't *change* it to that
379 int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
380 switch ( SvtCompatibilityEntry::Index(nCoptIdx) )
382 case SvtCompatibilityEntry::Index::AddSpacing:
383 m_pWrtShell->SetParaSpaceMax( bChecked );
384 break;
386 case SvtCompatibilityEntry::Index::AddSpacingAtPages:
387 m_pWrtShell->SetParaSpaceMaxAtPages( bChecked );
388 break;
390 case SvtCompatibilityEntry::Index::UseOurTabStops:
391 m_pWrtShell->SetTabCompat( !bChecked );
392 break;
394 case SvtCompatibilityEntry::Index::NoExtLeading:
395 m_pWrtShell->SetAddExtLeading( !bChecked );
396 break;
398 case SvtCompatibilityEntry::Index::UseLineSpacing:
399 m_pWrtShell->SetUseFormerLineSpacing( bChecked );
400 break;
402 case SvtCompatibilityEntry::Index::AddTableSpacing:
403 m_pWrtShell->SetAddParaSpacingToTableCells( bChecked );
404 break;
406 case SvtCompatibilityEntry::Index::UseObjectPositioning:
407 m_pWrtShell->SetUseFormerObjectPositioning( bChecked );
408 break;
410 case SvtCompatibilityEntry::Index::UseOurTextWrapping:
411 m_pWrtShell->SetUseFormerTextWrapping( bChecked );
412 break;
414 case SvtCompatibilityEntry::Index::ConsiderWrappingStyle:
415 m_pWrtShell->SetConsiderWrapOnObjPos( bChecked );
416 break;
418 case SvtCompatibilityEntry::Index::ExpandWordSpace:
419 m_pWrtShell->SetDoNotJustifyLinesWithManualBreak( !bChecked );
420 break;
422 case SvtCompatibilityEntry::Index::ProtectForm:
423 m_pWrtShell->SetProtectForm( bChecked );
424 break;
426 case SvtCompatibilityEntry::Index::MsWordTrailingBlanks:
427 m_pWrtShell->SetMsWordCompTrailingBlanks( bChecked );
428 break;
430 case SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys:
431 m_pWrtShell->SetSubtractFlysAnchoredAtFlys(bChecked);
432 break;
434 case SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara:
435 m_pWrtShell->SetEmptyDbFieldHidesPara(bChecked);
436 break;
438 default:
439 break;
441 bModified = true;
444 nSavedOptions = nSavedOptions >> 1;
448 if ( bModified )
449 WriteOptions();
451 bool bNewMSFormsMenuOption = m_xGlobalOptionsCLB->get_toggle(0);
452 if (m_bSavedMSFormsMenuOption != bNewMSFormsMenuOption)
454 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
455 officecfg::Office::Compatibility::View::MSCompatibleFormsMenu::set(bNewMSFormsMenuOption, batch);
456 batch->commit();
458 m_bSavedMSFormsMenuOption = bNewMSFormsMenuOption;
459 bModified = true;
461 // Show a message about that the option needs a restart to be applied
463 SolarMutexGuard aGuard;
464 if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(),
465 GetFrameWeld(), svtools::RESTART_REASON_MSCOMPATIBLE_FORMS_MENU))
467 GetDialogController()->response(RET_OK);
472 return bModified;
475 void SwCompatibilityOptPage::Reset( const SfxItemSet* )
477 m_xOptionsLB->select(0);
479 sal_uInt32 nOptions = GetDocumentOptions();
480 SetCurrentOptions( nOptions );
481 m_nSavedOptions = nOptions;
483 m_bSavedMSFormsMenuOption = officecfg::Office::Compatibility::View::MSCompatibleFormsMenu::get();
484 m_xGlobalOptionsCLB->set_toggle(0, m_bSavedMSFormsMenuOption ? TRISTATE_TRUE : TRISTATE_FALSE);
487 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */