Coverage Report

Created: 2026-11-06 11:29

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