namespace
{
view::PaperFormat convertToPaperFormat(Paper eFormat)
{
view::PaperFormat eRet; switch (eFormat)
{ case PAPER_A3:
eRet = view::PaperFormat_A3; break; case PAPER_A4:
eRet = view::PaperFormat_A4; break; case PAPER_A5:
eRet = view::PaperFormat_A5; break; case PAPER_B4_ISO:
eRet = view::PaperFormat_B4; break; case PAPER_B5_ISO:
eRet = view::PaperFormat_B5; break; case PAPER_LETTER:
eRet = view::PaperFormat_LETTER; break; case PAPER_LEGAL:
eRet = view::PaperFormat_LEGAL; break; case PAPER_TABLOID:
eRet = view::PaperFormat_TABLOID; break; case PAPER_USER: default:
eRet = view::PaperFormat_USER; break;
} return eRet;
}
Paper convertToPaper(view::PaperFormat eFormat)
{
Paper eRet(PAPER_USER); switch (eFormat)
{ case view::PaperFormat_A3:
eRet = PAPER_A3; break; case view::PaperFormat_A4:
eRet = PAPER_A4; break; case view::PaperFormat_A5:
eRet = PAPER_A5; break; case view::PaperFormat_B4:
eRet = PAPER_B4_ISO; break; case view::PaperFormat_B5:
eRet = PAPER_B5_ISO; break; case view::PaperFormat_LETTER:
eRet = PAPER_LETTER; break; case view::PaperFormat_LEGAL:
eRet = PAPER_LEGAL; break; case view::PaperFormat_TABLOID:
eRet = PAPER_TABLOID; break; case view::PaperFormat_USER:
eRet = PAPER_USER; break; case view::PaperFormat::PaperFormat_MAKE_FIXED_SIZE: break; //deliberate no default to force warn on a new papersize
} return eRet;
}
}
// search for any view of this document that is currently printing const Printer *pPrinter = nullptr;
SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ? SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr;
SfxViewFrame* pFirst = pViewFrm; while ( pViewFrm && !pPrinter )
{
pPrinter = pViewFrm->GetViewShell()->GetActivePrinter();
pViewFrm = SfxViewFrame::GetNext( *pViewFrm, m_pData->m_pObjectShell.get(), false );
}
// if no view is printing currently, use the permanent SfxPrinter instance if ( !pPrinter && pFirst )
pPrinter = pFirst->GetViewShell()->GetPrinter(true);
if ( !pPrinter ) return uno::Sequence< beans::PropertyValue >();
// The PaperSize may be set only when actually PAPER_USER // applies, otherwise the driver could choose an invalid format. if(nPaperFormat == view::PaperFormat_USER && aSetPaperSize.Width())
{ // Bug 56929 - MapMode of 100mm which recalculated when // the device is set. Additionally only set if they were really changed.
aSetPaperSize = pPrinter->LogicToPixel(aSetPaperSize, MapMode(MapUnit::Map100thMM)); if( aSetPaperSize != pPrinter->GetPaperSizePixel() )
{
pPrinter->SetPaperSizeUser( pPrinter->PixelToLogic( aSetPaperSize ) );
nChangeFlags |= SfxPrinterChangeFlags::CHG_SIZE;
}
}
//wait until printing is done
SfxPrinter* pDocPrinter = pViewSh->GetPrinter(); while ( pDocPrinter->IsPrinting() && !Application::IsQuit())
Application::Yield();
}
SfxViewShell* pViewSh = nullptr;
VclPtr<SfxPrinter> pPrinter;
SfxPrinterChangeFlags nChangeFlags = SfxPrinterChangeFlags::NONE;
impl_setPrinter(rPrinter,pPrinter,nChangeFlags,pViewSh); // set new printer if ( pViewSh && pPrinter )
pViewSh->SetPrinter( pPrinter, nChangeFlags );
}
// ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
namespace {
/* This implements a thread which will be started to wait for asynchronous printjobstotemp.locallyfiles.Iftheyfinishwemovethetemp.files totheirrightlocationsbyusingtheucb.
*/ class ImplUCBPrintWatcher : public ::osl::Thread
{ private: /// of course we must know the printer which execute the job
VclPtr<SfxPrinter> m_pPrinter; /// this describes the target location for the printed temp file
OUString m_sTargetURL; /// it holds the temp file alive, till the print job will finish and remove it from disk automatically if the object die
::utl::TempFileNamed* m_pTempFile;
/* waits for finishing of the print job and moves the temp file afterwards Note:Startingofthejobisdoneoutsidethisthread! Butwehavetofreesomeofthegivenresourcesonheap!
*/ void SAL_CALL run() override
{
osl_setThreadName("ImplUCBPrintWatcher");
// lock for further using of our member isn't necessary - because // we run alone by definition. Nobody join for us nor use us...
moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
// finishing of this run() method will call onTerminate() automatically // kill this thread there!
}
/* nobody wait for this thread. We must kill ourself ...
*/ void SAL_CALL onTerminated() override
{ deletethis;
}
/* static helper to move the temp. file to the target location by using the ucb It'sstatictobeusablefromoutsidetoo.Soit'snotreallynecessarytostart thethread,iffinishingofthejobwasdetectedoutsidethisthread. Butitmustbecalledwithoutusingacorrespondingthreadforthegivenparameter!
*/ staticvoid moveAndDeleteTemp( ::utl::TempFileNamed** ppTempFile, std::u16string_view sTargetURL )
{ // move the file try
{
INetURLObject aSplitter(sTargetURL);
OUString sFileName = aSplitter.getName(
INetURLObject::LAST_SEGMENT, true,
INetURLObject::DecodeMechanism::WithCharset); if (aSplitter.removeSegment() && !sFileName.isEmpty())
{
::ucbhelper::Content aSource(
(*ppTempFile)->GetURL(),
css::uno::Reference< css::ucb::XCommandEnvironment >(),
comphelper::getProcessComponentContext());
// get view for sfx printing capabilities
SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.is() ?
SfxViewFrame::GetFirst( m_pData->m_pObjectShell.get(), false ) : nullptr; if ( !pViewFrm ) return;
SfxViewShell* pView = pViewFrm->GetViewShell(); if ( !pView ) return; bool bMonitor = false; // We need this information at the end of this method, if we start the vcl printer // by executing the slot. Because if it is a ucb relevant URL we must wait for // finishing the print job and move the temporary local file by using the ucb // to the right location. But in case of no file name is given or it is already // a local one we can suppress this special handling. Because then vcl makes all // right for us.
OUString sUcbUrl;
::utl::TempFileNamed* pUCBPrintTempFile = nullptr;
uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() ); auto pCheckedArgs = aCheckedArgs.getArray();
sal_Int32 nProps = 0; bool bWaitUntilEnd = false;
sal_Int16 nDuplexMode = css::view::DuplexMode::UNKNOWN; for ( const beans::PropertyValue &rProp : rOptions )
{ // get Property-Value from options // FileName-Property? if ( rProp.Name == "FileName" )
{ // unpack th URL and check for a valid and well known protocol
OUString sTemp; if (
( rProp.Value.getValueType()!=cppu::UnoType<OUString>::get()) ||
(!(rProp.Value>>=sTemp))
)
{ throw css::lang::IllegalArgumentException();
}
OUString sPath;
OUString sURL (sTemp);
INetURLObject aCheck(sURL ); if (aCheck.GetProtocol()==INetProtocol::NotValid)
{ // OK - it's not a valid URL. But may it's a simple // system path directly. It will be supported for historical // reasons. Otherwise we break too much external code... // We try to convert it to a file URL. If it's possible // we put the system path to the item set and let vcl work with it. // No ucb or thread will be necessary then. In case it couldn't be // converted it's not a URL nor a system path. Then we can't accept // this parameter and have to throw an exception. const OUString& sSystemPath(sTemp);
OUString sFileURL; if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None) throw css::lang::IllegalArgumentException();
pCheckedArgs[nProps].Name = rProp.Name;
pCheckedArgs[nProps++].Value <<= sFileURL; // and append the local filename
aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
pCheckedArgs = aCheckedArgs.getArray();
pCheckedArgs[nProps].Name = "LocalFileName";
pCheckedArgs[nProps++].Value <<= sTemp;
} else // It's a valid URL. but now we must know, if it is a local one or not. // It's a question of using ucb or not! if (osl::FileBase::getSystemPathFromFileURL(sURL, sPath) == osl::FileBase::E_None)
{ // it's a local file, we can use vcl without special handling // And we have to use the system notation of the incoming URL. // But it into the descriptor and let the slot be executed at // the end of this method.
pCheckedArgs[nProps].Name = rProp.Name;
pCheckedArgs[nProps++].Value <<= sTemp; // and append the local filename
aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
pCheckedArgs = aCheckedArgs.getArray();
pCheckedArgs[nProps].Name = "LocalFileName";
pCheckedArgs[nProps++].Value <<= sPath;
} else
{ // it's a ucb target. So we must use a temp. file for vcl // and move it after printing by using the ucb. // Create a temp file on the heap (because it must delete the // real file on disk automatically if it die - bt we have to share it with // some other sources ... e.g. the ImplUCBPrintWatcher). // And we put the name of this temp file to the descriptor instead // of the URL. The URL we save for later using separately. // Execution of the print job will be done later by executing // a slot ... if(!pUCBPrintTempFile)
pUCBPrintTempFile = new ::utl::TempFileNamed();
pUCBPrintTempFile->EnableKillingFile();
//FIXME: does it work?
pCheckedArgs[nProps].Name = "LocalFileName";
pCheckedArgs[nProps++].Value <<= pUCBPrintTempFile->GetFileName();
sUcbUrl = sURL;
}
}
if ( nProps != aCheckedArgs.getLength() )
aCheckedArgs.realloc(nProps);
// Execute the print request every time. // It doesn't matter if it is a real printer used or we print to a local file // nor if we print to a temp file and move it afterwards by using the ucb. // That will be handled later. see pUCBPrintFile below!
pView->ExecPrint( aCheckedArgs, true, false );
// Ok - may be execution before has finished (or started!) printing. // And may it was a printing to a file. // Now we have to check if we can move the file (if necessary) via UCB to its right location. // Cases: // a) printing finished => move the file directly and forget the watcher thread // b) printing is asynchron and runs currently => start watcher thread and exit this method // This thread make all necessary things by itself. if (!pUCBPrintTempFile) return;
// a)
SfxPrinter* pPrinter = pView->GetPrinter(); if ( ! pPrinter->IsPrinting() )
ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl); // b) else
{ // Note: we create(d) some resource on the heap (thread and temp file). // They will be deleted by the thread automatically if it finishes its run() method.
ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
pWatcher->create();
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.