LibreOffice Module sw (master)  1
vbaview.cxx
Go to the documentation of this file.
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 #include "vbaview.hxx"
20 #include <vbahelper/vbahelper.hxx>
21 #include <basic/sberrors.hxx>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
24 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
25 #include <com/sun/star/text/XText.hpp>
26 #include <com/sun/star/text/XTextDocument.hpp>
27 #include <com/sun/star/text/XFootnotesSupplier.hpp>
28 #include <com/sun/star/text/XEndnotesSupplier.hpp>
29 #include <com/sun/star/text/XPageCursor.hpp>
30 #include <com/sun/star/container/XIndexAccess.hpp>
31 #include <com/sun/star/frame/XController.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <ooo/vba/word/WdSpecialPane.hpp>
34 #include <ooo/vba/word/WdViewType.hpp>
35 #include <ooo/vba/word/WdSeekView.hpp>
36 
37 #include "wordvbahelper.hxx"
39 #include <view.hxx>
40 
41 using namespace ::ooo::vba;
42 using namespace ::com::sun::star;
43 
44 const sal_Int32 DEFAULT_BODY_DISTANCE = 500;
45 
46 SwVbaView::SwVbaView( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext,
47  const uno::Reference< frame::XModel >& rModel ) :
48  SwVbaView_BASE( rParent, rContext ), mxModel( rModel )
49 {
50  uno::Reference< frame::XController > xController = mxModel->getCurrentController();
51 
52  uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupp( xController, uno::UNO_QUERY_THROW );
53  mxViewCursor = xTextViewCursorSupp->getViewCursor();
54 
55  uno::Reference< view::XViewSettingsSupplier > xViewSettingSupp( xController, uno::UNO_QUERY_THROW );
56  mxViewSettings.set( xViewSettingSupp->getViewSettings(), uno::UNO_SET_THROW );
57 }
58 
60 {
61 }
62 
63 ::sal_Int32 SAL_CALL
65 {
66  // FIXME: if the view cursor is in table, field, section and frame
67  // handle if the cursor is in table
68  uno::Reference< text::XText > xCurrentText = mxViewCursor->getText();
69  uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW );
70  uno::Reference< text::XTextContent > xTextContent;
71  while( xCursorProps->getPropertyValue("TextTable") >>= xTextContent )
72  {
73  xCurrentText = xTextContent->getAnchor()->getText();
74  xCursorProps.set( xCurrentText->createTextCursor(), uno::UNO_QUERY_THROW );
75  }
76  uno::Reference< lang::XServiceInfo > xServiceInfo( xCurrentText, uno::UNO_QUERY_THROW );
77  OUString aImplName = xServiceInfo->getImplementationName();
78  if ( aImplName == "SwXBodyText" )
79  {
80  return word::WdSeekView::wdSeekMainDocument;
81  }
82  else if ( aImplName == "SwXHeadFootText" )
83  {
85  {
87  return word::WdSeekView::wdSeekFirstPageHeader;
89  return word::WdSeekView::wdSeekEvenPagesHeader;
90  else
91  return word::WdSeekView::wdSeekPrimaryHeader;
92  }
93  else
94  {
96  return word::WdSeekView::wdSeekFirstPageFooter;
98  return word::WdSeekView::wdSeekEvenPagesFooter;
99  else
100  return word::WdSeekView::wdSeekPrimaryFooter;
101  }
102  }
103  else if ( aImplName == "SwXFootnote" )
104  {
105  if( xServiceInfo->supportsService("com.sun.star.text.Endnote") )
106  return word::WdSeekView::wdSeekEndnotes;
107  else
108  return word::WdSeekView::wdSeekFootnotes;
109  }
110 
111  return word::WdSeekView::wdSeekMainDocument;
112 }
113 
114 void SAL_CALL
115 SwVbaView::setSeekView( ::sal_Int32 _seekview )
116 {
117  // FIXME: save the current cursor position, if the cursor is in the main
118  // document, so we can jump back to this position, if the macro sets
119  // the ViewMode back to wdSeekMainDocument
120 
122  switch( _seekview )
123  {
124  case word::WdSeekView::wdSeekFirstPageFooter:
125  case word::WdSeekView::wdSeekFirstPageHeader:
126  case word::WdSeekView::wdSeekCurrentPageFooter:
127  case word::WdSeekView::wdSeekCurrentPageHeader:
128  case word::WdSeekView::wdSeekPrimaryFooter:
129  case word::WdSeekView::wdSeekPrimaryHeader:
130  case word::WdSeekView::wdSeekEvenPagesFooter:
131  case word::WdSeekView::wdSeekEvenPagesHeader:
132  {
133  // need to test
134  mxViewCursor->gotoRange( getHFTextRange( _seekview ), false );
135  break;
136  }
137  case word::WdSeekView::wdSeekFootnotes:
138  {
139  uno::Reference< text::XFootnotesSupplier > xFootnotesSupp( mxModel, uno::UNO_QUERY_THROW );
140  uno::Reference< container::XIndexAccess > xFootnotes( xFootnotesSupp->getFootnotes(), uno::UNO_SET_THROW );
141  if( xFootnotes->getCount() > 0 )
142  {
143  uno::Reference< text::XText > xText( xFootnotes->getByIndex(0), uno::UNO_QUERY_THROW );
144  mxViewCursor->gotoRange( xText->getStart(), false );
145  }
146  else
147  {
148  DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT );
149  }
150  break;
151  }
152  case word::WdSeekView::wdSeekEndnotes:
153  {
154  uno::Reference< text::XEndnotesSupplier > xEndnotesSupp( mxModel, uno::UNO_QUERY_THROW );
155  uno::Reference< container::XIndexAccess > xEndnotes( xEndnotesSupp->getEndnotes(), uno::UNO_SET_THROW );
156  if( xEndnotes->getCount() > 0 )
157  {
158  uno::Reference< text::XText > xText( xEndnotes->getByIndex(0), uno::UNO_QUERY_THROW );
159  mxViewCursor->gotoRange( xText->getStart(), false );
160  }
161  else
162  {
163  DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT );
164  }
165  break;
166  }
167  case word::WdSeekView::wdSeekMainDocument:
168  {
169  uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW );
170  uno::Reference< text::XText > xText = xTextDocument->getText();
171  mxViewCursor->gotoRange( word::getFirstObjectPosition( xText ), false );
172  break;
173  }
174  }
175 }
176 
177 ::sal_Int32 SAL_CALL
179 {
180  return word::WdSpecialPane::wdPaneNone;
181 }
182 
183 void SAL_CALL
184 SwVbaView::setSplitSpecial( ::sal_Int32/* _splitspecial */)
185 {
186  // not support in Writer
187 }
188 
189 sal_Bool SAL_CALL
191 {
192  bool bShowTableGridLine = false;
193  mxViewSettings->getPropertyValue("ShowTableBoundaries") >>= bShowTableGridLine;
194  return bShowTableGridLine;
195 }
196 
197 void SAL_CALL
199 {
200  mxViewSettings->setPropertyValue("ShowTableBoundaries", uno::makeAny( _tablegridlines ) );
201 }
202 
203 ::sal_Int32 SAL_CALL
205 {
206  // FIXME: handle wdPrintPreview type
207  bool bOnlineLayout = false;
208  mxViewSettings->getPropertyValue("ShowOnlineLayout") >>= bOnlineLayout;
209  return bOnlineLayout ? word::WdViewType::wdWebView : word::WdViewType::wdPrintView;
210 }
211 
212 void SAL_CALL
213 SwVbaView::setType( ::sal_Int32 _type )
214 {
215  // FIXME: handle wdPrintPreview type
216  switch( _type )
217  {
218  case word::WdViewType::wdPrintView:
219  case word::WdViewType::wdNormalView:
220  {
221  mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::makeAny( false ) );
222  break;
223  }
224  case word::WdViewType::wdWebView:
225  {
226  mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::makeAny( true ) );
227  break;
228  }
229  case word::WdViewType::wdPrintPreview:
230  {
232  break;
233  }
234  default:
235  DebugHelper::runtimeexception( ERRCODE_BASIC_NOT_IMPLEMENTED );
236 
237  }
238 }
239 
240 uno::Reference< text::XTextRange > SwVbaView::getHFTextRange( sal_Int32 nType )
241 {
242  mxModel->lockControllers();
243 
244  OUString aPropIsOn;
245  OUString aPropIsShared;
246  OUString aPropBodyDistance;
247  OUString aPropText;
248 
249  switch( nType )
250  {
251  case word::WdSeekView::wdSeekCurrentPageFooter:
252  case word::WdSeekView::wdSeekFirstPageFooter:
253  case word::WdSeekView::wdSeekPrimaryFooter:
254  case word::WdSeekView::wdSeekEvenPagesFooter:
255  {
256  aPropIsOn = "FooterIsOn";
257  aPropIsShared = "FooterIsShared";
258  aPropBodyDistance = "FooterBodyDistance";
259  aPropText = "FooterText";
260  break;
261  }
262  case word::WdSeekView::wdSeekCurrentPageHeader:
263  case word::WdSeekView::wdSeekFirstPageHeader:
264  case word::WdSeekView::wdSeekPrimaryHeader:
265  case word::WdSeekView::wdSeekEvenPagesHeader:
266  {
267  aPropIsOn = "HeaderIsOn";
268  aPropIsShared = "HeaderIsShared";
269  aPropBodyDistance = "HeaderBodyDistance";
270  aPropText = "HeaderText";
271  break;
272  }
273  }
274 
275  uno::Reference< text::XPageCursor > xPageCursor( mxViewCursor, uno::UNO_QUERY_THROW );
276 
277  if( nType == word::WdSeekView::wdSeekFirstPageFooter
278  || nType == word::WdSeekView::wdSeekFirstPageHeader )
279  {
280  xPageCursor->jumpToFirstPage();
281  }
282 
283  uno::Reference< style::XStyle > xStyle;
284  uno::Reference< text::XText > xText;
285  switch( nType )
286  {
287  case word::WdSeekView::wdSeekPrimaryFooter:
288  case word::WdSeekView::wdSeekPrimaryHeader:
289  case word::WdSeekView::wdSeekEvenPagesFooter:
290  case word::WdSeekView::wdSeekEvenPagesHeader:
291  {
292  // The primary header is the first header of the section.
293  // If the header is not shared between odd and even pages
294  // the odd page's header is the primary header. If the
295  // first page's header is different from the rest of the
296  // document, it is NOT the primary header ( the next primary
297  // header would be on page 3 )
298  // The even pages' header is only available if the header is
299  // not shared and the current style is applied to a page with
300  // an even page number
301  uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW );
302  OUString aPageStyleName;
303  xCursorProps->getPropertyValue("PageStyleName") >>= aPageStyleName;
304  if ( aPageStyleName == "First Page" )
305  {
306  // go to the beginning of where the next style is used
307  bool hasNextPage = false;
309  do
310  {
311  hasNextPage = xPageCursor->jumpToNextPage();
312  }
313  while( hasNextPage && ( xStyle == word::getCurrentPageStyle( mxModel ) ) );
314 
315  if( !hasNextPage )
316  DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, {} );
317  }
318  break;
319  }
320  default:
321  {
322  break;
323  }
324  }
325 
327  uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW );
328  bool isOn = false;
329  xPageProps->getPropertyValue( aPropIsOn ) >>= isOn;
330  bool isShared = false;
331  xPageProps->getPropertyValue( aPropIsShared ) >>= isShared;
332  if( !isOn )
333  {
334  xPageProps->setPropertyValue( aPropIsOn, uno::makeAny( true ) );
335  xPageProps->setPropertyValue( aPropBodyDistance, uno::makeAny( DEFAULT_BODY_DISTANCE ) );
336  }
337  if( !isShared )
338  {
339  OUString aTempPropText = aPropText;
340  if( nType == word::WdSeekView::wdSeekEvenPagesFooter
341  || nType == word::WdSeekView::wdSeekEvenPagesHeader )
342  {
343  aTempPropText += "Left";
344  }
345  else
346  {
347  aTempPropText += "Right";
348  }
349  xText.set( xPageProps->getPropertyValue( aTempPropText), uno::UNO_QUERY_THROW );
350  }
351  else
352  {
353  if( nType == word::WdSeekView::wdSeekEvenPagesFooter
354  || nType == word::WdSeekView::wdSeekEvenPagesHeader )
355  {
356  DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, {} );
357  }
358  xText.set( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW );
359  }
360 
361  mxModel->unlockControllers();
362  if( !xText.is() )
363  {
364  DebugHelper::basicexception( ERRCODE_BASIC_INTERNAL_ERROR, {} );
365  }
366  uno::Reference< text::XTextRange > xTextRange = word::getFirstObjectPosition( xText );
367  return xTextRange;
368 }
369 
370 OUString
372 {
373  return "SwVbaView";
374 }
375 
376 uno::Sequence< OUString >
378 {
379  static uno::Sequence< OUString > const aServiceNames
380  {
381  "ooo.vba.word.View"
382  };
383  return aServiceNames;
384 }
385 
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual OUString getServiceImplName() override
Definition: vbaview.cxx:371
void PrintPreviewHelper(const css::uno::Any &, SfxViewShell const *pViewShell)
virtual ~SwVbaView() override
Definition: vbaview.cxx:59
css::uno::Reference< css::frame::XModel > mxModel
Definition: vbaview.hxx:33
static bool isFirstPageHeader(const css::uno::Reference< css::frame::XModel > &xModel)
css::uno::Reference< css::frame::XModel2 > mxModel
Sequence< OUString > aServiceNames
static bool isEvenPagesFooter(const css::uno::Reference< css::frame::XModel > &xModel)
virtual void SAL_CALL setTableGridLines(sal_Bool _tablegridlines) override
Definition: vbaview.cxx:198
#define ERRCODE_BASIC_NOT_IMPLEMENTED
css::uno::Reference< css::text::XTextViewCursor > mxViewCursor
Definition: vbaview.hxx:34
Reference< XController > xController
virtual sal_Bool SAL_CALL getTableGridLines() override
Definition: vbaview.cxx:190
virtual css::uno::Sequence< OUString > getServiceNames() override
Definition: vbaview.cxx:377
virtual ::sal_Int32 SAL_CALL getSplitSpecial() override
Definition: vbaview.cxx:178
uno::Reference< style::XStyle > getCurrentPageStyle(const uno::Reference< frame::XModel > &xModel)
#define ERRCODE_BASIC_BAD_ACTION
css::uno::Reference< css::text::XTextRange > getHFTextRange(sal_Int32 nType)
Definition: vbaview.cxx:240
virtual void SAL_CALL setSeekView(::sal_Int32 _seekview) override
Definition: vbaview.cxx:115
SwView * getView(const uno::Reference< frame::XModel > &xModel)
bool gotoSelectedObjectAnchor(const uno::Reference< frame::XModel > &xModel)
virtual void SAL_CALL setType(::sal_Int32 _type) override
Definition: vbaview.cxx:213
unsigned char sal_Bool
css::uno::Reference< css::beans::XPropertySet > mxViewSettings
Definition: vbaview.hxx:35
#define ERRCODE_BASIC_NO_ACTIVE_OBJECT
virtual ::sal_Int32 SAL_CALL getSeekView() override
Definition: vbaview.cxx:64
#define ERRCODE_BASIC_INTERNAL_ERROR
static bool isEvenPagesHeader(const css::uno::Reference< css::frame::XModel > &xModel)
const sal_Int32 DEFAULT_BODY_DISTANCE
Definition: vbaview.cxx:44
static bool isFirstPageFooter(const css::uno::Reference< css::frame::XModel > &xModel)
uno::Reference< text::XTextRange > getFirstObjectPosition(const uno::Reference< text::XText > &xText)
SwVbaView(const css::uno::Reference< ooo::vba::XHelperInterface > &rParent, const css::uno::Reference< css::uno::XComponentContext > &rContext, const css::uno::Reference< css::frame::XModel > &rModel)
Definition: vbaview.cxx:46
static bool isHeader(const css::uno::Reference< css::frame::XModel > &xModel)
virtual ::sal_Int32 SAL_CALL getType() override
Definition: vbaview.cxx:204
virtual void SAL_CALL setSplitSpecial(::sal_Int32 _splitspecial) override
Definition: vbaview.cxx:184