Issue 123544

Summary: XFilePicker's setDisplayDirectory and setDefaultName do not work in Windows
Product: App Dev Reporter: Ariel D. Moya Sequeira <ardamose123>
Component: apiAssignee: AOO issues mailing list <issues>
Status: CLOSED DUPLICATE QA Contact:
Severity: Normal    
Priority: P3 CC: ardamose123, arisadam25, hdu, issues, marcelly.bernard, oliver.brinzing, oooforum, pescetti, pet.ebe, rb.henschel
Version: 4.0.1Flags: pescetti: 4.1.2_release_blocker-
Target Milestone: 4.2.0   
Hardware: PC   
OS: Windows 7   
See Also: https://issues.apache.org/ooo/show_bug.cgi?id=96720
Issue Type: DEFECT Latest Confirmation in: ---
Developer Difficulty: ---
Attachments:
Description Flags
Writer document with a macro to test
none
Uses Open or Save dialogs with different templates none

Description Ariel D. Moya Sequeira 2013-10-24 16:25:50 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.
Comment 1 Ariel Constenla-Haile 2013-10-24 16:41:40 UTC
(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?
Comment 2 Ariel D. Moya Sequeira 2013-10-24 16:55:33 UTC
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.
Comment 3 Ariel Constenla-Haile 2013-10-24 17:03:40 UTC
(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.
Comment 4 Ariel Constenla-Haile 2013-10-24 17:26:41 UTC
Created attachment 81818 [details]
Writer document with a macro to test
Comment 5 Ariel D. Moya Sequeira 2013-10-24 20:15:04 UTC
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.
Comment 6 Ariel Constenla-Haile 2013-10-24 20:20:16 UTC
(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);
        }
    }
}
Comment 7 Ariel Constenla-Haile 2013-10-24 20:24:17 UTC
(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"
Comment 8 Ariel Constenla-Haile 2013-10-24 20:39:03 UTC
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).
Comment 9 Ariel Constenla-Haile 2013-10-24 20:41:14 UTC
Setting hdu on CC for the crash described in comment 6
Comment 10 Ariel Constenla-Haile 2013-10-24 20:49:48 UTC
(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.
Comment 11 Oliver Brinzing 2013-10-25 08:47:48 UTC
.
Comment 12 hdu@apache.org 2013-10-25 11:15:51 UTC
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.
Comment 13 SVN Robot 2013-10-29 08:14:53 UTC
"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
Comment 14 hdu@apache.org 2013-10-29 13:49:11 UTC
Fixed with Ariel's commit above. Thanks!
Comment 15 Ariel Constenla-Haile 2013-10-30 15:19:43 UTC
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.
Comment 16 Oliver-Rainer Wittmann 2014-01-17 10:32:52 UTC
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.
Comment 17 Oliver-Rainer Wittmann 2014-02-25 13:40:00 UTC
removing keyword 'regression'
Comment 18 Oliver Brinzing 2014-07-03 06:14:57 UTC
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
Comment 19 eberlein 2014-12-30 08:12:10 UTC
Can confirm, with initializing it works.
Comment 20 Oliver Brinzing 2014-12-30 09:44:45 UTC
> 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
Comment 21 eberlein 2015-01-02 12:19:12 UTC
you're right, I have to stand corrected.
So the only solution seems to be to switch to the OpenOffice dialogs with Basic temporarily.
Comment 22 bmarcelly 2015-06-19 12:38:54 UTC
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.
Comment 23 Oliver Brinzing 2015-07-18 09:55:18 UTC
> 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
Comment 24 Andrea Pescetti 2015-07-24 21:40:44 UTC
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.
Comment 25 Oliver Brinzing 2015-09-01 18:35:01 UTC
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
Comment 26 Regina Henschel 2015-09-01 20:41:55 UTC
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.
Comment 27 Regina Henschel 2015-09-03 20:14:24 UTC
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]
Comment 28 Andrea Pescetti 2015-09-08 22:35:07 UTC
(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.
Comment 29 Redfred Garett 2016-08-30 04:54:46 UTC
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
Comment 30 oooforum (fr) 2019-10-08 12:26:19 UTC
.

*** This issue has been marked as a duplicate of issue 96720 ***