xref: /trunk/main/sc/source/ui/vba/vbawindow.cxx (revision 3f2293a34d640799d3a646809239d04f5e6f46e0)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include <vbahelper/helperdecl.hxx>
23 #include "vbawindow.hxx"
24 #include "vbaworksheets.hxx"
25 #include "vbaworksheet.hxx"
26 #include "vbaglobals.hxx"
27 #include "vbapane.hxx"
28 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
29 #include <com/sun/star/sheet/XSpreadsheet.hpp>
30 #include <com/sun/star/container/XNamed.hpp>
31 #include <com/sun/star/view/DocumentZoomType.hpp>
32 #include <com/sun/star/table/CellRangeAddress.hpp>
33 #include <ooo/vba/excel/XlWindowState.hpp>
34 #include <ooo/vba/excel/XlWindowView.hpp>
35 #include <ooo/vba/excel/Constants.hpp>
36 #include <com/sun/star/awt/XWindow.hpp>
37 #include <com/sun/star/awt/XWindow2.hpp>
38 #include <com/sun/star/awt/PosSize.hpp>
39 
40 #include <docsh.hxx>
41 #include <tabvwsh.hxx>
42 #include <docuno.hxx>
43 #include <sc.hrc>
44 #include <hash_map>
45 #include <sfx2/viewfrm.hxx>
46 #include <vcl/wrkwin.hxx>
47 #include "unonames.hxx"
48 
49 using namespace ::com::sun::star;
50 using namespace ::ooo::vba;
51 using namespace ::ooo::vba::excel::XlWindowState;
52 
53 typedef  std::hash_map< rtl::OUString,
54 SCTAB, ::rtl::OUStringHash,
55 ::std::equal_to< ::rtl::OUString > > NameIndexHash;
56 
57 typedef std::vector< uno::Reference< sheet::XSpreadsheet > > Sheets;
58 
59 typedef ::cppu::WeakImplHelper1< container::XEnumeration > Enumeration_BASE;
60 
61 typedef ::cppu::WeakImplHelper3< container::XEnumerationAccess
62     , com::sun::star::container::XIndexAccess
63     , com::sun::star::container::XNameAccess
64     > SelectedSheets_BASE;
65 
66 
67 class SelectedSheetsEnum : public Enumeration_BASE
68 {
69 public:
70     uno::Reference< uno::XComponentContext > m_xContext;
71     Sheets m_sheets;
72     uno::Reference< frame::XModel > m_xModel;
73     Sheets::const_iterator m_it;
74 
75     SelectedSheetsEnum( const uno::Reference< uno::XComponentContext >& xContext, const Sheets& sheets, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) :  m_xContext( xContext ), m_sheets( sheets ), m_xModel( xModel )
76     {
77         m_it = m_sheets.begin();
78     }
79     // XEnumeration
80     virtual ::sal_Bool SAL_CALL hasMoreElements(  ) throw (uno::RuntimeException)
81     {
82         return m_it != m_sheets.end();
83     }
84     virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
85     {
86         if ( !hasMoreElements() )
87         {
88             throw container::NoSuchElementException();
89         }
90         // #FIXME needs ThisWorkbook as parent
91         return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( uno::Reference< XHelperInterface >(), m_xContext, *(m_it++), m_xModel ) ) );
92     }
93 
94 
95 };
96 
97 class SelectedSheetsEnumAccess : public SelectedSheets_BASE
98 {
99     uno::Reference< uno::XComponentContext > m_xContext;
100     NameIndexHash namesToIndices;
101     Sheets sheets;
102     uno::Reference< frame::XModel > m_xModel;
103 public:
104     SelectedSheetsEnumAccess( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ):m_xContext( xContext ), m_xModel( xModel )
105     {
106         ScModelObj* pModel = static_cast< ScModelObj* >( m_xModel.get() );
107         if ( !pModel )
108             throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain current document" ) ), uno::Reference< uno::XInterface >() );
109         ScDocShell* pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
110         if ( !pDocShell )
111             throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain docshell" ) ), uno::Reference< uno::XInterface >() );
112         ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
113         if ( !pViewShell )
114             throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain view shell" ) ), uno::Reference< uno::XInterface >() );
115 
116         SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
117         uno::Sequence<sal_Int32> aSheets( nTabCount );
118         SCTAB nIndex = 0;
119         const ScMarkData& rMarkData = pViewShell->GetViewData()->GetMarkData();
120         sheets.reserve( nTabCount );
121         uno::Reference <sheet::XSpreadsheetDocument> xSpreadSheet( m_xModel, uno::UNO_QUERY_THROW );
122         uno::Reference <container::XIndexAccess> xIndex( xSpreadSheet->getSheets(), uno::UNO_QUERY_THROW );
123         for ( SCTAB nTab=0; nTab<nTabCount; nTab++ )
124         {
125             if ( rMarkData.GetTableSelect(nTab) )
126             {
127                 uno::Reference< sheet::XSpreadsheet > xSheet( xIndex->getByIndex( nTab ), uno::UNO_QUERY_THROW );
128                 uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
129                 sheets.push_back( xSheet );
130                 namesToIndices[ xNamed->getName() ] = nIndex++;
131             }
132         }
133 
134     }
135 
136     //XEnumerationAccess
137     virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration(  ) throw (uno::RuntimeException)
138     {
139         return new SelectedSheetsEnum( m_xContext, sheets, m_xModel  );
140     }
141     // XIndexAccess
142     virtual ::sal_Int32 SAL_CALL getCount(  ) throw (uno::RuntimeException)
143     {
144         return sheets.size();
145     }
146     virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw ( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
147     {
148         if ( Index < 0
149         || static_cast< Sheets::size_type >( Index ) >= sheets.size() )
150             throw lang::IndexOutOfBoundsException();
151 
152         return uno::makeAny( sheets[ Index ] );
153     }
154 
155     //XElementAccess
156     virtual uno::Type SAL_CALL getElementType(  ) throw (uno::RuntimeException)
157     {
158         return excel::XWorksheet::static_type(0);
159     }
160 
161     virtual ::sal_Bool SAL_CALL hasElements(  ) throw (uno::RuntimeException)
162     {
163         return (sheets.size() > 0);
164     }
165 
166     //XNameAccess
167     virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
168     {
169         NameIndexHash::const_iterator it = namesToIndices.find( aName );
170         if ( it == namesToIndices.end() )
171             throw container::NoSuchElementException();
172         return uno::makeAny( sheets[ it->second ] );
173 
174     }
175 
176     virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames(  ) throw (uno::RuntimeException)
177     {
178         uno::Sequence< ::rtl::OUString > names( namesToIndices.size() );
179         ::rtl::OUString* pString = names.getArray();
180         NameIndexHash::const_iterator it = namesToIndices.begin();
181         NameIndexHash::const_iterator it_end = namesToIndices.end();
182         for ( ; it != it_end; ++it, ++pString )
183             *pString = it->first;
184         return names;
185     }
186 
187     virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
188     {
189         NameIndexHash::const_iterator it = namesToIndices.find( aName );
190         return (it != namesToIndices.end());
191     }
192 
193 
194 };
195 
196 ScVbaWindow::ScVbaWindow(
197         const uno::Reference< XHelperInterface >& xParent,
198         const uno::Reference< uno::XComponentContext >& xContext,
199         const uno::Reference< frame::XModel >& xModel,
200         const uno::Reference< frame::XController >& xController ) throw (uno::RuntimeException) :
201     WindowImpl_BASE( xParent, xContext, xModel, xController )
202 {
203     init();
204 }
205 
206 ScVbaWindow::ScVbaWindow(
207         const uno::Sequence< uno::Any >& args,
208         const uno::Reference< uno::XComponentContext >& xContext ) throw (uno::RuntimeException) :
209     WindowImpl_BASE( args, xContext )
210 {
211     init();
212 }
213 
214 void
215 ScVbaWindow::init()
216 {
217     /*  This method is called from the constructor, thus the own refcount is
218         still zero. The implementation of ActivePane() uses a UNO reference of
219         this (to set this window as parent of the pane object). This requires
220         the own refcount to be non-zero, otherwise this instance will be
221         desctructed immediately! Guard the call to ActivePane() in try/catch to
222         not miss the decrementation of the reference count on exception. */
223     osl_incrementInterlockedCount( &m_refCount );
224     try
225     {
226        m_xPane = ActivePane();
227     }
228     catch( uno::Exception& )
229     {
230     }
231     osl_decrementInterlockedCount( &m_refCount );
232 }
233 
234 uno::Reference< beans::XPropertySet >
235 ScVbaWindow::getControllerProps() throw (uno::RuntimeException)
236 {
237     return uno::Reference< beans::XPropertySet >( getController(), uno::UNO_QUERY_THROW );
238 }
239 
240 uno::Reference< beans::XPropertySet >
241 ScVbaWindow::getFrameProps() throw (uno::RuntimeException)
242 {
243     return uno::Reference< beans::XPropertySet >( getController()->getFrame(), uno::UNO_QUERY_THROW );
244 }
245 
246 uno::Reference< awt::XDevice >
247 ScVbaWindow::getDevice() throw (uno::RuntimeException)
248 {
249     return uno::Reference< awt::XDevice >( getWindow(), uno::UNO_QUERY_THROW );
250 }
251 
252 void
253 ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft, bool bLargeScroll ) throw (uno::RuntimeException)
254 {
255     if( !m_xPane.is() )
256         throw uno::RuntimeException();
257     if( bLargeScroll )
258         m_xPane->LargeScroll( Down, Up, ToRight, ToLeft );
259     else
260         m_xPane->SmallScroll( Down, Up, ToRight, ToLeft );
261 }
262 
263 void SAL_CALL
264 ScVbaWindow::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException)
265 {
266     Scroll( Down, Up, ToRight, ToLeft );
267 }
268 
269 void SAL_CALL
270 ScVbaWindow::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException)
271 {
272     Scroll( Down, Up, ToRight, ToLeft, true );
273 }
274 
275 uno::Any SAL_CALL
276 ScVbaWindow::SelectedSheets( const uno::Any& aIndex ) throw (uno::RuntimeException)
277 {
278     uno::Reference< container::XEnumerationAccess > xEnumAccess( new SelectedSheetsEnumAccess( mxContext, m_xModel ) );
279     // #FIXME needs a workbook as a parent
280     uno::Reference< excel::XWorksheets > xSheets(  new ScVbaWorksheets( uno::Reference< XHelperInterface >(), mxContext, xEnumAccess, m_xModel ) );
281     if ( aIndex.hasValue() )
282     {
283         uno::Reference< XCollection > xColl( xSheets, uno::UNO_QUERY_THROW );
284         return xColl->Item( aIndex, uno::Any() );
285     }
286     return uno::makeAny( xSheets );
287 }
288 
289 void SAL_CALL
290 ScVbaWindow::ScrollWorkbookTabs( const uno::Any& /*Sheets*/, const uno::Any& /*Position*/ ) throw (uno::RuntimeException)
291 {
292 // #TODO #FIXME need some implementation to scroll through the tabs
293 // but where is this done?
294 /*
295     sal_Int32 nSheets = 0;
296     sal_Int32 nPosition = 0;
297     throw uno::RuntimeException( rtl::OUString::createFromAscii("No Implemented" ), uno::Reference< uno::XInterface >() );
298     sal_Bool bSheets = ( Sheets >>= nSheets );
299     sal_Bool bPosition = ( Position >>= nPosition );
300     if ( bSheets || bPosition ) // at least one param specified
301         if ( bSheets )
302             ;// use sheets
303         else if ( bPosition )
304             ; //use position
305 */
306 
307 }
308 
309 uno::Any SAL_CALL
310 ScVbaWindow::getCaption() throw (uno::RuntimeException)
311 {
312     static rtl::OUString sCrud(RTL_CONSTASCII_USTRINGPARAM(" - OpenOffice Calc" ) );
313     static sal_Int32 nCrudLen = sCrud.getLength();
314 
315     rtl::OUString sTitle;
316     getFrameProps()->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SC_UNONAME_TITLE ) ) ) >>= sTitle;
317     sal_Int32 nCrudIndex = sTitle.indexOf( sCrud );
318     // adjust title ( by removing crud )
319     // sCrud string present
320     if ( nCrudIndex != -1 )
321     {
322         // and ends with sCrud
323         if ( ( nCrudLen + nCrudIndex ) == sTitle.getLength() )
324         {
325             sTitle = sTitle.copy( 0, nCrudIndex );
326             ScVbaWorkbook workbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel );
327             rtl::OUString sName = workbook.getName();
328             // rather bizare hack to make sure the name behavior
329             // is like XL
330             // if the adjusted title == workbook name, use name
331             // if the adjusted title != workbook name but ...
332             //  name == title + extension ( .csv, ,odt, .xls )
333             //  etc. then also use the name
334 
335             if ( !sTitle.equals( sName ) )
336             {
337                 static rtl::OUString sDot( RTL_CONSTASCII_USTRINGPARAM(".") );
338                 // starts with title
339                 if ( sName.indexOf( sTitle ) == 0 )
340                     // extension starts immediately after
341                     if ( sName.match( sDot, sTitle.getLength() ) )
342                         sTitle = sName;
343             }
344         }
345     }
346     return uno::makeAny( sTitle );
347 }
348 
349 void SAL_CALL
350 ScVbaWindow::setCaption( const uno::Any& _caption ) throw (uno::RuntimeException)
351 {
352     getFrameProps()->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_TITLE ) ), _caption );
353 }
354 
355 uno::Any SAL_CALL
356 ScVbaWindow::getScrollRow() throw (uno::RuntimeException)
357 {
358     sal_Int32 nValue = 0;
359     // !! TODO !! get view shell from controller
360     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
361     if ( pViewShell )
362     {
363         ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
364         nValue = pViewShell->GetViewData()->GetPosY(WhichV(eWhich));
365     }
366 
367     return uno::makeAny( nValue + 1);
368 }
369 
370 void SAL_CALL
371 ScVbaWindow::setScrollRow( const uno::Any& _scrollrow ) throw (uno::RuntimeException)
372 {
373     // !! TODO !! get view shell from controller
374     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
375     if ( pViewShell )
376     {
377         sal_Int32 scrollRow = 0;
378         _scrollrow >>= scrollRow;
379         ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
380         sal_Int32 nOldValue = pViewShell->GetViewData()->GetPosY(WhichV(eWhich)) + 1;
381         pViewShell->ScrollLines(0, scrollRow - nOldValue);
382     }
383 }
384 
385 uno::Any SAL_CALL
386 ScVbaWindow::getScrollColumn() throw (uno::RuntimeException)
387 {
388     sal_Int32 nValue = 0;
389     // !! TODO !! get view shell from controller
390     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
391     if ( pViewShell )
392     {
393         ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
394         nValue = pViewShell->GetViewData()->GetPosX(WhichH(eWhich));
395     }
396 
397     return uno::makeAny( nValue + 1);
398 }
399 
400 void SAL_CALL
401 ScVbaWindow::setScrollColumn( const uno::Any& _scrollcolumn ) throw (uno::RuntimeException)
402 {
403     // !! TODO !! get view shell from controller
404     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
405     if ( pViewShell )
406     {
407         sal_Int32 scrollColumn = 0;
408         _scrollcolumn >>= scrollColumn;
409         ScSplitPos eWhich = pViewShell->GetViewData()->GetActivePart();
410         sal_Int32 nOldValue = pViewShell->GetViewData()->GetPosX(WhichH(eWhich)) + 1;
411         pViewShell->ScrollLines(scrollColumn - nOldValue, 0);
412     }
413 }
414 
415 uno::Any SAL_CALL
416 ScVbaWindow::getWindowState() throw (uno::RuntimeException)
417 {
418     sal_Int32 nwindowState = xlNormal;
419     // !! TODO !! get view shell from controller
420     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
421     SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame();
422     WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow();
423     if ( pWork )
424     {
425         if ( pWork -> IsMaximized())
426             nwindowState = xlMaximized;
427         else if (pWork -> IsMinimized())
428             nwindowState = xlMinimized;
429     }
430     return uno::makeAny( nwindowState );
431 }
432 
433 void SAL_CALL
434 ScVbaWindow::setWindowState( const uno::Any& _windowstate ) throw (uno::RuntimeException)
435 {
436     sal_Int32 nwindowState = xlMaximized;
437     _windowstate >>= nwindowState;
438     // !! TODO !! get view shell from controller
439     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
440     SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame();
441     WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow();
442     if ( pWork )
443     {
444         if ( nwindowState == xlMaximized)
445             pWork -> Maximize();
446         else if (nwindowState == xlMinimized)
447             pWork -> Minimize();
448         else if (nwindowState == xlNormal)
449             pWork -> Restore();
450         else
451             throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Invalid Parameter" ) ), uno::Reference< uno::XInterface >() );
452     }
453 }
454 
455 void
456 ScVbaWindow::Activate() throw (css::uno::RuntimeException)
457 {
458     ScVbaWorkbook workbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel );
459 
460     workbook.Activate();
461 }
462 
463 void
464 ScVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& FileName, const uno::Any& RouteWorkBook ) throw (uno::RuntimeException)
465 {
466     ScVbaWorkbook workbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel );
467     workbook.Close(SaveChanges, FileName, RouteWorkBook );
468 }
469 
470 uno::Reference< excel::XPane > SAL_CALL
471 ScVbaWindow::ActivePane() throw (script::BasicErrorException, uno::RuntimeException)
472 {
473     uno::Reference< sheet::XViewPane > xViewPane( getController(), uno::UNO_QUERY_THROW );
474     return new ScVbaPane( this, mxContext, m_xModel, xViewPane );
475 }
476 
477 uno::Reference< excel::XRange > SAL_CALL
478 ScVbaWindow::ActiveCell(  ) throw (script::BasicErrorException, uno::RuntimeException)
479 {
480     uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
481     return xApplication->getActiveCell();
482 }
483 
484 uno::Any SAL_CALL
485 ScVbaWindow::Selection(  ) throw (script::BasicErrorException, uno::RuntimeException)
486 {
487     uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
488     return xApplication->getSelection();
489 }
490 
491 uno::Reference< excel::XRange > SAL_CALL
492 ScVbaWindow::RangeSelection() throw (script::BasicErrorException, uno::RuntimeException)
493 {
494     /*  TODO / FIXME: According to documentation, this method returns the range
495         selection even if shapes are selected. */
496     return uno::Reference< excel::XRange >( Selection(), uno::UNO_QUERY_THROW );
497 }
498 
499 ::sal_Bool SAL_CALL
500 ScVbaWindow::getDisplayGridlines() throw (uno::RuntimeException)
501 {
502     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWGRID ) );
503     sal_Bool bGrid = sal_True;
504     getControllerProps()->getPropertyValue( sName ) >>= bGrid;
505     return bGrid;
506 }
507 
508 
509 void SAL_CALL
510 ScVbaWindow::setDisplayGridlines( ::sal_Bool _displaygridlines ) throw (uno::RuntimeException)
511 {
512     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWGRID ) );
513     getControllerProps()->setPropertyValue( sName, uno::makeAny( _displaygridlines ));
514 }
515 
516 ::sal_Bool SAL_CALL
517 ScVbaWindow::getDisplayHeadings() throw (uno::RuntimeException)
518 {
519     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLROWHDR ) );
520     sal_Bool bHeading = sal_True;
521     getControllerProps()->getPropertyValue( sName ) >>= bHeading;
522     return bHeading;
523 }
524 
525 void SAL_CALL
526 ScVbaWindow::setDisplayHeadings( ::sal_Bool _bDisplayHeadings ) throw (uno::RuntimeException)
527 {
528     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLROWHDR ) );
529     getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayHeadings ));
530 }
531 
532 ::sal_Bool SAL_CALL
533 ScVbaWindow::getDisplayHorizontalScrollBar() throw (uno::RuntimeException)
534 {
535     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_HORSCROLL ) );
536     sal_Bool bHorizontalScrollBar = sal_True;
537     getControllerProps()->getPropertyValue( sName ) >>= bHorizontalScrollBar;
538     return bHorizontalScrollBar;
539 }
540 
541 void SAL_CALL
542 ScVbaWindow::setDisplayHorizontalScrollBar( ::sal_Bool _bDisplayHorizontalScrollBar ) throw (uno::RuntimeException)
543 {
544     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_HORSCROLL ) );
545     getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayHorizontalScrollBar ));
546 }
547 
548 ::sal_Bool SAL_CALL
549 ScVbaWindow::getDisplayOutline() throw (uno::RuntimeException)
550 {
551     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_OUTLSYMB ) );
552     sal_Bool bOutline = sal_True;
553     getControllerProps()->getPropertyValue( sName ) >>= bOutline;
554     return bOutline;
555 }
556 
557 void SAL_CALL
558 ScVbaWindow::setDisplayOutline( ::sal_Bool _bDisplayOutline ) throw (uno::RuntimeException)
559 {
560     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_OUTLSYMB ) );
561     getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayOutline ));
562 }
563 
564 ::sal_Bool SAL_CALL
565 ScVbaWindow::getDisplayVerticalScrollBar() throw (uno::RuntimeException)
566 {
567     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_VERTSCROLL ) );
568     sal_Bool bVerticalScrollBar = sal_True;
569     getControllerProps()->getPropertyValue( sName ) >>= bVerticalScrollBar;
570     return bVerticalScrollBar;
571 }
572 
573 void SAL_CALL
574 ScVbaWindow::setDisplayVerticalScrollBar( ::sal_Bool _bDisplayVerticalScrollBar ) throw (uno::RuntimeException)
575 {
576     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_VERTSCROLL ) );
577     getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayVerticalScrollBar ));
578 }
579 
580 ::sal_Bool SAL_CALL
581 ScVbaWindow::getDisplayWorkbookTabs() throw (uno::RuntimeException)
582 {
583     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHEETTABS ) );
584     sal_Bool bWorkbookTabs = sal_True;
585     getControllerProps()->getPropertyValue( sName ) >>= bWorkbookTabs;
586     return bWorkbookTabs;
587 }
588 
589 void SAL_CALL
590 ScVbaWindow::setDisplayWorkbookTabs( ::sal_Bool _bDisplayWorkbookTabs ) throw (uno::RuntimeException)
591 {
592     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHEETTABS ) );
593     getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayWorkbookTabs ));
594 }
595 
596 ::sal_Bool SAL_CALL
597 ScVbaWindow::getFreezePanes() throw (uno::RuntimeException)
598 {
599     uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
600     return xViewFreezable->hasFrozenPanes();
601 }
602 
603 void SAL_CALL
604 ScVbaWindow::setFreezePanes( ::sal_Bool _bFreezePanes ) throw (uno::RuntimeException)
605 {
606     uno::Reference< sheet::XViewPane > xViewPane( getController(), uno::UNO_QUERY_THROW );
607     uno::Reference< sheet::XViewSplitable > xViewSplitable( xViewPane, uno::UNO_QUERY_THROW );
608     uno::Reference< sheet::XViewFreezable > xViewFreezable( xViewPane, uno::UNO_QUERY_THROW );
609     if( _bFreezePanes )
610     {
611         if( xViewSplitable->getIsWindowSplit() )
612         {
613             // if there is a split we freeze at the split
614             sal_Int32 nColumn = getSplitColumn();
615             sal_Int32 nRow = getSplitRow();
616             xViewFreezable->freezeAtPosition( nColumn, nRow );
617         }
618         else
619         {
620             // otherwise we freeze in the center of the visible sheet
621             table::CellRangeAddress aCellRangeAddress = xViewPane->getVisibleRange();
622             sal_Int32 nColumn = aCellRangeAddress.StartColumn + (( aCellRangeAddress.EndColumn - aCellRangeAddress.StartColumn )/2 );
623             sal_Int32 nRow = aCellRangeAddress.StartRow + (( aCellRangeAddress.EndRow - aCellRangeAddress.StartRow )/2 );
624             xViewFreezable->freezeAtPosition( nColumn, nRow );
625         }
626     }
627     else
628     {
629         //remove the freeze panes
630         xViewSplitable->splitAtPosition(0,0);
631     }
632 }
633 
634 ::sal_Bool SAL_CALL
635 ScVbaWindow::getSplit() throw (uno::RuntimeException)
636 {
637     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
638     return xViewSplitable->getIsWindowSplit();
639 }
640 
641 void SAL_CALL
642 ScVbaWindow::setSplit( ::sal_Bool _bSplit ) throw (uno::RuntimeException)
643 {
644     if( !_bSplit )
645     {
646         uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
647         xViewSplitable->splitAtPosition(0,0);
648     }
649     else
650     {
651         uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
652         uno::Reference< excel::XRange > xRange = ActiveCell();
653         sal_Int32 nRow = xRange->getRow();
654         sal_Int32 nColumn = xRange->getColumn();
655         SplitAtDefinedPosition( nColumn-1, nRow-1 );
656     }
657 }
658 
659 sal_Int32 SAL_CALL
660 ScVbaWindow::getSplitColumn() throw (uno::RuntimeException)
661 {
662     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
663     return xViewSplitable->getSplitColumn();
664 }
665 
666 void SAL_CALL
667 ScVbaWindow::setSplitColumn( sal_Int32 _splitcolumn ) throw (uno::RuntimeException)
668 {
669     if( getSplitColumn() != _splitcolumn )
670     {
671         uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
672         sal_Int32 nRow = getSplitRow();
673         SplitAtDefinedPosition( _splitcolumn, nRow );
674     }
675 }
676 
677 double SAL_CALL
678 ScVbaWindow::getSplitHorizontal() throw (uno::RuntimeException)
679 {
680     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
681     return PixelsToPoints( getDevice(), xViewSplitable->getSplitHorizontal(), sal_True );
682 }
683 
684 void SAL_CALL
685 ScVbaWindow::setSplitHorizontal( double _splithorizontal ) throw (uno::RuntimeException)
686 {
687     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
688     double fHoriPixels = PointsToPixels( getDevice(), _splithorizontal, sal_True );
689     xViewSplitable->splitAtPosition( static_cast< sal_Int32 >( fHoriPixels ), 0 );
690 }
691 
692 sal_Int32 SAL_CALL
693 ScVbaWindow::getSplitRow() throw (uno::RuntimeException)
694 {
695     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
696     return xViewSplitable->getSplitRow();
697 }
698 
699 void SAL_CALL
700 ScVbaWindow::setSplitRow( sal_Int32 _splitrow ) throw (uno::RuntimeException)
701 {
702     if( getSplitRow() != _splitrow )
703     {
704         uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
705         sal_Int32 nColumn = getSplitColumn();
706         SplitAtDefinedPosition( nColumn, _splitrow );
707     }
708 }
709 
710 double SAL_CALL
711 ScVbaWindow::getSplitVertical() throw (uno::RuntimeException)
712 {
713     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
714     return PixelsToPoints( getDevice(), xViewSplitable->getSplitVertical(), sal_False );
715 }
716 
717 void SAL_CALL
718 ScVbaWindow::setSplitVertical(double _splitvertical ) throw (uno::RuntimeException)
719 {
720     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
721     double fVertiPixels = PointsToPixels( getDevice(), _splitvertical, sal_False );
722     xViewSplitable->splitAtPosition( 0, static_cast<sal_Int32>( fVertiPixels ) );
723 }
724 
725 void ScVbaWindow::SplitAtDefinedPosition( sal_Int32 nColumns, sal_Int32 nRows )
726 {
727     uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
728     uno::Reference< sheet::XViewFreezable > xViewFreezable( xViewSplitable, uno::UNO_QUERY_THROW );
729     // nColumns and nRows means split columns/rows
730     if( nColumns == 0 && nRows == 0 )
731         return;
732 
733     sal_Int32 cellColumn = nColumns + 1;
734     sal_Int32 cellRow = nRows + 1;
735 
736     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
737     if ( pViewShell )
738     {
739         //firstly remove the old splitter
740         xViewSplitable->splitAtPosition(0,0);
741 
742         uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
743         uno::Reference< excel::XWorksheet > xSheet( xApplication->getActiveSheet(), uno::UNO_QUERY_THROW );
744         xSheet->Cells(uno::makeAny(cellRow), uno::makeAny(cellColumn))->Select();
745 
746         //pViewShell->FreezeSplitters( FALSE );
747         dispatchExecute( pViewShell, SID_WINDOW_SPLIT );
748     }
749 }
750 
751 uno::Any SAL_CALL
752 ScVbaWindow::getZoom() throw (uno::RuntimeException)
753 {
754     uno::Reference< beans::XPropertySet > xProps = getControllerProps();
755     rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ZOOMTYPE ) );
756     sal_Int16 nZoomType = view::DocumentZoomType::PAGE_WIDTH;
757     xProps->getPropertyValue( sName ) >>= nZoomType;
758     if( nZoomType == view::DocumentZoomType::PAGE_WIDTH )
759     {
760         return uno::makeAny( sal_True );
761     }
762     else if( nZoomType == view::DocumentZoomType::BY_VALUE )
763     {
764         sName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ZOOMVALUE));
765         sal_Int16 nZoom = 100;
766         xProps->getPropertyValue( sName ) >>= nZoom;
767         return uno::makeAny( nZoom );
768     }
769     return uno::Any();
770 }
771 
772 void SAL_CALL
773 ScVbaWindow::setZoom( const uno::Any& _zoom ) throw (uno::RuntimeException)
774 {
775     sal_Int16 nZoom = 100;
776     _zoom >>= nZoom;
777     uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( m_xModel, uno::UNO_QUERY_THROW );
778     uno::Reference< excel::XWorksheet > xActiveSheet = ActiveSheet();
779     SCTAB nTab = 0;
780     if ( !ScVbaWorksheets::nameExists (xSpreadDoc, xActiveSheet->getName(), nTab) )
781         throw uno::RuntimeException();
782     std::vector< SCTAB > vTabs;
783     vTabs.push_back( nTab );
784     excel::implSetZoom( m_xModel, nZoom, vTabs );
785 }
786 
787 uno::Reference< excel::XWorksheet > SAL_CALL
788 ScVbaWindow::ActiveSheet(  ) throw (script::BasicErrorException, uno::RuntimeException)
789 {
790     uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
791     return xApplication->getActiveSheet();
792 }
793 
794 uno::Any SAL_CALL
795 ScVbaWindow::getView() throw (uno::RuntimeException)
796 {
797     sal_Bool bPageBreak = sal_False;
798     sal_Int32 nWindowView = excel::XlWindowView::xlNormalView;
799 
800     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
801     if (pViewShell)
802         bPageBreak = pViewShell->GetViewData()->IsPagebreakMode();
803 
804     if( bPageBreak )
805         nWindowView = excel::XlWindowView::xlPageBreakPreview;
806     else
807         nWindowView = excel::XlWindowView::xlNormalView;
808 
809     return uno::makeAny( nWindowView );
810 }
811 
812 void SAL_CALL
813 ScVbaWindow::setView( const uno::Any& _view) throw (uno::RuntimeException)
814 {
815     sal_Int32 nWindowView = excel::XlWindowView::xlNormalView;
816     _view >>= nWindowView;
817     sal_uInt16 nSlot = FID_NORMALVIEWMODE;
818     switch ( nWindowView )
819     {
820         case excel::XlWindowView::xlNormalView:
821             nSlot = FID_NORMALVIEWMODE;
822             break;
823         case excel::XlWindowView::xlPageBreakPreview:
824             nSlot = FID_PAGEBREAKMODE;
825             break;
826         default:
827             DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
828     }
829     // !! TODO !! get view shell from controller
830     ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
831     if ( pViewShell )
832         dispatchExecute( pViewShell, nSlot );
833 }
834 
835 uno::Reference< excel::XRange > SAL_CALL
836 ScVbaWindow::getVisibleRange() throw (uno::RuntimeException)
837 {
838     uno::Reference< container::XIndexAccess > xPanesIA( getController(), uno::UNO_QUERY_THROW );
839     uno::Reference< sheet::XViewPane > xTopLeftPane( xPanesIA->getByIndex( 0 ), uno::UNO_QUERY_THROW );
840     uno::Reference< excel::XPane > xPane( new ScVbaPane( this, mxContext, m_xModel, xTopLeftPane ) );
841     return xPane->getVisibleRange();
842 }
843 
844 sal_Int32 SAL_CALL
845 ScVbaWindow::PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException)
846 {
847     sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points );
848     double fConvertFactor = (getDevice()->getInfo().PixelPerMeterX/100000);
849     return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters );
850 }
851 
852 sal_Int32 SAL_CALL
853 ScVbaWindow::PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException)
854 {
855     sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points );
856     double fConvertFactor = (getDevice()->getInfo().PixelPerMeterY/100000);
857     return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters );
858 }
859 
860 void SAL_CALL
861 ScVbaWindow::PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
862 {
863     // need test, print current active sheet
864     // !! TODO !! get view shell from controller
865     PrintOutHelper( excel::getBestViewShell( m_xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, sal_True );
866 }
867 
868 void SAL_CALL
869 ScVbaWindow::PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
870 {
871     // need test, print preview current active sheet
872     // !! TODO !! get view shell from controller
873     PrintPreviewHelper( EnableChanges, excel::getBestViewShell( m_xModel ) );
874 }
875 
876 rtl::OUString&
877 ScVbaWindow::getServiceImplName()
878 {
879     static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWindow") );
880     return sImplName;
881 }
882 
883 uno::Sequence< rtl::OUString >
884 ScVbaWindow::getServiceNames()
885 {
886     static uno::Sequence< rtl::OUString > aServiceNames;
887     if ( aServiceNames.getLength() == 0 )
888     {
889         aServiceNames.realloc( 1 );
890         aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Window" ) );
891     }
892     return aServiceNames;
893 }
894 namespace window
895 {
896 namespace sdecl = comphelper::service_decl;
897 sdecl::vba_service_class_<ScVbaWindow, sdecl::with_args<true> > serviceImpl;
898 extern sdecl::ServiceDecl const serviceDecl(
899     serviceImpl,
900     "ScVbaWindow",
901     "ooo.vba.excel.Window" );
902 }
903 
904 /* vim: set noet sw=4 ts=4: */
905