Apache OpenOffice (AOO) Bugzilla – Issue 123544
XFilePicker's setDisplayDirectory and setDefaultName do not work in Windows
Last modified: 2019-10-08 18:44:48 UTC
When a file picker is created using the following code, the directory and filename are not set when the file picker is shown. This happens in Windows 7; in Ubuntu 12.10 (using OpenOffice 4) it works as expected. Here, "originalUrl" is the URL taken from the currently open document; "Environment" is just a helper class to retrieve some information about the opened document. Object oFilePicker = component_factory.createInstanceWithContext("com.sun.star.ui.dialogs.FilePicker", Environment.getContext()); XFilePicker xFilePicker = (XFilePicker) UnoRuntime.queryInterface(XFilePicker.class, oFilePicker); xFilePicker.setMultiSelectionMode(false); if (originalUrl == null) { xFilePicker.setDisplayDirectory(Environment.getHomeDir()); xFilePicker.setDefaultName(""); } else { int idx = originalUrl.lastIndexOf('/'); if (idx >= 0) { xFilePicker.setDisplayDirectory(originalUrl.substring(0, idx)); xFilePicker.setDefaultName(originalUrl.substring(idx+1)); } } Steps to reproduce: 1. Create a new extension which shows a file picker using the code mentioned above. 2. Install the extension in LibreOffice in Windows. 2. Run LibreOffice in Windows. 3. Open an LibreOffice-compatible document. 4. Run the extension. Current behavior: The file picker doesn't start where the opened document is saved nor the filename of the document is set as default filename. Expected behavior: The default directory and filename of the file picker is the same as the opened document.
(In reply to Ariel D. Moya Sequeira from comment #0) > Steps to reproduce: > 1. Create a new extension which shows a file picker using the code mentioned > above. > 2. Install the extension in LibreOffice in Windows. Some comments: - This is OpenOffice bugzilla, did you reproduce the bug with OpenOffice? - are you using the system file dialog?
1) I filed the bug in LibreOffice first, then here. However, the issue exist in both applications. I reproduced the issue using OpenOffice 4.0.1 (in Windows). 2) I just use the file picker made available by the UNO interface. Apart from that, I do not use SWT/Swing file pickers.
(In reply to Ariel D. Moya Sequeira from comment #2) > 2) I just use the file picker made available by the UNO interface. Apart > from that, I do not use SWT/Swing file pickers. If you go to the menu Tools - Options..., in the Options dialogue go to OpenOffice - General, there is an option to use OpenOffice dialogues instead of the system one. IIRC this option is off by default, so you might be using the system dialogue.
Created attachment 81818 [details] Writer document with a macro to test
Thanks for the support. Indeed, when I switched to the OpenOffice's save dialog, the code now behaves as expected. It works as expected on Windows and Linux after the switch. Anyone may change the status of this ticket as NOTABUG or WONTFIX if the behavior using system's dialogs won't be fixed at all.
(In reply to Ariel Constenla-Haile from comment #4) > Created attachment 81818 [details] > Writer document with a macro to test This one crashes on Windows 7, it isn't setting any filter, so the following code tries to access element 0 of an empty vector: http://svn.apache.org/viewvc/openoffice/trunk/main/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx?diff_format=h&revision=1497691&view=markup#l922 On 3.4.1 it does not crash (but the dialog does not show up). The crash is likely a regression introduced by stlport removal. hResult = iDialog->GetFileTypeIndex(&nFileType); will return S_OK but nFileType will be 0 when no filters were specified. So the check should be: if ( SUCCEEDED(hResult) && nFileType > 0 ) this would already prevent accessing an empty vector, any way it would be safer to check nRealIndex against the vector actual size. Altogether: if ( bValue ) { ::rtl::OUString aExt; UINT nFileType; hResult = iDialog->GetFileTypeIndex(&nFileType); if ( SUCCEEDED(hResult) && nFileType > 0 ) { ::sal_Int32 nRealIndex = (nFileType-1); // COM dialog base on 1 ... filter container on 0 .-) ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters); if ( nRealIndex < lFilters.size() ) { LPCWSTR lpFilterExt = lFilters[nRealIndex].pszSpec; lpFilterExt = wcsrchr( lpFilterExt, '.' ); if ( lpFilterExt ) aFileURL += reinterpret_cast<const sal_Unicode*>(lpFilterExt); } } }
(In reply to Ariel D. Moya Sequeira from comment #5) > Thanks for the support. > > Indeed, when I switched to the OpenOffice's save dialog, the code now > behaves as expected. It works as expected on Windows and Linux after the > switch. > > Anyone may change the status of this ticket as NOTABUG or WONTFIX if the > behavior using system's dialogs won't be fixed at all. There is a bug, besides the crash. The API should work even when using the system dialog. In the meantime, while this bug gets fixed, try not using in your code the system file picker. You can force this (even if the user interface is using the system file picker) with the service name: "com.sun.star.ui.dialogs.OfficeFilePicker" instead of "com.sun.star.ui.dialogs.FilePicker"
This bug can be confirmed, independently of the API, just in the user interface: - New Writer document - type anything - press the Save button The default display directory will be set to "file://C:/Users/ariel/Documents", the default file name will be set to "Untitled 1" (in the debugger, watch m_sDirectory and m_sFilename). Bug: the file picker opens in the last used directory (C:\User\ariel\Downloads in my case), not the one set. This can be reproduced also with the macro in attachment 81818 [details] (once fixed the crash).
Setting hdu on CC for the crash described in comment 6
(In reply to Ariel Constenla-Haile from comment #6) > This one crashes on Windows 7, it isn't setting any filter, so the following > code tries to access element 0 of an empty vector: the index is negative: after hResult = iDialog->GetFileTypeIndex(&nFileType); nFileType is 0. Then ::sal_Int32 nRealIndex = (nFileType-1); nRealIndex is -1.
.
Thanks for analyzing the problem! The fix suggested in comment 6 looks good to me, please commit it. If this isn't possible for whatever reasons 'll be happy to do it.
"arielch" committed SVN revision 1535717 into trunk: i123544 - Prevent accessing empty filters' vector svnbz message delay caused by perl problems after Bugzilla 4.4.1 update
Fixed with Ariel's commit above. Thanks!
revision 1535717 only fixes the crash. The problem reported here is still there (not only using the API, but in the user interface). The whole code in http://svn.apache.org/viewvc/openoffice/trunk/main/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx?revision=1535717&view=markup&pathrev=1535717#l888 has a wrong approach: if there is a default directory and a file name, the code generates a file URL (directory + / + filename + extension), and the default directory is only set if this file exists (ll. 933 ss.); this is a nonsense, because when you are saving a file, this file does not exist yet, so FindFirstFile fails.
From my point of view the crash is fixed. Right? Thus, I am removing keyword 'crash' I also does not look like as the described defect is a regression. Right? If yes, please remove keyword 'regression'. Thx in advance.
removing keyword 'regression'
it seems setting the directory works, if the filpicker is initialized: REM ***** BASIC ***** OPTION EXPLICIT Sub Main Dim dlg as Object dlg = CreateUnoService( "com.sun.star.ui.dialogs.FilePicker" ) Dim Dialogtyp(0) DialogTyp(0) = com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_AUTOEXTENSION dlg.initialize(DialogTyp()) dlg.Title = "Test" ' dlg.DisplayDirectory = "file:///c:/users" dlg.DisplayDirectory = "file:///c:/" ' this will crash aoo401: ' dlg.DefaultName = "xxx" If dlg.Execute = 1 Then MsgBox dlg.SelectedFiles(0) End Sub could someone please confirm? btw: issue "Issue 110141 - FilePicker Dialog "setDisplayDirectory" ignored" seems a dupe of this issue
Can confirm, with initializing it works.
> Can confirm, with initializing it works. no, i mistakenly thought it will work, but it will only work the *first* time. after a file has been saved, the display directory will always point to the last save path. run macro twice, second time change "dlg.DisplayDirectory" to a different directory. Sub Main Dim dlg as Object Dim oDoc as Object Dim mNoArgs() Dim sURL as String dlg = CreateUnoService( "com.sun.star.ui.dialogs.FilePicker" ) Dim Dialogtyp(0) DialogTyp(0) = com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_AUTOEXTENSION dlg.initialize(DialogTyp()) dlg.Title = "Test" sURL = "private:factory/swriter" oDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, mNoArgs) ' dlg.DisplayDirectory = "file:///c:/users" dlg.DisplayDirectory = "file:///c:/temp" If dlg.Execute = 1 Then sURL = dlg.SelectedFiles(0) oDoc.storeToURL(sURL, mNoArgs) EndIf End Sub
you're right, I have to stand corrected. So the only solution seems to be to switch to the OpenOffice dialogs with Basic temporarily.
Created attachment 84800 [details] Uses Open or Save dialogs with different templates After several tests with macros, here are my conclusions explaining the variability of observations regarding the default directory displayed by the system FilePicker (service SystemFilePicker). The attached document contains macros that prove my point. The FilePicker can use different templates, through initialization. For file opening you can use: FILEOPEN_SIMPLE FILEOPEN_READONLY_VERSION FILEOPEN_LINK_PREVIEW FILEOPEN_PLAY FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE Each of these templates "remembers" the last directory where a file was selected. Also, each file saving template "remembers" the last directory where a file is to be stored. The storage of these directory addresses is handled by Windows, not by Apache OpenOffice. With the macro, set a specific directory for a given template, then close Apache OpenOffice. If you have LibreOffice on the same computer it will be used as default directory when running the macro with the same template! This problem of display directory did not appear on previous versions of Windows and of OpenOffice, see Bug 110141. I still use OpenOffice.org 1.1.5 that works perfectly well on Windows 7, but displays an old-fashioned dialog box. Since Windows Vista, the recommended open/save dialog has changed from Common File dialog to Common Item Dialog. See Microsoft doc https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913%28v=vs.85%29.aspx I suspect OpenOffice tried to follow Microsoft recommendation.
> I suspect OpenOffice tried to follow Microsoft recommendation. if one uses setDisplayDirectory() to set a directory it should work as expected the current behaviour is not acceptable, e.g. it still works on Win XP but not on Win 7. btw: https://bz.apache.org/ooo/show_bug.cgi?id=110141 FilePicker Dialog "setDisplayDirectory" ignored seems to be a dup of this issue
This issue was suggested as a 4.1.2 release blocker. Status: the issue has a patch available, but this patch only covers a crash and it is already included both in trunk and in AOO410 (so, among others, in OpenOffice 4.1.1 and to-be 4.1.2). We don't have a patch available for the filepicker problem, but we have a detailed description by Ariel (at the code level) in comment 15. As for two other filepicker issues that were nominated for 4.1.2, I'm forwarding to the API list for evaluation but in order to fix it in time for 4.1.2 we will need an interested developer to show up.
i think there is a "workaround" for the "setDisplayDirectory" problem: setting "/org.openoffice.Office.Common/Path/Info.WorkPathChanged" = true seems to force the folder change. see attached macro for details. VistaFilePickerImpl.cxx: void VistaFilePickerImpl::impl_sta_SetDirectory(const RequestRef& rRequest) { bool bForce = rRequest->getArgumentOrDefault(PROP_FORCE, false); [...] if ( m_bInExecute || bForce ) iDialog->SetFolder(pFolder); } VistaFilePicker.cxx: void SAL_CALL VistaFilePicker::setDisplayDirectory(const ::rtl::OUString& sDirectory) { [..] bool bChanged(false); if (( aValue >>= bChanged ) && bChanged ) { ::comphelper::ConfigurationHelper::writeDirectKey( m_xSMGR, aPackage, aRelPath, aKey, css::uno::makeAny(false), ::comphelper::ConfigurationHelper::E_STANDARD); } [...] rRequest->setArgument(PROP_FORCE, bChanged); } OPTION EXPLICIT Sub Main() Call TestSetdialog("file:///d:/test") Call TestSetdialog("file:///d:/temp") Call TestSetdialog("file:///d:/test") Call TestSetdialog("file:///d:/temp") End Sub Sub TestSetdialog(ByVal sPath as String) Dim dlg as Object Dim oDoc as Object Dim mNoArgs() Dim sURL as String dlg = CreateUnoService( "com.sun.star.ui.dialogs.FilePicker" ) Dim Dialogtyp(0) DialogTyp(0) = com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_AUTOEXTENSION dlg.initialize(DialogTyp()) dlg.Title = "Test" sURL = "private:factory/swriter" oDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, mNoArgs) Dim oConfigProvider as Object Dim oRegistryKeyContent as Object Dim aNodePath(0) as new com.sun.star.beans.PropertyValue oConfigProvider = createUnoService("com.sun.star.configuration.ConfigurationProvider") aNodePath(0).Name = "nodepath" aNodePath(0).Value = "/org.openoffice.Office.Common/Path/Info" oRegistryKeyContent = oConfigProvider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationUpdateAccess", aNodePath()) oRegistryKeyContent.WorkPathChanged = true oRegistryKeyContent.commitChanges dlg.DisplayDirectory = sPath If dlg.Execute = 1 Then sURL = dlg.Files(0) oDoc.storeAsURL(sURL, mNoArgs) EndIf End Sub
The corresponding bug in LO is https://bugs.documentfoundation.org/show_bug.cgi?id=43021 I have looked at the problem too. The method setDisplayDirectory is used internally too. I have tried to force the implementation to take the string sDirectory from the [in] parameter. RequestRef rRequest(new Request()); rRequest->setRequest (VistaFilePickerImpl::E_SET_DIRECTORY); rRequest->setArgument(PROP_FORCE, true); rRequest->setArgument(PROP_DIRECTORY, sDirectory); // rRequest->setArgument(PROP_FORCE, bChanged); That works for calls in a macro, but then on other places no longer the previous directory is used in the file dialog -as it should be-, but the default directory. Another question is, what is the purpose of the user setting item WorkPathChanged? Until now I have not found a place where this setting is evaluated. Inside the method it is not needed, because independent of its value, PROP_FORCE is always set to "false", only that in addition the user setting in registrymodifications.xcu is set to "false" in addition and remains so. The file open/save dialogs for graphics have their own implementations in FileDialogHelper in sfx2/source/dialog/filedlghelper.cxx. It might be, that it is needed to divide the usage via API from internal usage in other cases too. To me it looks as if there are so many question around this method, that there is no quick, well thought out solution for 4.1.2.
When I use the solution for Basic from Oliver from comment#25, then it opens with the correct directory. But when the user goes to a different directory in the dialog, after finish of "execute" the property "DisplayDirectory" is not updated. Nevertheless the new directory is stored somewhere, because the file picker from Insert > File or creating a new file picker dialog in the macro will use it. [To test the content of "DisplayDirectory" in Basic you need to patch AOO, look at https://bugs.documentfoundation.org/show_bug.cgi?id=93634]
(In reply to Regina Henschel from comment #26) > To me it looks as if there are so many question around this method, that > there is no quick, well thought out solution for 4.1.2. OK. Then this will not be considered as a blocker for 4.1.2, since we have no patch (there is a patch in the issue, but it fixes a crash and it is already fixed in 4.1.1 and in trunk, so no action needed for 4.1.2) and no feedback from the API list.
Uses Open or Save dialogs with different templates After several tests with macros, here are my conclusions explaining the variability of observations regarding the default directory displayed by the system FilePicker (service SystemFilePicker). The attached document contains macros that prove my point. The FilePicker can use different templates, through initialization. For file opening you can use: FILEOPEN_SIMPLE FILEOPEN_READONLY_VERSION FILEOPEN_LINK_PREVIEW FILEOPEN_PLAY FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE Each of these templates "remembers" the last directory where a file was selected. Also, each file saving template "remembers" the last directory where a file is to be stored. The storage of these directory addresses is handled by Windows, not by Apache OpenOffice. With the macro, set a specific directory for a given template, then close Apache OpenOffice. If you have LibreOffice on the same computer it will be used as default directory when running the macro with the same template! This problem of display directory did not appear on previous versions of Windows and of OpenOffice, see Bug 110141. I still use OpenOffice.org 1.1.5 that works perfectly well on Windows 7, but displays an old-fashioned dialog box. Since Windows Vista, the recommended open/save dialog has changed from Common File dialog to Common Item Dialog. See Microsoft doc https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913%28v=vs.85%29.aspx I suspect OpenOffice tried to follow Microsoft recommendation. -- http://www.reviewopedia.com/redgage-com-reviews
. *** This issue has been marked as a duplicate of issue 96720 ***