LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sfx2 / source / dialog / mgetempl.cxx
blobde570eb24228f6d0ab49400f85a831f72d1f698e
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 <comphelper/string.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/weld.hxx>
23 #include <svl/eitem.hxx>
24 #include <svl/intitem.hxx>
25 #include <svl/style.hxx>
26 #include <osl/diagnose.h>
28 #include <sfx2/styfitem.hxx>
29 #include <sfx2/styledlg.hxx>
30 #include <sfx2/tabdlg.hxx>
31 #include <sfx2/app.hxx>
32 #include <sfx2/objsh.hxx>
33 #include <sfx2/sfxresid.hxx>
34 #include <sfx2/module.hxx>
35 #include <sfx2/sfxsids.hrc>
37 #include <sfx2/strings.hrc>
39 #include <svl/stritem.hxx>
40 #include <sfx2/dispatch.hxx>
42 #include "mgetempl.hxx"
44 /* SfxManageStyleSheetPage Constructor
46 * initializes the list box with the templates
48 SfxManageStyleSheetPage::SfxManageStyleSheetPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
49 : SfxTabPage(pPage, pController, "sfx/ui/managestylepage.ui", "ManageStylePage", &rAttrSet)
50 , pStyle(&static_cast<SfxStyleDialogController*>(pController)->GetStyleSheet())
51 , pItem(nullptr)
52 , bModified(false)
53 , aName(pStyle->GetName())
54 , aFollow(pStyle->GetFollow())
55 , aParent(pStyle->GetParent())
56 , nFlags(pStyle->GetMask())
57 , m_xName(m_xBuilder->weld_entry("name"))
58 , m_xAutoCB(m_xBuilder->weld_check_button("autoupdate"))
59 , m_xFollowFt(m_xBuilder->weld_label("nextstyleft"))
60 , m_xFollowLb(m_xBuilder->weld_combo_box("nextstyle"))
61 , m_xEditStyleBtn(m_xBuilder->weld_button("editstyle"))
62 , m_xBaseFt(m_xBuilder->weld_label("linkedwithft"))
63 , m_xBaseLb(m_xBuilder->weld_combo_box("linkedwith"))
64 , m_xEditLinkStyleBtn(m_xBuilder->weld_button("editlinkstyle"))
65 , m_xFilterFt(m_xBuilder->weld_label("categoryft"))
66 , m_xFilterLb(m_xBuilder->weld_combo_box("category"))
67 , m_xDescFt(m_xBuilder->weld_label("desc"))
68 , m_xNameFt(m_xBuilder->weld_label("nameft"))
70 m_xFollowLb->make_sorted();
71 // tdf#120188 like SwCharURLPage limit the width of the style combos
72 const int nMaxWidth(m_xFollowLb->get_approximate_digit_width() * 50);
73 m_xFollowLb->set_size_request(nMaxWidth , -1);
74 m_xBaseLb->make_sorted();
75 m_xBaseLb->set_size_request(nMaxWidth , -1);
76 //note that the code depends on categories not being lexically
77 //sorted, so if it's changed to sorted, the code needs to
78 //be adapted to be position unaware
79 m_xFilterLb->set_size_request(nMaxWidth , -1);
81 // this Page needs ExchangeSupport
82 SetExchangeSupport();
84 if ( aFollow.isEmpty() || aFollow == aName )
85 m_xEditStyleBtn->set_sensitive(false);
86 else
87 m_xEditStyleBtn->set_sensitive(true);
89 int linkSelectPos = m_xBaseLb->get_active();
90 if ( linkSelectPos == 0 )
91 m_xEditLinkStyleBtn->set_sensitive(false);
92 else
93 m_xEditLinkStyleBtn->set_sensitive(true);
95 mxFamilies = SfxApplication::GetModule_Impl()->CreateStyleFamilies();
97 SfxStyleSheetBasePool* pPool = nullptr;
98 SfxObjectShell* pDocShell = SfxObjectShell::Current();
100 if ( pDocShell )
101 pPool = pDocShell->GetStyleSheetPool();
102 OSL_ENSURE( pPool, "no Pool or no DocShell" );
104 if ( pPool )
106 pPool->First(pStyle->GetFamily()); // for SW - update internal list
109 if ( pStyle->GetName().isEmpty() && pPool )
111 // NullString as Name -> generate Name
112 OUString aNoName(SfxStyleDialogController::GenerateUnusedName(*pPool, pStyle->GetFamily()));
113 pStyle->SetName( aNoName );
114 aName = aNoName;
115 aFollow = pStyle->GetFollow();
116 aParent = pStyle->GetParent();
118 m_xName->set_text(pStyle->GetName());
120 // Set the field read-only if it is NOT an user-defined style
121 // but allow selecting and copying
122 if (pStyle->IsUserDefined())
124 m_xName->set_can_focus(true);
125 m_xName->set_editable(true);
126 m_xName->set_sensitive(true);
127 m_xName->grab_focus(); // tdf#142017 default to focus within the page, not in notebook tab
129 else
131 m_xName->set_sensitive(false);
134 if ( pStyle->HasFollowSupport() && pPool )
136 SfxStyleSheetBase* pPoolStyle = pPool->First(pStyle->GetFamily());
138 m_xFollowLb->freeze();
140 while ( pPoolStyle )
142 m_xFollowLb->append_text(pPoolStyle->GetName());
143 pPoolStyle = pPool->Next();
146 // A new Template is not yet in the Pool
147 if (m_xFollowLb->find_text(pStyle->GetName()) == -1)
148 m_xFollowLb->append_text(pStyle->GetName());
150 m_xFollowLb->thaw();
152 else
154 m_xFollowFt->set_sensitive(false);
155 m_xFollowFt->hide();
156 m_xFollowLb->set_sensitive(false);
157 m_xFollowLb->hide();
158 m_xEditStyleBtn->hide();
161 if ( pStyle->HasParentSupport() && pPool )
163 m_xBaseLb->freeze();
165 if ( pStyle->HasClearParentSupport() )
166 // the base template can be set to NULL
167 m_xBaseLb->append_text(SfxResId(STR_NONE));
169 SfxStyleSheetBase* pPoolStyle = pPool->First(pStyle->GetFamily());
171 while ( pPoolStyle )
173 const OUString aStr( pPoolStyle->GetName() );
174 // own name as base template
175 if ( aStr != aName )
176 m_xBaseLb->append_text(aStr);
177 pPoolStyle = pPool->Next();
180 m_xBaseLb->thaw();
182 else
184 m_xBaseFt->set_sensitive(false);
185 m_xBaseLb->set_sensitive(false);
188 size_t nCount = mxFamilies->size();
189 size_t i;
190 for ( i = 0; i < nCount; ++i )
192 pItem = &(mxFamilies->at(i));
194 if ( pItem->GetFamily() == pStyle->GetFamily() )
195 break;
198 if ( i < nCount )
200 sal_uInt16 nStyleFilterIdx = 0xffff;
201 // Filter flags
202 const SfxStyleFilter& rList = pItem->GetFilterList();
203 nCount = rList.size();
204 sal_uInt16 nIdx = 0;
205 SfxStyleSearchBits nMask = pStyle->GetMask() & ~SfxStyleSearchBits::UserDefined;
207 if ( nMask == SfxStyleSearchBits::Auto ) // User Template?
208 nMask = pStyle->GetMask();
210 for ( i = 0; i < nCount; ++i )
212 const SfxFilterTuple& rTupel = rList[ i ];
214 if ( rTupel.nFlags != SfxStyleSearchBits::Auto &&
215 rTupel.nFlags != SfxStyleSearchBits::Used &&
216 rTupel.nFlags != SfxStyleSearchBits::AllVisible &&
217 rTupel.nFlags != SfxStyleSearchBits::All )
219 OUString sId(OUString::number(i));
220 m_xFilterLb->insert(nIdx, rTupel.aName, &sId, nullptr, nullptr);
221 if ( ( rTupel.nFlags & nMask ) == nMask )
222 nStyleFilterIdx = nIdx;
223 ++nIdx;
227 if ( nStyleFilterIdx != 0xFFFF )
228 m_xFilterLb->set_active(nStyleFilterIdx);
231 if ( !m_xFilterLb->get_count() || !pStyle->IsUserDefined() )
233 pItem = nullptr;
234 m_xFilterFt->set_sensitive(false);
235 m_xFilterLb->set_sensitive(false);
237 else
238 m_xFilterLb->save_value();
239 SetDescriptionText_Impl();
241 if (m_xFollowLb->get_sensitive() || m_xBaseLb->get_sensitive())
243 m_xName->connect_focus_in(
244 LINK( this, SfxManageStyleSheetPage, GetFocusHdl ) );
245 m_xName->connect_focus_out(
246 LINK( this, SfxManageStyleSheetPage, LoseFocusHdl ) );
248 // It is a style with auto update? (SW only)
249 if(SfxItemState::SET == rAttrSet.GetItemState(SID_ATTR_AUTO_STYLE_UPDATE))
250 m_xAutoCB->show();
251 m_xFollowLb->connect_changed(LINK(this, SfxManageStyleSheetPage, EditStyleSelectHdl_Impl));
252 m_xBaseLb->connect_changed(LINK(this, SfxManageStyleSheetPage, EditLinkStyleSelectHdl_Impl));
253 m_xEditStyleBtn->connect_clicked(LINK(this, SfxManageStyleSheetPage, EditStyleHdl_Impl));
254 m_xEditLinkStyleBtn->connect_clicked(LINK(this, SfxManageStyleSheetPage, EditLinkStyleHdl_Impl));
257 SfxManageStyleSheetPage::~SfxManageStyleSheetPage()
259 mxFamilies.reset();
260 pItem = nullptr;
261 pStyle = nullptr;
264 void SfxManageStyleSheetPage::UpdateName_Impl( weld::ComboBox* pBox,
265 const OUString& rNew )
267 /* [Description]
269 After the change of a template name update the ListBox pBox
271 [Parameter]
273 ListBox* pBox ListBox, whose entries are to be updated
274 const String& rNew the new Name
278 if (pBox->get_sensitive())
280 // it is the current entry, which name was modified
281 const bool bSelect = pBox->get_active_text() == aBuf;
282 int nOldIndex = pBox->find_text(aBuf);
283 if (nOldIndex != -1)
284 pBox->remove(nOldIndex);
285 pBox->append_text(rNew);
287 if (bSelect)
288 pBox->set_active_text(rNew);
292 void SfxManageStyleSheetPage::SetDescriptionText_Impl()
294 /* [Description]
296 Set attribute description. Get the set metric for this.
300 MapUnit eUnit = MapUnit::MapCM;
301 FieldUnit eFieldUnit( FieldUnit::CM );
302 SfxModule* pModule = SfxModule::GetActiveModule();
303 if ( pModule )
305 const SfxPoolItem* pPoolItem = pModule->GetItem( SID_ATTR_METRIC );
306 if ( pPoolItem )
307 eFieldUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>( pPoolItem )->GetValue());
310 switch ( eFieldUnit )
312 case FieldUnit::MM: eUnit = MapUnit::MapMM; break;
313 case FieldUnit::CM:
314 case FieldUnit::M:
315 case FieldUnit::KM: eUnit = MapUnit::MapCM; break;
316 case FieldUnit::POINT:
317 case FieldUnit::PICA: eUnit = MapUnit::MapPoint; break;
318 case FieldUnit::INCH:
319 case FieldUnit::FOOT:
320 case FieldUnit::MILE: eUnit = MapUnit::MapInch; break;
322 default:
323 OSL_FAIL( "non supported field unit" );
325 m_xDescFt->set_label(pStyle->GetDescription(eUnit));
328 IMPL_LINK_NOARG(SfxManageStyleSheetPage, EditStyleSelectHdl_Impl, weld::ComboBox&, void)
330 OUString aTemplName(m_xFollowLb->get_active_text());
331 OUString aEditTemplName(m_xName->get_text());
332 m_xEditStyleBtn->set_sensitive(aTemplName != aEditTemplName);
335 IMPL_LINK_NOARG(SfxManageStyleSheetPage, EditStyleHdl_Impl, weld::Button&, void)
337 OUString aTemplName(m_xFollowLb->get_active_text());
338 Execute_Impl(SID_STYLE_EDIT, aTemplName, static_cast<sal_uInt16>(pStyle->GetFamily()));
341 IMPL_LINK_NOARG(SfxManageStyleSheetPage, EditLinkStyleSelectHdl_Impl, weld::ComboBox&, void)
343 int linkSelectPos = m_xBaseLb->get_active();
344 if ( linkSelectPos == 0 )
345 m_xEditLinkStyleBtn->set_sensitive(false);
346 else
347 m_xEditLinkStyleBtn->set_sensitive(true);
350 IMPL_LINK_NOARG(SfxManageStyleSheetPage, EditLinkStyleHdl_Impl, weld::Button&, void)
352 OUString aTemplName(m_xBaseLb->get_active_text());
353 if (aTemplName != SfxResId(STR_NONE))
354 Execute_Impl( SID_STYLE_EDIT, aTemplName, static_cast<sal_uInt16>(pStyle->GetFamily()) );
357 // Internal: Perform functions through the Dispatcher
358 bool SfxManageStyleSheetPage::Execute_Impl(
359 sal_uInt16 nId, const OUString &rStr, sal_uInt16 nFamily)
362 SfxDispatcher &rDispatcher = *SfxGetpApp()->GetDispatcher_Impl();
363 SfxStringItem aItem(nId, rStr);
364 SfxUInt16Item aFamily(SID_STYLE_FAMILY, nFamily);
365 const SfxPoolItem* pItems[ 6 ];
366 sal_uInt16 nCount = 0;
367 if( !rStr.isEmpty() )
368 pItems[ nCount++ ] = &aItem;
369 pItems[ nCount++ ] = &aFamily;
371 pItems[ nCount++ ] = nullptr;
373 const SfxPoolItem* pItem = rDispatcher.Execute(
374 nId, SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
375 pItems );
377 return pItem != nullptr;
381 IMPL_LINK(SfxManageStyleSheetPage, GetFocusHdl, weld::Widget&, rControl, void)
383 /* [Description]
385 StarView Handler; GetFocus-Handler of the Edits with the template name.
389 weld::Entry& rEdit = dynamic_cast<weld::Entry&>(rControl);
390 aBuf = comphelper::string::stripStart(rEdit.get_text(), ' ');
393 IMPL_LINK(SfxManageStyleSheetPage, LoseFocusHdl, weld::Widget&, rControl, void)
395 /* [Description]
397 StarView Handler; lose-focus-handler of the edits of the template name.
398 This will update the listbox with the subsequent templates. The current
399 template itself is not returned in the listbox of the base templates.
403 weld::Entry& rEdit = dynamic_cast<weld::Entry&>(rControl);
404 const OUString aStr(comphelper::string::stripStart(rEdit.get_text(), ' '));
405 rEdit.set_text(aStr);
406 // Update the Listbox of the base template if possible
407 if ( aStr != aBuf )
408 UpdateName_Impl(m_xFollowLb.get(), aStr);
411 bool SfxManageStyleSheetPage::FillItemSet( SfxItemSet* rSet )
413 /* [Description]
415 Handler for setting the (modified) data. I called from the OK of the
416 SfxTabDialog.
418 [Parameter]
420 SfxItemSet &rAttrSet The set, which receives the data.
422 [Return value]
424 sal_Bool sal_True: The data had been changed
425 sal_False: The data had not been changed
427 [Cross-reference]
429 <class SfxTabDialog>
433 const int nFilterIdx = m_xFilterLb->get_active();
435 // Set Filter
437 if ( nFilterIdx != -1 &&
438 m_xFilterLb->get_value_changed_from_saved() &&
439 m_xFilterLb->get_sensitive() )
441 bModified = true;
442 OSL_ENSURE( pItem, "No Item" );
443 // is only possibly for user templates
444 SfxStyleSearchBits nMask = pItem->GetFilterList()[m_xFilterLb->get_id(nFilterIdx).toUInt32()].nFlags | SfxStyleSearchBits::UserDefined;
445 pStyle->SetMask( nMask );
447 if (m_xAutoCB->get_visible() && m_xAutoCB->get_state_changed_from_saved())
449 rSet->Put(SfxBoolItem(SID_ATTR_AUTO_STYLE_UPDATE, m_xAutoCB->get_active()));
452 return bModified;
456 void SfxManageStyleSheetPage::Reset( const SfxItemSet* /*rAttrSet*/ )
458 /* [Description]
460 Handler to initialize the page with the initial data.
462 [Parameter]
464 const SfxItemSet &rAttrSet The data set
466 [Cross-reference]
468 <class SfxTabDialog>
472 bModified = false;
473 OUString sCmp( pStyle->GetName() );
475 if ( sCmp != aName )
476 pStyle->SetName( aName );
477 m_xName->set_text( aName );
478 if (m_xName->get_editable())
479 m_xName->select_region(0, -1);
481 if ( m_xFollowLb->get_sensitive() )
483 sCmp = pStyle->GetFollow();
485 if ( sCmp != aFollow )
486 pStyle->SetFollow( aFollow );
488 if ( aFollow.isEmpty() )
490 m_xFollowLb->set_active_text( aName );
491 m_xEditStyleBtn->set_sensitive( false );
493 else
494 m_xFollowLb->set_active_text( aFollow );
497 if (m_xBaseLb->get_sensitive())
499 sCmp = pStyle->GetParent();
501 if ( sCmp != aParent )
502 pStyle->SetParent( aParent );
504 if ( aParent.isEmpty() )
506 m_xBaseLb->set_active_text( SfxResId(STR_NONE) );
507 m_xEditLinkStyleBtn->set_sensitive( false );
509 else
510 m_xBaseLb->set_active_text( aParent );
512 if ( SfxResId(STR_STANDARD) == aName )
514 // the default template can not be linked
515 m_xBaseFt->set_sensitive(false);
516 m_xBaseLb->set_sensitive(false);
519 else
520 m_xEditLinkStyleBtn->set_sensitive( false );
522 if (m_xFilterLb->get_sensitive())
524 SfxStyleSearchBits nCmp = pStyle->GetMask();
526 if ( nCmp != nFlags )
527 pStyle->SetMask( nFlags );
528 m_xFilterLb->set_active_text(m_xFilterLb->get_saved_value());
532 std::unique_ptr<SfxTabPage> SfxManageStyleSheetPage::Create( weld::Container* pPage, weld::DialogController* pController,
533 const SfxItemSet *rAttrSet )
535 return std::make_unique<SfxManageStyleSheetPage>(pPage, pController, *rAttrSet);
538 void SfxManageStyleSheetPage::ActivatePage( const SfxItemSet& rSet)
540 /* [Description]
542 ActivatePage handler of SfxTabDialog, is used for the update of the
543 descriptive text, since this might have changed through changes of data on
544 other pages.
546 [Parameter]
548 const SfxItemSet& the set for the exchange of data; is not used here.
550 [Cross-reference]
552 <SfxTabDialog::ActivatePage(const SfxItemSet &)>
556 SetDescriptionText_Impl();
558 // It is a style with auto update? (SW only)
559 const SfxPoolItem* pPoolItem;
561 if ( SfxItemState::SET ==
562 rSet.GetItemState( SID_ATTR_AUTO_STYLE_UPDATE, false, &pPoolItem ) )
563 m_xAutoCB->set_active(static_cast<const SfxBoolItem*>(pPoolItem)->GetValue());
564 m_xAutoCB->save_state();
565 m_xName->save_value();
568 DeactivateRC SfxManageStyleSheetPage::DeactivatePage( SfxItemSet* pItemSet )
570 /* [Description]
572 DeactivatePage-handler of SfxTabDialog; data is set on the template, so
573 that the correct inheritance on the other pages of the dialog is made.
574 If an error occurs, leaving the page is prevented.
575 [Parameter]
577 SfxItemSet* the set for the exchange of data; is not used here.
579 [Cross-reference]
581 <SfxTabDialog::DeactivatePage(SfxItemSet*)>
585 DeactivateRC nRet = DeactivateRC::LeavePage;
587 if (m_xName->get_value_changed_from_saved())
589 // By pressing <Enter> LoseFocus() is not triggered through StarView
590 if (m_xName->has_focus())
591 LoseFocusHdl( *m_xName );
593 if (!pStyle->SetName(comphelper::string::stripStart(m_xName->get_text(), ' ')))
595 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
596 VclMessageType::Info, VclButtonsType::Ok,
597 SfxResId(STR_TABPAGE_INVALIDNAME)));
598 xBox->run();
599 m_xName->grab_focus();
600 m_xName->select_region(0, -1);
601 return DeactivateRC::KeepPage;
603 bModified = true;
606 if (pStyle->HasFollowSupport() && m_xFollowLb->get_sensitive())
608 const OUString aFollowEntry( m_xFollowLb->get_active_text() );
610 if ( pStyle->GetFollow() != aFollowEntry )
612 if ( !pStyle->SetFollow( aFollowEntry ) )
614 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
615 VclMessageType::Info, VclButtonsType::Ok,
616 SfxResId(STR_TABPAGE_INVALIDSTYLE)));
617 xBox->run();
618 m_xFollowLb->grab_focus();
619 return DeactivateRC::KeepPage;
621 bModified = true;
625 if (m_xBaseLb->get_sensitive())
627 OUString aParentEntry( m_xBaseLb->get_active_text() );
629 if ( SfxResId(STR_NONE) == aParentEntry || aParentEntry == pStyle->GetName() )
630 aParentEntry.clear();
632 if ( pStyle->GetParent() != aParentEntry )
634 if ( !pStyle->SetParent( aParentEntry ) )
636 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
637 VclMessageType::Info, VclButtonsType::Ok,
638 SfxResId(STR_TABPAGE_INVALIDPARENT)));
639 xBox->run();
640 m_xBaseLb->grab_focus();
641 return DeactivateRC::KeepPage;
643 bModified = true;
644 nRet = nRet | DeactivateRC::RefreshSet;
648 if ( pItemSet )
649 FillItemSet( pItemSet );
651 return nRet;
654 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */