Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sw / source / uibase / uiview / srcview.cxx
blob84a3dd598a72b575bef1f2ebb022f43e2570bc47
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 .
20 #include <hintids.hxx>
21 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
22 #include <comphelper/string.hxx>
23 #include <unotools/tempfile.hxx>
24 #include <tools/urlobj.hxx>
25 #include <vcl/errinf.hxx>
26 #include <vcl/weld.hxx>
27 #include <vcl/print.hxx>
28 #include <vcl/wrkwin.hxx>
29 #include <vcl/metric.hxx>
30 #include <svtools/ctrltool.hxx>
31 #include <svl/intitem.hxx>
32 #include <svl/stritem.hxx>
33 #include <unotools/pathoptions.hxx>
34 #include <svl/undo.hxx>
35 #include <unotools/textsearch.hxx>
36 #include <svl/eitem.hxx>
37 #include <svl/whiter.hxx>
38 #include <unotools/saveopt.hxx>
39 #include <svtools/transfer.hxx>
40 #include <svtools/strings.hrc>
41 #include <svtools/svtresid.hxx>
42 #include <svx/svxids.hrc>
43 #include <svtools/htmlcfg.hxx>
44 #include <sfx2/app.hxx>
45 #include <sfx2/objface.hxx>
46 #include <sfx2/viewfrm.hxx>
47 #include <sfx2/bindings.hxx>
48 #include <sfx2/docfilt.hxx>
49 #include <sfx2/fcontnr.hxx>
50 #include <sfx2/request.hxx>
51 #include <sfx2/prnmon.hxx>
52 #include <sfx2/docfile.hxx>
53 #include <editeng/fhgtitem.hxx>
54 #include <svx/srchdlg.hxx>
55 #include <svl/srchitem.hxx>
56 #include <editeng/fontitem.hxx>
57 #include <editeng/flstitem.hxx>
58 #include <editeng/unolingu.hxx>
59 #include <sfx2/sfxhtml.hxx>
60 #include <swtypes.hxx>
61 #include <swmodule.hxx>
62 #include <docsh.hxx>
63 #include <wdocsh.hxx>
64 #include <srcview.hxx>
65 #include "viewfunc.hxx"
66 #include <doc.hxx>
67 #include <IDocumentDeviceAccess.hxx>
68 #include <IDocumentState.hxx>
69 #include <sfx2/msg.hxx>
70 #include <shellio.hxx>
72 #include <cmdid.h>
73 #include <globals.hrc>
74 #include <strings.hrc>
75 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
76 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
77 #include <sfx2/filedlghelper.hxx>
78 #define ShellClass_SwSrcView
79 #include <swslots.hxx>
81 #include <unomid.h>
83 #include <com/sun/star/document/XDocumentProperties.hpp>
84 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
86 using namespace ::com::sun::star;
87 using namespace ::com::sun::star::i18n;
88 using namespace ::com::sun::star::lang;
89 using namespace ::com::sun::star::uno;
90 using namespace ::com::sun::star::ui::dialogs;
91 using namespace ::sfx2;
93 #define SWSRCVIEWFLAGS SfxViewShellFlags::NO_NEWWINDOW
95 #define SRC_SEARCHOPTIONS (SearchOptionFlags::ALL & ~SearchOptionFlags(SearchOptionFlags::FORMAT|SearchOptionFlags::FAMILIES|SearchOptionFlags::SEARCHALL))
97 // Printing margins -> like Basic - Ide
98 #define LMARGPRN 1700
99 #define RMARGPRN 900
100 #define TMARGPRN 2000
101 #define BMARGPRN 1000
102 #define BORDERPRN 300
104 SFX_IMPL_NAMED_VIEWFACTORY(SwSrcView, "SourceView")
106 SFX_VIEW_REGISTRATION(SwWebDocShell);
109 SFX_IMPL_SUPERCLASS_INTERFACE(SwSrcView, SfxViewShell)
111 void SwSrcView::InitInterface_Impl()
113 GetStaticInterface()->RegisterPopupMenu("source");
115 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_TOOLS,
116 SfxVisibilityFlags::Standard|SfxVisibilityFlags::Server,
117 ToolbarId::Webtools_Toolbox);
119 GetStaticInterface()->RegisterChildWindow(SvxSearchDialogWrapper::GetChildWindowId());
123 static void lcl_PrintHeader( vcl::RenderContext &rOutDev, sal_Int32 nPages, sal_Int32 nCurPage, const OUString& rTitle )
125 short nLeftMargin = LMARGPRN;
126 Size aSz = rOutDev.GetOutputSize();
127 short nBorder = BORDERPRN;
129 Color aOldFillColor( rOutDev.GetFillColor() );
130 vcl::Font aOldFont( rOutDev.GetFont() );
132 rOutDev.SetFillColor( COL_TRANSPARENT );
134 vcl::Font aFont( aOldFont );
135 aFont.SetWeight( WEIGHT_BOLD );
136 aFont.SetAlignment( ALIGN_BOTTOM );
137 rOutDev.SetFont( aFont );
139 long nFontHeight = rOutDev.GetTextHeight();
141 // 1.Border => Line, 2+3 Border = Space.
142 long nYTop = TMARGPRN-3*nBorder-nFontHeight;
144 long nXLeft = nLeftMargin-nBorder;
145 long nXRight = aSz.Width()-RMARGPRN+nBorder;
147 rOutDev.DrawRect( tools::Rectangle(
148 Point( nXLeft, nYTop ),
149 Size( nXRight-nXLeft, aSz.Height() - nYTop - BMARGPRN + nBorder ) ) );
151 long nY = TMARGPRN-2*nBorder;
152 Point aPos( nLeftMargin, nY );
153 rOutDev.DrawText( aPos, rTitle );
154 if ( nPages != 1 )
156 aFont.SetWeight( WEIGHT_NORMAL );
157 rOutDev.SetFont( aFont );
158 OUString aPageStr( " [" );
159 aPageStr += SwResId( STR_PAGE );
160 aPageStr += " ";
161 aPageStr += OUString::number( nCurPage );
162 aPageStr += "]";
163 aPos.AdjustX(rOutDev.GetTextWidth( rTitle ) );
164 rOutDev.DrawText( aPos, aPageStr );
167 nY = TMARGPRN-nBorder;
169 rOutDev.DrawLine( Point( nXLeft, nY ), Point( nXRight, nY ) );
171 rOutDev.SetFont( aOldFont );
172 rOutDev.SetFillColor( aOldFillColor );
175 static rtl_TextEncoding lcl_GetStreamCharSet(rtl_TextEncoding eLoadEncoding)
177 rtl_TextEncoding eRet = eLoadEncoding;
178 if(RTL_TEXTENCODING_DONTKNOW == eRet)
180 SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
181 const sal_Char *pCharSet =
182 rtl_getBestMimeCharsetFromTextEncoding( rHtmlOptions.GetTextEncoding() );
183 eRet = rtl_getTextEncodingFromMimeCharset( pCharSet );
185 return eRet;
188 static OUString lcl_ConvertTabsToSpaces( const OUString& sLine )
190 if (sLine.isEmpty())
191 return sLine;
193 OUString aRet = sLine;
194 const sal_Unicode aPadSpaces[4] = {' ', ' ', ' ', ' '};
195 sal_Int32 nPos = 0;
196 for (;;)
198 nPos = aRet.indexOf('\t', nPos);
199 if (nPos<0)
201 break;
203 // Not 4 blanks, but on 4th TabPos:
204 const sal_Int32 nPadLen = 4 - (nPos % 4);
205 aRet = aRet.replaceAt(nPos, 1, OUString(aPadSpaces, nPadLen));
206 nPos += nPadLen;
208 return aRet;
211 SwSrcView::SwSrcView(SfxViewFrame* pViewFrame, SfxViewShell*) :
212 SfxViewShell( pViewFrame, SWSRCVIEWFLAGS ),
213 aEditWin( VclPtr<SwSrcEditWindow>::Create( &pViewFrame->GetWindow(), this ) ),
214 pSearchItem(nullptr),
215 bSourceSaved(false),
216 eLoadEncoding(RTL_TEXTENCODING_DONTKNOW)
218 Init();
221 SwSrcView::~SwSrcView()
223 SwDocShell* pDocShell = GetDocShell();
224 OSL_ENSURE(dynamic_cast<SwWebDocShell*>( pDocShell), "Why no WebDocShell?" );
225 const TextSelection& rSel = aEditWin->GetTextView()->GetSelection();
226 static_cast<SwWebDocShell*>(pDocShell)->SetSourcePara( static_cast< sal_uInt16 >( rSel.GetStart().GetPara() ) );
228 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
229 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
230 uno::Reference<document::XDocumentProperties> xDocProps
231 = xDPS->getDocumentProperties();
232 OUString url = xDocProps->getAutoloadURL();
233 sal_Int32 delay = xDocProps->getAutoloadSecs();
234 pDocShell->SetAutoLoad(INetURLObject(url), delay,
235 (delay != 0) || !url.isEmpty());
236 EndListening(*pDocShell);
237 delete pSearchItem;
239 aEditWin.disposeAndClear();
242 void SwSrcView::SaveContentTo(SfxMedium& rMed)
244 SvStream* pOutStream = rMed.GetOutStream();
245 pOutStream->SetStreamCharSet(lcl_GetStreamCharSet(eLoadEncoding));
246 aEditWin->Write( *pOutStream );
249 void SwSrcView::Init()
251 SetName("Source");
252 SetWindow( aEditWin.get() );
253 SwDocShell* pDocShell = GetDocShell();
254 // If the doc is still loading, then the DocShell must fire up
255 // the Load if the loading is completed.
256 if(!pDocShell->IsLoading())
257 Load(pDocShell);
258 else
260 aEditWin->SetReadonly(true);
263 SetNewWindowAllowed( false );
264 StartListening(*pDocShell, DuplicateHandling::Prevent);
267 SwDocShell* SwSrcView::GetDocShell()
269 SfxObjectShell* pObjShell = GetViewFrame()->GetObjectShell();
270 return dynamic_cast<SwDocShell*>( pObjShell );
273 void SwSrcView::SaveContent(const OUString& rTmpFile)
275 SfxMedium aMedium( rTmpFile, StreamMode::WRITE);
276 SvStream* pOutStream = aMedium.GetOutStream();
277 pOutStream->SetStreamCharSet( lcl_GetStreamCharSet(eLoadEncoding) );
278 aEditWin->Write(*pOutStream);
279 aMedium.Commit();
282 void SwSrcView::Execute(SfxRequest& rReq)
284 TextView* pTextView = aEditWin->GetTextView();
285 switch( rReq.GetSlot() )
287 case SID_SAVEACOPY:
288 case SID_SAVEASDOC:
290 SvtPathOptions aPathOpt;
291 // filesave dialog with autoextension
292 FileDialogHelper aDlgHelper(
293 TemplateDescription::FILESAVE_AUTOEXTENSION,
294 FileDialogFlags::NONE, aEditWin->GetFrameWeld());
295 uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
296 uno::Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY);
298 // search for an html filter for export
299 SfxFilterContainer* pFilterCont = GetObjectShell()->GetFactory().GetFilterContainer();
300 std::shared_ptr<const SfxFilter> pFilter =
301 pFilterCont->GetFilter4Extension( "html", SfxFilterFlags::EXPORT );
302 if ( pFilter )
304 // filter found -> use its uiname and wildcard
305 const OUString& rUIName = pFilter->GetUIName();
306 const WildCard& rCard = pFilter->GetWildcard();
307 xFltMgr->appendFilter( rUIName, rCard.getGlob() );
308 xFltMgr->setCurrentFilter( rUIName ) ;
310 else
312 // filter not found
313 OUString sHtml("HTML");
314 xFltMgr->appendFilter( sHtml, "*.html;*.htm" );
315 xFltMgr->setCurrentFilter( sHtml ) ;
318 xFP->setDisplayDirectory( aPathOpt.GetWorkPath() );
319 if( aDlgHelper.Execute() == ERRCODE_NONE)
321 SfxMedium aMedium( xFP->getSelectedFiles().getConstArray()[0],
322 StreamMode::WRITE | StreamMode::SHARE_DENYNONE );
323 SvStream* pOutStream = aMedium.GetOutStream();
324 pOutStream->SetStreamCharSet(lcl_GetStreamCharSet(eLoadEncoding));
325 aEditWin->Write( *pOutStream );
326 aMedium.Commit();
329 break;
330 case SID_SAVEDOC:
332 SwDocShell* pDocShell = GetDocShell();
333 SfxMedium* pMed = nullptr;
334 if(pDocShell->HasName())
335 pMed = pDocShell->GetMedium();
336 else
338 const SfxBoolItem* pItem = static_cast<const SfxBoolItem*>(pDocShell->ExecuteSlot(rReq, pDocShell->GetInterface()));
339 if(pItem && pItem->GetValue())
340 pMed = pDocShell->GetMedium();
342 if(pMed)
344 SvStream* pOutStream = pMed->GetOutStream();
345 pOutStream->Seek(0);
346 pOutStream->SetStreamSize(0);
347 pOutStream->SetStreamCharSet(lcl_GetStreamCharSet(eLoadEncoding));
348 aEditWin->Write( *pOutStream );
349 pMed->CloseOutStream();
350 pMed->Commit();
351 pDocShell->GetDoc()->getIDocumentState().ResetModified();
352 bSourceSaved = true;
353 aEditWin->ClearModifyFlag();
356 break;
357 case FID_SEARCH_NOW:
359 const SfxItemSet* pTmpArgs = rReq.GetArgs();
361 const sal_uInt16 nWhich = pTmpArgs->GetWhichByPos( 0 );
362 OSL_ENSURE( nWhich, "Which for SearchItem ?" );
363 const SfxPoolItem& rItem = pTmpArgs->Get( nWhich );
364 SetSearchItem( static_cast<const SvxSearchItem&>(rItem));
365 StartSearchAndReplace( static_cast<const SvxSearchItem&>(rItem), rReq.IsAPI() );
366 if(aEditWin->IsModified())
367 GetDocShell()->GetDoc()->getIDocumentState().SetModified();
369 break;
370 case FN_REPEAT_SEARCH:
372 SvxSearchItem* pSrchItem = GetSearchItem();
373 if(pSrchItem)
375 StartSearchAndReplace( *pSrchItem, rReq.IsAPI() );
376 if(aEditWin->IsModified())
377 GetDocShell()->GetDoc()->getIDocumentState().SetModified();
380 break;
381 case SID_PRINTDOC:
382 case SID_PRINTDOCDIRECT:
384 SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
386 break;
387 case SID_UNDO:
388 pTextView->Undo();
389 GetViewFrame()->GetBindings().InvalidateAll(false);
390 break;
391 case SID_REDO:
392 pTextView->Redo();
393 GetViewFrame()->GetBindings().InvalidateAll(false);
394 break;
395 case SID_REPEAT:
396 break;
397 case SID_CUT:
398 if(pTextView->HasSelection())
399 pTextView->Cut();
400 break;
401 case SID_COPY:
402 if(pTextView->HasSelection())
403 pTextView->Copy();
404 break;
405 case SID_PASTE:
406 pTextView->Paste();
407 break;
408 case SID_SELECTALL:
409 pTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) );
410 break;
412 aEditWin->Invalidate();
415 void SwSrcView::GetState(SfxItemSet& rSet)
417 SfxWhichIter aIter(rSet);
418 sal_uInt16 nWhich = aIter.FirstWhich();
419 TextView* pTextView = aEditWin->GetTextView();
421 while(nWhich)
423 switch(nWhich)
425 case SID_SAVEASDOC:
426 rSet.Put(SfxStringItem(nWhich, SwResId(STR_SAVEAS_SRC)));
427 break;
428 case SID_SAVEACOPY:
429 rSet.Put(SfxStringItem(nWhich, SwResId(STR_SAVEACOPY_SRC)));
430 break;
431 case SID_SAVEDOC:
433 SwDocShell* pDocShell = GetDocShell();
434 if(!pDocShell->IsModified())
435 rSet.DisableItem(nWhich);
437 break;
438 case SID_PRINTDOC:
439 case SID_PRINTDOCDIRECT:
440 break;
441 case SID_TABLE_CELL:
443 OUString aPos( SwResId(STR_SRCVIEW_ROW) );
444 TextSelection aSel = pTextView->GetSelection();
445 aPos += OUString::number( aSel.GetEnd().GetPara()+1 );
446 aPos += " : ";
447 aPos += SwResId(STR_SRCVIEW_COL);
448 aPos += OUString::number( aSel.GetEnd().GetIndex()+1 );
449 SfxStringItem aItem( nWhich, aPos );
450 rSet.Put( aItem );
452 break;
453 case SID_SEARCH_OPTIONS:
455 SearchOptionFlags nOpt = SRC_SEARCHOPTIONS;
456 if(GetDocShell()->IsReadOnly())
457 nOpt &= ~SearchOptionFlags(SearchOptionFlags::REPLACE|SearchOptionFlags::REPLACE_ALL);
459 rSet.Put( SfxUInt16Item( SID_SEARCH_OPTIONS, static_cast<sal_uInt16>(nOpt) ) );
461 break;
462 case SID_SEARCH_ITEM:
464 OUString sSelected;
465 if ( !pTextView->HasSelection() )
467 const TextSelection& rSel = pTextView->GetSelection();
468 sSelected = aEditWin->GetTextEngine()->GetWord( rSel.GetStart());
470 else
472 sSelected = pTextView->GetSelected();
474 SvxSearchItem * pSrchItem = GetSearchItem();
475 pSrchItem->SetSearchString( sSelected );
476 rSet.Put( *pSrchItem );
478 break;
479 case FN_REPEAT_SEARCH:
481 if(!GetSearchItem())
482 rSet.DisableItem(nWhich);
484 break;
485 case SID_UNDO:
486 case SID_REDO:
488 ::svl::IUndoManager& rMgr = pTextView->GetTextEngine()->GetUndoManager();
489 sal_uInt16 nCount = 0;
490 if(nWhich == SID_UNDO)
492 nCount = rMgr.GetUndoActionCount();
493 if(nCount)
495 OUString aStr(SvtResId( STR_UNDO));
496 aStr += rMgr.GetUndoActionComment(--nCount);
497 rSet.Put(SfxStringItem(nWhich, aStr));
499 else
500 rSet.DisableItem(nWhich);
502 else
504 nCount = rMgr.GetRedoActionCount();
505 if(nCount)
507 OUString aStr(SvtResId( STR_REDO));
508 aStr += rMgr.GetRedoActionComment(--nCount);
509 rSet.Put(SfxStringItem(nWhich,aStr));
511 else
512 rSet.DisableItem(nWhich);
515 break;
516 case SID_MAIL_SENDDOCASPDF:
517 case SID_MAIL_SENDDOC :
518 case SID_EXPORTDOCASPDF:
519 case SID_DIRECTEXPORTDOCASPDF:
520 case SID_EXPORTDOC:
521 case SID_REPEAT:
522 case SID_BROWSER_MODE:
523 case FN_PRINT_LAYOUT:
524 rSet.DisableItem(nWhich);
525 break;
526 case SID_CUT:
527 case SID_COPY:
528 if(!pTextView->HasSelection())
529 rSet.DisableItem(nWhich);
530 break;
531 case SID_PASTE:
533 TransferableDataHelper aDataHelper(
534 TransferableDataHelper::CreateFromSystemClipboard(
535 aEditWin.get()) );
536 bool bDisable = !aDataHelper.GetXTransferable().is() ||
537 0 == aDataHelper.GetFormatCount();
538 if( bDisable )
539 rSet.DisableItem(nWhich);
541 break;
543 nWhich = aIter.NextWhich();
547 SvxSearchItem* SwSrcView::GetSearchItem()
549 if(!pSearchItem)
551 pSearchItem = new SvxSearchItem(SID_SEARCH_ITEM);
553 return pSearchItem;
556 void SwSrcView::SetSearchItem( const SvxSearchItem& rItem )
558 delete pSearchItem;
559 pSearchItem = static_cast<SvxSearchItem*>(rItem.Clone());
562 void SwSrcView::StartSearchAndReplace(const SvxSearchItem& rSearchItem,
563 bool bApi,
564 bool bRecursive)
566 TextView* pTextView = aEditWin->GetTextView();
567 TextSelection aSel;
568 TextPaM aPaM;
570 bool bForward = !rSearchItem.GetBackward();
571 bool bAtStart = pTextView->GetSelection() == TextSelection( aPaM, aPaM );
573 if( !bForward )
574 aPaM = TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL );
576 i18nutil::SearchOptions2 aSearchOpt( rSearchItem.GetSearchOptions() );
577 aSearchOpt.Locale = GetAppLanguageTag().getLocale();
579 sal_uInt16 nFound;
580 bool bAll = false;
581 switch( rSearchItem.GetCommand() )
583 case SvxSearchCmd::FIND:
584 case SvxSearchCmd::FIND_ALL:
585 nFound = pTextView->Search( aSearchOpt, bForward ) ? 1 : 0;
586 break;
588 case SvxSearchCmd::REPLACE_ALL: bAll = true;
589 SAL_FALLTHROUGH;
590 case SvxSearchCmd::REPLACE:
591 nFound = pTextView->Replace( aSearchOpt, bAll, bForward );
592 break;
594 default:
595 nFound = 0;
598 if( !nFound )
600 bool bNotFoundMessage = false;
601 if(!bRecursive)
603 bNotFoundMessage = bAtStart;
605 else if(bAtStart)
607 bNotFoundMessage = true;
610 if(!bApi)
612 if(bNotFoundMessage)
614 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/infonotfounddialog.ui"));
615 std::unique_ptr<weld::MessageDialog> xInfoBox(xBuilder->weld_message_dialog("InfoNotFoundDialog"));
616 xInfoBox->run();
618 else if(!bRecursive)
620 int nRet;
622 if (!bForward)
624 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/querycontinueenddialog.ui"));
625 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("QueryContinueEndDialog"));
626 nRet = xQueryBox->run();
628 else
630 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/querycontinuebegindialog.ui"));
631 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("QueryContinueBeginDialog"));
632 nRet = xQueryBox->run();
635 if (nRet == RET_YES)
637 pTextView->SetSelection( TextSelection( aPaM, aPaM ) );
638 StartSearchAndReplace( rSearchItem, false, true );
645 sal_uInt16 SwSrcView::SetPrinter(SfxPrinter* pNew, SfxPrinterChangeFlags nDiffFlags )
647 SwDocShell* pDocSh = GetDocShell();
648 if ( (SfxPrinterChangeFlags::JOBSETUP | SfxPrinterChangeFlags::PRINTER) & nDiffFlags )
650 pDocSh->GetDoc()->getIDocumentDeviceAccess().setPrinter( pNew, true, true );
651 if ( nDiffFlags & SfxPrinterChangeFlags::PRINTER )
652 pDocSh->SetModified();
654 if ( nDiffFlags & SfxPrinterChangeFlags::OPTIONS )
655 ::SetPrinter( &pDocSh->getIDocumentDeviceAccess(), pNew, true );
657 const bool bChgOri = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION);
658 const bool bChgSize = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE);
659 if ( bChgOri || bChgSize )
661 pDocSh->SetModified();
663 return 0;
666 SfxPrinter* SwSrcView::GetPrinter( bool bCreate )
668 return GetDocShell()->GetDoc()->getIDocumentDeviceAccess().getPrinter( bCreate );
671 sal_Int32 SwSrcView::PrintSource(
672 OutputDevice *pOutDev,
673 sal_Int32 nPage,
674 bool bCalcNumPagesOnly )
676 if (!pOutDev || nPage <= 0)
677 return 0;
679 //! This algorithm for printing the n-th page is very poor since it
680 //! needs to go over the text of all previous pages to get to the correct one.
681 //! But since HTML source code is expected to be just a small number of pages
682 //! even this poor algorithm should be enough...
684 pOutDev->Push();
686 TextEngine* pTextEngine = aEditWin->GetTextEngine();
687 pOutDev->SetMapMode(MapMode(MapUnit::Map100thMM));
688 vcl::Font aFont( aEditWin->GetOutWin()->GetFont() );
689 Size aSize( aFont.GetFontSize() );
690 aSize = aEditWin->GetOutWin()->PixelToLogic(aSize, MapMode(MapUnit::Map100thMM));
691 aFont.SetFontSize( aSize );
692 aFont.SetColor( COL_BLACK );
693 pOutDev->SetFont( aFont );
695 OUString aTitle( GetViewFrame()->GetWindow().GetText() );
697 const long nLineHeight = pOutDev->GetTextHeight(); // slightly more
698 const long nParaSpace = 10;
700 Size aPaperSz = pOutDev->GetOutputSize();
701 aPaperSz.AdjustWidth( -(LMARGPRN + RMARGPRN) );
702 aPaperSz.AdjustHeight( -(TMARGPRN + BMARGPRN) );
704 // nLinepPage is not true, if lines have to be wrapped...
705 const long nLinespPage = nLineHeight ? aPaperSz.Height() / nLineHeight : 1;
706 const long nCharWidth = pOutDev->GetTextWidth("X");
707 const sal_Int32 nCharspLine = nCharWidth ? static_cast<sal_Int32>(aPaperSz.Width() / nCharWidth) : 1;
708 const sal_uInt32 nParas = pTextEngine->GetParagraphCount();
710 const sal_Int32 nPages = static_cast<sal_Int32>(nParas / nLinespPage + 1 );
711 sal_Int32 nCurPage = 1;
713 // Print header...
714 if (!bCalcNumPagesOnly && nPage == nCurPage)
715 lcl_PrintHeader( *pOutDev, nPages, nCurPage, aTitle );
716 const Point aStartPos( LMARGPRN, TMARGPRN );
717 Point aPos( aStartPos );
718 for ( sal_uInt32 nPara = 0; nPara < nParas; ++nPara )
720 const OUString aLine( lcl_ConvertTabsToSpaces(pTextEngine->GetText( nPara )) );
721 const sal_Int32 nLineLen = aLine.getLength();
722 const sal_Int32 nLines = (nLineLen+nCharspLine-1) / nCharspLine;
723 for ( sal_Int32 nLine = 0; nLine < nLines; ++nLine )
725 aPos.AdjustY(nLineHeight );
726 if ( aPos.Y() > ( aPaperSz.Height() + TMARGPRN - nLineHeight/2 ) )
728 ++nCurPage;
729 if (!bCalcNumPagesOnly && nPage == nCurPage)
730 lcl_PrintHeader( *pOutDev, nPages, nCurPage, aTitle );
731 aPos = aStartPos;
733 if (!bCalcNumPagesOnly && nPage == nCurPage)
735 const sal_Int32 nStart = nLine * nCharspLine;
736 const sal_Int32 nLen = std::min(nLineLen-nStart, nCharspLine);
737 pOutDev->DrawText( aPos, aLine.copy(nStart, nLen) );
740 aPos.AdjustY(nParaSpace );
743 pOutDev->Pop();
745 OSL_ENSURE( bCalcNumPagesOnly || nPage <= nCurPage, "page number out of range" );
746 return nCurPage;
749 void SwSrcView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
751 if ( rHint.GetId() == SfxHintId::ModeChanged ||
753 rHint.GetId() == SfxHintId::TitleChanged &&
754 !GetDocShell()->IsReadOnly() && aEditWin->IsReadonly()
758 // Broadcast only comes once!
759 const SwDocShell* pDocSh = GetDocShell();
760 const bool bReadonly = pDocSh->IsReadOnly();
761 aEditWin->SetReadonly(bReadonly);
763 SfxViewShell::Notify(rBC, rHint);
766 void SwSrcView::Load(SwDocShell* pDocShell)
768 SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
769 const sal_Char *pCharSet =
770 rtl_getBestMimeCharsetFromTextEncoding( rHtmlOptions.GetTextEncoding() );
771 rtl_TextEncoding eDestEnc = rtl_getTextEncodingFromMimeCharset( pCharSet );
773 aEditWin->SetReadonly(pDocShell->IsReadOnly());
774 aEditWin->SetTextEncoding(eDestEnc);
775 SfxMedium* pMedium = pDocShell->GetMedium();
777 std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
778 bool bHtml = pFilter && pFilter->GetUserData() == "HTML";
779 bool bDocModified = pDocShell->IsModified();
780 if(bHtml && !bDocModified && pDocShell->HasName())
782 SvStream* pStream = pMedium->GetInStream();
783 if(pStream && ERRCODE_NONE == pStream->GetError() )
785 rtl_TextEncoding eHeaderEnc =
786 SfxHTMLParser::GetEncodingByHttpHeader(
787 pDocShell->GetHeaderAttributes() );
788 if( RTL_TEXTENCODING_DONTKNOW == eHeaderEnc )
790 const sal_Char *pTmpCharSet =
791 rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 );
792 eHeaderEnc = rtl_getTextEncodingFromMimeCharset( pTmpCharSet );
794 if( RTL_TEXTENCODING_DONTKNOW != eHeaderEnc &&
795 eDestEnc != eHeaderEnc )
797 eDestEnc = eHeaderEnc;
798 aEditWin->SetTextEncoding(eDestEnc);
800 pStream->SetStreamCharSet( eDestEnc );
801 pStream->Seek(0);
802 TextEngine* pTextEngine = aEditWin->GetTextEngine();
803 pTextEngine->EnableUndo(false);
804 aEditWin->Read(*pStream);
805 pTextEngine->EnableUndo(true);
807 else
809 vcl::Window& rTmpWindow = GetViewFrame()->GetWindow();
810 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(rTmpWindow.GetFrameWeld(),
811 VclMessageType::Info, VclButtonsType::Ok,
812 SwResId(STR_ERR_SRCSTREAM)));
813 xBox->run();
816 else
818 utl::TempFile aTempFile;
819 aTempFile.EnableKillingFile();
820 const OUString sFileURL( aTempFile.GetURL() );
821 SvtSaveOptions aOpt;
824 SfxMedium aMedium( sFileURL,StreamMode::READWRITE );
825 SwWriter aWriter( aMedium, *pDocShell->GetDoc() );
826 WriterRef xWriter;
827 ::GetHTMLWriter(OUString(), aMedium.GetBaseURL( true ), xWriter);
828 const OUString sWriteName = pDocShell->HasName()
829 ? pMedium->GetName()
830 : sFileURL;
831 ErrCode nRes = aWriter.Write(xWriter, &sWriteName);
832 if(nRes)
834 ErrorHandler::HandleError(ErrCode(nRes));
835 aEditWin->SetReadonly(true);
837 aMedium.Commit();
838 SvStream* pInStream = aMedium.GetInStream();
839 pInStream->Seek(0);
840 pInStream->SetStreamCharSet( eDestEnc );
842 aEditWin->Read(*pInStream);
845 aEditWin->ClearModifyFlag();
847 eLoadEncoding = eDestEnc;
849 if(bDocModified)
850 pDocShell->SetModified();// The flag will be reset in between times.
851 // Disable AutoLoad
852 pDocShell->SetAutoLoad(INetURLObject(), 0, false);
853 OSL_ENSURE(dynamic_cast<SwWebDocShell*>( pDocShell), "Why no WebDocShell?" );
854 sal_uInt16 nLine = static_cast<SwWebDocShell*>(pDocShell)->GetSourcePara();
855 aEditWin->SetStartLine(nLine);
856 aEditWin->GetTextEngine()->ResetUndo();
857 aEditWin->GetOutWin()->GrabFocus();
860 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */