Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / basctl / source / dlged / dlged.cxx
blob5588752c4054ab4b52763575b33f6c1a78cb3486
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 .
21 #include <basidesh.hxx>
22 #include <dlged.hxx>
23 #include <dlgedclip.hxx>
24 #include <dlgeddef.hxx>
25 #include <dlgedfac.hxx>
26 #include <dlgedfunc.hxx>
27 #include <dlgedmod.hxx>
28 #include <dlgedobj.hxx>
29 #include <dlgedpage.hxx>
30 #include <dlgedview.hxx>
31 #include <iderdll.hxx>
32 #include <localizationmgr.hxx>
33 #include <baside3.hxx>
35 #include <com/sun/star/awt/Toolkit.hpp>
36 #include <com/sun/star/awt/UnoControlDialog.hpp>
37 #include <com/sun/star/awt/XDialog.hpp>
38 #include <com/sun/star/resource/StringResource.hpp>
39 #include <com/sun/star/util/XCloneable.hpp>
40 #include <com/sun/star/util/NumberFormatsSupplier.hpp>
41 #include <comphelper/types.hxx>
42 #include <sfx2/viewfrm.hxx>
43 #include <svl/itempool.hxx>
44 #include <svx/sdrpaintwindow.hxx>
45 #include <svx/svxids.hrc>
46 #include <toolkit/helper/vclunohelper.hxx>
47 #include <vcl/svapp.hxx>
48 #include <xmlscript/xml_helper.hxx>
49 #include <xmlscript/xmldlg_imexp.hxx>
51 namespace basctl
54 using namespace comphelper;
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::io;
60 static const char aResourceResolverPropName[] = "ResourceResolver";
61 static const char aDecorationPropName[] = "Decoration";
64 // DlgEdHint
67 DlgEdHint::DlgEdHint(Kind eHint)
68 : eKind(eHint)
69 , pDlgEdObj(nullptr)
73 DlgEdHint::DlgEdHint(Kind eHint, DlgEdObj* pObj)
74 : eKind(eHint)
75 , pDlgEdObj(pObj)
79 DlgEdHint::~DlgEdHint()
84 // DlgEditor
87 void DlgEditor::ShowDialog()
89 uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext();
91 // create a dialog
92 uno::Reference< awt::XUnoControlDialog > xDlg = awt::UnoControlDialog::create( xContext );
94 // clone the dialog model
95 uno::Reference< util::XCloneable > xC( m_xUnoControlDialogModel, uno::UNO_QUERY );
96 uno::Reference< util::XCloneable > xNew = xC->createClone();
97 uno::Reference< awt::XControlModel > xDlgMod( xNew, uno::UNO_QUERY );
99 uno::Reference< beans::XPropertySet > xSrcDlgModPropSet( m_xUnoControlDialogModel, uno::UNO_QUERY );
100 uno::Reference< beans::XPropertySet > xNewDlgModPropSet( xDlgMod, uno::UNO_QUERY );
101 if( xNewDlgModPropSet.is() )
103 if( xSrcDlgModPropSet.is() )
107 Any aResourceResolver = xSrcDlgModPropSet->getPropertyValue( aResourceResolverPropName );
108 xNewDlgModPropSet->setPropertyValue( aResourceResolverPropName, aResourceResolver );
110 catch(const UnknownPropertyException& )
112 OSL_FAIL( "DlgEditor::ShowDialog(): No ResourceResolver property" );
116 // Disable decoration
119 bool bDecoration = true;
121 Any aDecorationAny = xSrcDlgModPropSet->getPropertyValue( aDecorationPropName );
122 aDecorationAny >>= bDecoration;
123 if( !bDecoration )
125 xNewDlgModPropSet->setPropertyValue( aDecorationPropName, Any( true ) );
126 xNewDlgModPropSet->setPropertyValue( "Title", Any( OUString() ) );
129 catch(const UnknownPropertyException& )
133 // set the model
134 xDlg->setModel( xDlgMod );
136 // create a peer
137 uno::Reference< awt::XToolkit> xToolkit = awt::Toolkit::create( xContext );
138 xDlg->createPeer( xToolkit, rWindow.GetComponentInterface() );
140 xDlg->execute();
142 // need to cast because of multiple inheritance
143 Reference<awt::XControl>(xDlg)->dispose();
147 bool DlgEditor::UnmarkDialog()
149 SdrObject* pDlgObj = pDlgEdModel->GetPage(0)->GetObj(0);
150 SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
152 bool bWasMarked = pDlgEdView->IsObjMarked( pDlgObj );
154 if( bWasMarked )
155 pDlgEdView->MarkObj( pDlgObj, pPgView, true );
157 return bWasMarked;
161 bool DlgEditor::RemarkDialog()
163 SdrObject* pDlgObj = pDlgEdModel->GetPage(0)->GetObj(0);
164 SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
166 bool bWasMarked = pDlgEdView->IsObjMarked( pDlgObj );
168 if( !bWasMarked )
169 pDlgEdView->MarkObj( pDlgObj, pPgView );
171 return bWasMarked;
175 DlgEditor::DlgEditor (
176 vcl::Window& rWindow_, DialogWindowLayout& rLayout_,
177 css::uno::Reference<css::frame::XModel> const& xModel,
178 css::uno::Reference<css::container::XNameContainer> const & xDialogModel
180 :pHScroll(nullptr)
181 ,pVScroll(nullptr)
182 ,pDlgEdModel(new DlgEdModel())
183 ,pDlgEdPage(new DlgEdPage(*pDlgEdModel))
184 ,m_ClipboardDataFlavors(1)
185 ,m_ClipboardDataFlavorsResource(2)
186 ,pObjFac(new DlgEdFactory(xModel))
187 ,rWindow(rWindow_)
188 ,pFunc(new DlgEdFuncSelect(*this))
189 ,rLayout(rLayout_)
190 ,eMode( DlgEditor::SELECT )
191 ,eActObj( OBJ_DLG_PUSHBUTTON )
192 ,bFirstDraw(false)
193 ,bCreateOK(true)
194 ,bDialogModelChanged(false)
195 ,aMarkIdle("basctl DlgEditor Mark")
196 ,mnPaintGuard(0)
197 ,m_xDocument( xModel )
199 pDlgEdModel->GetItemPool().FreezeIdRanges();
200 pDlgEdView.reset(new DlgEdView(*pDlgEdModel, rWindow_, *this));
201 pDlgEdModel->SetScaleUnit( MapUnit::Map100thMM );
203 SdrLayerAdmin& rAdmin = pDlgEdModel->GetLayerAdmin();
204 rAdmin.NewLayer( rAdmin.GetControlLayerName() );
205 rAdmin.NewLayer( "HiddenLayer" );
207 pDlgEdModel->InsertPage(pDlgEdPage);
209 // set clipboard data flavors
210 m_ClipboardDataFlavors[0].MimeType = "application/vnd.sun.xml.dialog" ;
211 m_ClipboardDataFlavors[0].HumanPresentableName = "Dialog 6.0" ;
212 m_ClipboardDataFlavors[0].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
214 m_ClipboardDataFlavorsResource[0] = m_ClipboardDataFlavors[0];
215 m_ClipboardDataFlavorsResource[1].MimeType = "application/vnd.sun.xml.dialogwithresource" ;
216 m_ClipboardDataFlavorsResource[1].HumanPresentableName = "Dialog 8.0" ;
217 m_ClipboardDataFlavorsResource[1].DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
219 aMarkIdle.SetInvokeHandler( LINK( this, DlgEditor, MarkTimeout ) );
221 rWindow.SetMapMode( MapMode( MapUnit::Map100thMM ) );
222 pDlgEdPage->SetSize( rWindow.PixelToLogic( Size(DLGED_PAGE_WIDTH_MIN, DLGED_PAGE_HEIGHT_MIN) ) );
224 pDlgEdView->ShowSdrPage(pDlgEdView->GetModel()->GetPage(0));
225 pDlgEdView->SetLayerVisible( "HiddenLayer", false );
226 pDlgEdView->SetMoveSnapOnlyTopLeft(true);
227 pDlgEdView->SetWorkArea( tools::Rectangle( Point( 0, 0 ), pDlgEdPage->GetSize() ) );
229 Size aGridSize( 100, 100 ); // 100TH_MM
230 pDlgEdView->SetGridCoarse( aGridSize );
231 pDlgEdView->SetSnapGridWidth(Fraction(aGridSize.Width(), 1), Fraction(aGridSize.Height(), 1));
232 pDlgEdView->SetGridSnap( true );
233 pDlgEdView->SetGridVisible( false );
234 pDlgEdView->SetDragStripes(false);
236 pDlgEdView->SetDesignMode();
238 ::comphelper::disposeComponent( m_xControlContainer );
240 SetDialog(xDialogModel);
244 DlgEditor::~DlgEditor()
246 aMarkIdle.Stop();
248 ::comphelper::disposeComponent( m_xControlContainer );
252 Reference< awt::XControlContainer > const & DlgEditor::GetWindowControlContainer()
254 if (!m_xControlContainer.is())
255 m_xControlContainer = VCLUnoHelper::CreateControlContainer(&rWindow);
256 return m_xControlContainer;
260 void DlgEditor::SetScrollBars( ScrollBar* pHS, ScrollBar* pVS )
262 pHScroll = pHS;
263 pVScroll = pVS;
265 InitScrollBars();
269 void DlgEditor::InitScrollBars()
271 DBG_ASSERT( pHScroll, "DlgEditor::InitScrollBars: no horizontal scroll bar!" );
272 DBG_ASSERT( pVScroll, "DlgEditor::InitScrollBars: no vertical scroll bar!" );
273 if ( !pHScroll || !pVScroll )
274 return;
276 Size aOutSize = rWindow.GetOutputSize();
277 Size aPgSize = pDlgEdPage->GetSize();
279 pHScroll->SetRange( Range( 0, aPgSize.Width() ));
280 pVScroll->SetRange( Range( 0, aPgSize.Height() ));
281 pHScroll->SetVisibleSize( static_cast<sal_uLong>(aOutSize.Width()) );
282 pVScroll->SetVisibleSize( static_cast<sal_uLong>(aOutSize.Height()) );
284 pHScroll->SetLineSize( aOutSize.Width() / 10 );
285 pVScroll->SetLineSize( aOutSize.Height() / 10 );
286 pHScroll->SetPageSize( aOutSize.Width() / 2 );
287 pVScroll->SetPageSize( aOutSize.Height() / 2 );
289 DoScroll();
293 void DlgEditor::DoScroll()
295 if( !pHScroll || !pVScroll )
296 return;
298 MapMode aMap = rWindow.GetMapMode();
299 Point aOrg = aMap.GetOrigin();
301 Size aScrollPos( pHScroll->GetThumbPos(), pVScroll->GetThumbPos() );
302 aScrollPos = rWindow.LogicToPixel( aScrollPos );
303 aScrollPos = rWindow.PixelToLogic( aScrollPos );
305 long nX = aScrollPos.Width() + aOrg.X();
306 long nY = aScrollPos.Height() + aOrg.Y();
308 if( !nX && !nY )
309 return;
311 rWindow.Update();
313 // #i31562#
314 // When scrolling, someone was rescuing the Wallpaper and forced the window scroll to
315 // be done without background refresh. I do not know why, but that causes the repaint
316 // problems. Taking that out.
317 // Wallpaper aOldBackground = rWindow.GetBackground();
318 // rWindow.SetBackground();
320 // #i74769# children should be scrolled
321 rWindow.Scroll( -nX, -nY, ScrollFlags::Children);
322 aMap.SetOrigin( Point( -aScrollPos.Width(), -aScrollPos.Height() ) );
323 rWindow.SetMapMode( aMap );
324 rWindow.Update();
326 DlgEdHint aHint( DlgEdHint::WINDOWSCROLLED );
327 Broadcast( aHint );
331 void DlgEditor::UpdateScrollBars()
333 MapMode aMap = rWindow.GetMapMode();
334 Point aOrg = aMap.GetOrigin();
336 if ( pHScroll )
337 pHScroll->SetThumbPos( -aOrg.X() );
339 if ( pVScroll )
340 pVScroll->SetThumbPos( -aOrg.Y() );
344 void DlgEditor::SetDialog( const uno::Reference< container::XNameContainer >& xUnoControlDialogModel )
346 // set dialog model
347 m_xUnoControlDialogModel = xUnoControlDialogModel;
349 // create dialog form
350 pDlgEdForm = new DlgEdForm(*pDlgEdModel, *this);
351 uno::Reference< awt::XControlModel > xDlgMod( m_xUnoControlDialogModel , uno::UNO_QUERY );
352 pDlgEdForm->SetUnoControlModel(xDlgMod);
353 static_cast<DlgEdPage*>(pDlgEdModel->GetPage(0))->SetDlgEdForm( pDlgEdForm );
354 pDlgEdModel->GetPage(0)->InsertObject( pDlgEdForm );
355 AdjustPageSize();
356 pDlgEdForm->SetRectFromProps();
357 pDlgEdForm->UpdateTabIndices(); // for backward compatibility
358 pDlgEdForm->StartListening();
360 // create controls
361 Reference< css::container::XNameAccess > xNameAcc( m_xUnoControlDialogModel, UNO_QUERY );
362 if ( xNameAcc.is() )
364 // get sequence of control names
365 Sequence< OUString > aNames = xNameAcc->getElementNames();
366 const OUString* pNames = aNames.getConstArray();
367 sal_Int32 nCtrls = aNames.getLength();
369 // create a map of tab indices and control names, sorted by tab index
370 IndexToNameMap aIndexToNameMap;
371 for ( sal_Int32 i = 0; i < nCtrls; ++i )
373 // get name
374 OUString aName( pNames[i] );
376 // get tab index
377 sal_Int16 nTabIndex = -1;
378 Any aCtrl = xNameAcc->getByName( aName );
379 Reference< css::beans::XPropertySet > xPSet;
380 aCtrl >>= xPSet;
381 if ( xPSet.is() )
382 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
384 // insert into map
385 aIndexToNameMap.emplace( nTabIndex, aName );
388 // create controls and insert them into drawing page
389 for (auto const& indexToName : aIndexToNameMap)
391 Any aCtrl = xNameAcc->getByName( indexToName.second );
392 Reference< css::awt::XControlModel > xCtrlModel;
393 aCtrl >>= xCtrlModel;
394 DlgEdObj* pCtrlObj = new DlgEdObj(*pDlgEdModel);
395 pCtrlObj->SetUnoControlModel( xCtrlModel );
396 pCtrlObj->SetDlgEdForm( pDlgEdForm );
397 pDlgEdForm->AddChild( pCtrlObj );
398 pDlgEdModel->GetPage(0)->InsertObject( pCtrlObj );
399 pCtrlObj->SetRectFromProps();
400 pCtrlObj->UpdateStep();
401 pCtrlObj->StartListening();
405 bFirstDraw = true;
407 pDlgEdModel->SetChanged(false);
410 void DlgEditor::ResetDialog ()
412 DlgEdForm* pOldDlgEdForm = pDlgEdForm;
413 DlgEdPage* pPage = static_cast<DlgEdPage*>(pDlgEdModel->GetPage(0));
414 SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
415 bool bWasMarked = pDlgEdView->IsObjMarked( pOldDlgEdForm );
416 pDlgEdView->UnmarkAll();
418 // clear SdrObjects with broadcasting
419 pPage->ClearSdrObjList();
421 pPage->SetDlgEdForm( nullptr );
422 SetDialog( m_xUnoControlDialogModel );
423 if( bWasMarked )
424 pDlgEdView->MarkObj( pDlgEdForm, pPgView );
428 Reference< util::XNumberFormatsSupplier > const & DlgEditor::GetNumberFormatsSupplier()
430 if ( !m_xSupplier.is() )
432 Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
433 Reference< util::XNumberFormatsSupplier > xSupplier( util::NumberFormatsSupplier::createWithDefaultLocale(xContext) );
435 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
436 if ( !m_xSupplier.is() )
438 m_xSupplier = xSupplier;
441 return m_xSupplier;
445 void DlgEditor::MouseButtonDown( const MouseEvent& rMEvt )
447 rWindow.GrabFocus();
448 pFunc->MouseButtonDown( rMEvt );
452 void DlgEditor::MouseButtonUp( const MouseEvent& rMEvt )
454 bool bRet = pFunc->MouseButtonUp( rMEvt );
456 if( eMode == DlgEditor::INSERT )
457 bCreateOK = bRet;
461 void DlgEditor::MouseMove( const MouseEvent& rMEvt )
463 pFunc->MouseMove( rMEvt );
467 bool DlgEditor::KeyInput( const KeyEvent& rKEvt )
469 return pFunc->KeyInput( rKEvt );
473 void DlgEditor::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
475 aPaintRect = rRect;
476 mnPaintGuard++;
478 if (bFirstDraw && rWindow.IsVisible() && (rRenderContext.GetOutputSize() != Size()))
480 bFirstDraw = false;
482 // get property set
483 css::uno::Reference<css::beans::XPropertySet> xPSet(pDlgEdForm->GetUnoControlModel(), css::uno::UNO_QUERY);
485 if (xPSet.is())
487 // get dialog size from properties
488 sal_Int32 nWidth = 0, nHeight = 0;
489 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
490 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
492 if (nWidth == 0 && nHeight == 0)
494 Size aSize = rRenderContext.PixelToLogic( Size( 400, 300 ) );
496 // align with grid
497 Size aGridSize_(long(pDlgEdView->GetSnapGridWidthX()), long(pDlgEdView->GetSnapGridWidthY()));
498 aSize.AdjustWidth( -(aSize.Width() % aGridSize_.Width()) );
499 aSize.AdjustHeight( -(aSize.Height() % aGridSize_.Height()) );
501 Point aPos;
502 Size aOutSize = rRenderContext.GetOutputSize();
503 aPos.setX( (aOutSize.Width()>>1) - (aSize.Width()>>1) );
504 aPos.setY( (aOutSize.Height()>>1) - (aSize.Height()>>1) );
506 // align with grid
507 aPos.AdjustX( -(aPos.X() % aGridSize_.Width()) );
508 aPos.AdjustY( -(aPos.Y() % aGridSize_.Height()) );
510 // don't put in the corner
511 Point aMinPos = rRenderContext.PixelToLogic( Point( 30, 20 ) );
512 if( (aPos.X() < aMinPos.X()) || (aPos.Y() < aMinPos.Y()) )
514 aPos = aMinPos;
515 aPos.AdjustX( -(aPos.X() % aGridSize_.Width()) );
516 aPos.AdjustY( -(aPos.Y() % aGridSize_.Height()) );
519 // set dialog position and size
520 pDlgEdForm->SetSnapRect( tools::Rectangle( aPos, aSize ) );
521 pDlgEdForm->EndListening(false);
522 pDlgEdForm->SetPropsFromRect();
523 pDlgEdForm->GetDlgEditor().SetDialogModelChanged();
524 pDlgEdForm->StartListening();
526 // set position and size of controls
527 if (const size_t nObjCount = pDlgEdPage->GetObjCount())
529 for (size_t i = 0 ; i < nObjCount ; ++i)
531 if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pDlgEdPage->GetObj(i)))
533 if (!dynamic_cast<DlgEdForm*>(pDlgEdObj))
535 pDlgEdObj->SetRectFromProps();
544 // repaint, get PageView and prepare Region
545 SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
546 const vcl::Region aPaintRectRegion(aPaintRect);
548 // #i74769#
549 SdrPaintWindow* pTargetPaintWindow = nullptr;
551 // mark repaint start
552 if (pPgView)
554 pTargetPaintWindow = pPgView->GetView().BeginDrawLayers(&rRenderContext, aPaintRectRegion);
555 OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
558 // draw background self using wallpaper
559 // #i79128# ...and use correct OutDev for that
560 if (pTargetPaintWindow)
562 OutputDevice& rTargetOutDev = pTargetPaintWindow->GetTargetOutputDevice();
563 rTargetOutDev.DrawWallpaper(aPaintRect, Wallpaper(COL_WHITE));
566 // do paint (unbuffered) and mark repaint end
567 if (pPgView)
569 // paint of control layer is done in EndDrawLayers anyway...
570 pPgView->GetView().EndDrawLayers(*pTargetPaintWindow, true);
573 mnPaintGuard--;
577 IMPL_LINK_NOARG(DlgEditor, MarkTimeout, Timer *, void)
579 rLayout.UpdatePropertyBrowser();
583 void DlgEditor::SetMode (Mode eNewMode )
585 if ( eNewMode != eMode )
587 if ( eNewMode == INSERT )
588 pFunc.reset(new DlgEdFuncInsert(*this));
589 else
590 pFunc.reset(new DlgEdFuncSelect(*this));
592 if ( eNewMode == READONLY )
593 pDlgEdModel->SetReadOnly( true );
594 else
595 pDlgEdModel->SetReadOnly( false );
598 if ( eNewMode == TEST )
599 ShowDialog();
601 eMode = eNewMode;
605 void DlgEditor::SetInsertObj( sal_uInt16 eObj )
607 eActObj = eObj;
609 pDlgEdView->SetCurrentObj( eActObj, SdrInventor::BasicDialog );
612 void DlgEditor::CreateDefaultObject()
614 // create object by factory
615 SdrObject* pObj = SdrObjFactory::MakeNewObject(
616 *pDlgEdModel,
617 pDlgEdView->GetCurrentObjInventor(),
618 pDlgEdView->GetCurrentObjIdentifier(),
619 pDlgEdPage);
621 if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pObj))
623 // set position and size
624 Size aSize = rWindow.PixelToLogic( Size( 96, 24 ) );
625 Point aPoint = pDlgEdForm->GetSnapRect().Center();
626 aPoint.AdjustX( -(aSize.Width() / 2) );
627 aPoint.AdjustY( -(aSize.Height() / 2) );
628 pDlgEdObj->SetSnapRect( tools::Rectangle( aPoint, aSize ) );
630 // set default property values
631 pDlgEdObj->SetDefaults();
633 // insert object into drawing page
634 SdrPageView* pPageView = pDlgEdView->GetSdrPageView();
635 pDlgEdView->InsertObjectAtView( pDlgEdObj, *pPageView);
637 // start listening
638 pDlgEdObj->StartListening();
643 void DlgEditor::Cut()
645 Copy();
646 Delete();
650 void implCopyStreamToByteSequence( const Reference< XInputStream >& xStream,
651 Sequence< sal_Int8 >& bytes )
653 xStream->readBytes( bytes, xStream->available() );
654 for (;;)
656 Sequence< sal_Int8 > readBytes;
657 sal_Int32 nRead = xStream->readBytes( readBytes, 1024 );
658 if (! nRead)
659 break;
661 sal_Int32 nPos = bytes.getLength();
662 bytes.realloc( nPos + nRead );
663 memcpy( bytes.getArray() + nPos, readBytes.getConstArray(), static_cast<sal_uInt32>(nRead) );
667 void DlgEditor::Copy()
669 if( !pDlgEdView->AreObjectsMarked() )
670 return;
672 // stop all drawing actions
673 pDlgEdView->BrkAction();
675 // create an empty clipboard dialog model
676 Reference< util::XCloneable > xClone( m_xUnoControlDialogModel, UNO_QUERY );
677 Reference< util::XCloneable > xNewClone = xClone->createClone();
678 Reference< container::XNameContainer > xClipDialogModel( xNewClone, UNO_QUERY );
680 Reference< container::XNameAccess > xNAcc( xClipDialogModel, UNO_QUERY );
681 if ( xNAcc.is() )
683 Sequence< OUString > aNames = xNAcc->getElementNames();
684 const OUString* pNames = aNames.getConstArray();
685 sal_uInt32 nCtrls = aNames.getLength();
687 for ( sal_uInt32 n = 0; n < nCtrls; n++ )
689 xClipDialogModel->removeByName( pNames[n] );
693 // insert control models of marked objects into clipboard dialog model
694 const size_t nMark = pDlgEdView->GetMarkedObjectList().GetMarkCount();
695 for( size_t i = 0; i < nMark; ++i )
697 SdrObject* pObj = pDlgEdView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
698 DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pObj);
700 if (pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj))
702 OUString aName;
703 Reference< beans::XPropertySet > xMarkPSet(pDlgEdObj->GetUnoControlModel(), uno::UNO_QUERY);
704 if (xMarkPSet.is())
706 xMarkPSet->getPropertyValue( DLGED_PROP_NAME ) >>= aName;
709 Reference< container::XNameAccess > xNameAcc(m_xUnoControlDialogModel, UNO_QUERY );
710 if ( xNameAcc.is() && xNameAcc->hasByName(aName) )
712 Any aCtrl = xNameAcc->getByName( aName );
714 // clone control model
715 Reference< util::XCloneable > xCtrl;
716 aCtrl >>= xCtrl;
717 Reference< util::XCloneable > xNewCtrl = xCtrl->createClone();
718 Any aNewCtrl;
719 aNewCtrl <<= xNewCtrl;
721 if (xClipDialogModel.is())
722 xClipDialogModel->insertByName( aName , aNewCtrl );
727 // export clipboard dialog model to xml
728 Reference< XComponentContext > xContext(
729 comphelper::getProcessComponentContext() );
730 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xClipDialogModel, xContext, m_xDocument );
731 Reference< XInputStream > xStream( xISP->createInputStream() );
732 Sequence< sal_Int8 > DialogModelBytes;
733 implCopyStreamToByteSequence( xStream, DialogModelBytes );
734 xStream->closeInput();
736 // set clipboard content
737 Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow().GetClipboard();
738 if ( xClipboard.is() )
740 // With resource?
741 uno::Reference< beans::XPropertySet > xDialogModelPropSet( m_xUnoControlDialogModel, uno::UNO_QUERY );
742 uno::Reference< resource::XStringResourcePersistence > xStringResourcePersistence;
743 if( xDialogModelPropSet.is() )
747 Any aResourceResolver = xDialogModelPropSet->getPropertyValue( aResourceResolverPropName );
748 aResourceResolver >>= xStringResourcePersistence;
750 catch(const UnknownPropertyException& )
754 DlgEdTransferableImpl* pTrans = nullptr;
755 if( xStringResourcePersistence.is() )
757 // With resource, support old and new format
759 // Export xClipDialogModel another time with ids replaced by current language string
760 uno::Reference< resource::XStringResourceManager >
761 xStringResourceManager( xStringResourcePersistence, uno::UNO_QUERY );
762 LocalizationMgr::resetResourceForDialog( xClipDialogModel, xStringResourceManager );
763 Reference< XInputStreamProvider > xISP2 = ::xmlscript::exportDialogModel( xClipDialogModel, xContext, m_xDocument );
764 Reference< XInputStream > xStream2( xISP2->createInputStream() );
765 Sequence< sal_Int8 > NoResourceDialogModelBytes;
766 implCopyStreamToByteSequence( xStream2, NoResourceDialogModelBytes );
767 xStream2->closeInput();
769 // Old format contains dialog with replaced ids
770 Sequence< Any > aSeqData(2);
771 Any aNoResourceDialogModelBytesAny;
772 aNoResourceDialogModelBytesAny <<= NoResourceDialogModelBytes;
773 aSeqData[0] = aNoResourceDialogModelBytesAny;
775 // New format contains dialog and resource
776 Sequence< sal_Int8 > aResData = xStringResourcePersistence->exportBinary();
778 // Create sequence for combined dialog and resource
779 sal_Int32 nDialogDataLen = DialogModelBytes.getLength();
780 sal_Int32 nResDataLen = aResData.getLength();
782 // Combined data = 4 Bytes 32Bit Offset to begin of resource data, lowest byte first
783 // + nDialogDataLen bytes dialog data + nResDataLen resource data
784 sal_Int32 nTotalLen = 4 + nDialogDataLen + nResDataLen;
785 sal_Int32 nResOffset = 4 + nDialogDataLen;
786 Sequence< sal_Int8 > aCombinedData( nTotalLen );
787 sal_Int8* pCombinedData = aCombinedData.getArray();
789 // Write offset
790 sal_Int32 n = nResOffset;
791 for( sal_Int16 i = 0 ; i < 4 ; i++ )
793 pCombinedData[i] = sal_Int8( n & 0xff );
794 n >>= 8;
796 memcpy( pCombinedData + 4, DialogModelBytes.getConstArray(), nDialogDataLen );
797 memcpy( pCombinedData + nResOffset, aResData.getConstArray(), nResDataLen );
799 aSeqData[1] <<= aCombinedData;
801 pTrans = new DlgEdTransferableImpl( m_ClipboardDataFlavorsResource, aSeqData );
803 else
805 // No resource, support only old format
806 Sequence< Any > aSeqData(1);
807 Any aDialogModelBytesAny;
808 aDialogModelBytesAny <<= DialogModelBytes;
809 aSeqData[0] = aDialogModelBytesAny;
810 pTrans = new DlgEdTransferableImpl( m_ClipboardDataFlavors , aSeqData );
812 SolarMutexReleaser aReleaser;
813 xClipboard->setContents( pTrans , pTrans );
818 void DlgEditor::Paste()
820 // stop all drawing actions
821 pDlgEdView->BrkAction();
823 // unmark all objects
824 pDlgEdView->UnmarkAll();
826 // get clipboard
827 Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow().GetClipboard();
828 if ( xClipboard.is() )
830 Reference< datatransfer::XTransferable > xTransf;
832 SolarMutexReleaser aReleaser;
833 // get clipboard content
834 xTransf = xClipboard->getContents();
836 if ( xTransf.is() )
838 // Is target dialog (library) localized?
839 uno::Reference< beans::XPropertySet > xDialogModelPropSet( m_xUnoControlDialogModel, uno::UNO_QUERY );
840 uno::Reference< resource::XStringResourceManager > xStringResourceManager;
841 if( xDialogModelPropSet.is() )
845 Any aResourceResolver = xDialogModelPropSet->getPropertyValue( aResourceResolverPropName );
846 aResourceResolver >>= xStringResourceManager;
848 catch(const UnknownPropertyException& )
851 bool bLocalized = false;
852 if( xStringResourceManager.is() )
853 bLocalized = ( xStringResourceManager->getLocales().getLength() > 0 );
855 if ( xTransf->isDataFlavorSupported( m_ClipboardDataFlavors[0] ) )
857 // create clipboard dialog model from xml
858 Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
859 Reference< container::XNameContainer > xClipDialogModel( xContext->getServiceManager()->createInstanceWithContext(
860 "com.sun.star.awt.UnoControlDialogModel", xContext ), uno::UNO_QUERY );
862 bool bSourceIsLocalized = false;
863 Sequence< sal_Int8 > DialogModelBytes;
864 Sequence< sal_Int8 > aResData;
865 if( bLocalized && xTransf->isDataFlavorSupported( m_ClipboardDataFlavorsResource[1] ) )
867 bSourceIsLocalized = true;
869 Any aCombinedDataAny = xTransf->getTransferData( m_ClipboardDataFlavorsResource[1] );
870 Sequence< sal_Int8 > aCombinedData;
871 aCombinedDataAny >>= aCombinedData;
872 const sal_Int8* pCombinedData = aCombinedData.getConstArray();
874 sal_Int32 nTotalLen = aCombinedData.getLength();
876 // Reading offset
877 sal_Int32 nResOffset = 0;
878 sal_Int32 nFactor = 1;
879 for( sal_Int16 i = 0; i < 4; i++ )
881 nResOffset += nFactor * sal_uInt8( pCombinedData[i] );
882 nFactor *= 256;
885 sal_Int32 nResDataLen = nTotalLen - nResOffset;
886 sal_Int32 nDialogDataLen = nTotalLen - nResDataLen - 4;
888 DialogModelBytes.realloc( nDialogDataLen );
889 memcpy( DialogModelBytes.getArray(), pCombinedData + 4, nDialogDataLen );
891 aResData.realloc( nResDataLen );
892 memcpy( aResData.getArray(), pCombinedData + nResOffset, nResDataLen );
894 else
896 Any aAny = xTransf->getTransferData( m_ClipboardDataFlavors[0] );
897 aAny >>= DialogModelBytes;
900 if ( xClipDialogModel.is() )
902 Reference<XInputStream> xIn = ::xmlscript::createInputStream( DialogModelBytes.getConstArray(), DialogModelBytes.getLength() );
903 ::xmlscript::importDialogModel( xIn , xClipDialogModel, xContext, m_xDocument );
906 // get control models from clipboard dialog model
907 Reference< css::container::XNameAccess > xNameAcc( xClipDialogModel, UNO_QUERY );
908 if ( xNameAcc.is() )
910 Sequence< OUString > aNames = xNameAcc->getElementNames();
911 const OUString* pNames = aNames.getConstArray();
912 sal_uInt32 nCtrls = aNames.getLength();
914 Reference< resource::XStringResourcePersistence > xStringResourcePersistence;
915 if( nCtrls > 0 && bSourceIsLocalized )
917 xStringResourcePersistence = css::resource::StringResource::create( getProcessComponentContext() );
918 xStringResourcePersistence->importBinary( aResData );
920 for( sal_uInt32 n = 0; n < nCtrls; n++ )
922 Any aA = xNameAcc->getByName( pNames[n] );
923 Reference< css::awt::XControlModel > xCM;
924 aA >>= xCM;
926 // clone the control model
927 Reference< util::XCloneable > xClone( xCM, uno::UNO_QUERY );
928 Reference< awt::XControlModel > xCtrlModel( xClone->createClone(), uno::UNO_QUERY );
930 DlgEdObj* pCtrlObj = new DlgEdObj(*pDlgEdModel);
931 pCtrlObj->SetDlgEdForm(pDlgEdForm); // set parent form
932 pDlgEdForm->AddChild(pCtrlObj); // add child to parent form
933 pCtrlObj->SetUnoControlModel( xCtrlModel ); // set control model
935 // set new name
936 OUString aOUniqueName( pCtrlObj->GetUniqueName() );
937 Reference< beans::XPropertySet > xPSet( xCtrlModel , UNO_QUERY );
938 xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOUniqueName) );
940 // set tabindex
941 Reference< container::XNameAccess > xNA( m_xUnoControlDialogModel , UNO_QUERY );
942 Sequence< OUString > aNames_ = xNA->getElementNames();
943 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(aNames_.getLength())) );
945 if( bLocalized )
947 Any aControlAny;
948 aControlAny <<= xCtrlModel;
949 if( bSourceIsLocalized && xStringResourcePersistence.is() )
951 Reference< resource::XStringResourceResolver >
952 xSourceStringResolver( xStringResourcePersistence, UNO_QUERY );
953 LocalizationMgr::copyResourcesForPastedEditorObject( this,
954 aControlAny, aOUniqueName, xSourceStringResolver );
956 else
958 LocalizationMgr::setControlResourceIDsForNewEditorObject
959 ( this, aControlAny, aOUniqueName );
963 // insert control model in editor dialog model
964 Any aCtrlModel;
965 aCtrlModel <<= xCtrlModel;
966 m_xUnoControlDialogModel->insertByName( aOUniqueName , aCtrlModel );
968 // insert object into drawing page
969 pDlgEdModel->GetPage(0)->InsertObject( pCtrlObj );
970 pCtrlObj->SetRectFromProps();
971 pCtrlObj->UpdateStep();
972 pDlgEdForm->UpdateTabOrderAndGroups();
973 pCtrlObj->StartListening(); // start listening
975 // mark object
976 SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
977 pDlgEdView->MarkObj( pCtrlObj, pPgView, false, true);
980 // center marked objects in dialog editor form
981 Point aMarkCenter = pDlgEdView->GetMarkedObjRect().Center();
982 Point aFormCenter = pDlgEdForm->GetSnapRect().Center();
983 Point aPoint = aFormCenter - aMarkCenter;
984 Size aSize( aPoint.X() , aPoint.Y() );
985 pDlgEdView->MoveMarkedObj( aSize ); // update of control model properties (position + size) in NbcMove
986 pDlgEdView->MarkListHasChanged();
988 // dialog model changed
989 SetDialogModelChanged();
997 void DlgEditor::Delete()
999 if( !pDlgEdView->AreObjectsMarked() )
1000 return;
1002 // remove control models of marked objects from dialog model
1003 const size_t nMark = pDlgEdView->GetMarkedObjectList().GetMarkCount();
1005 for( size_t i = 0; i < nMark; ++i )
1007 SdrObject* pObj = pDlgEdView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj();
1008 DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pObj);
1010 if ( pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj) )
1012 // get name from property
1013 OUString aName;
1014 uno::Reference< beans::XPropertySet > xPSet(pDlgEdObj->GetUnoControlModel(), uno::UNO_QUERY);
1015 if (xPSet.is())
1017 xPSet->getPropertyValue( DLGED_PROP_NAME ) >>= aName;
1020 // remove control from dialog model
1021 Reference< css::container::XNameAccess > xNameAcc(pDlgEdObj->GetDlgEdForm()->GetUnoControlModel(), UNO_QUERY );
1022 if ( xNameAcc.is() && xNameAcc->hasByName(aName) )
1024 Reference< css::container::XNameContainer > xCont(xNameAcc, UNO_QUERY );
1025 if ( xCont.is() )
1027 if( xCont->hasByName( aName ) )
1029 Any aAny = xCont->getByName( aName );
1030 LocalizationMgr::deleteControlResourceIDsForDeletedEditorObject( this, aAny, aName );
1032 xCont->removeByName( aName );
1036 // remove child from parent form
1037 pDlgEdForm->RemoveChild( pDlgEdObj );
1041 // update tab indices
1042 pDlgEdForm->UpdateTabIndices();
1044 pDlgEdView->BrkAction();
1046 bool const bDlgMarked = UnmarkDialog();
1047 pDlgEdView->DeleteMarked();
1048 if( bDlgMarked )
1049 RemarkDialog();
1053 bool DlgEditor::IsPasteAllowed()
1055 // get clipboard
1056 Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow().GetClipboard();
1057 if ( xClipboard.is() )
1059 Reference< datatransfer::XTransferable > xTransf;
1061 SolarMutexReleaser aReleaser;
1062 // get clipboard content
1063 xTransf = xClipboard->getContents();
1065 if (xTransf.is())
1066 return xTransf->isDataFlavorSupported(m_ClipboardDataFlavors[0]);
1068 return false;
1072 void DlgEditor::ShowProperties()
1074 rLayout.ShowPropertyBrowser();
1078 void DlgEditor::UpdatePropertyBrowserDelayed()
1080 aMarkIdle.Start();
1084 bool DlgEditor::IsModified() const
1086 return pDlgEdModel->IsChanged() || bDialogModelChanged;
1090 void DlgEditor::ClearModifyFlag()
1092 pDlgEdModel->SetChanged(false);
1093 bDialogModelChanged = false;
1097 namespace Print
1099 long const nLeftMargin = 1700;
1100 long const nRightMargin = 900;
1101 long const nTopMargin = 2000;
1102 long const nBottomMargin = 1000;
1103 long const nBorder = 300;
1106 void lcl_PrintHeader( Printer* pPrinter, const OUString& rTitle ) // not working yet
1109 pPrinter->Push();
1111 Size const aSz = pPrinter->GetOutputSize();
1113 pPrinter->SetLineColor( COL_BLACK );
1114 pPrinter->SetFillColor();
1116 vcl::Font aFont( pPrinter->GetFont() );
1117 aFont.SetWeight( WEIGHT_BOLD );
1118 aFont.SetAlignment( ALIGN_BOTTOM );
1119 pPrinter->SetFont( aFont );
1121 long const nFontHeight = pPrinter->GetTextHeight();
1123 // 1st border => line, 2+3 border = free space
1124 long const nYTop = Print::nTopMargin - 3*Print::nBorder - nFontHeight;
1126 long const nXLeft = Print::nLeftMargin - Print::nBorder;
1127 long const nXRight = aSz.Width() - Print::nRightMargin + Print::nBorder;
1129 pPrinter->DrawRect(tools::Rectangle(
1130 Point(nXLeft, nYTop),
1131 Size(nXRight - nXLeft, aSz.Height() - nYTop - Print::nBottomMargin + Print::nBorder)
1134 long nY = Print::nTopMargin - 2*Print::nBorder;
1135 Point aPos(Print::nLeftMargin, nY);
1136 pPrinter->DrawText( aPos, rTitle );
1138 nY = Print::nTopMargin - Print::nBorder;
1139 pPrinter->DrawLine( Point( nXLeft, nY ), Point( nXRight, nY ) );
1141 pPrinter->Pop();
1145 void DlgEditor::printPage( sal_Int32 nPage, Printer* pPrinter, const OUString& rTitle )
1147 if( nPage == 0 )
1148 Print( pPrinter, rTitle );
1152 void DlgEditor::Print( Printer* pPrinter, const OUString& rTitle ) // not working yet
1154 MapMode aOldMap( pPrinter->GetMapMode());
1155 vcl::Font aOldFont( pPrinter->GetFont() );
1157 MapMode aMap( MapUnit::Map100thMM );
1158 pPrinter->SetMapMode( aMap );
1159 vcl::Font aFont;
1160 aFont.SetAlignment( ALIGN_BOTTOM );
1161 aFont.SetFontSize( Size( 0, 360 ));
1162 pPrinter->SetFont( aFont );
1164 Size aPaperSz = pPrinter->GetOutputSize();
1165 aPaperSz.AdjustWidth( -(Print::nLeftMargin + Print::nRightMargin) );
1166 aPaperSz.AdjustHeight( -(Print::nTopMargin + Print::nBottomMargin) );
1168 lcl_PrintHeader( pPrinter, rTitle );
1170 Bitmap aDlg;
1171 Size aBmpSz( pPrinter->PixelToLogic( aDlg.GetSizePixel() ) );
1172 double nPaperSzWidth = aPaperSz.Width();
1173 double nPaperSzHeight = aPaperSz.Height();
1174 double nBmpSzWidth = aBmpSz.Width();
1175 double nBmpSzHeight = aBmpSz.Height();
1176 double nScaleX = (nPaperSzWidth / nBmpSzWidth );
1177 double nScaleY = (nPaperSzHeight / nBmpSzHeight );
1179 Size aOutputSz;
1180 if( nBmpSzHeight * nScaleX <= nPaperSzHeight )
1182 aOutputSz.setWidth( static_cast<long>(nBmpSzWidth * nScaleX) );
1183 aOutputSz.setHeight( static_cast<long>(nBmpSzHeight * nScaleX) );
1185 else
1187 aOutputSz.setWidth( static_cast<long>(nBmpSzWidth * nScaleY) );
1188 aOutputSz.setHeight( static_cast<long>(nBmpSzHeight * nScaleY) );
1191 Point aPosOffs(
1192 (aPaperSz.Width() / 2) - (aOutputSz.Width() / 2),
1193 (aPaperSz.Height()/ 2) - (aOutputSz.Height() / 2));
1195 aPosOffs.AdjustX(Print::nLeftMargin );
1196 aPosOffs.AdjustY(Print::nTopMargin );
1198 pPrinter->DrawBitmap( aPosOffs, aOutputSz, aDlg );
1200 pPrinter->SetMapMode( aOldMap );
1201 pPrinter->SetFont( aOldFont );
1205 bool DlgEditor::AdjustPageSize()
1207 bool bAdjustedPageSize = false;
1208 Reference< beans::XPropertySet > xPSet( m_xUnoControlDialogModel, UNO_QUERY );
1209 if ( xPSet.is() )
1211 sal_Int32 nFormXIn = 0, nFormYIn = 0, nFormWidthIn = 0, nFormHeightIn = 0;
1212 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nFormXIn;
1213 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nFormYIn;
1214 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nFormWidthIn;
1215 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nFormHeightIn;
1217 sal_Int32 nFormX, nFormY, nFormWidth, nFormHeight;
1218 if ( pDlgEdForm && pDlgEdForm->TransformFormToSdrCoordinates( nFormXIn, nFormYIn, nFormWidthIn, nFormHeightIn, nFormX, nFormY, nFormWidth, nFormHeight ) )
1220 Size aPageSizeDelta( 400, 300 );
1221 aPageSizeDelta = rWindow.PixelToLogic( aPageSizeDelta, MapMode( MapUnit::Map100thMM ) );
1223 sal_Int32 nNewPageWidth = nFormX + nFormWidth + aPageSizeDelta.Width();
1224 sal_Int32 nNewPageHeight = nFormY + nFormHeight + aPageSizeDelta.Height();
1226 Size aPageSizeMin( DLGED_PAGE_WIDTH_MIN, DLGED_PAGE_HEIGHT_MIN );
1227 aPageSizeMin = rWindow.PixelToLogic( aPageSizeMin, MapMode( MapUnit::Map100thMM ) );
1228 sal_Int32 nPageWidthMin = aPageSizeMin.Width();
1229 sal_Int32 nPageHeightMin = aPageSizeMin.Height();
1231 if ( nNewPageWidth < nPageWidthMin )
1232 nNewPageWidth = nPageWidthMin;
1234 if ( nNewPageHeight < nPageHeightMin )
1235 nNewPageHeight = nPageHeightMin;
1237 if ( pDlgEdPage )
1239 Size aPageSize = pDlgEdPage->GetSize();
1240 if ( nNewPageWidth != aPageSize.Width() || nNewPageHeight != aPageSize.Height() )
1242 Size aNewPageSize( nNewPageWidth, nNewPageHeight );
1243 pDlgEdPage->SetSize( aNewPageSize );
1244 pDlgEdView->SetWorkArea( tools::Rectangle( Point( 0, 0 ), aNewPageSize ) );
1245 bAdjustedPageSize = true;
1251 return bAdjustedPageSize;
1255 } // namespace basctl
1257 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */