1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sfx2/viewfrm.hxx>
21 #include <vcl/msgbox.hxx>
22 #include <sfx2/dispatch.hxx>
23 #include <sfx2/basedlgs.hxx>
24 #include <IDocumentUndoRedo.hxx>
26 #include <sfx2/app.hxx>
27 #include <swtypes.hxx>
28 #include <swmodule.hxx>
32 #include <chartins.hxx>
33 #include <tablemgr.hxx>
35 #include <swtable.hxx>
37 #include <unochart.hxx>
38 #include <autoedit.hxx>
44 #include <anchoredobject.hxx>
46 #include <comphelper/classids.hxx>
48 #include <cppuhelper/bootstrap.hxx>
49 #include <cppuhelper/component_context.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <com/sun/star/chart2/data/XDataProvider.hpp>
52 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
53 #include <com/sun/star/chart/ChartDataRowSource.hpp>
54 #include <com/sun/star/frame/XComponentLoader.hpp>
55 #include <com/sun/star/lang/XInitialization.hpp>
56 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
57 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
58 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::uno
;
65 Point
SwGetChartDialogPos( const Window
*pParentWin
, const Size
& rDialogSize
, const Rectangle
& rLogicChart
)
67 // !! positioning code according to spepc; similar to Calc fuins2.cxx
71 OSL_ENSURE( pParentWin
, "Window not found" );
74 Rectangle aObjPixel
= pParentWin
->LogicToPixel( rLogicChart
, pParentWin
->GetMapMode() );
75 Rectangle
aObjAbs( pParentWin
->OutputToAbsoluteScreenPixel( aObjPixel
.TopLeft() ),
76 pParentWin
->OutputToAbsoluteScreenPixel( aObjPixel
.BottomRight() ) );
78 Rectangle aDesktop
= pParentWin
->GetDesktopRectPixel();
79 Size aSpace
= pParentWin
->LogicToPixel( Size( 8, 12 ), MAP_APPFONT
);
81 sal_Bool bLayoutRTL
= ::GetActiveView()->GetWrtShell().IsTableRightToLeft();
82 bool bCenterHor
= false;
84 if ( aDesktop
.Bottom() - aObjAbs
.Bottom() >= rDialogSize
.Height() + aSpace
.Height() )
86 // first preference: below the chart
87 aRet
.Y() = aObjAbs
.Bottom() + aSpace
.Height();
90 else if ( aObjAbs
.Top() - aDesktop
.Top() >= rDialogSize
.Height() + aSpace
.Height() )
92 // second preference: above the chart
93 aRet
.Y() = aObjAbs
.Top() - rDialogSize
.Height() - aSpace
.Height();
98 bool bFitLeft
= ( aObjAbs
.Left() - aDesktop
.Left() >= rDialogSize
.Width() + aSpace
.Width() );
99 bool bFitRight
= ( aDesktop
.Right() - aObjAbs
.Right() >= rDialogSize
.Width() + aSpace
.Width() );
101 if ( bFitLeft
|| bFitRight
)
103 // if both fit, prefer right in RTL mode, left otherwise
104 bool bPutRight
= bFitRight
&& ( bLayoutRTL
|| !bFitLeft
);
106 aRet
.X() = aObjAbs
.Right() + aSpace
.Width();
108 aRet
.X() = aObjAbs
.Left() - rDialogSize
.Width() - aSpace
.Width();
111 aRet
.Y() = aObjAbs
.Top() + ( aObjAbs
.GetHeight() - rDialogSize
.Height() ) / 2;
115 // doesn't fit on any edge - put at the bottom of the screen
116 aRet
.Y() = aDesktop
.Bottom() - rDialogSize
.Height();
121 aRet
.X() = aObjAbs
.Left() + ( aObjAbs
.GetWidth() - rDialogSize
.Width() ) / 2;
123 // limit to screen (centering might lead to invalid positions)
124 if ( aRet
.X() + rDialogSize
.Width() - 1 > aDesktop
.Right() )
125 aRet
.X() = aDesktop
.Right() - rDialogSize
.Width() + 1;
126 if ( aRet
.X() < aDesktop
.Left() )
127 aRet
.X() = aDesktop
.Left();
128 if ( aRet
.Y() + rDialogSize
.Height() - 1 > aDesktop
.Bottom() )
129 aRet
.Y() = aDesktop
.Bottom() - rDialogSize
.Height() + 1;
130 if ( aRet
.Y() < aDesktop
.Top() )
131 aRet
.Y() = aDesktop
.Top();
137 void SwInsertChart(Window
* pParent
, SfxBindings
* pBindings
)
141 SwView
*pView
= ::GetActiveView();
143 // get range string of marked data
144 SwWrtShell
&rWrtShell
= pView
->GetWrtShell();
145 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
;
146 uno::Reference
< frame::XModel
> xChartModel
;
147 OUString aRangeString
;
149 if( rWrtShell
.IsCrsrInTbl())
151 if (!rWrtShell
.IsTableMode())
153 // select whole table
154 rWrtShell
.GetView().GetViewFrame()->GetDispatcher()->
155 Execute(FN_TABLE_SELECT_ALL
, SFX_CALLMODE_SYNCHRON
);
157 if( ! rWrtShell
.IsTblComplexForChart())
159 SwFrmFmt
* pTblFmt
= rWrtShell
.GetTableFmt();
160 String aCurrentTblName
= pTblFmt
->GetName();
161 aRangeString
= aCurrentTblName
;
162 aRangeString
+= OUString::valueOf( sal_Unicode('.') );
163 aRangeString
+= rWrtShell
.GetBoxNms();
165 // get table data provider
166 xDataProvider
.set( pView
->GetDocShell()->getIDocumentChartDataProviderAccess()->GetChartDataProvider( true ) );
170 SwFlyFrmFmt
*pFlyFrmFmt
= 0;
171 xChartModel
.set( SwTableFUNC( &rWrtShell
, sal_False
).InsertChart( xDataProvider
, (sal_True
== xDataProvider
.is()), aRangeString
, &pFlyFrmFmt
));
174 //@todo get context from writer if that has one
175 uno::Reference
< uno::XComponentContext
> xContext(
176 ::cppu::defaultBootstrap_InitialComponentContext() );
177 if( xContext
.is() && xChartModel
.is() && xDataProvider
.is())
179 uno::Reference
< lang::XMultiComponentFactory
> xMCF( xContext
->getServiceManager() );
182 uno::Reference
< ui::dialogs::XExecutableDialog
> xDialog(
183 xMCF
->createInstanceWithContext(
184 OUString("com.sun.star.comp.chart2.WizardDialog")
185 , xContext
), uno::UNO_QUERY
);
186 uno::Reference
< lang::XInitialization
> xInit( xDialog
, uno::UNO_QUERY
);
189 uno::Reference
< awt::XWindow
> xDialogParentWindow(0);
191 uno::Sequence
<uno::Any
> aSeq(2);
192 uno::Any
* pArray
= aSeq
.getArray();
193 beans::PropertyValue aParam1
;
194 aParam1
.Name
= OUString("ParentWindow");
195 aParam1
.Value
<<= uno::makeAny(xDialogParentWindow
);
196 beans::PropertyValue aParam2
;
197 aParam2
.Name
= OUString("ChartModel");
198 aParam2
.Value
<<= uno::makeAny(xChartModel
);
199 pArray
[0] <<= uno::makeAny(aParam1
);
200 pArray
[1] <<= uno::makeAny(aParam2
);
201 xInit
->initialize( aSeq
);
203 // try to set the dialog's position so it doesn't hide the chart
204 uno::Reference
< beans::XPropertySet
> xDialogProps( xDialog
, uno::UNO_QUERY
);
205 if ( xDialogProps
.is() )
210 awt::Size aDialogAWTSize
;
211 if( xDialogProps
->getPropertyValue( OUString("Size") )
214 Size
aDialogSize( aDialogAWTSize
.Width
, aDialogAWTSize
.Height
);
215 if ( aDialogSize
.Width() > 0 && aDialogSize
.Height() > 0 )
217 //calculate and set new position
220 aSwRect
= pFlyFrmFmt
->GetAnchoredObj()->GetObjRectWithSpaces();
221 Rectangle
aRect( aSwRect
.SVRect() );
222 Point aDialogPos
= SwGetChartDialogPos( &rWrtShell
.GetView().GetEditWin(), aDialogSize
, aRect
);
223 xDialogProps
->setPropertyValue( OUString("Position"),
224 uno::makeAny( awt::Point(aDialogPos
.getX(),aDialogPos
.getY()) ) );
228 catch (const uno::Exception
&)
230 OSL_FAIL("Chart wizard couldn't be positioned automatically\n" );
234 sal_Int16 nDialogRet
= xDialog
->execute();
235 if( nDialogRet
== ui::dialogs::ExecutableDialogResults::CANCEL
)
238 rWrtShell
.GetIDocumentUndoRedo().ClearRedo();
242 OSL_ENSURE( nDialogRet
== ui::dialogs::ExecutableDialogResults::OK
,
243 "dialog execution failed" );
246 uno::Reference
< lang::XComponent
> xComponent( xDialog
, uno::UNO_QUERY
);
248 xComponent
->dispose();
254 void AutoEdit::KeyInput( const KeyEvent
& rEvt
)
256 sal_uInt16 nCode
= rEvt
.GetKeyCode().GetCode();
257 if( nCode
!= KEY_SPACE
)
258 Edit::KeyInput( rEvt
);
264 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */