44
55namespace Boson \Api \Dialog ;
66
7- use Boson \Api \Dialog \Event \DirectoriesSelecting ;
87use Boson \Api \Dialog \Event \DirectorySelected ;
98use Boson \Api \Dialog \Event \DirectorySelecting ;
109use Boson \Api \Dialog \Event \FileSelected ;
1312use Boson \Api \Dialog \Event \UriOpened ;
1413use Boson \Api \Dialog \Event \UriOpening ;
1514use Boson \Api \LoadedApplicationExtension ;
15+ use Boson \Shared \Marker \RequiresDealloc ;
1616use FFI \CData ;
1717
1818/**
@@ -31,36 +31,33 @@ private function applyDirectory(CData $options, ?string $directory): void
3131 {
3232 $ directory ??= \getcwd ();
3333
34- if (\is_string ($ directory ) && $ directory ! == '' ) {
35- $ this -> app -> saucer -> saucer_picker_options_set_initial ( $ options , $ directory ) ;
34+ if (! \is_string ($ directory ) || $ directory = == '' ) {
35+ return ;
3636 }
37+
38+ $ this ->app ->saucer ->saucer_picker_options_set_initial ($ options , $ directory );
3739 }
3840
3941 /**
40- * @param iterable<mixed, mixed > $filter
42+ * @param list<non-empty-string > $filter
4143 */
42- private function applyFilter (CData $ options , iterable $ filter ): void
44+ private function applyFilter (CData $ options , array $ filter ): void
4345 {
44- $ index = 0 ;
45-
46- foreach ($ filter as $ item ) {
47- ++$ index ;
48-
49- if (\is_string ($ item ) && $ item !== '' ) {
50- $ this ->app ->saucer ->saucer_picker_options_add_filter ($ options , $ item );
51- continue ;
52- }
53-
54- throw new \InvalidArgumentException (\sprintf (
55- 'Filter #%d element must be a non empty string ' ,
56- $ index - 1 ,
57- ));
46+ if ($ filter === []) {
47+ return ;
5848 }
49+
50+ $ this ->app ->saucer ->saucer_picker_options_set_filters (
51+ $ options ,
52+ $ filterAsString = \implode ("\0" , $ filter ),
53+ \strlen ($ filterAsString ),
54+ );
5955 }
6056
6157 /**
6258 * @param list<non-empty-string> $filter
6359 */
60+ #[RequiresDealloc]
6461 private function createOptions (?string $ directory , array $ filter ): CData
6562 {
6663 $ options = $ this ->app ->saucer ->saucer_picker_options_new ();
@@ -73,7 +70,7 @@ private function createOptions(?string $directory, array $filter): CData
7370
7471 /**
7572 * @param list<non-empty-string> $filter
76- * @param \Closure(CData, CData): ?CData $selector
73+ * @param \Closure(CData, CData, CData|null, CData|null, CData|null ): ?CData $selector
7774 *
7875 * @return non-empty-string|null
7976 */
@@ -82,15 +79,17 @@ private function selectOne(?string $directory, array $filter, \Closure $selector
8279 $ options = $ this ->createOptions ($ directory , $ filter );
8380
8481 try {
85- $ pointer = $ selector ($ this ->ptr , $ options );
82+ $ length = $ this ->saucer ->new ('size_t ' );
83+ $ selector ($ this ->ptr , $ options , null , \FFI ::addr ($ length ), null );
8684
87- if ($ pointer === null || \ FFI :: isNull ( $ pointer ) ) {
85+ if ($ length -> cdata === 0 ) {
8886 return null ;
8987 }
9088
91- $ result = \FFI ::string ($ pointer );
89+ $ result = $ this ->saucer ->new ("char[ {$ length ->cdata }] " );
90+ $ selector ($ this ->ptr , $ options , \FFI ::addr ($ result [0 ]), \FFI ::addr ($ length ), null );
9291
93- return $ result === '' ? null : $ result ;
92+ return \ FFI :: string (\ FFI :: addr ( $ result[ 0 ]), $ length -> cdata ) ;
9493 } finally {
9594 $ this ->app ->saucer ->saucer_picker_options_free ($ options );
9695 }
@@ -106,25 +105,18 @@ private function selectMany(?string $directory, array $filter, \Closure $selecto
106105 {
107106 $ options = $ this ->createOptions ($ directory , $ filter );
108107
109- $ result = [];
110108 try {
111- $ pointer = $ selector ($ this ->ptr , $ options );
109+ $ length = $ this ->saucer ->new ('size_t ' );
110+ $ selector ($ this ->ptr , $ options , null , \FFI ::addr ($ length ), null );
112111
113- if ($ pointer === null || \ FFI :: isNull ( $ pointer ) ) {
112+ if ($ length -> cdata === 0 ) {
114113 return [];
115114 }
116115
117- /** @phpstan-ignore-next-line : The $pointer[$i] is CData|null */
118- for ($ i = 0 ; !\FFI ::isNull ($ pointer [$ i ]); ++$ i ) {
119- /** @phpstan-ignore-next-line : The $pointer[$i] is CData */
120- $ item = \FFI ::string ($ pointer [$ i ]);
116+ $ result = $ this ->saucer ->new ("char[ {$ length ->cdata }] " );
117+ $ selector ($ this ->ptr , $ options , \FFI ::addr ($ result [0 ]), \FFI ::addr ($ length ), null );
121118
122- if ($ item !== '' ) {
123- $ result [] = $ item ;
124- }
125- }
126-
127- return $ result ;
119+ return \explode ("\0" , \FFI ::string (\FFI ::addr ($ result [0 ]), $ length ->cdata ));
128120 } finally {
129121 $ this ->app ->saucer ->saucer_picker_options_free ($ options );
130122 }
@@ -145,55 +137,35 @@ public function open(string|\Stringable $uri): void
145137 $ this ->dispatch (new UriOpened ($ this ->app , $ uri ));
146138 }
147139
148- public function selectDirectory (?string $ directory = null , iterable $ filter = []): ?string
140+ public function selectDirectory (?string $ path = null , iterable $ filter = []): ?string
149141 {
150- if (!$ this ->intent (new DirectorySelecting ($ this ->app , $ directory , $ filter ))) {
142+ if (!$ this ->intent (new DirectorySelecting ($ this ->app , $ path , $ filter ))) {
151143 return null ;
152144 }
153145
154146 $ filter = \iterator_to_array ($ filter , false );
155147
156- $ result = $ this ->selectOne ($ directory , $ filter , $ this ->app ->saucer ->saucer_desktop_pick_folder (...));
148+ $ result = $ this ->selectOne ($ path , $ filter , $ this ->app ->saucer ->saucer_picker_pick_folder (...));
157149
158150 if ($ result !== null ) {
159- $ this ->dispatch (new DirectorySelected ($ this ->app , $ result , $ directory , $ filter ));
151+ $ this ->dispatch (new DirectorySelected ($ this ->app , $ result , $ path , $ filter ));
160152 }
161153
162154 return $ result ;
163155 }
164156
165- public function selectFile (?string $ directory = null , iterable $ filter = []): ?string
157+ public function selectFile (?string $ path = null , iterable $ filter = []): ?string
166158 {
167- if (!$ this ->intent (new FileSelecting ($ this ->app , $ directory , $ filter ))) {
159+ if (!$ this ->intent (new FileSelecting ($ this ->app , $ path , $ filter ))) {
168160 return null ;
169161 }
170162
171163 $ filter = \iterator_to_array ($ filter , false );
172164
173- $ result = $ this ->selectOne ($ directory , $ filter , $ this ->app ->saucer ->saucer_desktop_pick_file (...));
165+ $ result = $ this ->selectOne ($ path , $ filter , $ this ->app ->saucer ->saucer_picker_pick_file (...));
174166
175167 if ($ result !== null ) {
176- $ this ->dispatch (new FileSelected ($ this ->app , $ result , $ directory , $ filter ));
177- }
178-
179- return $ result ;
180- }
181-
182- /**
183- * @return list<non-empty-string>
184- */
185- public function selectFiles (?string $ directory = null , iterable $ filter = []): array
186- {
187- if (!$ this ->intent (new FilesSelecting ($ this ->app , $ directory , $ filter ))) {
188- return [];
189- }
190-
191- $ filter = \iterator_to_array ($ filter , false );
192-
193- $ result = $ this ->selectMany ($ directory , $ filter , $ this ->app ->saucer ->saucer_desktop_pick_files (...));
194-
195- foreach ($ result as $ selection ) {
196- $ this ->dispatch (new FileSelected ($ this ->app , $ selection , $ directory , $ filter ));
168+ $ this ->dispatch (new FileSelected ($ this ->app , $ result , $ path , $ filter ));
197169 }
198170
199171 return $ result ;
@@ -202,18 +174,18 @@ public function selectFiles(?string $directory = null, iterable $filter = []): a
202174 /**
203175 * @return list<non-empty-string>
204176 */
205- public function selectDirectories (?string $ directory = null , iterable $ filter = []): array
177+ public function selectFiles (?string $ path = null , iterable $ filter = []): array
206178 {
207- if (!$ this ->intent (new DirectoriesSelecting ($ this ->app , $ directory , $ filter ))) {
179+ if (!$ this ->intent (new FilesSelecting ($ this ->app , $ path , $ filter ))) {
208180 return [];
209181 }
210182
211183 $ filter = \iterator_to_array ($ filter , false );
212184
213- $ result = $ this ->selectMany ($ directory , $ filter , $ this ->app ->saucer ->saucer_desktop_pick_folders (...));
185+ $ result = $ this ->selectMany ($ path , $ filter , $ this ->app ->saucer ->saucer_picker_pick_files (...));
214186
215187 foreach ($ result as $ selection ) {
216- $ this ->dispatch (new DirectorySelected ($ this ->app , $ selection , $ directory , $ filter ));
188+ $ this ->dispatch (new FileSelected ($ this ->app , $ selection , $ path , $ filter ));
217189 }
218190
219191 return $ result ;
0 commit comments