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 <libxml/xmlwriter.h>
21 #include <cmdid.h>
22 #include <officecfg/Office/Common.hxx>
23 #include <sfx2/request.hxx>
24 #include <sfx2/viewfrm.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/stdtext.hxx>
27 #include <vcl/weld.hxx>
28 #include <sfx2/printer.hxx>
29 #include <editeng/paperinf.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <svx/dialmgr.hxx>
32 #include <svx/strings.hrc>
33 #include <svl/eitem.hxx>
34 #include <svl/stritem.hxx>
35 #include <svl/intitem.hxx>
36 #include <svl/flagitem.hxx>
37 #include <sfx2/linkmgr.hxx>
38 #include <osl/diagnose.h>
39 
40 #include <modcfg.hxx>
41 #include <edtwin.hxx>
42 #include <view.hxx>
43 #include <wrtsh.hxx>
44 #include <viewopt.hxx>
45 #include <prtopt.hxx>
46 #include <cfgitems.hxx>
47 #include "viewfunc.hxx"
48 #include <swmodule.hxx>
49 #include <wview.hxx>
50 #include <IDocumentDeviceAccess.hxx>
51 
52 #include <globals.hrc>
53 #include <strings.hrc>
54 #include <swabstdlg.hxx>
55 
56 #include <uivwimp.hxx>
57 
58 using namespace ::com::sun::star;
59 
60 // Hand over the printer to Sfx
61 
GetPrinter(bool bCreate)62 SfxPrinter* SwView::GetPrinter( bool bCreate )
63 {
64     const IDocumentDeviceAccess& rIDDA = GetWrtShell().getIDocumentDeviceAccess();
65     SfxPrinter *pOld = rIDDA.getPrinter( false );
66     SfxPrinter *pPrt = rIDDA.getPrinter( bCreate );
67     if ( pOld != pPrt )
68     {
69         bool bWeb = dynamic_cast<SwWebView*>(this) !=  nullptr;
70         ::SetAppPrintOptions( &GetWrtShell(), bWeb );
71     }
72     return pPrt;
73 }
74 
75 // Propagate printer change
76 
SetPrinter(IDocumentDeviceAccess * pIDDA,SfxPrinter const * pNew,bool bWeb)77 void SetPrinter( IDocumentDeviceAccess* pIDDA, SfxPrinter const * pNew, bool bWeb )
78 {
79     SwPrintOptions* pOpt = SW_MOD()->GetPrtOptions(bWeb);
80     if( !pOpt)
81         return;
82 
83     // Reading Application own printing options from SfxPrinter
84     const SfxItemSet& rSet = pNew->GetOptions();
85 
86     const SwAddPrinterItem* pAddPrinterAttr;
87     if( SfxItemState::SET == rSet.GetItemState( FN_PARAM_ADDPRINTER, false,
88         reinterpret_cast<const SfxPoolItem**>(&pAddPrinterAttr) ) )
89     {
90         if( pIDDA )
91             pIDDA->setPrintData( *pAddPrinterAttr );
92         if( !pAddPrinterAttr->GetFaxName().isEmpty() )
93             pOpt->SetFaxName(pAddPrinterAttr->GetFaxName());
94     }
95 }
96 
SetPrinter(SfxPrinter * pNew,SfxPrinterChangeFlags nDiffFlags)97 sal_uInt16 SwView::SetPrinter(SfxPrinter* pNew, SfxPrinterChangeFlags nDiffFlags  )
98 {
99     SwWrtShell &rSh = GetWrtShell();
100     SfxPrinter* pOld = rSh.getIDocumentDeviceAccess().getPrinter( false );
101     if ( pOld && pOld->IsPrinting() )
102         return SFX_PRINTERROR_BUSY;
103 
104     if ( (SfxPrinterChangeFlags::JOBSETUP | SfxPrinterChangeFlags::PRINTER) & nDiffFlags )
105     {
106         rSh.getIDocumentDeviceAccess().setPrinter( pNew, true, true );
107         if ( nDiffFlags & SfxPrinterChangeFlags::PRINTER )
108             rSh.SetModified();
109     }
110     bool bWeb = dynamic_cast< const SwWebView *>( this ) !=  nullptr;
111     if ( nDiffFlags & SfxPrinterChangeFlags::OPTIONS )
112         ::SetPrinter( &rSh.getIDocumentDeviceAccess(), pNew, bWeb );
113 
114     const bool bChgOri  = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION);
115     const bool bChgSize = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE);
116     if ( bChgOri || bChgSize )
117     {
118         rSh.StartAllAction();
119         if ( bChgOri )
120             rSh.ChgAllPageOrientation( pNew->GetOrientation() );
121         if ( bChgSize )
122         {
123             Size aSz( SvxPaperInfo::GetPaperSize( pNew ) );
124             rSh.ChgAllPageSize( aSz );
125         }
126         rSh.SetModified();
127         rSh.EndAllAction();
128         InvalidateRulerPos();
129     }
130     return 0;
131 }
132 
HasPrintOptionsPage() const133 bool SwView::HasPrintOptionsPage() const
134 {
135     return true;
136 }
137 
138 namespace
139 {
140     class SvxPrtQryBox
141     {
142     private:
143         std::unique_ptr<weld::MessageDialog> m_xQueryBox;
144     public:
SvxPrtQryBox(weld::Window * pParent)145         SvxPrtQryBox(weld::Window* pParent)
146             : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, SvxResId(RID_SVXSTR_QRY_PRINT_MSG)))
147         {
148             m_xQueryBox->set_title(SvxResId(RID_SVXSTR_QRY_PRINT_TITLE));
149 
150             m_xQueryBox->add_button(SvxResId(RID_SVXSTR_QRY_PRINT_SELECTION), RET_OK);
151             m_xQueryBox->add_button(SvxResId(RID_SVXSTR_QRY_PRINT_ALL), 2);
152             m_xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
153             m_xQueryBox->set_default_response(RET_OK);
154         }
run()155         short run() { return m_xQueryBox->run(); }
156     };
157 }
158 
159 // TabPage for application-specific print options
160 
CreatePrintOptionsPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)161 std::unique_ptr<SfxTabPage> SwView::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController,
162                                                   const SfxItemSet& rSet)
163 {
164     return ::CreatePrintOptionsPage(pPage, pController, rSet, false);
165 }
166 
167 // Print dispatcher
168 
ExecutePrint(SfxRequest & rReq)169 void SwView::ExecutePrint(SfxRequest& rReq)
170 {
171     bool bWeb = dynamic_cast<SwWebView*>( this ) !=  nullptr;
172     ::SetAppPrintOptions( &GetWrtShell(), bWeb );
173     switch (rReq.GetSlot())
174     {
175         case FN_FAX:
176         {
177             SwPrintOptions* pPrintOptions = SW_MOD()->GetPrtOptions(bWeb);
178             const OUString& sFaxName(pPrintOptions->GetFaxName());
179             if (!sFaxName.isEmpty())
180             {
181                 SfxStringItem aPrinterName(SID_PRINTER_NAME, sFaxName);
182                 SfxBoolItem aSilent( SID_SILENT, true );
183                 GetViewFrame()->GetDispatcher()->ExecuteList(SID_PRINTDOC,
184                             SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
185                             { &aPrinterName, &aSilent });
186             }
187             else
188             {
189                 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetEditWin().GetFrameWeld(),
190                                                               VclMessageType::Info, VclButtonsType::Ok,
191                                                               SwResId(STR_ERR_NO_FAX)));
192                 const char* pResId = bWeb ? STR_WEBOPTIONS : STR_TEXTOPTIONS;
193                 xInfoBox->set_primary_text(xInfoBox->get_primary_text().replaceFirst("%1", SwResId(pResId)));
194                 xInfoBox->run();
195                 SfxUInt16Item aDefPage(SID_SW_EDITOPTIONS, TP_OPTPRINT_PAGE);
196                 GetViewFrame()->GetDispatcher()->ExecuteList(SID_SW_EDITOPTIONS,
197                             SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
198                             { &aDefPage });
199             }
200         }
201         break;
202         case SID_PRINTDOC:
203         case SID_PRINTDOCDIRECT:
204         {
205             SwWrtShell* pSh = &GetWrtShell();
206             const SfxBoolItem* pSilentItem = rReq.GetArg<SfxBoolItem>(SID_SILENT);
207             bool bSilent = pSilentItem && pSilentItem->GetValue();
208             const SfxBoolItem* pPrintFromMergeItem = rReq.GetArg<SfxBoolItem>(FN_QRY_MERGE);
209             if(pPrintFromMergeItem)
210                 rReq.RemoveItem(FN_QRY_MERGE);
211             bool bFromMerge = pPrintFromMergeItem && pPrintFromMergeItem->GetValue();
212             bool bPrintSelection = false;
213             if(!bSilent && !bFromMerge &&
214                     SW_MOD()->GetModuleConfig()->IsAskForMailMerge() && pSh->IsAnyDatabaseFieldInDoc())
215             {
216                 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetEditWin().GetFrameWeld(), "modules/swriter/ui/printmergedialog.ui"));
217                 std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("PrintMergeDialog"));
218                 short nRet = xBox->run();
219                 if(RET_NO != nRet)
220                 {
221                     if(RET_YES == nRet)
222                     {
223                         SfxBoolItem aBool(FN_QRY_MERGE, true);
224                         GetViewFrame()->GetDispatcher()->ExecuteList(
225                                     FN_QRY_MERGE, SfxCallMode::ASYNCHRON,
226                                     { &aBool });
227                         rReq.Ignore();
228                     }
229                     return;
230                 }
231             }
232             else if( rReq.GetSlot() == SID_PRINTDOCDIRECT && ! bSilent )
233             {
234                 if( pSh->IsSelection() || pSh->IsFrameSelected() || pSh->IsObjSelected() )
235                 {
236                     SvxPrtQryBox aBox(GetEditWin().GetFrameWeld());
237                     short nBtn = aBox.run();
238                     if( RET_CANCEL == nBtn )
239                         return;
240 
241                     if( RET_OK == nBtn )
242                         bPrintSelection = true;
243                 }
244             }
245 
246             //#i61455# if master documents are printed silently without loaded links then update the links now
247             if( bSilent && pSh->IsGlobalDoc() && !pSh->IsGlblDocSaveLinks() )
248             {
249                 pSh->GetLinkManager().UpdateAllLinks( false, false, nullptr );
250             }
251             SfxRequest aReq( rReq );
252             SfxBoolItem aBool(SID_SELECTION, bPrintSelection);
253             aReq.AppendItem( aBool );
254             SfxViewShell::ExecuteSlot( aReq, SfxViewShell::GetInterface() );
255             return;
256         }
257         default:
258             OSL_ENSURE(false, "wrong dispatcher");
259             return;
260     }
261 }
262 
getPart() const263 int SwView::getPart() const
264 {
265     return 0;
266 }
267 
dumpAsXml(xmlTextWriterPtr pWriter) const268 void SwView::dumpAsXml(xmlTextWriterPtr pWriter) const
269 {
270     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwView"));
271     SfxViewShell::dumpAsXml(pWriter);
272     if (m_pWrtShell)
273         m_pWrtShell->dumpAsXml(pWriter);
274     (void)xmlTextWriterEndElement(pWriter);
275 }
276 
SetRedlineAuthor(const OUString & rAuthor)277 void SwView::SetRedlineAuthor(const OUString& rAuthor)
278 {
279     m_pViewImpl->m_sRedlineAuthor = rAuthor;
280 }
281 
GetRedlineAuthor() const282 const OUString& SwView::GetRedlineAuthor() const
283 {
284     return m_pViewImpl->m_sRedlineAuthor;
285 }
286 
NotifyCursor(SfxViewShell * pViewShell) const287 void SwView::NotifyCursor(SfxViewShell* pViewShell) const
288 {
289     m_pWrtShell->NotifyCursor(pViewShell);
290 }
291 
292 // Create page printer/additions for SwView and SwPagePreview
293 
CreatePrintOptionsPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rOptions,bool bPreview)294 std::unique_ptr<SfxTabPage> CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController,
295                                           const SfxItemSet &rOptions,
296                                           bool bPreview)
297 {
298     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
299 
300     ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc(TP_OPTPRINT_PAGE);
301     OSL_ENSURE(pFact, "No Page Creator");
302     if (!fnCreatePage)
303         return nullptr;
304 
305     std::unique_ptr<SfxTabPage> xSfxPage = fnCreatePage(pPage, pController, &rOptions);
306     OSL_ENSURE(xSfxPage, "No page");
307     if (!xSfxPage)
308         return nullptr;
309 
310     SfxAllItemSet aSet(*(rOptions.GetPool()));
311     aSet.Put(SfxBoolItem(SID_PREVIEWFLAG_TYPE, bPreview));
312     aSet.Put(SfxBoolItem(SID_FAX_LIST, true));
313     xSfxPage->PageCreated(aSet);
314     return xSfxPage;
315 }
316 
SetAppPrintOptions(SwViewShell * pSh,bool bWeb)317 void SetAppPrintOptions( SwViewShell* pSh, bool bWeb )
318 {
319     const IDocumentDeviceAccess& rIDDA = pSh->getIDocumentDeviceAccess();
320     const SwPrintData& aPrtData = rIDDA.getPrintData();
321 
322     if( !rIDDA.getPrinter( false ) )
323         return;
324 
325     // Close application own printing options in SfxPrinter.
326     SwAddPrinterItem aAddPrinterItem(aPrtData);
327     SfxItemSet aSet(
328         pSh->GetAttrPool(),
329         svl::Items<
330             SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
331             SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
332             SID_HTML_MODE, SID_HTML_MODE,
333             FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER>{});
334 
335     if(bWeb)
336         aSet.Put(SfxUInt16Item(SID_HTML_MODE,
337                 ::GetHtmlMode(static_cast<SwWrtShell*>(pSh)->GetView().GetDocShell())));
338     aSet.Put(SfxBoolItem(SID_PRINTER_NOTFOUND_WARN,
339                     officecfg::Office::Common::Print::Warning::NotFound::get() ));
340     aSet.Put(aAddPrinterItem);
341     aSet.Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC,
342         static_cast<int>(officecfg::Office::Common::Print::Warning::PaperSize::get()
343             ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE)   |
344         static_cast<int>(officecfg::Office::Common::Print::Warning::PaperOrientation::get()
345             ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE )));
346 
347     rIDDA.getPrinter( true )->SetOptions( aSet );
348 
349 }
350 
351 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
352