blob: d36f039bb1737fe3a4e554a660a72c036414a49b [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include <sfx2/opengrf.hxx>
#include <svx/svdograf.hxx>
#include <svx/svdomedia.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdpagv.hxx>
#include <svx/svdview.hxx>
#include <svtools/filter.hxx>
#include <svl/stritem.hxx>
#include <vcl/msgbox.hxx>
#include <tools/urlobj.hxx>
#include <avmedia/mediawindow.hxx>
#include <vcl/svapp.hxx>
#include "fuinsert.hxx"
#include "tabvwsh.hxx"
#include "drwlayer.hxx"
#include "drawview.hxx"
#include "document.hxx"
#include "scresid.hxx"
#include "progress.hxx"
#include "sc.hrc"
#include "globstr.hrc"
////========================================================================
//// class ImportProgress
////
//// Bemerkung:
//// Diese Klasse stellt lediglich den Handler fuer den ImportProgress des
//// Grafikfilters bereit.
////========================================================================
//
//class ImportProgress
//{
//public:
// ImportProgress( GraphicFilter& rFilter );
// ~ImportProgress();
//
// DECL_LINK( Update, GraphicFilter* );
//
//private:
// ScProgress aProgress;
//};
//
////------------------------------------------------------------------------
//
//ImportProgress::ImportProgress( GraphicFilter& rFilter )
// : aProgress( NULL, // SfxViewFrame*, NULL == alle Docs locken
// String( ScResId(STR_INSERTGRAPHIC) ),
// 100 )
//{
// rFilter.SetUpdatePercentHdl( LINK( this, ImportProgress, Update) );
//}
//
////------------------------------------------------------------------------
//
//__EXPORT ImportProgress::~ImportProgress()
//{
// aProgress.SetState( 100 );
//}
//
////------------------------------------------------------------------------
//
//IMPL_LINK( ImportProgress, Update, GraphicFilter*, pGraphicFilter )
//{
// aProgress.SetState( pGraphicFilter->GetPercent() );
// return 0;
//}
//------------------------------------------------------------------------
void SC_DLLPUBLIC ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage )
{
if ( !rPage.Width() || !rPage.Height() )
return;
Size aPageSize = rPage;
sal_Bool bNegative = aPageSize.Width() < 0;
if ( bNegative )
{
// make everything positive temporarily
aPageSize.Width() = -aPageSize.Width();
rPos.X() = -rPos.X() - rSize.Width();
}
if ( rSize.Width() > aPageSize.Width() || rSize.Height() > aPageSize.Height() )
{
double fX = aPageSize.Width() / (double) rSize.Width();
double fY = aPageSize.Height() / (double) rSize.Height();
if ( fX < fY )
{
rSize.Width() = aPageSize.Width();
rSize.Height() = (long) ( rSize.Height() * fX );
}
else
{
rSize.Height() = aPageSize.Height();
rSize.Width() = (long) ( rSize.Width() * fY );
}
if (!rSize.Width())
rSize.Width() = 1;
if (!rSize.Height())
rSize.Height() = 1;
}
if ( rPos.X() + rSize.Width() > aPageSize.Width() )
rPos.X() = aPageSize.Width() - rSize.Width();
if ( rPos.Y() + rSize.Height() > aPageSize.Height() )
rPos.Y() = aPageSize.Height() - rSize.Height();
if ( bNegative )
rPos.X() = -rPos.X() - rSize.Width(); // back to real position
}
//------------------------------------------------------------------------
void lcl_InsertGraphic( const Graphic& rGraphic,
const String& rFileName, const String& rFilterName, sal_Bool bAsLink, sal_Bool bApi,
ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView )
{
ScDrawView* pDrawView = pViewSh->GetScDrawView();
// #123922# check if an existing object is selected; if yes, evtl. replace
// the graphic for a SdrGraphObj (including link state updates) or adapt the fill
// style for other objects
if(pDrawView && 1 == pDrawView->GetMarkedObjectCount())
{
SdrObject* pPickObj = pDrawView->GetMarkedObjectByIndex(0);
if(pPickObj)
{
//sal_Int8 nAction(DND_ACTION_MOVE);
//Point aPos;
const String aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP));
const String aEmpty;
SdrObject* pResult = pDrawView->ApplyGraphicToObject(
*pPickObj,
rGraphic,
aBeginUndo,
bAsLink ? rFileName : aEmpty,
bAsLink ? rFilterName : aEmpty);
if(pResult)
{
// we are done; mark the modified/new object
pDrawView->MarkObj(pResult, pDrawView->GetSdrPageView());
return;
}
}
}
// #74778# set the size so the graphic has its original pixel size
// at 100% view scale (as in SetMarkedOriginalSize),
// instead of respecting the current view scale
MapMode aSourceMap = rGraphic.GetPrefMapMode();
MapMode aDestMap( MAP_100TH_MM );
if ( aSourceMap.GetMapUnit() == MAP_PIXEL && pDrawView )
{
Fraction aScaleX, aScaleY;
pDrawView->CalcNormScale( aScaleX, aScaleY );
aDestMap.SetScaleX(aScaleX);
aDestMap.SetScaleY(aScaleY);
}
Size aLogicSize = pWindow->LogicToLogic(
rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
// Limit size
SdrPageView* pPV = pView->GetSdrPageView();
SdrPage* pPage = pPV->GetPage();
Point aInsertPos = pViewSh->GetInsertPos();
ScViewData* pData = pViewSh->GetViewData();
if ( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
aInsertPos.X() -= aLogicSize.Width(); // move position to left edge
ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
Rectangle aRect ( aInsertPos, aLogicSize );
SdrGrafObj* pObj = new SdrGrafObj( rGraphic, aRect );
// #118522# calling SetGraphicLink here doesn't work
// #49961# Path is no longer used as name for the graphics object
ScDrawLayer* pLayer = (ScDrawLayer*) pView->GetModel();
String aName = pLayer->GetNewGraphicName(); // "Grafik x"
pObj->SetName(aName);
// don't select if from (dispatch) API, to allow subsequent cell operations
sal_uLong nInsOptions = bApi ? SDRINSERT_DONTMARK : 0;
pView->InsertObjectAtView( pObj, *pPV, nInsOptions );
// #118522# SetGraphicLink has to be used after inserting the object,
// otherwise an empty graphic is swapped in and the contact stuff crashes.
// See #i37444#.
if ( bAsLink )
pObj->SetGraphicLink( rFileName, rFilterName );
}
//------------------------------------------------------------------------
void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi,
ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView,
const Size& rPrefSize )
{
SdrPageView* pPV = pView->GetSdrPageView();
SdrPage* pPage = pPV->GetPage();
ScViewData* pData = pViewSh->GetViewData();
Point aInsertPos( pViewSh->GetInsertPos() );
Size aSize;
if( rPrefSize.Width() && rPrefSize.Height() )
{
if( pWindow )
aSize = pWindow->PixelToLogic( rPrefSize, MAP_100TH_MM );
else
aSize = Application::GetDefaultDevice()->PixelToLogic( rPrefSize, MAP_100TH_MM );
}
else
aSize = Size( 5000, 5000 );
ScLimitSizeOnDrawPage( aSize, aInsertPos, pPage->GetSize() );
if( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
aInsertPos.X() -= aSize.Width();
SdrMediaObj* pObj = new SdrMediaObj( Rectangle( aInsertPos, aSize ) );
pObj->setURL( rMediaURL );
pView->InsertObjectAtView( pObj, *pPV, bApi ? SDRINSERT_DONTMARK : 0 );
}
/*************************************************************************
|*
|* FuInsertGraphic::Konstruktor
|*
\************************************************************************/
#ifdef _MSC_VER
#pragma optimize("",off)
#endif
FuInsertGraphic::FuInsertGraphic( ScTabViewShell* pViewSh,
Window* pWin,
ScDrawView* pViewP,
SdrModel* pDoc,
SfxRequest& rReq )
: FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
{
const SfxItemSet* pReqArgs = rReq.GetArgs();
const SfxPoolItem* pItem;
if ( pReqArgs &&
pReqArgs->GetItemState( SID_INSERT_GRAPHIC, sal_True, &pItem ) == SFX_ITEM_SET )
{
String aFileName = ((const SfxStringItem*)pItem)->GetValue();
String aFilterName;
if ( pReqArgs->GetItemState( FN_PARAM_FILTER, sal_True, &pItem ) == SFX_ITEM_SET )
aFilterName = ((const SfxStringItem*)pItem)->GetValue();
sal_Bool bAsLink = sal_False;
if ( pReqArgs->GetItemState( FN_PARAM_1, sal_True, &pItem ) == SFX_ITEM_SET )
bAsLink = ((const SfxBoolItem*)pItem)->GetValue();
Graphic aGraphic;
int nError = GraphicFilter::LoadGraphic( aFileName, aFilterName, aGraphic, GraphicFilter::GetGraphicFilter() );
if ( nError == GRFILTER_OK )
{
lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, sal_True, pViewSh, pWindow, pView );
}
}
else
{
SvxOpenGraphicDialog aDlg(ScResId(STR_INSERTGRAPHIC));
if( aDlg.Execute() == GRFILTER_OK )
{
Graphic aGraphic;
int nError = aDlg.GetGraphic(aGraphic);
if( nError == GRFILTER_OK )
{
String aFileName = aDlg.GetPath();
String aFilterName = aDlg.GetCurrentFilter();
sal_Bool bAsLink = aDlg.IsAsLink();
lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, sal_False, pViewSh, pWindow, pView );
// append items for recording
rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) );
rReq.AppendItem( SfxStringItem( FN_PARAM_FILTER, aFilterName ) );
rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
rReq.Done();
}
else
{
// error is handled in SvxOpenGraphicDialog::GetGraphic
#if 0
sal_uInt16 nRes = 0;
switch ( nError )
{
case GRFILTER_OPENERROR: nRes = SCSTR_GRFILTER_OPENERROR; break;
case GRFILTER_IOERROR: nRes = SCSTR_GRFILTER_IOERROR; break;
case GRFILTER_FORMATERROR: nRes = SCSTR_GRFILTER_FORMATERROR; break;
case GRFILTER_VERSIONERROR: nRes = SCSTR_GRFILTER_VERSIONERROR; break;
case GRFILTER_FILTERERROR: nRes = SCSTR_GRFILTER_FILTERERROR; break;
case GRFILTER_TOOBIG: nRes = SCSTR_GRFILTER_TOOBIG; break;
}
if ( nRes )
{
InfoBox aInfoBox( pWindow, String(ScResId(nRes)) );
aInfoBox.Execute();
}
else
{
sal_uLong nStreamError = GetGrfFilter()->GetLastError().nStreamError;
if( ERRCODE_NONE != nStreamError )
ErrorHandler::HandleError( nStreamError );
}
#endif
}
}
}
}
/*************************************************************************
|*
|* FuInsertGraphic::Destruktor
|*
\************************************************************************/
FuInsertGraphic::~FuInsertGraphic()
{
}
/*************************************************************************
|*
|* FuInsertGraphic::Function aktivieren
|*
\************************************************************************/
void FuInsertGraphic::Activate()
{
FuPoor::Activate();
}
/*************************************************************************
|*
|* FuInsertGraphic::Function deaktivieren
|*
\************************************************************************/
void FuInsertGraphic::Deactivate()
{
FuPoor::Deactivate();
}
/*************************************************************************
|*
|* FuInsertMedia::Konstruktor
|*
\************************************************************************/
FuInsertMedia::FuInsertMedia( ScTabViewShell* pViewSh,
Window* pWin,
ScDrawView* pViewP,
SdrModel* pDoc,
SfxRequest& rReq ) :
FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
{
::rtl::OUString aURL;
const SfxItemSet* pReqArgs = rReq.GetArgs();
bool bAPI = false;
if( pReqArgs )
{
const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, &pReqArgs->Get( rReq.GetSlot() ) );
if( pStringItem )
{
aURL = pStringItem->GetValue();
bAPI = aURL.getLength();
}
}
if( bAPI || ::avmedia::MediaWindow::executeMediaURLDialog( pWindow, aURL ) )
{
Size aPrefSize;
if( pWin )
pWin->EnterWait();
if( !::avmedia::MediaWindow::isMediaURL( aURL, true, &aPrefSize ) )
{
if( pWin )
pWin->LeaveWait();
if( !bAPI )
::avmedia::MediaWindow::executeFormatErrorBox( pWindow );
}
else
{
lcl_InsertMedia( aURL, bAPI, pViewSh, pWindow, pView, aPrefSize );
if( pWin )
pWin->LeaveWait();
}
}
}
/*************************************************************************
|*
|* FuInsertMedia::Destruktor
|*
\************************************************************************/
FuInsertMedia::~FuInsertMedia()
{
}
/*************************************************************************
|*
|* FuInsertMedia::Function aktivieren
|*
\************************************************************************/
void FuInsertMedia::Activate()
{
FuPoor::Activate();
}
/*************************************************************************
|*
|* FuInsertMedia::Function deaktivieren
|*
\************************************************************************/
void FuInsertMedia::Deactivate()
{
FuPoor::Deactivate();
}