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 <fusumry.hxx>
21 #include <editeng/eeitem.hxx>
22 #include <svx/svdotext.hxx>
23 #include <svx/svdundo.hxx>
24 #include <svx/xfillit0.hxx>
25 #include <svx/xlineit0.hxx>
26 #include <editeng/outlobj.hxx>
27 #include <xmloff/autolayout.hxx>
28 
29 #include <strings.hrc>
30 
31 #include <pres.hxx>
32 #include <View.hxx>
33 #include <sdpage.hxx>
34 #include <Outliner.hxx>
35 #include <drawdoc.hxx>
36 #include <ViewShell.hxx>
37 #include <sdmod.hxx>
38 #include <sdresid.hxx>
39 #include <DrawViewShell.hxx>
40 
41 using namespace com::sun::star;
42 
43 namespace sd {
44 
45 
FuSummaryPage(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)46 FuSummaryPage::FuSummaryPage (
47     ViewShell* pViewSh,
48     ::sd::Window* pWin,
49     ::sd::View* pView,
50     SdDrawDocument* pDoc,
51     SfxRequest& rReq)
52     : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
53 {
54 }
55 
Create(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)56 rtl::Reference<FuPoor> FuSummaryPage::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
57 {
58     rtl::Reference<FuPoor> xFunc( new FuSummaryPage( pViewSh, pWin, pView, pDoc, rReq ) );
59     xFunc->DoExecute(rReq);
60     return xFunc;
61 }
62 
DoExecute(SfxRequest &)63 void FuSummaryPage::DoExecute( SfxRequest& )
64 {
65     std::unique_ptr<SdOutliner> pOutl;
66     rtl::Reference<SdPage> pSummaryPage;
67     sal_uInt16 i = 0;
68     sal_uInt16 nFirstPage = SDRPAGE_NOTFOUND;
69     sal_uInt16 nSelectedPages = 0;
70     sal_uInt16 nCount = mpDoc->GetSdPageCount(PageKind::Standard);
71 
72     while (i < nCount && nSelectedPages <= 1)
73     {
74         /* How many pages are selected?
75              exactly one: pool everything from this page
76              otherwise:   only pool the selected pages  */
77         SdPage* pActualPage = mpDoc->GetSdPage(i, PageKind::Standard);
78 
79         if (pActualPage->IsSelected())
80         {
81             if (nFirstPage == SDRPAGE_NOTFOUND)
82             {
83                 nFirstPage = i;
84             }
85 
86             nSelectedPages++;
87         }
88 
89         i++;
90     }
91 
92     bool bBegUndo = false;
93 
94     SfxStyleSheet* pStyle = nullptr;
95 
96     for (i = nFirstPage; i < nCount; i++)
97     {
98         SdPage* pActualPage = mpDoc->GetSdPage(i, PageKind::Standard);
99 
100         if (nSelectedPages <= 1 || pActualPage->IsSelected())
101         {
102             SdPage* pActualNotesPage = mpDoc->GetSdPage(i, PageKind::Notes);
103             SdrTextObj* pTextObj = static_cast<SdrTextObj*>( pActualPage->GetPresObj(PresObjKind::Title) );
104 
105             if (pTextObj && !pTextObj->IsEmptyPresObj())
106             {
107                 if (!pSummaryPage)
108                 {
109                     // insert "table of content"-page and create outliner
110                     const bool bUndo = mpView->IsUndoEnabled();
111 
112                     if( bUndo )
113                     {
114                         mpView->BegUndo(SdResId(STR_UNDO_SUMMARY_PAGE));
115                         bBegUndo = true;
116                     }
117 
118                     SdrLayerIDSet aVisibleLayers = pActualPage->TRG_GetMasterPageVisibleLayers();
119 
120                     // page with title & structuring!
121                     pSummaryPage = mpDoc->AllocSdPage(false);
122                     pSummaryPage->SetSize(pActualPage->GetSize() );
123                     pSummaryPage->SetBorder(pActualPage->GetLeftBorder(),
124                                      pActualPage->GetUpperBorder(),
125                                      pActualPage->GetRightBorder(),
126                                      pActualPage->GetLowerBorder() );
127 
128                     // insert page at the back
129                     mpDoc->InsertPage(pSummaryPage.get(), nCount * 2 + 1);
130                     if( bUndo )
131                         mpView->AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoNewPage(*pSummaryPage));
132 
133                     // use MasterPage of the current page
134                     pSummaryPage->TRG_SetMasterPage(pActualPage->TRG_GetMasterPage());
135                     pSummaryPage->SetLayoutName(pActualPage->GetLayoutName());
136                     pSummaryPage->SetAutoLayout(AUTOLAYOUT_TITLE_CONTENT, true);
137                     pSummaryPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
138                     pSummaryPage->setHeaderFooterSettings(pActualPage->getHeaderFooterSettings());
139 
140                     // notes-page
141                     rtl::Reference<SdPage> pNotesPage = mpDoc->AllocSdPage(false);
142                     pNotesPage->SetSize(pActualNotesPage->GetSize());
143                     pNotesPage->SetBorder(pActualNotesPage->GetLeftBorder(),
144                                           pActualNotesPage->GetUpperBorder(),
145                                           pActualNotesPage->GetRightBorder(),
146                                           pActualNotesPage->GetLowerBorder() );
147                     pNotesPage->SetPageKind(PageKind::Notes);
148 
149                     // insert page at the back
150                     mpDoc->InsertPage(pNotesPage.get(), nCount * 2 + 2);
151 
152                     if( bUndo )
153                         mpView->AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoNewPage(*pNotesPage));
154 
155                     // use MasterPage of the current page
156                     pNotesPage->TRG_SetMasterPage(pActualNotesPage->TRG_GetMasterPage());
157                     pNotesPage->SetLayoutName(pActualNotesPage->GetLayoutName());
158                     pNotesPage->SetAutoLayout(pActualNotesPage->GetAutoLayout(), true);
159                     pNotesPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
160                     pNotesPage->setHeaderFooterSettings(pActualNotesPage->getHeaderFooterSettings());
161 
162                     pOutl.reset(new SdOutliner( mpDoc, OutlinerMode::OutlineObject ));
163                     pOutl->SetUpdateMode(false);
164                     pOutl->EnableUndo(false);
165 
166                     if (mpDocSh)
167                         pOutl->SetRefDevice(SD_MOD()->GetVirtualRefDevice());
168 
169                     pOutl->SetDefTab( mpDoc->GetDefaultTabulator() );
170                     pOutl->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(mpDoc->GetStyleSheetPool()));
171                     pStyle = pSummaryPage->GetStyleSheetForPresObj( PresObjKind::Outline );
172                     pOutl->SetStyleSheet( 0, pStyle );
173                 }
174 
175                 // add text
176                 OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
177                 // #118876#, check if the OutlinerParaObject is created successfully
178                 if( pParaObj )
179                 {
180                     pParaObj->SetOutlinerMode( OutlinerMode::OutlineObject );
181                     pOutl->AddText(*pParaObj);
182                 }
183             }
184         }
185     }
186 
187     if (!pSummaryPage)
188         return;
189 
190     SdrTextObj* pTextObj = static_cast<SdrTextObj*>( pSummaryPage->GetPresObj(PresObjKind::Outline) );
191 
192     if (!pTextObj)
193         return;
194 
195     // remove hard break- and character attributes
196     SfxItemSet aEmptyEEAttr(mpDoc->GetPool(), svl::Items<EE_ITEMS_START, EE_ITEMS_END>{});
197     sal_Int32 nParaCount = pOutl->GetParagraphCount();
198 
199     for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
200     {
201         pOutl->SetStyleSheet( nPara, pStyle );
202         pOutl->RemoveCharAttribs(nPara);
203         pOutl->SetParaAttribs(nPara, aEmptyEEAttr);
204         pOutl->SetDepth(pOutl->GetParagraph(nPara), 0);
205     }
206 
207     pTextObj->SetOutlinerParaObject( pOutl->CreateParaObject() );
208     pTextObj->SetEmptyPresObj(false);
209 
210     // remove hard attributes (Flag to sal_True)
211     SfxItemSet aAttr(mpDoc->GetPool());
212     aAttr.Put(XLineStyleItem(drawing::LineStyle_NONE));
213     aAttr.Put(XFillStyleItem(drawing::FillStyle_NONE));
214     pTextObj->SetMergedItemSet(aAttr);
215 
216     if( bBegUndo )
217         mpView->EndUndo();
218     pOutl.reset();
219 
220     DrawViewShell* pDrawViewShell= dynamic_cast< DrawViewShell* >( mpViewShell );
221     if(pDrawViewShell)
222     {
223         pDrawViewShell->SwitchPage( (pSummaryPage->GetPageNum() - 1) / 2);
224     }
225 }
226 
227 } // end of namespace sd
228 
229 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
230