Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / cui / source / tabpages / tplneend.cxx
blob3119058f739f90319fe71f8f5372d788de9cd900
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 <tools/urlobj.hxx>
21 #include <vcl/settings.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/weld.hxx>
24 #include <unotools/pathoptions.hxx>
25 #include <sfx2/filedlghelper.hxx>
26 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
28 #include <strings.hrc>
29 #include <svx/dialmgr.hxx>
30 #include <svx/dlgctrl.hxx>
31 #include <svx/svdobj.hxx>
32 #include <svx/svdopath.hxx>
33 #include <svx/xtable.hxx>
34 #include <svx/xlineit0.hxx>
35 #include <svx/xlnwtit.hxx>
36 #include <svx/xlnclit.hxx>
37 #include <svx/xlnstwit.hxx>
38 #include <svx/xlnedwit.hxx>
39 #include <svx/xlnstit.hxx>
40 #include <svx/xlnedit.hxx>
41 #include <cuitabline.hxx>
42 #include <cuitabarea.hxx>
43 #include <svx/svxdlg.hxx>
44 #include <dialmgr.hxx>
45 #include <basegfx/range/b2drange.hxx>
46 #include <basegfx/polygon/b2dpolypolygontools.hxx>
47 #include <basegfx/matrix/b2dhommatrixtools.hxx>
48 #include <svx/strings.hrc>
50 #define XOUT_WIDTH 150
52 SvxLineEndDefTabPage::SvxLineEndDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
53 : SfxTabPage(pPage, pController, "cui/ui/lineendstabpage.ui", "LineEndPage", &rInAttrs)
54 , rOutAttrs(rInAttrs)
55 , pPolyObj(nullptr)
56 , aXLineAttr(rInAttrs.GetPool())
57 , rXLSet(aXLineAttr.GetItemSet())
58 , pnLineEndListState(nullptr)
59 , pPageType(nullptr)
60 , nDlgType(0)
61 , pPosLineEndLb(nullptr)
62 , m_xEdtName(m_xBuilder->weld_entry("EDT_NAME"))
63 , m_xLbLineEnds(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_LINEENDS")))
64 , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
65 , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
66 , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
67 , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
68 , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
69 , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
71 // this page needs ExchangeSupport
72 SetExchangeSupport();
74 rXLSet.Put( XLineStyleItem(css::drawing::LineStyle_SOLID) );
75 rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
76 rXLSet.Put( XLineColorItem( OUString(), COL_BLACK ) );
77 rXLSet.Put( XLineStartWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
78 rXLSet.Put( XLineEndWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
80 // #i34740#
81 m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
83 m_xBtnAdd->connect_clicked(LINK(this, SvxLineEndDefTabPage, ClickAddHdl_Impl));
84 m_xBtnModify->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickModifyHdl_Impl));
85 m_xBtnDelete->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickDeleteHdl_Impl));
86 m_xBtnLoad->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickLoadHdl_Impl));
87 m_xBtnSave->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickSaveHdl_Impl));
89 m_xLbLineEnds->connect_changed(LINK(this, SvxLineEndDefTabPage, SelectLineEndHdl_Impl));
92 SvxLineEndDefTabPage::~SvxLineEndDefTabPage()
94 m_xCtlPreview.reset();
95 m_xLbLineEnds.reset();
98 void SvxLineEndDefTabPage::Construct()
100 m_xLbLineEnds->Fill( pLineEndList );
102 bool bCreateArrowPossible = true;
104 if( !pPolyObj )
106 bCreateArrowPossible = false;
108 else if( nullptr == dynamic_cast<const SdrPathObj*>( pPolyObj) )
110 SdrObjTransformInfoRec aInfoRec;
111 pPolyObj->TakeObjInfo( aInfoRec );
112 SdrObjectUniquePtr pNewObj;
113 if( aInfoRec.bCanConvToPath )
114 pNewObj = pPolyObj->ConvertToPolyObj( true, false );
116 bCreateArrowPossible = nullptr != dynamic_cast<const SdrPathObj*>( pNewObj.get());
119 if( !bCreateArrowPossible )
120 m_xBtnAdd->set_sensitive(false);
123 void SvxLineEndDefTabPage::ActivatePage( const SfxItemSet& )
125 if( nDlgType == 0 ) // area dialog
127 // ActivatePage() is called before the dialog receives PageCreated() !!!
128 if( pLineEndList.is() )
130 if( *pPosLineEndLb != -1)
132 m_xLbLineEnds->set_active(*pPosLineEndLb);
133 SelectLineEndHdl_Impl();
135 INetURLObject aURL( pLineEndList->GetPath() );
137 aURL.Append( pLineEndList->GetName() );
138 DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
139 *pPageType = PageType::Area; // 3
140 *pPosLineEndLb = -1;
146 DeactivateRC SvxLineEndDefTabPage::DeactivatePage( SfxItemSet* _pSet )
148 CheckChanges_Impl();
150 if( _pSet )
151 FillItemSet( _pSet );
153 return DeactivateRC::LeavePage;
157 void SvxLineEndDefTabPage::CheckChanges_Impl()
159 int nPos = m_xLbLineEnds->get_active();
161 if (nPos != -1)
163 OUString aString = m_xEdtName->get_text();
165 if( aString != m_xLbLineEnds->get_active_text() )
167 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querychangelineenddialog.ui"));
168 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskChangeLineEndDialog"));
169 if (xQueryBox->run() == RET_YES)
170 ClickModifyHdl_Impl(*m_xBtnModify);
173 nPos = m_xLbLineEnds->get_active();
175 if (nPos != -1)
176 *pPosLineEndLb = nPos;
180 bool SvxLineEndDefTabPage::FillItemSet( SfxItemSet* rSet )
182 if( nDlgType == 0 ) // line dialog
184 if( *pPageType == PageType::Bitmap )
186 CheckChanges_Impl();
188 int nPos = m_xLbLineEnds->get_active();
189 const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
191 rSet->Put( XLineStartItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
192 rSet->Put( XLineEndItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
195 return true;
198 void SvxLineEndDefTabPage::Reset( const SfxItemSet* )
200 m_xLbLineEnds->set_active(0);
202 // Update lineend
203 if( pLineEndList->Count() > 0 )
205 int nPos = m_xLbLineEnds->get_active();
207 const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
209 m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
211 rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
212 rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
214 // #i34740#
215 m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
216 m_aCtlPreview.Invalidate();
219 // determine button state
220 if( pLineEndList->Count() )
222 m_xBtnModify->set_sensitive(true);
223 m_xBtnDelete->set_sensitive(true);
224 m_xBtnSave->set_sensitive(true);
226 else
228 m_xBtnModify->set_sensitive(false);
229 m_xBtnDelete->set_sensitive(false);
230 m_xBtnSave->set_sensitive(false);
234 std::unique_ptr<SfxTabPage> SvxLineEndDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
236 return std::make_unique<SvxLineEndDefTabPage>(pPage, pController, *rSet );
239 void SvxLineEndDefTabPage::SelectLineEndHdl_Impl()
241 if( pLineEndList->Count() > 0 )
243 int nPos = m_xLbLineEnds->get_active();
245 const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
247 m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
249 rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
250 rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
252 // #i34740#
253 m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
254 m_aCtlPreview.Invalidate();
256 // Is not set before, in order to only take the new style,
257 // if there is an entry selected in the ListBox
258 *pPageType = PageType::Bitmap;
262 IMPL_LINK_NOARG(SvxLineEndDefTabPage, SelectLineEndHdl_Impl, weld::ComboBox&, void)
264 SelectLineEndHdl_Impl();
267 IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
269 int nPos = m_xLbLineEnds->get_active();
270 if (nPos != -1)
272 OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINEEND));
273 OUString aName(m_xEdtName->get_text());
274 long nCount = pLineEndList->Count();
275 bool bDifferent = true;
277 // check whether the name is existing already
278 for ( long i = 0; i < nCount && bDifferent; i++ )
279 if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
280 bDifferent = false;
282 // if yes, repeat and demand a new name
283 if ( !bDifferent )
285 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
286 std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
287 xWarningBox->run();
289 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
290 ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
291 bool bLoop = true;
293 while( !bDifferent && bLoop && pDlg->Execute() == RET_OK )
295 pDlg->GetName( aName );
296 bDifferent = true;
298 for( long i = 0; i < nCount && bDifferent; i++ )
300 if( aName == pLineEndList->GetLineEnd( i )->GetName() )
301 bDifferent = false;
304 if( bDifferent )
305 bLoop = false;
306 else
307 xWarningBox->run();
311 // if not existing, enter the entry
312 if( bDifferent )
314 const XLineEndEntry* pOldEntry = pLineEndList->GetLineEnd(nPos);
316 if(pOldEntry)
318 // #123497# Need to replace the existing entry with a new one
319 pLineEndList->Replace(std::make_unique<XLineEndEntry>(pOldEntry->GetLineEnd(), aName), nPos);
321 m_xEdtName->set_text(aName);
323 m_xLbLineEnds->Modify(*pLineEndList->GetLineEnd(nPos), nPos, pLineEndList->GetUiBitmap(nPos));
324 m_xLbLineEnds->set_active(nPos);
326 // set flag for modified
327 *pnLineEndListState |= ChangeType::MODIFIED;
329 *pPageType = PageType::Bitmap;
331 else
333 OSL_ENSURE(false, "LineEnd to be modified not existing (!)");
339 IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
341 if( pPolyObj )
343 const SdrObject* pNewObj;
344 SdrObjectUniquePtr pConvPolyObj;
346 if( nullptr != dynamic_cast<const SdrPathObj*>( pPolyObj) )
348 pNewObj = pPolyObj;
350 else
352 SdrObjTransformInfoRec aInfoRec;
353 pPolyObj->TakeObjInfo( aInfoRec );
355 if( aInfoRec.bCanConvToPath )
357 pConvPolyObj = pPolyObj->ConvertToPolyObj( true, false );
358 pNewObj = pConvPolyObj.get();
360 if( !pNewObj || nullptr == dynamic_cast<const SdrPathObj*>( pNewObj) )
361 return; // cancel, additional safety, which
362 // has no use for group objects though.
364 else return; // cancel
367 basegfx::B2DPolyPolygon aNewPolyPolygon(static_cast<const SdrPathObj*>(pNewObj)->GetPathPoly());
368 basegfx::B2DRange aNewRange(basegfx::utils::getRange(aNewPolyPolygon));
370 // normalize
371 aNewPolyPolygon.transform(basegfx::utils::createTranslateB2DHomMatrix( -aNewRange.getMinX(), -aNewRange.getMinY()));
373 pConvPolyObj.reset();
375 OUString aNewName(SvxResId(RID_SVXSTR_LINEEND));
376 OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINEEND));
377 OUString aName;
379 long nCount = pLineEndList->Count();
380 long j = 1;
381 bool bDifferent = false;
383 while ( !bDifferent )
385 aName = aNewName + " " + OUString::number( j++ );
386 bDifferent = true;
388 for( long i = 0; i < nCount && bDifferent; i++ )
389 if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
390 bDifferent = false;
393 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
394 ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc ));
395 bool bLoop = true;
397 while ( bLoop && pDlg->Execute() == RET_OK )
399 pDlg->GetName( aName );
400 bDifferent = true;
402 for( long i = 0; i < nCount && bDifferent; i++ )
404 if( aName == pLineEndList->GetLineEnd( i )->GetName() )
405 bDifferent = false;
408 if( bDifferent )
410 bLoop = false;
412 auto nLineEndCount = pLineEndList->Count();
413 pLineEndList->Insert(std::make_unique<XLineEndEntry>(aNewPolyPolygon, aName), nLineEndCount);
415 // add to the ListBox
416 m_xLbLineEnds->Append(*pLineEndList->GetLineEnd(nLineEndCount), pLineEndList->GetUiBitmap(nLineEndCount));
417 m_xLbLineEnds->set_active(m_xLbLineEnds->get_count() - 1);
419 *pnLineEndListState |= ChangeType::MODIFIED;
421 SelectLineEndHdl_Impl();
423 else
425 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
426 std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
427 xWarningBox->run();
431 else
432 m_xBtnAdd->set_sensitive(false);
434 // determine button state
435 if ( pLineEndList->Count() )
437 m_xBtnModify->set_sensitive(true);
438 m_xBtnDelete->set_sensitive(true);
439 m_xBtnSave->set_sensitive(true);
443 IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
445 int nPos = m_xLbLineEnds->get_active();
447 if (nPos != -1)
449 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelineenddialog.ui"));
450 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineEndDialog"));
452 if (xQueryBox->run() == RET_YES)
454 pLineEndList->Remove(nPos);
455 m_xLbLineEnds->remove(nPos);
456 m_xLbLineEnds->set_active(0);
458 SelectLineEndHdl_Impl();
459 *pPageType = PageType::Area; // LineEnd shall not be taken over
461 *pnLineEndListState |= ChangeType::MODIFIED;
463 m_aCtlPreview.Invalidate();
466 // determine button state
467 if( !pLineEndList->Count() )
469 m_xBtnModify->set_sensitive(false);
470 m_xBtnDelete->set_sensitive(false);
471 m_xBtnSave->set_sensitive(false);
475 IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
477 sal_uInt16 nReturn = RET_YES;
479 if ( *pnLineEndListState & ChangeType::MODIFIED )
481 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
482 std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
484 nReturn = xBox->run();
486 if ( nReturn == RET_YES )
487 pLineEndList->Save();
490 if ( nReturn != RET_CANCEL )
492 ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
493 FileDialogFlags::NONE, GetFrameWeld());
494 OUString aStrFilterType( "*.soe" );
495 aDlg.AddFilter( aStrFilterType, aStrFilterType );
497 OUString aPalettePath(SvtPathOptions().GetPalettePath());
498 OUString aLastDir;
499 sal_Int32 nIndex = 0;
502 aLastDir = aPalettePath.getToken(0, ';', nIndex);
504 while (nIndex >= 0);
506 INetURLObject aFile(aLastDir);
507 aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
509 if( aDlg.Execute() == ERRCODE_NONE )
511 INetURLObject aURL( aDlg.GetPath() );
512 INetURLObject aPathURL( aURL );
514 aPathURL.removeSegment();
515 aPathURL.removeFinalSlash();
517 XLineEndListRef pLeList = XPropertyList::AsLineEndList(
518 XPropertyList::CreatePropertyList(
519 XPropertyListType::LineEnd,
520 aPathURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), ""));
521 pLeList->SetName( aURL.getName() );
522 if( pLeList->Load() )
524 pLineEndList = pLeList;
525 static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewLineEndList( pLineEndList );
526 m_xLbLineEnds->clear();
527 m_xLbLineEnds->Fill( pLineEndList );
528 Reset( &rOutAttrs );
530 pLineEndList->SetName( aURL.getName() );
532 *pnLineEndListState |= ChangeType::CHANGED;
533 *pnLineEndListState &= ~ChangeType::MODIFIED;
535 else
537 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
538 std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
539 xBox->run();
544 // determine button state
545 if ( pLineEndList->Count() )
547 m_xBtnModify->set_sensitive(true);
548 m_xBtnDelete->set_sensitive(true);
549 m_xBtnSave->set_sensitive(true);
551 else
553 m_xBtnModify->set_sensitive(false);
554 m_xBtnDelete->set_sensitive(false);
555 m_xBtnSave->set_sensitive(false);
559 IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
561 ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
562 OUString aStrFilterType( "*.soe" );
563 aDlg.AddFilter( aStrFilterType, aStrFilterType );
565 OUString aPalettePath(SvtPathOptions().GetPalettePath());
566 OUString aLastDir;
567 sal_Int32 nIndex = 0;
570 aLastDir = aPalettePath.getToken(0, ';', nIndex);
572 while (nIndex >= 0);
574 INetURLObject aFile(aLastDir);
575 DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
577 if( !pLineEndList->GetName().isEmpty() )
579 aFile.Append( pLineEndList->GetName() );
581 if( aFile.getExtension().isEmpty() )
582 aFile.SetExtension( "soe" );
585 aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
586 if ( aDlg.Execute() == ERRCODE_NONE )
588 INetURLObject aURL( aDlg.GetPath() );
589 INetURLObject aPathURL( aURL );
591 aPathURL.removeSegment();
592 aPathURL.removeFinalSlash();
594 pLineEndList->SetName( aURL.getName() );
595 pLineEndList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
597 if( pLineEndList->Save() )
599 *pnLineEndListState &= ~ChangeType::MODIFIED;
601 else
603 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
604 std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
605 xBox->run();
610 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */