android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / ui / frmdlg / cption.cxx
blobe6b387a42910f2d030a534e30b908717cef524b9
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 <utility>
21 #include <view.hxx>
22 #include <wrtsh.hxx>
23 #include <cption.hxx>
24 #include <fldmgr.hxx>
25 #include <expfld.hxx>
26 #include <numrule.hxx>
27 #include <poolfmt.hxx>
28 #include <docsh.hxx>
29 #include <calc.hxx>
30 #include <uitool.hxx>
31 #include <doc.hxx>
32 #include <modcfg.hxx>
33 #include <swmodule.hxx>
34 #include <com/sun/star/frame/XModel.hpp>
35 #include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
36 #include <com/sun/star/text/XTextTablesSupplier.hpp>
37 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
38 #include <com/sun/star/text/XTextFramesSupplier.hpp>
39 #include <comphelper/string.hxx>
40 #include <vcl/weld.hxx>
41 #include <strings.hrc>
42 #include <SwStyleNameMapper.hxx>
44 using namespace ::com::sun::star;
46 namespace {
48 class SwSequenceOptionDialog : public weld::GenericDialogController
50 SwView& m_rView;
51 OUString m_aFieldTypeName;
53 std::unique_ptr<weld::ComboBox> m_xLbLevel;
54 std::unique_ptr<weld::Entry> m_xEdDelim;
56 std::unique_ptr<weld::ComboBox> m_xLbCharStyle;
57 std::unique_ptr<weld::CheckButton> m_xApplyBorderAndShadowCB;
59 //#i61007# order of captions
60 std::unique_ptr<weld::ComboBox> m_xLbCaptionOrder;
62 public:
63 SwSequenceOptionDialog(weld::Window *pParent, SwView &rV, OUString aSeqFieldType);
64 void Apply();
66 bool IsApplyBorderAndShadow() const { return m_xApplyBorderAndShadowCB->get_active(); }
67 void SetApplyBorderAndShadow( bool bSet ) { m_xApplyBorderAndShadowCB->set_active(bSet); }
69 //#i61007# order of captions
70 bool IsOrderNumberingFirst() const { return m_xLbCaptionOrder->get_active() == 1; }
71 void SetOrderNumberingFirst(bool bSet) { m_xLbCaptionOrder->set_active(bSet ? 1 : 0); }
73 void SetCharacterStyle(const OUString& rStyle);
74 OUString GetCharacterStyle() const;
79 OUString SwCaptionDialog::s_aSepTextSave(": "); // Caption separator text
81 //Resolves: tdf#47427 disallow typing *or* pasting invalid content into the category box
82 OUString TextFilterAutoConvert::filter(const OUString &rText)
84 if (!rText.isEmpty() && rText != m_sNone && !SwCalc::IsValidVarName(rText))
85 return m_sLastGoodText;
86 m_sLastGoodText = rText;
87 return rText;
90 SwCaptionDialog::SwCaptionDialog(weld::Window *pParent, SwView &rV)
91 : SfxDialogController(pParent, "modules/swriter/ui/insertcaption.ui", "InsertCaptionDialog")
92 , m_sNone(SwResId(SW_STR_NONE))
93 , m_aTextFilter(m_sNone)
94 , m_rView(rV)
95 , m_pMgr(new SwFieldMgr(m_rView.GetWrtShellPtr()))
96 , m_bCopyAttributes(false)
97 , m_bOrderNumberingFirst(SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst())
98 , m_xTextEdit(m_xBuilder->weld_entry("caption_edit"))
99 , m_xCategoryBox(m_xBuilder->weld_combo_box("category"))
100 , m_xFormatText(m_xBuilder->weld_label("numbering_label"))
101 , m_xFormatBox(m_xBuilder->weld_combo_box("numbering"))
102 , m_xNumberingSeparatorFT(m_xBuilder->weld_label("num_separator"))
103 , m_xNumberingSeparatorED(m_xBuilder->weld_entry("num_separator_edit"))
104 , m_xSepText(m_xBuilder->weld_label("separator_label"))
105 , m_xSepEdit(m_xBuilder->weld_entry("separator_edit"))
106 , m_xPosBox(m_xBuilder->weld_combo_box("position"))
107 , m_xOKButton(m_xBuilder->weld_button("ok"))
108 , m_xAutoCaptionButton(m_xBuilder->weld_button("auto"))
109 , m_xOptionButton(m_xBuilder->weld_button("options"))
110 , m_xPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreview))
112 //#i61007# order of captions
113 ApplyCaptionOrder();
114 SwWrtShell &rSh = m_rView.GetWrtShell();
115 uno::Reference< frame::XModel > xModel = m_rView.GetDocShell()->GetBaseModel();
117 SelectionType eType = rSh.GetSelectionType();
118 if ( eType & SelectionType::Ole )
120 eType = SelectionType::Graphic;
121 uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY);
122 m_xNameAccess = xObjs->getEmbeddedObjects();
125 m_xCategoryBox->connect_changed(LINK(this, SwCaptionDialog, ModifyComboHdl));
126 Link<weld::Entry&,void> aLk = LINK(this, SwCaptionDialog, ModifyEntryHdl);
127 m_xTextEdit->connect_changed(aLk);
128 m_xNumberingSeparatorED->connect_changed(aLk);
129 m_xSepEdit->connect_changed(aLk);
131 m_xFormatBox->connect_changed(LINK(this, SwCaptionDialog, SelectListBoxHdl));
132 m_xOKButton->connect_clicked(LINK(this, SwCaptionDialog, OKHdl));
133 m_xOptionButton->connect_clicked(LINK(this, SwCaptionDialog, OptionHdl));
134 m_xAutoCaptionButton->connect_clicked(LINK(this, SwCaptionDialog, CaptionHdl));
135 m_xAutoCaptionButton->set_accessible_description(SwResId(STR_A11Y_DESC_AUTO));
137 m_xCategoryBox->append_text(m_sNone);
138 size_t nCount = m_pMgr->GetFieldTypeCount();
139 for (size_t i = 0; i < nCount; ++i)
141 SwFieldType *pType = m_pMgr->GetFieldType( SwFieldIds::Unknown, i );
142 if( pType->Which() == SwFieldIds::SetExp &&
143 static_cast<SwSetExpFieldType *>( pType)->GetType() & nsSwGetSetExpType::GSE_SEQ )
144 m_xCategoryBox->append_text(pType->GetName());
147 OUString sString;
148 sal_uInt16 nPoolId = 0;
149 if (eType & SelectionType::Graphic)
151 nPoolId = RES_POOLCOLL_LABEL_FIGURE;
153 SwSetExpFieldType* pTypeIll= static_cast<SwSetExpFieldType*>(rSh.GetFieldType(SwFieldIds::SetExp, SwResId(STR_POOLCOLL_LABEL_ABB)));
154 if(rSh.IsUsed(*pTypeIll)) //default to illustration for legacy docs
156 nPoolId = RES_POOLCOLL_LABEL_ABB;
160 sString = m_rView.GetOldGrfCat();
161 m_bCopyAttributes = true;
162 //if not OLE
163 if(!m_xNameAccess.is())
165 uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY);
166 m_xNameAccess = xGraphics->getGraphicObjects();
170 else if( eType & SelectionType::Table )
172 nPoolId = RES_POOLCOLL_LABEL_TABLE;
173 sString = m_rView.GetOldTabCat();
174 uno::Reference< text::XTextTablesSupplier > xTables(xModel, uno::UNO_QUERY);
175 m_xNameAccess = xTables->getTextTables();
177 else if( eType & SelectionType::Frame )
179 nPoolId = RES_POOLCOLL_LABEL_FRAME;
180 sString = m_rView.GetOldFrameCat();
181 uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY);
182 m_xNameAccess = xFrames->getTextFrames();
184 else if( eType == SelectionType::Text )
186 nPoolId = RES_POOLCOLL_LABEL_FRAME;
187 sString = m_rView.GetOldFrameCat();
189 else if( eType & SelectionType::DrawObject )
191 nPoolId = RES_POOLCOLL_LABEL_DRAWING;
192 sString = m_rView.GetOldDrwCat();
194 if( nPoolId )
196 if (sString.isEmpty())
197 sString = SwStyleNameMapper::GetUIName(nPoolId, OUString());
198 auto nIndex = m_xCategoryBox->find_text(sString);
199 if (nIndex != -1)
200 m_xCategoryBox->set_active(nIndex);
201 else
202 m_xCategoryBox->set_entry_text(sString);
205 // aFormatBox
206 sal_uInt16 nSelFormat = SVX_NUM_ARABIC;
207 nCount = m_pMgr->GetFieldTypeCount();
208 for ( size_t i = nCount; i; )
210 SwFieldType* pFieldType = m_pMgr->GetFieldType(SwFieldIds::Unknown, --i);
211 if (pFieldType->GetName() == m_xCategoryBox->get_active_text())
213 nSelFormat = o3tl::narrowing<sal_uInt16>(static_cast<SwSetExpFieldType*>(pFieldType)->GetSeqFormat());
214 break;
218 sal_uInt16 nFormatCount = m_pMgr->GetFormatCount(SwFieldTypesEnum::Sequence, false);
219 for ( sal_uInt16 i = 0; i < nFormatCount; ++i )
221 const sal_uInt16 nFormatId = m_pMgr->GetFormatId(SwFieldTypesEnum::Sequence, i);
222 m_xFormatBox->append(OUString::number(nFormatId), m_pMgr->GetFormatStr(SwFieldTypesEnum::Sequence, i));
223 if (nFormatId == nSelFormat)
224 m_xFormatBox->set_active(i);
227 // aPosBox
228 if (eType == SelectionType::Graphic
229 || eType == SelectionType::Table
230 || eType == (SelectionType::Table | SelectionType::NumberList)
231 || eType == (SelectionType::Table | SelectionType::Text)
232 || eType == (SelectionType::Table | SelectionType::NumberList | SelectionType::Text)
233 || eType == SelectionType::DrawObject
234 || eType == (SelectionType::DrawObject | SelectionType::Ornament))
236 m_xPosBox->append_text(SwResId(STR_CAPTION_ABOVE));
237 m_xPosBox->append_text(SwResId(STR_CAPTION_BELOW));
239 else if(eType == SelectionType::Frame
240 || eType == SelectionType::Text)
242 m_xPosBox->append_text(SwResId(STR_CAPTION_BEGINNING));
243 m_xPosBox->append_text(SwResId(STR_CAPTION_END));
246 if (eType & SelectionType::Table)
248 m_xPosBox->set_active(0);
250 else
252 m_xPosBox->set_active(1);
255 ModifyHdl();
257 m_xSepEdit->set_text(s_aSepTextSave);
258 m_xTextEdit->grab_focus();
259 DrawSample();
262 IMPL_LINK_NOARG(SwCaptionDialog, OKHdl, weld::Button&, void)
264 Apply();
265 m_xDialog->response(RET_OK);
268 void SwCaptionDialog::Apply()
270 InsCaptionOpt aOpt;
271 aOpt.UseCaption() = true;
272 OUString aName(m_xCategoryBox->get_active_text());
273 if ( aName == m_sNone )
275 aOpt.SetCategory( OUString() );
276 aOpt.SetNumSeparator( OUString() );
278 else
280 aOpt.SetCategory(comphelper::string::strip(aName, ' '));
281 aOpt.SetNumSeparator(m_xNumberingSeparatorED->get_text());
283 aOpt.SetNumType(m_xFormatBox->get_active_id().toUInt32());
284 aOpt.SetSeparator(m_xSepEdit->get_sensitive() ? m_xSepEdit->get_text() : OUString());
285 aOpt.SetCaption(m_xTextEdit->get_text());
286 aOpt.SetPos(m_xPosBox->get_active());
287 aOpt.IgnoreSeqOpts() = true;
288 aOpt.CopyAttributes() = m_bCopyAttributes;
289 aOpt.SetCharacterStyle( m_sCharacterStyle );
290 m_rView.InsertCaption( &aOpt );
291 s_aSepTextSave = m_xSepEdit->get_text();
294 short SwCaptionDialog::run()
296 short nRet = SfxDialogController::run();
297 if (nRet == RET_OK)
298 Apply();
299 return nRet;
302 IMPL_LINK_NOARG(SwCaptionDialog, OptionHdl, weld::Button&, void)
304 OUString sFieldTypeName = m_xCategoryBox->get_active_text();
305 if(sFieldTypeName == m_sNone)
306 sFieldTypeName.clear();
307 auto pDlg = std::make_shared<SwSequenceOptionDialog>(m_xDialog.get(), m_rView, sFieldTypeName);
308 pDlg->SetApplyBorderAndShadow(m_bCopyAttributes);
309 pDlg->SetCharacterStyle( m_sCharacterStyle );
310 pDlg->SetOrderNumberingFirst( m_bOrderNumberingFirst );
312 GenericDialogController::runAsync(pDlg, [pDlg, this](sal_Int32 nResult){
313 if (nResult == RET_OK) {
314 pDlg->Apply();
315 m_bCopyAttributes = pDlg->IsApplyBorderAndShadow();
316 m_sCharacterStyle = pDlg->GetCharacterStyle();
317 //#i61007# order of captions
318 if( m_bOrderNumberingFirst != pDlg->IsOrderNumberingFirst() )
320 m_bOrderNumberingFirst = pDlg->IsOrderNumberingFirst();
321 SW_MOD()->GetModuleConfig()->SetCaptionOrderNumberingFirst(m_bOrderNumberingFirst);
322 ApplyCaptionOrder();
324 DrawSample();
329 IMPL_LINK_NOARG(SwCaptionDialog, SelectListBoxHdl, weld::ComboBox&, void)
331 DrawSample();
334 void SwCaptionDialog::ModifyHdl()
336 SwWrtShell &rSh = m_rView.GetWrtShell();
337 OUString sFieldTypeName = m_xCategoryBox->get_active_text();
338 bool bCorrectFieldName = !sFieldTypeName.isEmpty();
339 bool bNone = sFieldTypeName == m_sNone;
340 SwFieldType* pType = (bCorrectFieldName && !bNone)
341 ? rSh.GetFieldType( SwFieldIds::SetExp, sFieldTypeName )
342 : nullptr;
343 m_xOKButton->set_sensitive( bCorrectFieldName &&
344 (!pType ||
345 static_cast<SwSetExpFieldType*>(pType)->GetType() == nsSwGetSetExpType::GSE_SEQ) );
346 m_xOptionButton->set_sensitive(m_xOKButton->get_sensitive() && !bNone);
347 m_xNumberingSeparatorFT->set_sensitive(m_bOrderNumberingFirst && !bNone);
348 m_xNumberingSeparatorED->set_sensitive(m_bOrderNumberingFirst && !bNone);
349 m_xFormatText->set_sensitive(!bNone);
350 m_xFormatBox->set_sensitive(!bNone);
351 m_xSepText->set_sensitive(!bNone);
352 m_xSepEdit->set_sensitive(!bNone);
353 DrawSample();
356 IMPL_LINK_NOARG(SwCaptionDialog, ModifyEntryHdl, weld::Entry&, void)
358 ModifyHdl();
361 IMPL_LINK_NOARG(SwCaptionDialog, ModifyComboHdl, weld::ComboBox&, void)
363 OUString sText = m_xCategoryBox->get_active_text();
364 OUString sAllowedText = m_aTextFilter.filter(sText);
365 if (sText != sAllowedText)
367 m_xCategoryBox->set_entry_text(sAllowedText);
368 m_xCategoryBox->select_entry_region(sAllowedText.getLength(), sAllowedText.getLength());
370 ModifyHdl();
373 IMPL_LINK_NOARG(SwCaptionDialog, CaptionHdl, weld::Button&, void)
375 SfxItemSet aSet(m_rView.GetDocShell()->GetDoc()->GetAttrPool());
376 SwCaptionOptDlg aDlg(m_xDialog.get(), aSet);
377 aDlg.run();
380 void SwCaptionDialog::DrawSample()
382 OUString aStr;
383 OUString sCaption = m_xTextEdit->get_text();
385 // number
386 OUString sFieldTypeName = m_xCategoryBox->get_active_text();
387 bool bNone = sFieldTypeName == m_sNone;
388 if( !bNone )
390 const sal_uInt16 nNumFormat = m_xFormatBox->get_active_id().toUInt32();
391 if (SVX_NUM_NUMBER_NONE != nNumFormat)
393 // category
394 //#i61007# order of captions
395 if( !m_bOrderNumberingFirst )
397 aStr = sFieldTypeName;
398 if ( !aStr.isEmpty() )
399 aStr += " ";
402 SwWrtShell &rSh = m_rView.GetWrtShell();
403 SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(rSh.GetFieldType(
404 SwFieldIds::SetExp, sFieldTypeName ));
405 if( pFieldType && pFieldType->GetOutlineLvl() < MAXLEVEL )
407 SwNumberTree::tNumberVector aNumVector;
408 aNumVector.insert(aNumVector.end(), pFieldType->GetOutlineLvl() + 1, 1);
410 OUString sNumber( rSh.GetOutlineNumRule()->
411 MakeNumString(aNumVector, false ));
412 if( !sNumber.isEmpty() )
413 aStr += sNumber + pFieldType->GetDelimiter();
416 switch( nNumFormat )
418 case SVX_NUM_CHARS_UPPER_LETTER: aStr += "A"; break;
419 case SVX_NUM_CHARS_UPPER_LETTER_N: aStr += "A"; break;
420 case SVX_NUM_CHARS_LOWER_LETTER: aStr += "a"; break;
421 case SVX_NUM_CHARS_LOWER_LETTER_N: aStr += "a"; break;
422 case SVX_NUM_ROMAN_UPPER: aStr += "I"; break;
423 case SVX_NUM_ROMAN_LOWER: aStr += "i"; break;
424 default: aStr += "1"; break;
426 //#i61007# order of captions
427 if( m_bOrderNumberingFirst )
429 aStr += m_xNumberingSeparatorED->get_text() + sFieldTypeName;
433 if( !sCaption.isEmpty() )
435 aStr += m_xSepEdit->get_text();
438 aStr += sCaption;
439 // do preview!
440 m_aPreview.SetPreviewText(aStr);
443 SwCaptionDialog::~SwCaptionDialog()
447 SwSequenceOptionDialog::SwSequenceOptionDialog(weld::Window *pParent, SwView &rV, OUString aSeqFieldType )
448 : GenericDialogController(pParent, "modules/swriter/ui/captionoptions.ui", "CaptionOptionsDialog")
449 , m_rView(rV)
450 , m_aFieldTypeName(std::move(aSeqFieldType))
451 , m_xLbLevel(m_xBuilder->weld_combo_box("level"))
452 , m_xEdDelim(m_xBuilder->weld_entry("separator"))
453 , m_xLbCharStyle(m_xBuilder->weld_combo_box("style"))
454 , m_xApplyBorderAndShadowCB(m_xBuilder->weld_check_button("border_and_shadow"))
455 , m_xLbCaptionOrder(m_xBuilder->weld_combo_box("caption_order"))
457 SwWrtShell &rSh = m_rView.GetWrtShell();
459 const OUString sNone(SwResId(SW_STR_NONE));
461 m_xLbLevel->append_text(sNone);
462 for (sal_uInt16 n = 0; n < MAXLEVEL; ++n)
463 m_xLbLevel->append_text(OUString::number(n + 1));
465 SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(rSh.GetFieldType(
466 SwFieldIds::SetExp, m_aFieldTypeName ));
468 sal_Unicode nLvl = MAXLEVEL;
469 OUString sDelim(": ");
470 if( pFieldType )
472 sDelim = pFieldType->GetDelimiter();
473 nLvl = pFieldType->GetOutlineLvl();
476 m_xLbLevel->set_active(nLvl < MAXLEVEL ? nLvl + 1 : 0);
477 m_xEdDelim->set_text(sDelim);
479 m_xLbCharStyle->append_text(sNone);
480 ::FillCharStyleListBox(*m_xLbCharStyle, m_rView.GetDocShell(), true, true);
481 m_xLbCharStyle->set_active(0);
484 void SwSequenceOptionDialog::Apply()
486 SwWrtShell &rSh = m_rView.GetWrtShell();
487 SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(rSh.GetFieldType(
488 SwFieldIds::SetExp, m_aFieldTypeName ));
490 sal_Int8 nLvl = static_cast<sal_Int8>(m_xLbLevel->get_active() - 1);
491 sal_Unicode cDelim = m_xEdDelim->get_text()[0];
493 bool bUpdate = true;
494 if( pFieldType )
496 pFieldType->SetDelimiter( OUString(cDelim) );
497 pFieldType->SetOutlineLvl( nLvl );
499 else if( !m_aFieldTypeName.isEmpty() && nLvl < MAXLEVEL )
501 // then we have to insert that
502 SwSetExpFieldType aFieldType( rSh.GetDoc(), m_aFieldTypeName, nsSwGetSetExpType::GSE_SEQ );
503 aFieldType.SetDelimiter( OUString(cDelim) );
504 aFieldType.SetOutlineLvl( nLvl );
505 rSh.InsertFieldType( aFieldType );
507 else
508 bUpdate = false;
510 if( bUpdate )
511 rSh.UpdateExpFields();
514 OUString SwSequenceOptionDialog::GetCharacterStyle() const
516 if (m_xLbCharStyle->get_active() != -1)
517 return m_xLbCharStyle->get_active_text();
518 return OUString();
521 void SwSequenceOptionDialog::SetCharacterStyle(const OUString& rStyle)
523 const int nPos = m_xLbCharStyle->find_text(rStyle);
524 if (nPos == -1)
525 m_xLbCharStyle->set_active(0);
526 else
527 m_xLbCharStyle->set_active(nPos);
530 // #i61007# order of captions
531 void SwCaptionDialog::ApplyCaptionOrder()
533 m_xNumberingSeparatorFT->set_sensitive(m_bOrderNumberingFirst);
534 m_xNumberingSeparatorED->set_sensitive(m_bOrderNumberingFirst);
537 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */