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