Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
21 : #include <com/sun/star/embed/Aspects.hpp>
22 : #include <com/sun/star/beans/XPropertySet.hpp>
23 :
24 : //------------------------------------------------------------------------
25 :
26 : #include <toolkit/helper/vclunohelper.hxx>
27 : #include <sot/exchange.hxx>
28 : #include <svl/globalnameitem.hxx>
29 : #include <sfx2/viewfrm.hxx>
30 : #include <sfx2/docfile.hxx>
31 : #include <svl/stritem.hxx>
32 : #include <svx/svdoole2.hxx>
33 : #include <svx/pfiledlg.hxx>
34 : #include <tools/urlobj.hxx>
35 : #include <vcl/msgbox.hxx>
36 : #include <svl/urihelper.hxx>
37 : #include <unotools/moduleoptions.hxx>
38 : #include <svtools/insdlg.hxx>
39 : #include <svtools/soerr.hxx>
40 : #include <svx/svxdlg.hxx>
41 : #include <sot/clsids.hxx>
42 : #include <svx/svdpagv.hxx>
43 : #include <svx/svdpage.hxx>
44 : #include <svx/svdundo.hxx>
45 : #include <sfx2/msgpool.hxx>
46 : #include <scmod.hxx>
47 :
48 : // BM/IHA --
49 : #include <cppuhelper/component_context.hxx>
50 : #include <comphelper/processfactory.hxx>
51 : #include <comphelper/storagehelper.hxx>
52 : #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
53 : #include <com/sun/star/frame/XComponentLoader.hpp>
54 : #include <com/sun/star/beans/PropertyValue.hpp>
55 : #include <com/sun/star/chart2/data/XDataProvider.hpp>
56 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
57 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
58 : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
59 : #include <com/sun/star/lang/XInitialization.hpp>
60 : #include <com/sun/star/frame/XModel.hpp>
61 : #include <com/sun/star/chart/ChartDataRowSource.hpp>
62 : #include <cppuhelper/bootstrap.hxx>
63 :
64 : using namespace ::com::sun::star;
65 : // BM/IHA --
66 :
67 : // erAck
68 : #include "chart2uno.hxx"
69 : // erAck
70 :
71 : #include "fuinsert.hxx"
72 : #include "tabvwsh.hxx"
73 : #include "sc.hrc"
74 : #include "chartarr.hxx"
75 : #include "docsh.hxx"
76 : #include "document.hxx"
77 : #include "undotab.hxx"
78 : #include "chartlis.hxx"
79 : #include "uiitems.hxx"
80 : #include "globstr.hrc"
81 : #include "drawview.hxx"
82 : #include "markdata.hxx"
83 :
84 : extern SdrObject* pSkipPaintObj; // output.cxx - dieses Objekt nicht zeichnen
85 :
86 : namespace {
87 :
88 0 : void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScViewData* pViewData,
89 : const rtl::OUString& rRangeParam )
90 : {
91 0 : ScDocShell* pDocShell = pViewData->GetDocShell();
92 0 : ScDocument* pScDoc = pDocShell->GetDocument();
93 :
94 0 : rtl::OUString aRangeString( rRangeParam );
95 0 : if ( aRangeString.isEmpty() )
96 : {
97 0 : SCCOL nCol1 = 0;
98 0 : SCROW nRow1 = 0;
99 0 : SCTAB nTab1 = 0;
100 0 : SCCOL nCol2 = 0;
101 0 : SCROW nRow2 = 0;
102 0 : SCTAB nTab2 = 0;
103 :
104 0 : ScMarkData& rMark = pViewData->GetMarkData();
105 0 : if ( !rMark.IsMarked() )
106 0 : pViewData->GetView()->MarkDataArea( true );
107 :
108 0 : if ( pViewData->GetSimpleArea( nCol1,nRow1,nTab1, nCol2,nRow2,nTab2 ) == SC_MARK_SIMPLE )
109 : {
110 0 : PutInOrder( nCol1, nCol2 );
111 0 : PutInOrder( nRow1, nRow2 );
112 0 : if ( nCol2>nCol1 || nRow2>nRow1 )
113 : {
114 0 : ScDocument* pDoc = pViewData->GetDocument();
115 0 : pDoc->LimitChartArea( nTab1, nCol1,nRow1, nCol2,nRow2 );
116 :
117 0 : ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
118 0 : aRange.Format( aRangeString, SCR_ABS_3D, pScDoc );
119 : }
120 : }
121 : }
122 :
123 0 : if ( !aRangeString.isEmpty() )
124 : {
125 : // connect to Calc data (if no range string, leave chart alone, with its own data)
126 :
127 0 : uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
128 0 : uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
129 0 : if( xCompSupp.is())
130 0 : xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
131 : OSL_ASSERT( xReceiver.is());
132 0 : if( xReceiver.is() )
133 : {
134 0 : uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( pScDoc );
135 0 : xReceiver->attachDataProvider( xDataProvider );
136 :
137 0 : uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY );
138 0 : xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
139 :
140 : // Same behavior as with old chart: Always assume data series in columns
141 0 : chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
142 0 : bool bHasCategories = false;
143 0 : bool bFirstCellAsLabel = false;
144 :
145 : // use ScChartPositioner to auto-detect column/row headers (like ScChartArray in old version)
146 0 : ScRangeListRef aRangeListRef( new ScRangeList );
147 0 : aRangeListRef->Parse( aRangeString, pScDoc, SCA_VALID, pScDoc->GetAddressConvention() );
148 0 : if ( !aRangeListRef->empty() )
149 : {
150 0 : pScDoc->LimitChartIfAll( aRangeListRef ); // limit whole columns/rows to used area
151 :
152 : // update string from modified ranges. The ranges must be in the current formula syntax.
153 0 : String aTmpStr;
154 0 : aRangeListRef->Format( aTmpStr, SCR_ABS_3D, pScDoc, pScDoc->GetAddressConvention() );
155 0 : aRangeString = aTmpStr;
156 :
157 0 : ScChartPositioner aChartPositioner( pScDoc, aRangeListRef );
158 0 : const ScChartPositionMap* pPositionMap( aChartPositioner.GetPositionMap() );
159 0 : if( pPositionMap )
160 : {
161 0 : SCSIZE nRowCount = pPositionMap->GetRowCount();
162 0 : if( 1==nRowCount )
163 0 : eDataRowSource = chart::ChartDataRowSource_ROWS;
164 : }
165 0 : if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
166 : {
167 0 : bHasCategories = aChartPositioner.HasRowHeaders();
168 0 : bFirstCellAsLabel = aChartPositioner.HasColHeaders();
169 : }
170 : else // in case the default is changed
171 : {
172 0 : bHasCategories = aChartPositioner.HasColHeaders();
173 0 : bFirstCellAsLabel = aChartPositioner.HasRowHeaders();
174 0 : }
175 : }
176 :
177 0 : uno::Sequence< beans::PropertyValue > aArgs( 4 );
178 0 : aArgs[0] = beans::PropertyValue(
179 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellRangeRepresentation")), -1,
180 0 : uno::makeAny( aRangeString ), beans::PropertyState_DIRECT_VALUE );
181 0 : aArgs[1] = beans::PropertyValue(
182 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasCategories")), -1,
183 0 : uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
184 0 : aArgs[2] = beans::PropertyValue(
185 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstCellAsLabel")), -1,
186 0 : uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
187 0 : aArgs[3] = beans::PropertyValue(
188 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataRowSource")), -1,
189 0 : uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE );
190 0 : xReceiver->setArguments( aArgs );
191 :
192 : // don't create chart listener here (range may be modified in chart dialog)
193 0 : }
194 0 : }
195 0 : }
196 :
197 : }
198 :
199 : /*************************************************************************
200 : |*
201 : |* FuInsertOLE::Konstruktor
202 : |*
203 : \************************************************************************/
204 :
205 0 : FuInsertOLE::FuInsertOLE(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
206 : SdrModel* pDoc, SfxRequest& rReq)
207 0 : : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
208 : {
209 0 : if( ! rReq.IsAPI() )
210 0 : rReq.Done();
211 :
212 : //! hier DLL's initalisieren, damit die Factories existieren?
213 :
214 0 : uno::Reference < embed::XEmbeddedObject > xObj;
215 0 : uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
216 0 : sal_Bool bIsFromFile = false;
217 0 : ::rtl::OUString aName;
218 :
219 0 : sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
220 0 : ::rtl::OUString aIconMediaType;
221 0 : uno::Reference< io::XInputStream > xIconMetaFile;
222 :
223 :
224 0 : sal_uInt16 nSlot = rReq.GetSlot();
225 0 : SFX_REQUEST_ARG( rReq, pNameItem, SfxGlobalNameItem, SID_INSERT_OBJECT, false );
226 0 : if ( nSlot == SID_INSERT_OBJECT && pNameItem )
227 : {
228 0 : SvGlobalName aClassName = pNameItem->GetValue();
229 0 : xObj = pViewShell->GetViewFrame()->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( aClassName.GetByteSequence(), aName );
230 : }
231 0 : else if ( nSlot == SID_INSERT_SMATH )
232 : {
233 0 : if ( SvtModuleOptions().IsMath() )
234 : {
235 0 : nSlot = SID_INSERT_OBJECT;
236 0 : xObj = pViewShell->GetViewFrame()->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SM_CLASSID_60 ).GetByteSequence(), aName );
237 0 : rReq.AppendItem( SfxGlobalNameItem( SID_INSERT_OBJECT, SvGlobalName( SO3_SM_CLASSID_60 ) ) );
238 : }
239 : }
240 : else
241 : {
242 0 : SvObjectServerList aServerLst;
243 0 : switch ( nSlot )
244 : {
245 : case SID_INSERT_OBJECT :
246 0 : aServerLst.FillInsertObjects();
247 0 : aServerLst.Remove( ScDocShell::Factory().GetClassId() ); // Starcalc nicht anzeigen
248 : //TODO/LATER: currently no inserting of ClassId into SfxRequest!
249 : case SID_INSERT_PLUGIN :
250 : case SID_INSERT_FLOATINGFRAME :
251 : {
252 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
253 : SfxAbstractInsertObjectDialog* pDlg =
254 0 : pFact->CreateInsertObjectDialog( pViewShell->GetWindow(), SC_MOD()->GetSlotPool()->GetSlot(nSlot)->GetCommandString(),
255 0 : xStorage, &aServerLst );
256 0 : if ( pDlg )
257 : {
258 0 : pDlg->Execute();
259 0 : xObj = pDlg->GetObject();
260 :
261 0 : xIconMetaFile = pDlg->GetIconIfIconified( &aIconMediaType );
262 0 : if ( xIconMetaFile.is() )
263 0 : nAspect = embed::Aspects::MSOLE_ICON;
264 :
265 0 : if ( xObj.is() )
266 0 : pViewSh->GetObjectShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
267 : // damit DrawShell eingeschaltet wird (Objekt aktivieren ist unnoetig):
268 0 : bIsFromFile = !pDlg->IsCreateNew();
269 0 : DELETEZ( pDlg );
270 : }
271 :
272 0 : break;
273 : }
274 : case SID_INSERT_SOUND :
275 : case SID_INSERT_VIDEO :
276 : {
277 : // create special filedialog for plugins
278 0 : SvxPluginFileDlg aPluginFileDialog(pWin, nSlot);
279 :
280 : // open filedlg
281 0 : if ( ERRCODE_NONE == aPluginFileDialog.Execute() )
282 : {
283 : // get URL
284 0 : INetURLObject aURL;
285 0 : aURL.SetSmartProtocol( INET_PROT_FILE );
286 0 : if ( aURL.SetURL( aPluginFileDialog.GetPath() ) )
287 : {
288 : // create a plugin object
289 0 : ::rtl::OUString aObjName;
290 0 : SvGlobalName aClassId( SO3_PLUGIN_CLASSID );
291 0 : comphelper::EmbeddedObjectContainer aCnt( xStorage );
292 0 : xObj = aCnt.CreateEmbeddedObject( aClassId.GetByteSequence(), aObjName );
293 0 : if ( xObj.is() && svt::EmbeddedObjectRef::TryRunningState( xObj ) )
294 : {
295 : // set properties from dialog
296 0 : uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
297 0 : if ( xSet.is() )
298 : {
299 0 : xSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PluginURL")),
300 0 : uno::makeAny( ::rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) );
301 0 : }
302 0 : }
303 : }
304 : else
305 : {
306 : OSL_FAIL("Invalid URL!");
307 : //! error message
308 : //! can this happen???
309 0 : }
310 0 : }
311 : }
312 0 : }
313 : }
314 :
315 : // SvInsertObjectDialog (alles in einem Dialog) wird nicht mehr benutzt
316 0 : if (xObj.is())
317 : {
318 0 : pView->UnmarkAll();
319 :
320 : try
321 : {
322 0 : ::svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
323 0 : Size aSize;
324 0 : MapMode aMap100( MAP_100TH_MM );
325 0 : MapUnit aMapUnit = MAP_100TH_MM;
326 :
327 0 : if ( nAspect == embed::Aspects::MSOLE_ICON )
328 : {
329 0 : aObjRef.SetGraphicStream( xIconMetaFile, aIconMediaType );
330 0 : aSize = aObjRef.GetSize( &aMap100 );
331 : }
332 : else
333 : {
334 0 : awt::Size aSz;
335 : try
336 : {
337 0 : aSz = xObj->getVisualAreaSize( nAspect );
338 : }
339 0 : catch( embed::NoVisualAreaSizeException& )
340 : {
341 : // the default size will be set later
342 : }
343 :
344 0 : aSize = Size( aSz.Width, aSz.Height );
345 :
346 0 : aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
347 0 : if (aSize.Height() == 0 || aSize.Width() == 0)
348 : {
349 : // Rechteck mit ausgewogenem Kantenverhaeltnis
350 0 : aSize.Width() = 5000;
351 0 : aSize.Height() = 5000;
352 0 : Size aTmp = OutputDevice::LogicToLogic( aSize, MAP_100TH_MM, aMapUnit );
353 0 : aSz.Width = aTmp.Width();
354 0 : aSz.Height = aTmp.Height();
355 0 : xObj->setVisualAreaSize( nAspect, aSz );
356 :
357 : // re-convert aSize to 1/100th mm to avoid rounding errors in comparison below
358 : aSize = Window::LogicToLogic( aTmp,
359 0 : MapMode( aMapUnit ), aMap100 );
360 : }
361 : else
362 : aSize = Window::LogicToLogic( aSize,
363 0 : MapMode( aMapUnit ), aMap100 );
364 : }
365 :
366 : // Chart initialisieren ?
367 0 : if ( SvtModuleOptions().IsChart() && SotExchange::IsChart( SvGlobalName( xObj->getClassID() ) ) )
368 0 : lcl_ChartInit( xObj, pViewSh->GetViewData(), rtl::OUString() );
369 :
370 0 : ScViewData* pData = pViewSh->GetViewData();
371 :
372 0 : Point aPnt = pViewSh->GetInsertPos();
373 0 : if ( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
374 0 : aPnt.X() -= aSize.Width(); // move position to left edge
375 0 : Rectangle aRect (aPnt, aSize);
376 0 : SdrOle2Obj* pObj = new SdrOle2Obj( aObjRef, aName, aRect);
377 :
378 : // Dieses Objekt nicht vor dem Aktivieren zeichnen
379 : // (in MarkListHasChanged kommt ein Update)
380 0 : if (!bIsFromFile)
381 0 : pSkipPaintObj = pObj;
382 :
383 0 : SdrPageView* pPV = pView->GetSdrPageView();
384 0 : pView->InsertObjectAtView(pObj, *pPV);
385 :
386 0 : if ( nAspect != embed::Aspects::MSOLE_ICON )
387 : {
388 : // Math objects change their object size during InsertObject.
389 : // New size must be set in SdrObject, or a wrong scale will be set at
390 : // ActivateObject.
391 :
392 : try
393 : {
394 0 : awt::Size aSz = xObj->getVisualAreaSize( nAspect );
395 :
396 0 : Size aNewSize( aSz.Width, aSz.Height );
397 0 : aNewSize = OutputDevice::LogicToLogic( aNewSize, aMapUnit, MAP_100TH_MM );
398 :
399 0 : if ( aNewSize != aSize )
400 : {
401 0 : aRect.SetSize( aNewSize );
402 0 : pObj->SetLogicRect( aRect );
403 : }
404 : }
405 0 : catch( embed::NoVisualAreaSizeException& )
406 : {}
407 : }
408 :
409 0 : if ( !rReq.IsAPI() )
410 : {
411 : // XXX Activate aus Makro ist toedlich !!! ???
412 0 : if (bIsFromFile)
413 : {
414 : // Objekt ist selektiert, also Draw-Shell aktivieren
415 0 : pViewShell->SetDrawShell( true );
416 : }
417 : else
418 : {
419 0 : pViewShell->ActivateObject( (SdrOle2Obj*) pObj, SVVERB_SHOW );
420 0 : pSkipPaintObj = NULL;
421 : }
422 : }
423 :
424 0 : rReq.Done();
425 : }
426 0 : catch( uno::Exception& )
427 : {
428 : OSL_FAIL( "May need error handling here!\n" );
429 : }
430 : }
431 : else
432 0 : rReq.Ignore();
433 0 : }
434 :
435 : /*************************************************************************
436 : |*
437 : |* FuInsertOLE::Destruktor
438 : |*
439 : \************************************************************************/
440 :
441 0 : FuInsertOLE::~FuInsertOLE()
442 : {
443 0 : }
444 :
445 : /*************************************************************************
446 : |*
447 : |* FuInsertOLE::Function aktivieren
448 : |*
449 : \************************************************************************/
450 :
451 0 : void FuInsertOLE::Activate()
452 : {
453 0 : FuPoor::Activate();
454 0 : }
455 :
456 : /*************************************************************************
457 : |*
458 : |* FuInsertOLE::Function deaktivieren
459 : |*
460 : \************************************************************************/
461 :
462 0 : void FuInsertOLE::Deactivate()
463 : {
464 0 : FuPoor::Deactivate();
465 0 : }
466 :
467 : /*************************************************************************
468 : |*
469 : |* FuInsertChart::Konstruktor
470 : |*
471 : \************************************************************************/
472 :
473 0 : FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
474 : SdrModel* pDoc, SfxRequest& rReq)
475 0 : : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
476 : {
477 0 : const SfxItemSet* pReqArgs = rReq.GetArgs();
478 :
479 0 : if( ! rReq.IsAPI() )
480 0 : rReq.Done();
481 :
482 0 : if( SvtModuleOptions().IsChart() )
483 : {
484 : // ----------------------------------------
485 : // BM/IHA --
486 :
487 : // get range
488 0 : ::rtl::OUString aRangeString;
489 0 : ScRange aPositionRange; // cell range for chart positioning
490 0 : if( pReqArgs )
491 : {
492 : const SfxPoolItem* pItem;
493 0 : if( pReqArgs->HasItem( FN_PARAM_5, &pItem ) )
494 0 : aRangeString = ::rtl::OUString( ((const SfxStringItem*)pItem)->GetValue());
495 :
496 0 : aPositionRange = pViewSh->GetViewData()->GetCurPos();
497 : }
498 : else
499 : {
500 0 : ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
501 0 : bool bAutomaticMark = false;
502 0 : if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
503 : {
504 0 : pViewSh->GetViewData()->GetView()->MarkDataArea( sal_True );
505 0 : bAutomaticMark = true;
506 : }
507 :
508 0 : ScMarkData aMultiMark( rMark );
509 0 : aMultiMark.MarkToMulti();
510 :
511 0 : ScRangeList aRanges;
512 0 : aMultiMark.FillRangeListWithMarks( &aRanges, false );
513 0 : String aStr;
514 0 : ScDocument* pDocument = pViewSh->GetViewData()->GetDocument();
515 0 : aRanges.Format( aStr, SCR_ABS_3D, pDocument, pDocument->GetAddressConvention() );
516 0 : aRangeString = aStr;
517 :
518 : // get "total" range for positioning
519 0 : if ( !aRanges.empty() )
520 : {
521 0 : aPositionRange = *aRanges[ 0 ];
522 0 : for ( size_t i = 1, nCount = aRanges.size(); i < nCount; ++i )
523 : {
524 0 : aPositionRange.ExtendTo( *aRanges[ i ] );
525 : }
526 : }
527 :
528 0 : if(bAutomaticMark)
529 0 : pViewSh->GetViewData()->GetView()->Unmark();
530 : }
531 :
532 : // ----------------------------------------
533 : // adapted old code
534 0 : pView->UnmarkAll();
535 :
536 0 : ::rtl::OUString aName;
537 0 : const sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
538 :
539 : uno::Reference < embed::XEmbeddedObject > xObj =
540 0 : pViewShell->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID_60 ).GetByteSequence(), aName );
541 :
542 0 : uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
543 0 : uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
544 0 : if( xCompSupp.is())
545 0 : xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
546 :
547 : // lock the model to suppress any internal updates
548 0 : uno::Reference< frame::XModel > xChartModel( xReceiver, uno::UNO_QUERY );
549 0 : if( xChartModel.is() )
550 0 : xChartModel->lockControllers();
551 :
552 0 : ScRangeListRef aDummy;
553 0 : Rectangle aMarkDest;
554 : SCTAB nMarkTab;
555 0 : sal_Bool bDrawRect = pViewShell->GetChartArea( aDummy, aMarkDest, nMarkTab );
556 :
557 : // Objekt-Groesse
558 0 : awt::Size aSz = xObj->getVisualAreaSize( nAspect );
559 0 : Size aSize( aSz.Width, aSz.Height );
560 :
561 0 : MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
562 :
563 0 : sal_Bool bSizeCh = false;
564 0 : if (bDrawRect && !aMarkDest.IsEmpty())
565 : {
566 0 : aSize = aMarkDest.GetSize();
567 0 : bSizeCh = sal_True;
568 : }
569 0 : if (aSize.Height() <= 0 || aSize.Width() <= 0)
570 : {
571 0 : aSize.Width() = 5000;
572 0 : aSize.Height() = 5000;
573 0 : bSizeCh = sal_True;
574 : }
575 0 : if (bSizeCh)
576 : {
577 0 : aSize = Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) );
578 0 : aSz.Width = aSize.Width();
579 0 : aSz.Height = aSize.Height();
580 0 : xObj->setVisualAreaSize( nAspect, aSz );
581 : }
582 :
583 0 : ScViewData* pData = pViewSh->GetViewData();
584 0 : ScDocShell* pScDocSh = pData->GetDocShell();
585 0 : ScDocument* pScDoc = pScDocSh->GetDocument();
586 0 : sal_Bool bUndo (pScDoc->IsUndoEnabled());
587 :
588 0 : if( pReqArgs )
589 : {
590 : const SfxPoolItem* pItem;
591 0 : sal_uInt16 nToTable = 0;
592 :
593 0 : if( pReqArgs->HasItem( FN_PARAM_4, &pItem ) )
594 : {
595 0 : if ( pItem->ISA( SfxUInt16Item ) )
596 0 : nToTable = ((const SfxUInt16Item*)pItem)->GetValue();
597 0 : else if ( pItem->ISA( SfxBoolItem ) )
598 : {
599 : // in der idl fuer Basic steht FN_PARAM_4 als SfxBoolItem
600 : // -> wenn gesetzt, neue Tabelle, sonst aktuelle Tabelle
601 :
602 0 : if ( ((const SfxBoolItem*)pItem)->GetValue() )
603 0 : nToTable = static_cast<sal_uInt16>(pScDoc->GetTableCount());
604 : else
605 0 : nToTable = static_cast<sal_uInt16>(pData->GetTabNo());
606 : }
607 : }
608 : else
609 : {
610 0 : if (bDrawRect)
611 0 : nToTable = static_cast<sal_uInt16>(nMarkTab);
612 0 : rReq.AppendItem( SfxUInt16Item( FN_PARAM_4, nToTable ) );
613 : }
614 :
615 : // auf neue Tabelle ausgeben?
616 0 : if ( nToTable == pScDoc->GetTableCount() )
617 : {
618 : // dann los...
619 0 : rtl::OUString aTabName;
620 0 : SCTAB nNewTab = pScDoc->GetTableCount();
621 :
622 0 : pScDoc->CreateValidTabName( aTabName );
623 :
624 0 : if ( pScDoc->InsertTab( nNewTab, aTabName ) )
625 : {
626 0 : sal_Bool bAppend = sal_True;
627 :
628 0 : if (bUndo)
629 : {
630 0 : pScDocSh->GetUndoManager()->AddUndoAction(
631 : new ScUndoInsertTab( pScDocSh, nNewTab,
632 0 : bAppend, aTabName ) );
633 : }
634 :
635 0 : pScDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nNewTab ) );
636 0 : pViewSh->SetTabNo( nNewTab, sal_True );
637 0 : pScDocSh->PostPaintExtras(); //! erst hinterher ???
638 : }
639 : else
640 : {
641 : OSL_FAIL( "Could not create new table :-/" );
642 0 : }
643 : }
644 0 : else if ( nToTable != pData->GetTabNo() )
645 : {
646 0 : pViewSh->SetTabNo( nToTable, sal_True );
647 : }
648 : }
649 :
650 0 : lcl_ChartInit( xObj, pData, aRangeString ); // set source range, auto-detect column/row headers
651 :
652 : // Objekt-Position
653 :
654 0 : Point aStart;
655 0 : if ( bDrawRect )
656 0 : aStart = aMarkDest.TopLeft(); // marked by hand
657 : else
658 : {
659 : // get chart position (from window size and data range)
660 0 : aStart = pViewSh->GetChartInsertPos( aSize, aPositionRange );
661 : }
662 :
663 0 : Rectangle aRect (aStart, aSize);
664 0 : SdrOle2Obj* pObj = new SdrOle2Obj( svt::EmbeddedObjectRef( xObj, nAspect ), aName, aRect);
665 :
666 : // Dieses Objekt nicht vor dem Aktivieren zeichnen
667 : // (in MarkListHasChanged kommt ein Update)
668 0 : pSkipPaintObj = pObj;
669 :
670 0 : SdrPageView* pPV = pView->GetSdrPageView();
671 :
672 : // pView->InsertObjectAtView(pObj, *pPV);//this call leads to an immidiate redraw and asks the chart for a visual representation
673 :
674 : // use the page instead of the view to insert, so no undo action is created yet
675 0 : SdrPage* pInsPage = pPV->GetPage();
676 0 : pInsPage->InsertObject( pObj );
677 0 : pView->UnmarkAllObj();
678 0 : pView->MarkObj( pObj, pPV );
679 0 : bool bAddUndo = true; // add undo action later, unless the dialog is canceled
680 :
681 0 : if (rReq.IsAPI())
682 : {
683 0 : if( xChartModel.is() )
684 0 : xChartModel->unlockControllers();
685 : }
686 : else
687 : {
688 : //the controller will be unlocked by the dialog when the dialog is told to do so
689 :
690 : // only activate object if not called via API (e.g. macro)
691 0 : pViewShell->ActivateObject( (SdrOle2Obj*) pObj, SVVERB_SHOW );
692 :
693 : //open wizard
694 : //@todo get context from calc if that has one
695 : uno::Reference< uno::XComponentContext > xContext(
696 0 : ::cppu::defaultBootstrap_InitialComponentContext() );
697 0 : if(xContext.is())
698 : {
699 0 : uno::Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
700 0 : if(xMCF.is())
701 : {
702 : uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
703 0 : xMCF->createInstanceWithContext(
704 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.chart2.WizardDialog"))
705 0 : , xContext), uno::UNO_QUERY);
706 0 : uno::Reference< lang::XInitialization > xInit( xDialog, uno::UNO_QUERY );
707 0 : if( xChartModel.is() && xInit.is() )
708 : {
709 0 : uno::Reference< awt::XWindow > xDialogParentWindow(0);
710 : // initialize dialog
711 0 : uno::Sequence<uno::Any> aSeq(2);
712 0 : uno::Any* pArray = aSeq.getArray();
713 0 : beans::PropertyValue aParam1;
714 0 : aParam1.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow"));
715 0 : aParam1.Value <<= uno::makeAny(xDialogParentWindow);
716 0 : beans::PropertyValue aParam2;
717 0 : aParam2.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ChartModel"));
718 0 : aParam2.Value <<= uno::makeAny(xChartModel);
719 0 : pArray[0] <<= uno::makeAny(aParam1);
720 0 : pArray[1] <<= uno::makeAny(aParam2);
721 0 : xInit->initialize( aSeq );
722 :
723 : // try to set the dialog's position so it doesn't hide the chart
724 0 : uno::Reference < beans::XPropertySet > xDialogProps( xDialog, uno::UNO_QUERY );
725 0 : if ( xDialogProps.is() )
726 : {
727 : try
728 : {
729 : //get dialog size:
730 0 : awt::Size aDialogAWTSize;
731 0 : if( xDialogProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size")) )
732 0 : >>= aDialogAWTSize )
733 : {
734 0 : Size aDialogSize( aDialogAWTSize.Width, aDialogAWTSize.Height );
735 0 : if ( aDialogSize.Width() > 0 && aDialogSize.Height() > 0 )
736 : {
737 : //calculate and set new position
738 0 : Point aDialogPos = pViewShell->GetChartDialogPos( aDialogSize, aRect );
739 0 : xDialogProps->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Position")),
740 0 : uno::makeAny( awt::Point(aDialogPos.getX(),aDialogPos.getY()) ) );
741 : }
742 : }
743 : //tell the dialog to unlock controller
744 0 : xDialogProps->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UnlockControllersOnExecute")),
745 0 : uno::makeAny( sal_True ) );
746 :
747 : }
748 0 : catch( uno::Exception& )
749 : {
750 : OSL_FAIL( "Chart wizard couldn't be positioned automatically\n" );
751 : }
752 : }
753 :
754 0 : sal_Int16 nDialogRet = xDialog->execute();
755 0 : if( nDialogRet == ui::dialogs::ExecutableDialogResults::CANCEL )
756 : {
757 : // leave OLE inplace mode and unmark
758 : OSL_ASSERT( pViewShell );
759 : OSL_ASSERT( pView );
760 0 : pViewShell->DeactivateOle();
761 0 : pView->UnmarkAll();
762 :
763 : // old page view pointer is invalid after switching sheets
764 0 : pPV = pView->GetSdrPageView();
765 :
766 : // remove the chart
767 : OSL_ASSERT( pPV );
768 0 : SdrPage * pPage( pPV->GetPage());
769 : OSL_ASSERT( pPage );
770 : OSL_ASSERT( pObj );
771 0 : if( pPage )
772 0 : pPage->RemoveObject( pObj->GetOrdNum());
773 :
774 0 : bAddUndo = false; // don't create the undo action for inserting
775 :
776 : // leave the draw shell
777 0 : pViewShell->SetDrawShell( false );
778 : }
779 : else
780 : {
781 : OSL_ASSERT( nDialogRet == ui::dialogs::ExecutableDialogResults::OK );
782 : //@todo maybe move chart to different table
783 0 : }
784 : }
785 0 : uno::Reference< lang::XComponent > xComponent( xDialog, uno::UNO_QUERY );
786 0 : if( xComponent.is())
787 0 : xComponent->dispose();
788 0 : }
789 0 : }
790 : }
791 :
792 0 : if ( bAddUndo )
793 : {
794 : // add undo action the same way as in SdrEditView::InsertObjectAtView
795 : // (using UndoActionHdl etc.)
796 0 : pView->AddUndo(pDoc->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
797 0 : }
798 :
799 : // BM/IHA --
800 : }
801 0 : }
802 :
803 : /*************************************************************************
804 : |*
805 : |* FuInsertChart::Destruktor
806 : |*
807 : \************************************************************************/
808 :
809 0 : FuInsertChart::~FuInsertChart()
810 : {
811 0 : }
812 :
813 : /*************************************************************************
814 : |*
815 : |* FuInsertChart::Function aktivieren
816 : |*
817 : \************************************************************************/
818 :
819 0 : void FuInsertChart::Activate()
820 : {
821 0 : FuPoor::Activate();
822 0 : }
823 :
824 : /*************************************************************************
825 : |*
826 : |* FuInsertChart::Function deaktivieren
827 : |*
828 : \************************************************************************/
829 :
830 0 : void FuInsertChart::Deactivate()
831 : {
832 0 : FuPoor::Deactivate();
833 15 : }
834 :
835 :
836 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|