sc/qa/extras/vba-macro-test.cxx | 66 ++++++++++++++++++++++++++++++++++++++++ sc/source/ui/vba/vbawindows.cxx | 22 +++++++++++++ 2 files changed, 88 insertions(+)
New commits: commit deb0bb9f2635a8dfec90b42e3727f4224548a8e9 Author: Andreas Heinisch <andreas.heini...@yahoo.de> AuthorDate: Mon Sep 26 20:36:15 2022 +0200 Commit: Andreas Heinisch <andreas.heini...@yahoo.de> CommitDate: Sun Nov 20 12:02:58 2022 +0100 tdf#126457 - Add URL and workbook name to window titles The Windows object allows to activate a window using its caption. The window caption is the text shown in the title bar at the top of the window. It can be changed which does not affect the name of the workbook. In MS these captions are unique, i.e., a file with the same file name stored in a different directory can't be open. However, LibreOffice allows to open files with the same name. So in order to make it as closely to the functionality of MS, the windows activate method now works with URLs and changed window captions. It has still to be clarified what happens if two workbooks have the same caption. Change-Id: I77a8680bc64b5992191df2fa1a7d475f9a48f518 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140627 Tested-by: Jenkins Reviewed-by: Andreas Heinisch <andreas.heini...@yahoo.de> diff --git a/sc/qa/extras/vba-macro-test.cxx b/sc/qa/extras/vba-macro-test.cxx index 30375807a6ad..5c4bb5b88cc4 100644 --- a/sc/qa/extras/vba-macro-test.cxx +++ b/sc/qa/extras/vba-macro-test.cxx @@ -31,6 +31,8 @@ #include <ooo/vba/excel/XlSpecialCellsValue.hpp> +#include <comphelper/propertysequence.hxx> + using namespace css; using namespace ooo::vba; @@ -62,6 +64,7 @@ public: void testTdf90278(); void testTdf149531(); void testTdf118247(); + void testTdf126457(); CPPUNIT_TEST_SUITE(VBAMacroTest); CPPUNIT_TEST(testSimpleCopyAndPaste); @@ -84,6 +87,7 @@ public: CPPUNIT_TEST(testTdf90278); CPPUNIT_TEST(testTdf149531); CPPUNIT_TEST(testTdf118247); + CPPUNIT_TEST(testTdf126457); CPPUNIT_TEST_SUITE_END(); }; @@ -763,6 +767,68 @@ void VBAMacroTest::testTdf118247() CPPUNIT_ASSERT_EQUAL(sRange, aReturnValue); } } + +void VBAMacroTest::testTdf126457() +{ + auto xComponent = loadFromDesktop("private:factory/scalc"); + + // Save a copy of the file to get its URL + uno::Reference<frame::XStorable> xDocStorable(xComponent, uno::UNO_QUERY); + utl::TempFileNamed aTempFile(u"testWindowsActivate", true, u".ods"); + aTempFile.EnableKillingFile(); + uno::Sequence<beans::PropertyValue> descSaveAs( + comphelper::InitPropertySequence({ { "FilterName", uno::Any(OUString("calc8")) } })); + xDocStorable->storeAsURL(aTempFile.GetURL(), descSaveAs); + + // Insert initial library + css::uno::Reference<css::document::XEmbeddedScripts> xDocScr(xComponent, uno::UNO_QUERY_THROW); + auto xLibs = xDocScr->getBasicLibraries(); + auto xLibrary = xLibs->createLibrary("TestLibrary"); + xLibrary->insertByName( + "TestModule", + uno::Any(OUString("Option VBASupport 1\n" + "Function TestWindowsActivate\n" + " dirName = Workbooks(1).Path\n" + " workbookName = Workbooks(1).Name\n" + " fileName = dirName + Application.PathSeparator + workbookName\n" + " Workbooks.Open Filename := fileName\n" + " On Error Goto handler\n" + // activate window using its URL + " Windows(fileName).Activate\n" + // activate window using its caption name + " Windows(workbookName).Activate\n" + // activate window using a newly generated window caption + " newCaption = \"New Window Caption\"\n" + " Windows(fileName).Caption = newCaption\n" + " Windows(newCaption).Activate\n" + " TestWindowsActivate = 0\n" + " Exit Function\n" + "handler:\n" + " TestWindowsActivate = 1\n" + "End Function\n"))); + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutParamIndex; + uno::Sequence<uno::Any> aOutParam; + + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); + ScDocShell* pDocSh = static_cast<ScDocShell*>(pFoundShell); + CPPUNIT_ASSERT(pDocSh); + + ErrCode result + = SfxObjectShell::CallXScript(xComponent, + "vnd.sun.Star.script:TestLibrary.TestModule." + "TestWindowsActivate?language=Basic&location=document", + {}, aRet, aOutParamIndex, aOutParam); + + // Without the fix in place, the windows could not be activated in the macro + CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, result); + sal_Int16 nReturnValue; + aRet >>= nReturnValue; + CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nReturnValue); + + pDocSh->DoClose(); +} CPPUNIT_TEST_SUITE_REGISTRATION(VBAMacroTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/ui/vba/vbawindows.cxx b/sc/source/ui/vba/vbawindows.cxx index 00cacc5f39cc..8c5e7e565314 100644 --- a/sc/source/ui/vba/vbawindows.cxx +++ b/sc/source/ui/vba/vbawindows.cxx @@ -32,6 +32,9 @@ #include <unordered_map> #include <utility> +#include <osl/file.hxx> +#include <ooo/vba/excel/XApplication.hpp> + using namespace ::com::sun::star; using namespace ::ooo::vba; @@ -129,6 +132,10 @@ class WindowsAccessImpl : public WindowsAccessImpl_BASE public: explicit WindowsAccessImpl( uno::Reference< uno::XComponentContext > xContext ):m_xContext(std::move( xContext )) { + css::uno::Reference<css::container::XNameAccess> xNameAccess(m_xContext, + css::uno::UNO_QUERY_THROW); + const auto aAppplication = xNameAccess->getByName("Application"); + uno::Reference< container::XEnumeration > xEnum = new WindowComponentEnumImpl( m_xContext ); sal_Int32 nIndex=0; while( xEnum->hasMoreElements() ) @@ -138,6 +145,21 @@ public: { m_windows.push_back( xNext ); uno::Reference< frame::XModel > xModel( xNext, uno::UNO_QUERY_THROW ); // that the spreadsheetdocument is a xmodel is a given + + // tdf#126457 - add workbook name to window titles + rtl::Reference<ScVbaWorkbook> workbook(new ScVbaWorkbook( + uno::Reference<XHelperInterface>(aAppplication, uno::UNO_QUERY_THROW), + m_xContext, xModel)); + const OUString aWorkBookName(workbook->getName()); + if (!hasByName(aWorkBookName)) + namesToIndices[aWorkBookName] = nIndex; + + // tdf#126457 - add file url to window titles + OUString sName; + ::osl::File::getSystemPathFromFileURL(xModel->getURL(), sName); + if (!hasByName(sName)) + namesToIndices[sName] = nIndex; + // !! TODO !! iterate over all controllers uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); uno::Reference< XHelperInterface > xTemp; // temporary needed for g++ 3.3.5