source/ui/xcalc.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  The Contents of this file are made available subject to
00004  *  the terms of GNU Lesser General Public License Version 2.1.
00005  *
00006  *
00007  *    GNU Lesser General Public License Version 2.1
00008  *    =============================================
00009  *    Copyright 2005 by Kohei Yoshida.
00010  *    1039 Kingsway Dr., Apex, NC 27502, USA
00011  *
00012  *    This library is free software; you can redistribute it and/or
00013  *    modify it under the terms of the GNU Lesser General Public
00014  *    License version 2.1, as published by the Free Software Foundation.
00015  *
00016  *    This library is distributed in the hope that it will be useful,
00017  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *    Lesser General Public License for more details.
00020  *
00021  *    You should have received a copy of the GNU Lesser General Public
00022  *    License along with this library; if not, write to the Free Software
00023  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00024  *    MA  02111-1307  USA
00025  *
00026  ************************************************************************/
00027 
00028 
00029 #include "xcalc.hxx"
00030 #include "tool/global.hxx"
00031 #include "unoglobal.hxx"
00032 
00033 #include <com/sun/star/beans/XPropertyContainer.hpp>
00034 #include <com/sun/star/beans/XProperty.hpp>
00035 #include <com/sun/star/beans/XPropertySet.hpp>
00036 #include <com/sun/star/beans/XPropertySetInfo.hpp>
00037 #include <com/sun/star/beans/PropertyAttribute.hpp>
00038 #include <com/sun/star/container/XIndexAccess.hpp>
00039 #include <com/sun/star/container/XNameAccess.hpp>
00040 #include <com/sun/star/document/XDocumentInfo.hpp>
00041 #include <com/sun/star/document/XDocumentInfoSupplier.hpp>
00042 
00043 #include <com/sun/star/frame/XDesktop.hpp>
00044 
00045 #include <com/sun/star/lang/XComponent.hpp>
00046 
00047 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
00048 #include <com/sun/star/sheet/XRangeSelection.hpp>
00049 #include <com/sun/star/sheet/XSpreadsheet.hpp>
00050 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
00051 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
00052 #include <com/sun/star/sheet/XSpreadsheets.hpp>
00053 
00054 #include <com/sun/star/table/XCell.hpp>
00055 #include <com/sun/star/table/XCellRange.hpp>
00056 
00057 #include <com/sun/star/uno/XComponentContext.hpp>
00058 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
00059 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
00060 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
00061 
00062 #include <iostream>
00063 
00064 using com::sun::star::uno::UNO_QUERY;
00065 using namespace ::com::sun::star::sheet;
00066 
00067 namespace scsolver {    
00068 
00069 CalcInterface::CalcInterface( const Reference< uno::XComponentContext >& xCC ) :
00070         m_xCC( xCC ), m_xSM( NULL ), m_xCurComp( NULL )
00071 {
00072 }
00073 
00074 CalcInterface::~CalcInterface()
00075 {
00076 }
00077 
00078 //------------------------------------------------------------------------------
00079 // Basic Component Methods
00080         
00081 Reference< lang::XComponent > CalcInterface::getCurrentComponent() const
00082 {
00083         if ( m_xCurComp == NULL )
00084                 updateCurrentComponent();
00085         return m_xCurComp;
00086 }
00087 
00088 void CalcInterface::updateCurrentComponent() const
00089 {
00090         Reference< uno::XInterface > aDesktop = getServiceManager()->createInstanceWithContext(
00091                 ascii( "com.sun.star.frame.Desktop" ), m_xCC );
00092 
00093         Reference< frame::XDesktop > xDesktop( aDesktop, UNO_QUERY );
00094         m_xCurComp = xDesktop->getCurrentComponent();   
00095 }
00096 
00097 Reference< lang::XMultiComponentFactory > CalcInterface::getServiceManager() const
00098 {
00099         if ( m_xSM == NULL )
00100                 m_xSM = getComponentContext()->getServiceManager();
00101         return m_xSM;
00102 }
00103 
00104 void CalcInterface::setDocumentProperty( const rtl::OUString& sName, uno::Any aVal )
00105 {
00106         Reference< document::XDocumentInfoSupplier > xDIS( getCurrentComponent(), UNO_QUERY );
00107         Reference< document::XDocumentInfo > xDI = xDIS->getDocumentInfo();
00108 
00109         Reference< beans::XPropertySet > xPS( xDI, UNO_QUERY );
00110         Reference< beans::XPropertySetInfo > xPInfo = xPS->getPropertySetInfo();
00111         if ( !xPInfo->hasPropertyByName( sName ) )
00112         {
00113                 Reference< beans::XPropertyContainer > xPC( xDI, UNO_QUERY );
00114                 xPC->addProperty( sName, beans::PropertyAttribute::OPTIONAL, aVal );
00115         }
00116         xPS->setPropertyValue( sName, aVal );
00117 }
00118 
00119 uno::Any CalcInterface::getDocumentProperty( const rtl::OUString& sName ) const
00120 {
00121         Reference< document::XDocumentInfoSupplier > xDIS( getCurrentComponent(), UNO_QUERY );
00122         Reference< document::XDocumentInfo > xDI = xDIS->getDocumentInfo();
00123         Reference< beans::XPropertySet > xPS( xDI, UNO_QUERY );
00124         uno::Any aVal = xPS->getPropertyValue( sName );
00125         return aVal;
00126 }
00127 
00128 //------------------------------------------------------------------------------
00129 // Calc Component Methods
00130         
00131 Reference< XRangeSelection > CalcInterface::getXRangeSelection() const
00132 {
00133         if ( m_xRngSel == NULL )
00134         {
00135                 Reference< frame::XModel > xModel( getCurrentComponent(), UNO_QUERY );
00136                 OSL_ASSERT( xModel != NULL );
00137                 
00138                 Reference< frame::XController > xController = xModel->getCurrentController();
00139                 OSL_ASSERT( xController != NULL );
00140                 
00141                 Reference< XRangeSelection > xRngSel( xController, UNO_QUERY );
00142                 OSL_ASSERT( xRngSel != NULL );
00143 
00144                 m_xRngSel = xRngSel;
00145         }
00146         
00147         return m_xRngSel;
00148 }
00149 
00150 //------------------------------------------------------------------------------
00151 // Sheet-Related Methods
00152 
00153 Reference< XSpreadsheet > CalcInterface::getActiveSheet() const
00154 {
00155         Reference< lang::XComponent > xCurComp = getCurrentComponent();
00156         Reference< frame::XModel > xModel( xCurComp, UNO_QUERY );
00157         Reference< frame::XController > xCtrler = xModel->getCurrentController();
00158         Reference< sheet::XSpreadsheetView > xView( xCtrler, UNO_QUERY );
00159         return xView->getActiveSheet();
00160 }
00161         
00162 Reference< XSpreadsheet > CalcInterface::getSheetByIndex( const sal_uInt16 nIdx ) const
00163 {
00164         Reference< XSpreadsheetDocument > xDoc( getCurrentComponent(), UNO_QUERY );
00165         Reference< XSpreadsheets > xSheets = xDoc->getSheets();
00166         Reference< container::XIndexAccess > xIndexAccess( xSheets, UNO_QUERY );
00167         uno::Any aSheet = xIndexAccess->getByIndex( nIdx );
00168         Reference< XSpreadsheet > xSheet;
00169         aSheet >>= xSheet;
00170         
00171         return xSheet;
00172 }
00173 
00174 Reference< XSpreadsheet > CalcInterface::getSheetByName( const rtl::OUString& sName ) const
00175 {
00176         Reference< XSpreadsheetDocument > xDoc( getCurrentComponent(), UNO_QUERY );
00177         Reference< XSpreadsheets > xSheets = xDoc->getSheets();
00178         Reference< container::XNameAccess > xNameAccess( xSheets, UNO_QUERY );
00179         uno::Any aSheet = xNameAccess->getByName( sName );
00180         Reference< XSpreadsheet > xSheet;
00181         aSheet >>= xSheet;
00182         
00183         return xSheet;
00184 }
00185 
00186 
00187 
00188 
00189 rtl::OUString lcl_resolveSheetName( const rtl::OUString& sSheetAddr )
00190 {
00191         rtl::OUString sSheetName;
00192         if ( sSheetAddr.indexOf( ascii( "$" ) ) == 0 )
00193         {
00194                 if ( sSheetAddr.indexOf( ascii( "'" ) ) == 1 && 
00195                          sSheetAddr.lastIndexOf( ascii( "'" ) ) == sSheetAddr.getLength() - 1 )
00196                         sSheetName = sSheetAddr.copy( 2, sSheetAddr.getLength() - 3 );
00197                 else
00198                         sSheetName = sSheetAddr.copy( 1, sSheetAddr.getLength() - 1 );
00199         }
00200         else
00201         {
00202                 if ( sSheetAddr.indexOf( ascii( "'" ) ) == 0 && 
00203                          sSheetAddr.lastIndexOf( ascii( "'" ) ) == sSheetAddr.getLength() - 1 )
00204                         sSheetName = sSheetAddr.copy( 1, sSheetAddr.getLength() - 2 );
00205                 else
00206                         sSheetName = sSheetAddr;
00207         }
00208         return sSheetName;
00209 }
00210 
00211 Reference< table::XCell > CalcInterface::getCell( const table::CellAddress& aAddr ) const
00212 {
00213         return getSheetByIndex( aAddr.Sheet )->getCellByPosition( aAddr.Column, aAddr.Row );
00214 }
00215 
00216 table::CellAddress CalcInterface::getCellAddress( const rtl::OUString& sFullAddr )
00217 {
00218         rtl::OUString sSheetAddr, sCellAddr;
00219         splitCellRangeAddress( sFullAddr, sSheetAddr, sCellAddr );
00220         return getCellAddress( sSheetAddr, sCellAddr );
00221 }
00222 
00223 table::CellAddress CalcInterface::getCellAddress(
00224         const rtl::OUString& sSheetAddr, const rtl::OUString& sCellAddr )
00225 {
00226         table::CellRangeAddress aCRAddr = getCellRangeAddress( sSheetAddr, sCellAddr );
00227         table::CellAddress aAddr;
00228         aAddr.Sheet = aCRAddr.Sheet;
00229         aAddr.Column = aCRAddr.StartColumn;
00230         aAddr.Row = aCRAddr.StartRow;
00231         
00232         return aAddr;
00233 }
00234 
00235 table::CellRangeAddress CalcInterface::getCellRangeAddress( 
00236         const rtl::OUString& sFullAddr )
00237 {
00238         rtl::OUString sSheetAddr, sCellAddr;
00239         splitCellRangeAddress( sFullAddr, sSheetAddr, sCellAddr );
00240         return getCellRangeAddress( sSheetAddr, sCellAddr );
00241 }
00242 
00243 table::CellRangeAddress CalcInterface::getCellRangeAddress( 
00244         const rtl::OUString& sSheetAddr, const rtl::OUString& sCellAddr )
00245 {
00246         rtl::OUString sSheetName = lcl_resolveSheetName( sSheetAddr );
00247         
00248         Reference< sheet::XSpreadsheet > xSheet;
00249         table::CellRangeAddress aCRAddr;
00250         try
00251         {
00252                 xSheet = getSheetByName( sSheetName );
00253         }
00254         catch ( const container::NoSuchElementException& e )
00255         {
00256                 Debug( "There is no such sheet!" );
00257                 return aCRAddr;
00258         }
00259         
00260         Reference< table::XCellRange > xCR( xSheet, UNO_QUERY );
00261         Reference< table::XCellRange > xCR2 = xCR->getCellRangeByName( sCellAddr );
00262         
00263         Reference< sheet::XCellRangeAddressable > xCRA( xCR2, UNO_QUERY );
00264         aCRAddr = xCRA->getRangeAddress();
00265 #if SCSOLVER_DEBUG
00266         sal_Int16 nSheetId = aCRAddr.Sheet;
00267         sal_Int32 nSCol = aCRAddr.StartColumn;
00268         sal_Int32 nSRow = aCRAddr.StartRow;
00269         sal_Int32 nECol = aCRAddr.EndColumn;
00270         sal_Int32 nERow = aCRAddr.EndRow;
00271         
00272         cout << "Sheet: " << nSheetId << " (" << nSRow << ", " << nSCol << ") - (" 
00273                  << nERow << ", " << nECol << ")" << endl;
00274 #endif
00275         return aCRAddr;
00276 }
00277 
00278 rtl::OUString CalcInterface::getCellFormula( const table::CellAddress& aAddr )
00279 {
00280         return getCell( aAddr )->getFormula();
00281 }
00282 
00283 void CalcInterface::setCellFormula( 
00284                 const table::CellAddress& aAddr, const rtl::OUString& sStr ) const
00285 {
00286         getCell( aAddr )->setFormula( sStr );
00287 }
00288 
00289 void CalcInterface::setCellValue(
00290                 const table::CellAddress& aAddr, double fVal ) const
00291 {
00292         getCell( aAddr )->setValue( fVal );
00293 }
00294 
00295 double CalcInterface::getCellValue( const table::CellAddress& aAddr )
00296 {
00297         return getCell( aAddr )->getValue();
00298 }
00299 
00300 rtl::OUString CalcInterface::getCellFormula( const rtl::OUString& sSheetAddr, 
00301                 const rtl::OUString& sCellAddr )
00302 {
00303         rtl::OUString sSheetName = lcl_resolveSheetName( sSheetAddr );
00304         
00305         Reference< sheet::XSpreadsheet > xSheet = getSheetByName( sSheetName );
00306         Reference< table::XCellRange > xCR( xSheet, UNO_QUERY );
00307         Reference< table::XCellRange > xCR2 = xCR->getCellRangeByName( sCellAddr );
00308         Reference< table::XCell > xCell = xCR2->getCellByPosition( 0, 0 );
00309         rtl::OUString sFormula = xCell->getFormula();
00310         
00311         return sFormula;
00312 }
00313 
00314 void CalcInterface::disableCellUpdates() const
00315 {
00316         Reference< lang::XComponent > xCurComp = getCurrentComponent();
00317         Reference< frame::XModel > xModel( xCurComp, UNO_QUERY );
00318         if ( xModel.is() )
00319                 xModel->lockControllers();
00320 }
00321 
00322 void CalcInterface::enableCellUpdates() const
00323 {
00324         Reference< lang::XComponent > xCurComp = getCurrentComponent();
00325         Reference< frame::XModel > xModel( xCurComp, UNO_QUERY );
00326         if ( xModel.is() )
00327                 xModel->unlockControllers();
00328 }
00329 
00330 
00331 void CalcInterface::splitCellRangeAddress( const rtl::OUString& sFullAddr,
00332                 rtl::OUString& sSheetAddr, rtl::OUString& sCellAddr )
00333 {
00334         sal_Int32 nIdDot = sFullAddr.indexOf( ascii( "." ) );
00335         sSheetAddr = sFullAddr.copy( 0, nIdDot );
00336         sCellAddr = sFullAddr.copy( nIdDot + 1 );
00337 }
00338 
00339 #if 0
00340 int getCommandID(const Reference<container::XIndexAccess>& items, 
00341                                  const rtl::OUString& command)
00342 {
00343         for (int i = 0; i < items->getCount(); ++i)
00344         {
00345                 uno::Any any = items->getByIndex(i);
00346                 uno::Sequence<beans::PropertyValue> menus;
00347                 any >>= menus;
00348                 for (int j = 0; j < menus.getLength(); ++j)
00349                 {
00350                         beans::PropertyValue prop = menus[j];
00351                         if ( prop.Name.equals( ascii("CommandURL") ) )
00352                         {
00353                                 uno::Any anyTemp = prop.Value;
00354                                 rtl::OUString foo;
00355                                 anyTemp >>= foo;
00356                                 if ( foo.equals(command) )
00357                                         return i;
00358                         }
00359                 }
00360         }
00361         return -1;
00362 }
00363 
00364 void CalcInterface::addMenuItem() const
00365 {
00366         using uno::Any;
00367 
00368         Reference< uno::XInterface > aUIMgr = getServiceManager()->createInstanceWithContext(
00369                 ascii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier"), m_xCC );
00370 
00371         if ( !aUIMgr.is() )
00372         {
00373                 fprintf(stderr, "UI ConfigMgr Supplier not found\n");
00374                 return;
00375         }
00376 
00377         Reference< ui::XModuleUIConfigurationManagerSupplier > xUIMgrSup( aUIMgr, UNO_QUERY );
00378         Reference< ui::XUIConfigurationManager > xUIMgr = xUIMgrSup->getUIConfigurationManager(
00379                 ascii("com.sun.star.sheet.SpreadsheetDocument") );
00380         Reference< container::XIndexAccess > settings = xUIMgr->getSettings(
00381                 ascii("private:resource/menubar/menubar"), true );
00382 
00383         // Search for the Tools menu item.
00384         int nToolID = getCommandID(settings, ascii(".uno:ToolsMenu"));
00385         if (nToolID == -1)
00386                 return;
00387 
00388         // Tools menu has a property named ItemDescriptorContainer, which stores
00389         // menu items.
00390         Any anyTemp = settings->getByIndex(nToolID);
00391         uno::Sequence<beans::PropertyValue> props;
00392         anyTemp >>= props;
00393         for (int i = 0; i < props.getLength(); ++i)
00394         {
00395                 beans::PropertyValue prop = props[i];
00396                 if ( prop.Name.equals( ascii("ItemDescriptorContainer") ) )
00397                 {
00398                         anyTemp = prop.Value;
00399                         Reference<container::XIndexAccess> xIA(anyTemp, UNO_QUERY);
00400                         if (!xIA.is())
00401                         {
00402                                 printf("index access failed\n");
00403                                 return;
00404                         }
00405 
00406                         int nGoalSeekID = getCommandID(xIA, ascii(".uno:GoalSeekDialog"));
00407                         if (nGoalSeekID > -1)
00408                                 printf("goal seek menu found\n");
00409 
00410                         int nNewComID = getCommandID(xIA, ascii("macro:///Standard.Module1.Test()"));
00411                         if (nNewComID < 0)
00412                         {
00413                                 // Command not found.  Add the new menu item.
00414                                 uno::Sequence<beans::PropertyValue> newmenu(3);
00415                                 newmenu[0].Name = ascii("CommandURL");
00416                                 anyTemp <<= ascii("macro:///Standard.Module1.Test()");
00417                                 newmenu[0].Value = anyTemp;
00418                                 newmenu[1].Name = ascii("Label");
00419                                 anyTemp <<= ascii("New Menu Test...");
00420                                 newmenu[1].Value = anyTemp;
00421                                 sal_Int16 foo = 0;
00422                                 anyTemp <<= foo;
00423                                 newmenu[2].Name = ascii("Type");
00424                                 newmenu[2].Value = anyTemp;
00425                                 Reference<container::XIndexContainer> xIC(xIA, UNO_QUERY);
00426                                 if (!xIC.is())
00427                                 {
00428                                         fprintf(stderr, "xIC not found\n");
00429                                         return;
00430                                 }
00431                                 anyTemp <<= newmenu;
00432                                 xIC->insertByIndex(nGoalSeekID+1, anyTemp);
00433                                 xUIMgr->replaceSettings(ascii("private:resource/menubar/menubar"), settings);
00434                                 Reference<ui::XUIConfigurationPersistence> xUIPers(xUIMgr, UNO_QUERY);
00435                                 if (!xUIPers.is())
00436                                 {
00437                                         fprintf(stderr, "xUIPers not found\n");
00438                                         return;
00439                                 }
00440                                 xUIPers->store();
00441                         }
00442 
00443                         break;
00444                 }
00445         }
00446 }
00447 #endif
00448 
00449 }

Generated on Mon Jul 28 09:13:20 2008 for scsolver by  doxygen 1.5.3