00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
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
00384 int nToolID = getCommandID(settings, ascii(".uno:ToolsMenu"));
00385 if (nToolID == -1)
00386 return;
00387
00388
00389
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
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 }