Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / uiview / srcview.cxx
blob0a936b67f311373e3eb65bea02f6d156c6f11b55
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 <rtl/tencinfo.h>
21 #include <osl/diagnose.h>
22 #include <com/sun/star/frame/XModel.hpp>
23 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
24 #include <unotools/tempfile.hxx>
25 #include <tools/urlobj.hxx>
26 #include <vcl/errinf.hxx>
27 #include <vcl/weld.hxx>
28 #include <vcl/textview.hxx>
29 #include <vcl/svapp.hxx>
30 #include <svl/intitem.hxx>
31 #include <svl/stritem.hxx>
32 #include <svl/undo.hxx>
33 #include <svl/eitem.hxx>
34 #include <svl/whiter.hxx>
35 #include <vcl/transfer.hxx>
36 #include <svtools/strings.hrc>
37 #include <svtools/svtresid.hxx>
38 #include <svtools/htmlcfg.hxx>
39 #include <sfx2/app.hxx>
40 #include <sfx2/objface.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/docfilt.hxx>
44 #include <sfx2/fcontnr.hxx>
45 #include <sfx2/request.hxx>
46 #include <sfx2/docfile.hxx>
47 #include <svx/srchdlg.hxx>
48 #include <svx/statusitem.hxx>
49 #include <svl/srchitem.hxx>
50 #include <sfx2/sfxhtml.hxx>
51 #include <swtypes.hxx>
52 #include <docsh.hxx>
53 #include <wdocsh.hxx>
54 #include <srcview.hxx>
55 #include "viewfunc.hxx"
56 #include <doc.hxx>
57 #include <IDocumentDeviceAccess.hxx>
58 #include <IDocumentState.hxx>
59 #include <sfx2/msg.hxx>
60 #include <shellio.hxx>
62 #include <cmdid.h>
63 #include <strings.hrc>
64 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
65 #include <sfx2/filedlghelper.hxx>
66 #define ShellClass_SwSrcView
67 #include <swslots.hxx>
69 #include <com/sun/star/document/XDocumentProperties.hpp>
70 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
72 using namespace ::com::sun::star;
73 using namespace ::com::sun::star::i18n;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::ui::dialogs;
77 using namespace ::sfx2;
79 #define SWSRCVIEWFLAGS SfxViewShellFlags::NO_NEWWINDOW
81 #define SRC_SEARCHOPTIONS (SearchOptionFlags::ALL & ~SearchOptionFlags(SearchOptionFlags::FORMAT|SearchOptionFlags::FAMILIES|SearchOptionFlags::SEARCHALL))
83 // Printing margins -> like Basic - Ide
84 #define LMARGPRN 1700
85 #define RMARGPRN 900
86 #define TMARGPRN 2000
87 #define BMARGPRN 1000
88 #define BORDERPRN 300
90 SFX_IMPL_NAMED_VIEWFACTORY(SwSrcView, "SourceView")
92 SFX_VIEW_REGISTRATION(SwWebDocShell);
95 SFX_IMPL_SUPERCLASS_INTERFACE(SwSrcView, SfxViewShell)
97 void SwSrcView::InitInterface_Impl()
99 GetStaticInterface()->RegisterPopupMenu("source");
101 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_TOOLS,
102 SfxVisibilityFlags::Standard|SfxVisibilityFlags::Server,
103 ToolbarId::Webtools_Toolbox);
105 GetStaticInterface()->RegisterChildWindow(SvxSearchDialogWrapper::GetChildWindowId());
109 static void lcl_PrintHeader( vcl::RenderContext &rOutDev, sal_Int32 nPages, sal_Int32 nCurPage, const OUString& rTitle )
111 short nLeftMargin = LMARGPRN;
112 Size aSz = rOutDev.GetOutputSize();
113 short nBorder = BORDERPRN;
115 Color aOldFillColor( rOutDev.GetFillColor() );
116 vcl::Font aOldFont( rOutDev.GetFont() );
118 rOutDev.SetFillColor( COL_TRANSPARENT );
120 vcl::Font aFont( aOldFont );
121 aFont.SetWeight( WEIGHT_BOLD );
122 aFont.SetAlignment( ALIGN_BOTTOM );
123 rOutDev.SetFont( aFont );
125 tools::Long nFontHeight = rOutDev.GetTextHeight();
127 // 1.Border => Line, 2+3 Border = Space.
128 tools::Long nYTop = TMARGPRN-3*nBorder-nFontHeight;
130 tools::Long nXLeft = nLeftMargin-nBorder;
131 tools::Long nXRight = aSz.Width()-RMARGPRN+nBorder;
133 rOutDev.DrawRect( tools::Rectangle(
134 Point( nXLeft, nYTop ),
135 Size( nXRight-nXLeft, aSz.Height() - nYTop - BMARGPRN + nBorder ) ) );
137 tools::Long nY = TMARGPRN-2*nBorder;
138 Point aPos( nLeftMargin, nY );
139 rOutDev.DrawText( aPos, rTitle );
140 if ( nPages != 1 )
142 aFont.SetWeight( WEIGHT_NORMAL );
143 rOutDev.SetFont( aFont );
144 OUString aPageStr = " [" + SwResId( STR_PAGE ) + " " + OUString::number( nCurPage ) + "]";
145 aPos.AdjustX(rOutDev.GetTextWidth( rTitle ) );
146 rOutDev.DrawText( aPos, aPageStr );
149 nY = TMARGPRN-nBorder;
151 rOutDev.DrawLine( Point( nXLeft, nY ), Point( nXRight, nY ) );
153 rOutDev.SetFont( aOldFont );
154 rOutDev.SetFillColor( aOldFillColor );
157 static rtl_TextEncoding lcl_GetStreamCharSet(rtl_TextEncoding eLoadEncoding)
159 rtl_TextEncoding eRet = eLoadEncoding;
160 if(RTL_TEXTENCODING_DONTKNOW == eRet)
162 eRet = RTL_TEXTENCODING_UTF8;
164 return eRet;
167 static OUString lcl_ConvertTabsToSpaces( const OUString& sLine )
169 if (sLine.isEmpty())
170 return sLine;
172 OUString aRet = sLine;
173 const sal_Unicode aPadSpaces[4] = {' ', ' ', ' ', ' '};
174 sal_Int32 nPos = 0;
175 for (;;)
177 nPos = aRet.indexOf('\t', nPos);
178 if (nPos<0)
180 break;
182 // Not 4 blanks, but on 4th TabPos:
183 const sal_Int32 nPadLen = 4 - (nPos % 4);
184 aRet = aRet.replaceAt(nPos, 1, std::u16string_view{aPadSpaces, static_cast<size_t>(nPadLen)});
185 nPos += nPadLen;
187 return aRet;
190 SwSrcView::SwSrcView(SfxViewFrame& rViewFrame, SfxViewShell*) :
191 SfxViewShell( rViewFrame, SWSRCVIEWFLAGS ),
192 m_aEditWin( VclPtr<SwSrcEditWindow>::Create( &rViewFrame.GetWindow(), this ) ),
193 m_bSourceSaved(false),
194 m_eLoadEncoding(RTL_TEXTENCODING_DONTKNOW)
196 Init();
199 SwSrcView::~SwSrcView()
201 SwDocShell* pDocShell = GetDocShell();
202 assert(dynamic_cast<SwWebDocShell*>( pDocShell) && "Why no WebDocShell?" );
203 const TextSelection& rSel = m_aEditWin->GetTextView()->GetSelection();
204 static_cast<SwWebDocShell*>(pDocShell)->SetSourcePara( static_cast< sal_uInt16 >( rSel.GetStart().GetPara() ) );
206 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
207 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
208 uno::Reference<document::XDocumentProperties> xDocProps
209 = xDPS->getDocumentProperties();
210 OUString url = xDocProps->getAutoloadURL();
211 sal_Int32 delay = xDocProps->getAutoloadSecs();
212 pDocShell->SetAutoLoad(INetURLObject(url), delay,
213 (delay != 0) || !url.isEmpty());
214 EndListening(*pDocShell);
215 m_pSearchItem.reset();
217 m_aEditWin.disposeAndClear();
220 void SwSrcView::SaveContentTo(SfxMedium& rMed)
222 SvStream* pOutStream = rMed.GetOutStream();
223 pOutStream->SetStreamCharSet(lcl_GetStreamCharSet(m_eLoadEncoding));
224 m_aEditWin->Write( *pOutStream );
227 void SwSrcView::Init()
229 SetName("Source");
230 SetWindow( m_aEditWin.get() );
231 SwDocShell* pDocShell = GetDocShell();
232 // If the doc is still loading, then the DocShell must fire up
233 // the Load if the loading is completed.
234 if(!pDocShell->IsLoading())
235 Load(pDocShell);
236 else
238 m_aEditWin->SetReadonly(true);
241 SetNewWindowAllowed( false );
242 StartListening(*pDocShell, DuplicateHandling::Prevent);
245 SwDocShell* SwSrcView::GetDocShell()
247 SfxObjectShell* pObjShell = GetViewFrame().GetObjectShell();
248 return dynamic_cast<SwDocShell*>( pObjShell );
251 void SwSrcView::SaveContent(const OUString& rTmpFile)
253 SfxMedium aMedium( rTmpFile, StreamMode::WRITE);
254 SvStream* pOutStream = aMedium.GetOutStream();
255 pOutStream->SetStreamCharSet( lcl_GetStreamCharSet(m_eLoadEncoding) );
256 m_aEditWin->Write(*pOutStream);
257 aMedium.Commit();
260 void SwSrcView::Execute(SfxRequest& rReq)
262 TextView* pTextView = m_aEditWin->GetTextView();
263 switch( rReq.GetSlot() )
265 case SID_SAVEACOPY:
266 case SID_SAVEASDOC:
268 // filesave dialog with autoextension
269 FileDialogHelper aDlgHelper(
270 TemplateDescription::FILESAVE_AUTOEXTENSION,
271 FileDialogFlags::NONE, m_aEditWin->GetFrameWeld());
272 uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
274 // search for an html filter for export
275 SfxFilterContainer* pFilterCont = GetObjectShell()->GetFactory().GetFilterContainer();
276 std::shared_ptr<const SfxFilter> pFilter =
277 pFilterCont->GetFilter4Extension( "html", SfxFilterFlags::EXPORT );
278 if ( pFilter )
280 // filter found -> use its uiname and wildcard
281 const OUString& rUIName = pFilter->GetUIName();
282 const WildCard& rCard = pFilter->GetWildcard();
283 xFP->appendFilter( rUIName, rCard.getGlob() );
284 xFP->setCurrentFilter( rUIName ) ;
286 else
288 // filter not found
289 OUString sHtml("HTML");
290 xFP->appendFilter( sHtml, "*.html;*.htm" );
291 xFP->setCurrentFilter( sHtml ) ;
294 if( aDlgHelper.Execute() == ERRCODE_NONE)
296 SfxMedium aMedium( xFP->getSelectedFiles().getConstArray()[0],
297 StreamMode::WRITE | StreamMode::SHARE_DENYNONE );
298 SvStream* pOutStream = aMedium.GetOutStream();
299 pOutStream->SetStreamCharSet(lcl_GetStreamCharSet(m_eLoadEncoding));
300 m_aEditWin->Write( *pOutStream );
301 aMedium.Commit();
304 break;
305 case SID_SAVEDOC:
307 SwDocShell* pDocShell = GetDocShell();
308 assert(pDocShell);
309 SfxMedium* pMed = nullptr;
310 if(pDocShell->HasName())
311 pMed = pDocShell->GetMedium();
312 else
314 const SfxBoolItem* pItem = static_cast<const SfxBoolItem*>(pDocShell->ExecuteSlot(rReq, pDocShell->GetInterface()));
315 if(pItem && pItem->GetValue())
316 pMed = pDocShell->GetMedium();
318 if(pMed)
320 SvStream* pOutStream = pMed->GetOutStream();
321 pOutStream->Seek(0);
322 pOutStream->SetStreamSize(0);
323 pOutStream->SetStreamCharSet(lcl_GetStreamCharSet(m_eLoadEncoding));
324 m_aEditWin->Write( *pOutStream );
325 pMed->CloseOutStream();
326 pMed->Commit();
327 pDocShell->GetDoc()->getIDocumentState().ResetModified();
328 m_bSourceSaved = true;
329 m_aEditWin->ClearModifyFlag();
332 break;
333 case FID_SEARCH_NOW:
335 const SfxItemSet* pTmpArgs = rReq.GetArgs();
337 const sal_uInt16 nWhich = pTmpArgs->GetWhichByPos( 0 );
338 OSL_ENSURE( nWhich, "Which for SearchItem ?" );
339 const SfxPoolItem& rItem = pTmpArgs->Get( nWhich );
340 SetSearchItem( static_cast<const SvxSearchItem&>(rItem));
341 StartSearchAndReplace( static_cast<const SvxSearchItem&>(rItem), rReq.IsAPI() );
342 if(m_aEditWin->IsModified())
344 SwDocShell* pDocShell = GetDocShell();
345 assert(pDocShell);
346 pDocShell->GetDoc()->getIDocumentState().SetModified();
349 break;
350 case FN_REPEAT_SEARCH:
352 SvxSearchItem* pSrchItem = GetSearchItem();
353 if(pSrchItem)
355 StartSearchAndReplace( *pSrchItem, rReq.IsAPI() );
356 if(m_aEditWin->IsModified())
357 GetDocShell()->GetDoc()->getIDocumentState().SetModified();
360 break;
361 case SID_PRINTDOC:
362 case SID_PRINTDOCDIRECT:
364 SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
366 break;
367 case SID_UNDO:
368 pTextView->Undo();
369 GetViewFrame().GetBindings().InvalidateAll(false);
370 break;
371 case SID_REDO:
372 pTextView->Redo();
373 GetViewFrame().GetBindings().InvalidateAll(false);
374 break;
375 case SID_REPEAT:
376 break;
377 case SID_CUT:
378 if(pTextView->HasSelection())
379 pTextView->Cut();
380 break;
381 case SID_COPY:
382 if(pTextView->HasSelection())
383 pTextView->Copy();
384 break;
385 case SID_PASTE:
386 pTextView->Paste();
387 break;
388 case SID_SELECTALL:
389 pTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) );
390 break;
392 m_aEditWin->Invalidate();
395 void SwSrcView::GetState(SfxItemSet& rSet)
397 SfxWhichIter aIter(rSet);
398 sal_uInt16 nWhich = aIter.FirstWhich();
399 TextView* pTextView = m_aEditWin->GetTextView();
401 while(nWhich)
403 switch(nWhich)
405 case SID_SAVEASDOC:
406 rSet.Put(SfxStringItem(nWhich, SwResId(STR_SAVEAS_SRC)));
407 break;
408 case SID_SAVEACOPY:
409 rSet.Put(SfxStringItem(nWhich, SwResId(STR_SAVEACOPY_SRC)));
410 break;
411 case SID_SAVEDOC:
413 SwDocShell* pDocShell = GetDocShell();
414 assert(pDocShell);
415 if(!pDocShell->IsModified())
416 rSet.DisableItem(nWhich);
418 break;
419 case SID_PRINTDOC:
420 case SID_PRINTDOCDIRECT:
421 break;
422 case SID_TABLE_CELL:
424 TextSelection aSel = pTextView->GetSelection();
425 OUString aPos =
426 SwResId(STR_SRCVIEW_ROW)
427 + OUString::number( aSel.GetEnd().GetPara()+1 )
428 + " : "
429 + SwResId(STR_SRCVIEW_COL)
430 + OUString::number( aSel.GetEnd().GetIndex()+1 );
431 SvxStatusItem aItem( SID_TABLE_CELL, aPos, StatusCategory::RowColumn );
432 rSet.Put( aItem );
434 break;
435 case SID_SEARCH_OPTIONS:
437 SearchOptionFlags nOpt = SRC_SEARCHOPTIONS;
438 SwDocShell* pDocShell = GetDocShell();
439 assert(pDocShell);
440 if (pDocShell->IsReadOnly())
441 nOpt &= ~SearchOptionFlags(SearchOptionFlags::REPLACE|SearchOptionFlags::REPLACE_ALL);
443 rSet.Put( SfxUInt16Item( SID_SEARCH_OPTIONS, static_cast<sal_uInt16>(nOpt) ) );
445 break;
446 case SID_SEARCH_ITEM:
448 OUString sSelected;
449 if ( !pTextView->HasSelection() )
451 const TextSelection& rSel = pTextView->GetSelection();
452 sSelected = m_aEditWin->GetTextEngine()->GetWord( rSel.GetStart());
454 else
456 sSelected = pTextView->GetSelected();
458 SvxSearchItem * pSrchItem = GetSearchItem();
459 pSrchItem->SetSearchString( sSelected );
460 rSet.Put( *pSrchItem );
462 break;
463 case FN_REPEAT_SEARCH:
465 if(!GetSearchItem())
466 rSet.DisableItem(nWhich);
468 break;
469 case SID_UNDO:
470 case SID_REDO:
472 SfxUndoManager& rMgr = pTextView->GetTextEngine()->GetUndoManager();
473 sal_uInt16 nCount = 0;
474 if(nWhich == SID_UNDO)
476 nCount = rMgr.GetUndoActionCount();
477 if(nCount)
479 OUString aStr = SvtResId( STR_UNDO) + rMgr.GetUndoActionComment(--nCount);
480 rSet.Put(SfxStringItem(nWhich, aStr));
482 else
483 rSet.DisableItem(nWhich);
485 else
487 nCount = rMgr.GetRedoActionCount();
488 if(nCount)
490 OUString aStr = SvtResId( STR_REDO) + rMgr.GetRedoActionComment(--nCount);
491 rSet.Put(SfxStringItem(nWhich,aStr));
493 else
494 rSet.DisableItem(nWhich);
497 break;
498 case SID_MAIL_SENDDOCASPDF:
499 case SID_MAIL_SENDDOC :
500 case SID_EXPORTDOCASPDF:
501 case SID_DIRECTEXPORTDOCASPDF:
502 case SID_EXPORTDOC:
503 case SID_REPEAT:
504 case SID_BROWSER_MODE:
505 case FN_PRINT_LAYOUT:
506 rSet.DisableItem(nWhich);
507 break;
508 case SID_CUT:
509 case SID_COPY:
510 if(!pTextView->HasSelection())
511 rSet.DisableItem(nWhich);
512 break;
513 case SID_PASTE:
515 TransferableDataHelper aDataHelper(
516 TransferableDataHelper::CreateFromSystemClipboard(
517 m_aEditWin.get()) );
518 bool bDisable = !aDataHelper.GetXTransferable().is() ||
519 0 == aDataHelper.GetFormatCount();
520 if( bDisable )
521 rSet.DisableItem(nWhich);
523 break;
525 nWhich = aIter.NextWhich();
529 SvxSearchItem* SwSrcView::GetSearchItem()
531 if(!m_pSearchItem)
533 m_pSearchItem.reset(new SvxSearchItem(SID_SEARCH_ITEM));
535 return m_pSearchItem.get();
538 void SwSrcView::SetSearchItem( const SvxSearchItem& rItem )
540 m_pSearchItem.reset(rItem.Clone());
543 void SwSrcView::StartSearchAndReplace(const SvxSearchItem& rSearchItem,
544 bool bApi,
545 bool bRecursive)
547 TextView* pTextView = m_aEditWin->GetTextView();
548 TextPaM aPaM;
550 bool bForward = !rSearchItem.GetBackward();
551 bool bAtStart = pTextView->GetSelection() == TextSelection( aPaM, aPaM );
553 if( !bForward )
554 aPaM = TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL );
556 i18nutil::SearchOptions2 aSearchOpt( rSearchItem.GetSearchOptions() );
557 aSearchOpt.Locale = GetAppLanguageTag().getLocale();
559 sal_uInt16 nFound;
560 bool bAll = false;
561 switch( rSearchItem.GetCommand() )
563 case SvxSearchCmd::FIND:
564 case SvxSearchCmd::FIND_ALL:
565 nFound = pTextView->Search( aSearchOpt, bForward ) ? 1 : 0;
566 break;
568 case SvxSearchCmd::REPLACE_ALL: bAll = true;
569 [[fallthrough]];
570 case SvxSearchCmd::REPLACE:
571 nFound = pTextView->Replace( aSearchOpt, bAll, bForward );
572 break;
574 default:
575 nFound = 0;
578 if( nFound )
579 return;
581 bool bNotFoundMessage = false;
582 if(!bRecursive)
584 bNotFoundMessage = bAtStart;
586 else if(bAtStart)
588 bNotFoundMessage = true;
591 if(bApi)
592 return;
594 if(bNotFoundMessage)
596 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/infonotfounddialog.ui"));
597 std::unique_ptr<weld::MessageDialog> xInfoBox(xBuilder->weld_message_dialog("InfoNotFoundDialog"));
598 xInfoBox->run();
600 else if(!bRecursive)
602 int nRet;
604 if (!bForward)
606 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/querycontinueenddialog.ui"));
607 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("QueryContinueEndDialog"));
608 nRet = xQueryBox->run();
610 else
612 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/querycontinuebegindialog.ui"));
613 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("QueryContinueBeginDialog"));
614 nRet = xQueryBox->run();
617 if (nRet == RET_YES)
619 pTextView->SetSelection( TextSelection( aPaM, aPaM ) );
620 StartSearchAndReplace( rSearchItem, false, true );
625 sal_uInt16 SwSrcView::SetPrinter(SfxPrinter* pNew, SfxPrinterChangeFlags nDiffFlags )
627 SwDocShell* pDocSh = GetDocShell();
628 assert(pDocSh);
629 if ( (SfxPrinterChangeFlags::JOBSETUP | SfxPrinterChangeFlags::PRINTER) & nDiffFlags )
631 pDocSh->GetDoc()->getIDocumentDeviceAccess().setPrinter( pNew, true, true );
632 if ( nDiffFlags & SfxPrinterChangeFlags::PRINTER )
633 pDocSh->SetModified();
635 if ( nDiffFlags & SfxPrinterChangeFlags::OPTIONS )
636 ::SetPrinter( &pDocSh->getIDocumentDeviceAccess(), pNew, true );
638 const bool bChgOri = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION);
639 const bool bChgSize = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE);
640 if ( bChgOri || bChgSize )
642 pDocSh->SetModified();
644 return 0;
647 SfxPrinter* SwSrcView::GetPrinter( bool bCreate )
649 SwDocShell* pDocSh = GetDocShell();
650 assert(pDocSh);
651 return pDocSh->GetDoc()->getIDocumentDeviceAccess().getPrinter(bCreate);
654 sal_Int32 SwSrcView::PrintSource(
655 OutputDevice *pOutDev,
656 sal_Int32 nPage,
657 bool bCalcNumPagesOnly )
659 if (!pOutDev || nPage <= 0)
660 return 0;
662 //! This algorithm for printing the n-th page is very poor since it
663 //! needs to go over the text of all previous pages to get to the correct one.
664 //! But since HTML source code is expected to be just a small number of pages
665 //! even this poor algorithm should be enough...
667 pOutDev->Push();
669 TextEngine* pTextEngine = m_aEditWin->GetTextEngine();
670 pOutDev->SetMapMode(MapMode(MapUnit::Map100thMM));
671 vcl::Font aFont( m_aEditWin->GetOutWin()->GetFont() );
672 Size aSize( aFont.GetFontSize() );
673 aSize = m_aEditWin->GetOutWin()->PixelToLogic(aSize, MapMode(MapUnit::Map100thMM));
674 aFont.SetFontSize( aSize );
675 aFont.SetColor( COL_BLACK );
676 pOutDev->SetFont( aFont );
678 OUString aTitle( GetViewFrame().GetWindow().GetText() );
680 const tools::Long nLineHeight = pOutDev->GetTextHeight(); // slightly more
681 const tools::Long nParaSpace = 10;
683 Size aPaperSz = pOutDev->GetOutputSize();
684 aPaperSz.AdjustWidth( -(LMARGPRN + RMARGPRN) );
685 aPaperSz.AdjustHeight( -(TMARGPRN + BMARGPRN) );
687 // nLinepPage is not true, if lines have to be wrapped...
688 const tools::Long nLinespPage = nLineHeight ? aPaperSz.Height() / nLineHeight : 1;
689 const tools::Long nCharWidth = pOutDev->GetTextWidth("X");
690 const sal_Int32 nCharspLine = nCharWidth ? static_cast<sal_Int32>(aPaperSz.Width() / nCharWidth) : 1;
691 const sal_uInt32 nParas = pTextEngine->GetParagraphCount();
693 const sal_Int32 nPages = static_cast<sal_Int32>(nParas / nLinespPage + 1 );
694 sal_Int32 nCurPage = 1;
696 // Print header...
697 if (!bCalcNumPagesOnly && nPage == nCurPage)
698 lcl_PrintHeader( *pOutDev, nPages, nCurPage, aTitle );
699 const Point aStartPos( LMARGPRN, TMARGPRN );
700 Point aPos( aStartPos );
701 for ( sal_uInt32 nPara = 0; nPara < nParas; ++nPara )
703 const OUString aLine( lcl_ConvertTabsToSpaces(pTextEngine->GetText( nPara )) );
704 const sal_Int32 nLineLen = aLine.getLength();
705 const sal_Int32 nLines = (nLineLen+nCharspLine-1) / nCharspLine;
706 for ( sal_Int32 nLine = 0; nLine < nLines; ++nLine )
708 aPos.AdjustY(nLineHeight );
709 if ( aPos.Y() > ( aPaperSz.Height() + TMARGPRN - nLineHeight/2 ) )
711 ++nCurPage;
712 if (!bCalcNumPagesOnly && nPage == nCurPage)
713 lcl_PrintHeader( *pOutDev, nPages, nCurPage, aTitle );
714 aPos = aStartPos;
716 if (!bCalcNumPagesOnly && nPage == nCurPage)
718 const sal_Int32 nStart = nLine * nCharspLine;
719 const sal_Int32 nLen = std::min(nLineLen-nStart, nCharspLine);
720 pOutDev->DrawText( aPos, aLine.copy(nStart, nLen) );
723 aPos.AdjustY(nParaSpace );
726 pOutDev->Pop();
728 OSL_ENSURE( bCalcNumPagesOnly || nPage <= nCurPage, "page number out of range" );
729 return nCurPage;
732 void SwSrcView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
734 if (rHint.GetId() == SfxHintId::ModeChanged || rHint.GetId() == SfxHintId::TitleChanged)
736 const SwDocShell* pDocSh = GetDocShell();
737 assert(pDocSh);
738 if (!(rHint.GetId() == SfxHintId::TitleChanged
739 && (pDocSh->IsReadOnly() || !m_aEditWin->IsReadonly())))
741 // Broadcast only comes once!
742 const bool bReadonly = pDocSh->IsReadOnly();
743 m_aEditWin->SetReadonly(bReadonly);
746 SfxViewShell::Notify(rBC, rHint);
749 void SwSrcView::Load(SwDocShell* pDocShell)
751 rtl_TextEncoding eDestEnc = RTL_TEXTENCODING_UTF8;
753 m_aEditWin->SetReadonly(pDocShell->IsReadOnly());
754 m_aEditWin->SetTextEncoding(eDestEnc);
755 SfxMedium* pMedium = pDocShell->GetMedium();
757 std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
758 bool bHtml = pFilter && pFilter->GetUserData() == "HTML";
759 bool bDocModified = pDocShell->IsModified();
760 if(bHtml && !bDocModified && pDocShell->HasName())
762 SvStream* pStream = pMedium->GetInStream();
763 if(pStream && ERRCODE_NONE == pStream->GetError() )
765 rtl_TextEncoding eHeaderEnc =
766 SfxHTMLParser::GetEncodingByHttpHeader(
767 pDocShell->GetHeaderAttributes() );
768 if( RTL_TEXTENCODING_DONTKNOW == eHeaderEnc )
770 const char *pTmpCharSet =
771 rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 );
772 eHeaderEnc = rtl_getTextEncodingFromMimeCharset( pTmpCharSet );
774 if( RTL_TEXTENCODING_DONTKNOW != eHeaderEnc &&
775 eDestEnc != eHeaderEnc )
777 eDestEnc = eHeaderEnc;
778 m_aEditWin->SetTextEncoding(eDestEnc);
780 pStream->SetStreamCharSet( eDestEnc );
781 pStream->Seek(0);
782 TextEngine* pTextEngine = m_aEditWin->GetTextEngine();
783 pTextEngine->EnableUndo(false);
784 m_aEditWin->Read(*pStream);
785 pTextEngine->EnableUndo(true);
787 else
789 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetViewFrame().GetFrameWeld(),
790 VclMessageType::Info, VclButtonsType::Ok,
791 SwResId(STR_ERR_SRCSTREAM)));
792 xBox->run();
795 else
797 utl::TempFileNamed aTempFile;
798 aTempFile.EnableKillingFile();
799 const OUString sFileURL( aTempFile.GetURL() );
802 SfxMedium aMedium( sFileURL,StreamMode::READWRITE );
803 SwWriter aWriter( aMedium, *pDocShell->GetDoc() );
804 WriterRef xWriter;
805 ::GetHTMLWriter(std::u16string_view(), aMedium.GetBaseURL( true ), xWriter);
806 const OUString sWriteName = pDocShell->HasName()
807 ? pMedium->GetName()
808 : sFileURL;
809 ErrCode nRes = aWriter.Write(xWriter, &sWriteName);
810 if(nRes)
812 ErrorHandler::HandleError(nRes);
813 m_aEditWin->SetReadonly(true);
815 aMedium.Commit();
816 SvStream* pInStream = aMedium.GetInStream();
817 pInStream->Seek(0);
818 pInStream->SetStreamCharSet( eDestEnc );
820 m_aEditWin->Read(*pInStream);
823 m_aEditWin->ClearModifyFlag();
825 m_eLoadEncoding = eDestEnc;
827 if(bDocModified)
828 pDocShell->SetModified();// The flag will be reset in between times.
829 // Disable AutoLoad
830 pDocShell->SetAutoLoad(INetURLObject(), 0, false);
831 assert(dynamic_cast<SwWebDocShell*>( pDocShell) && "Why no WebDocShell?" );
832 sal_uInt16 nLine = static_cast<SwWebDocShell*>(pDocShell)->GetSourcePara();
833 m_aEditWin->SetStartLine(nLine);
834 m_aEditWin->GetTextEngine()->ResetUndo();
835 m_aEditWin->GetOutWin()->GrabFocus();
838 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */