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 <memory>
21 #include <hintids.hxx>
22 
23 #include <svl/eitem.hxx>
24 #include <vcl/settings.hxx>
25 #include <vcl/transfer.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <sfx2/viewfrm.hxx>
28 #include <svx/gallery.hxx>
29 #include <svx/graphichelper.hxx>
30 #include <editeng/brushitem.hxx>
31 
32 #include <fmtinfmt.hxx>
33 #include <docsh.hxx>
34 #include <view.hxx>
35 #include <wrtsh.hxx>
36 #include <viewopt.hxx>
37 #include <swmodule.hxx>
38 #include "romenu.hxx"
39 #include <pagedesc.hxx>
40 #include <modcfg.hxx>
41 
42 #include <cmdid.h>
43 
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star;
47 using namespace ::sfx2;
48 
~SwReadOnlyPopup()49 SwReadOnlyPopup::~SwReadOnlyPopup()
50 {
51     m_xMenu.disposeAndClear();
52 }
53 
Check(sal_uInt16 nMID,sal_uInt16 nSID,SfxDispatcher const & rDis)54 void SwReadOnlyPopup::Check( sal_uInt16 nMID, sal_uInt16 nSID, SfxDispatcher const &rDis )
55 {
56     std::unique_ptr<SfxPoolItem> _pItem;
57     SfxItemState eState = rDis.GetBindings()->QueryState( nSID, _pItem );
58     if (eState >= SfxItemState::DEFAULT)
59     {
60         m_xMenu->EnableItem(nMID);
61         if (_pItem)
62         {
63             m_xMenu->CheckItem(nMID, !_pItem->IsVoidItem() &&
64                             dynamic_cast< const SfxBoolItem *>( _pItem.get() ) !=  nullptr &&
65                             static_cast<SfxBoolItem*>(_pItem.get())->GetValue());
66             //remove full screen entry when not in full screen mode
67             if (SID_WIN_FULLSCREEN == nSID && !m_xMenu->IsItemChecked(m_nReadonlyFullscreen))
68                 m_xMenu->EnableItem(nMID, false);
69         }
70     }
71     else
72         m_xMenu->EnableItem(nMID, false);
73 }
74 
75 #define MN_READONLY_GRAPHICTOGALLERY 1000
76 #define MN_READONLY_BACKGROUNDTOGALLERY 2000
77 
SwReadOnlyPopup(const Point & rDPos,SwView & rV)78 SwReadOnlyPopup::SwReadOnlyPopup(const Point &rDPos, SwView &rV)
79     : m_aBuilder(nullptr, AllSettings::GetUIRootDir(), "modules/swriter/ui/readonlymenu.ui", "")
80     , m_xMenu(m_aBuilder.get_menu("menu"))
81     , m_nReadonlyOpenurl(m_xMenu->GetItemId("openurl"))
82     , m_nReadonlyOpendoc(m_xMenu->GetItemId("opendoc"))
83     , m_nReadonlyEditdoc(m_xMenu->GetItemId("edit"))
84     , m_nReadonlySelectionMode(m_xMenu->GetItemId("selection"))
85     , m_nReadonlyReload(m_xMenu->GetItemId("reload"))
86     , m_nReadonlyReloadFrame(m_xMenu->GetItemId("reloadframe"))
87     , m_nReadonlySourceview(m_xMenu->GetItemId("html"))
88     , m_nReadonlyBrowseBackward(m_xMenu->GetItemId("backward"))
89     , m_nReadonlyBrowseForward(m_xMenu->GetItemId("forward"))
90     , m_nReadonlySaveGraphic(m_xMenu->GetItemId("savegraphic"))
91     , m_nReadonlyGraphictogallery(m_xMenu->GetItemId("graphictogallery"))
92     , m_nReadonlyTogallerylink(m_xMenu->GetItemId("graphicaslink"))
93     , m_nReadonlyTogallerycopy(m_xMenu->GetItemId("graphicascopy"))
94     , m_nReadonlySaveBackground(m_xMenu->GetItemId("savebackground"))
95     , m_nReadonlyBackgroundtogallery(m_xMenu->GetItemId("backgroundtogallery"))
96     , m_nReadonlyBackgroundTogallerylink(m_xMenu->GetItemId("backaslink"))
97     , m_nReadonlyBackgroundTogallerycopy(m_xMenu->GetItemId("backascopy"))
98     , m_nReadonlyCopylink(m_xMenu->GetItemId("copylink"))
99     , m_nReadonlyLoadGraphic(m_xMenu->GetItemId("loadgraphic"))
100     , m_nReadonlyGraphicoff(m_xMenu->GetItemId("imagesoff"))
101     , m_nReadonlyFullscreen(m_xMenu->GetItemId("fullscreen"))
102     , m_nReadonlyCopy(m_xMenu->GetItemId("copy"))
103     , m_rView(rV)
104     , m_xBrushItem(std::make_unique<SvxBrushItem>(RES_BACKGROUND))
105 {
106     m_bGrfToGalleryAsLnk = SW_MOD()->GetModuleConfig()->IsGrfToGalleryAsLnk();
107     SwWrtShell &rSh = m_rView.GetWrtShell();
108     OUString sDescription;
109     rSh.IsURLGrfAtPos( rDPos, &m_sURL, &m_sTargetFrameName, &sDescription );
110     if ( m_sURL.isEmpty() )
111     {
112         SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
113         if( rSh.GetContentAtPos( rDPos, aContentAtPos))
114         {
115             const SwFormatINetFormat &rIItem = *static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr);
116             m_sURL = rIItem.GetValue();
117             m_sTargetFrameName = rIItem.GetTargetFrame();
118         }
119     }
120 
121     bool bLink = false;
122     const Graphic *pGrf = rSh.GetGrfAtPos( rDPos, m_sGrfName, bLink );
123     if ( nullptr == pGrf )
124     {
125         m_xMenu->EnableItem(m_nReadonlySaveGraphic, false);
126     }
127     else
128     {
129         m_aGraphic = *pGrf;
130     }
131 
132     bool bEnableGraphicToGallery = bLink;
133     if ( bEnableGraphicToGallery )
134     {
135         if (GalleryExplorer::FillThemeList( m_aThemeList ))
136         {
137             PopupMenu *pMenu = m_xMenu->GetPopupMenu(m_nReadonlyGraphictogallery);
138             pMenu->CheckItem(m_nReadonlyTogallerylink,  m_bGrfToGalleryAsLnk);
139             pMenu->CheckItem(m_nReadonlyTogallerycopy, !m_bGrfToGalleryAsLnk);
140 
141             for ( size_t i=0; i < m_aThemeList.size(); ++i )
142                 pMenu->InsertItem(MN_READONLY_GRAPHICTOGALLERY + i, m_aThemeList[i]);
143         }
144         else
145             bEnableGraphicToGallery = false;
146     }
147 
148     m_xMenu->EnableItem(m_nReadonlyGraphictogallery, bEnableGraphicToGallery);
149 
150     SfxViewFrame * pVFrame = rV.GetViewFrame();
151     SfxDispatcher &rDis = *pVFrame->GetDispatcher();
152     const SwPageDesc &rDesc = rSh.GetPageDesc( rSh.GetCurPageDesc() );
153     m_xBrushItem = rDesc.GetMaster().makeBackgroundBrushItem();
154     bool bEnableBackGallery = false,
155          bEnableBack = false;
156 
157     if ( m_xBrushItem && GPOS_NONE != m_xBrushItem->GetGraphicPos() )
158     {
159         bEnableBack = true;
160         if ( !m_xBrushItem->GetGraphicLink().isEmpty() )
161         {
162             if ( m_aThemeList.empty() )
163                 GalleryExplorer::FillThemeList( m_aThemeList );
164 
165             if ( !m_aThemeList.empty() )
166             {
167                 PopupMenu *pMenu = m_xMenu->GetPopupMenu(m_nReadonlyBackgroundtogallery);
168                 pMenu->CheckItem(m_nReadonlyBackgroundTogallerylink,  m_bGrfToGalleryAsLnk);
169                 pMenu->CheckItem(m_nReadonlyBackgroundTogallerycopy, !m_bGrfToGalleryAsLnk);
170                 bEnableBackGallery = true;
171 
172                 for ( size_t i=0; i < m_aThemeList.size(); ++i )
173                     pMenu->InsertItem(MN_READONLY_BACKGROUNDTOGALLERY + i, m_aThemeList[i]);
174             }
175         }
176     }
177     m_xMenu->EnableItem(m_nReadonlySaveBackground, bEnableBack);
178     m_xMenu->EnableItem(m_nReadonlyBackgroundtogallery, bEnableBackGallery);
179 
180     if ( !rSh.GetViewOptions()->IsGraphic() )
181         m_xMenu->CheckItem(m_nReadonlyGraphicoff);
182     else
183         m_xMenu->EnableItem(m_nReadonlyLoadGraphic, false);
184 
185     m_xMenu->EnableItem(m_nReadonlyReloadFrame, false);
186     m_xMenu->EnableItem(m_nReadonlyReload);
187 
188     Check(m_nReadonlyEditdoc, SID_EDITDOC, rDis);
189     Check(m_nReadonlySelectionMode, FN_READONLY_SELECTION_MODE, rDis);
190     Check(m_nReadonlySourceview, SID_SOURCEVIEW, rDis);
191     Check(m_nReadonlyBrowseBackward, SID_BROWSE_BACKWARD, rDis);
192     Check(m_nReadonlyBrowseForward,SID_BROWSE_FORWARD, rDis);
193     Check(m_nReadonlyOpenurl, SID_OPENDOC, rDis);
194     Check(m_nReadonlyOpendoc, SID_OPENDOC, rDis);
195 
196     std::unique_ptr<SfxPoolItem> pState;
197 
198     SfxItemState eState = pVFrame->GetBindings().QueryState( SID_COPY, pState );
199     Check(m_nReadonlyCopy, SID_COPY, rDis);
200     if (eState < SfxItemState::DEFAULT)
201         m_xMenu->EnableItem(m_nReadonlyCopy, false);
202 
203     eState = pVFrame->GetBindings().QueryState( SID_EDITDOC, pState );
204     if (
205         eState < SfxItemState::DEFAULT ||
206         (rSh.IsGlobalDoc() && m_rView.GetDocShell()->IsReadOnlyUI())
207        )
208     {
209         m_xMenu->EnableItem(m_nReadonlyEditdoc, false);
210     }
211 
212     if ( m_sURL.isEmpty() )
213     {
214         m_xMenu->EnableItem(m_nReadonlyOpenurl, false);
215         m_xMenu->EnableItem(m_nReadonlyOpendoc, false);
216         m_xMenu->EnableItem(m_nReadonlyCopylink, false);
217     }
218     Check(m_nReadonlyFullscreen, SID_WIN_FULLSCREEN, rDis);
219 
220     m_xMenu->RemoveDisabledEntries( true, true );
221 }
222 
Execute(vcl::Window * pWin,const Point & rPixPos)223 void SwReadOnlyPopup::Execute( vcl::Window* pWin, const Point &rPixPos )
224 {
225     sal_uInt16 nId = m_xMenu->Execute(pWin, rPixPos);
226     Execute(pWin, nId);
227 }
228 
229 // execute the resulting ID only - necessary to support XContextMenuInterception
Execute(vcl::Window * pWin,sal_uInt16 nId)230 void SwReadOnlyPopup::Execute( vcl::Window* pWin, sal_uInt16 nId )
231 {
232     SwWrtShell &rSh = m_rView.GetWrtShell();
233     SfxDispatcher &rDis = *m_rView.GetViewFrame()->GetDispatcher();
234     if (nId >= MN_READONLY_GRAPHICTOGALLERY)
235     {
236         OUString sTmp;
237         sal_uInt16 nSaveId;
238         if (m_xBrushItem && nId >= MN_READONLY_BACKGROUNDTOGALLERY)
239         {
240             nId -= MN_READONLY_BACKGROUNDTOGALLERY;
241             nSaveId = m_nReadonlySaveBackground;
242             sTmp = m_xBrushItem->GetGraphicLink();
243         }
244         else
245         {
246             nId -= MN_READONLY_GRAPHICTOGALLERY;
247             nSaveId = m_nReadonlySaveGraphic;
248             sTmp = m_sGrfName;
249         }
250         if ( !m_bGrfToGalleryAsLnk )
251             sTmp = SaveGraphic(nSaveId);
252 
253         if ( !sTmp.isEmpty() )
254             GalleryExplorer::InsertURL( m_aThemeList[nId], sTmp );
255 
256         return;
257     }
258 
259     rtl::Reference<TransferDataContainer> pClipCntnr;
260 
261     sal_uInt16 nExecId = USHRT_MAX;
262     bool bFilterSet = false;
263     LoadUrlFlags nFilter = LoadUrlFlags::NONE;
264     if (nId == m_nReadonlyFullscreen)
265         nExecId = SID_WIN_FULLSCREEN;
266     else if (nId == m_nReadonlyOpenurl)
267     {
268         nFilter = LoadUrlFlags::NONE;
269         bFilterSet = true;
270     }
271     else if (nId == m_nReadonlyOpendoc)
272     {
273         nFilter = LoadUrlFlags::NewView;
274         bFilterSet = true;
275     }
276     else if (nId == m_nReadonlyCopy)
277         nExecId = SID_COPY;
278     else if (nId == m_nReadonlyEditdoc)
279         nExecId = SID_EDITDOC;
280     else if (nId == m_nReadonlySelectionMode)
281         nExecId = FN_READONLY_SELECTION_MODE;
282     else if (nId == m_nReadonlyReload || nId == m_nReadonlyReloadFrame)
283         rSh.GetView().GetViewFrame()->GetDispatcher()->Execute(SID_RELOAD);
284     else if (nId == m_nReadonlyBrowseBackward)
285         nExecId = SID_BROWSE_BACKWARD;
286     else if (nId == m_nReadonlyBrowseForward)
287         nExecId = SID_BROWSE_FORWARD;
288     else if (nId == m_nReadonlySourceview)
289         nExecId = SID_SOURCEVIEW;
290     else if (nId == m_nReadonlySaveGraphic || nId == m_nReadonlySaveBackground)
291         SaveGraphic(nId);
292     else if (nId == m_nReadonlyCopylink)
293     {
294         pClipCntnr = new TransferDataContainer;
295         pClipCntnr->CopyString( m_sURL );
296     }
297     else if (nId == m_nReadonlyLoadGraphic)
298     {
299         bool bModified = rSh.IsModified();
300         SwViewOption aOpt( *rSh.GetViewOptions() );
301         aOpt.SetGraphic( true );
302         rSh.ApplyViewOptions( aOpt );
303         if(!bModified)
304             rSh.ResetModified();
305     }
306     else if (nId == m_nReadonlyGraphicoff)
307         nExecId = FN_VIEW_GRAPHIC;
308     else if (nId == m_nReadonlyTogallerylink || nId == m_nReadonlyBackgroundTogallerylink)
309         SW_MOD()->GetModuleConfig()->SetGrfToGalleryAsLnk(true);
310     else if (nId == m_nReadonlyTogallerycopy || nId == m_nReadonlyBackgroundTogallerycopy)
311         SW_MOD()->GetModuleConfig()->SetGrfToGalleryAsLnk(false);
312 
313     if( USHRT_MAX != nExecId )
314         rDis.GetBindings()->Execute( nExecId );
315     if( bFilterSet )
316         ::LoadURL(rSh, m_sURL, nFilter, m_sTargetFrameName);
317 
318     if( pClipCntnr && pClipCntnr->HasAnyData() )
319     {
320         pClipCntnr->CopyToClipboard( pWin );
321     }
322 }
323 
SaveGraphic(sal_uInt16 nId)324 OUString SwReadOnlyPopup::SaveGraphic(sal_uInt16 nId)
325 {
326     // fish out the graphic's name
327     if (nId == m_nReadonlySaveBackground)
328     {
329         if ( m_xBrushItem && !m_xBrushItem->GetGraphicLink().isEmpty() )
330             m_sGrfName = m_xBrushItem->GetGraphicLink();
331         const Graphic *pGrf = m_xBrushItem ? m_xBrushItem->GetGraphic() : nullptr;
332         if ( pGrf )
333         {
334             m_aGraphic = *pGrf;
335             if ( !m_xBrushItem->GetGraphicLink().isEmpty() )
336                 m_sGrfName = m_xBrushItem->GetGraphicLink();
337         }
338         else
339             return OUString();
340     }
341     return GraphicHelper::ExportGraphic(m_rView.GetFrameWeld(), m_aGraphic, m_sGrfName);
342 }
343 
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
345