blob: 0bb28d411aab69b20ea89a42db92a489f21c533b [file] [log] [blame]
The Android Open Source Projected217d92008-12-17 18:05:52 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.app.Activity;
20import android.content.Context;
21import android.graphics.Bitmap;
22import android.graphics.BitmapFactory;
23import android.graphics.Color;
24import android.net.Uri;
25import android.os.Environment;
26import android.os.Handler;
27import android.os.Looper;
28import android.os.Message;
29import android.provider.MediaStore;
30import android.util.Log;
31import android.view.LayoutInflater;
32import android.view.MotionEvent;
33import android.view.View;
34import android.view.ViewGroup;
35import android.widget.AdapterView;
36import android.widget.BaseAdapter;
37import android.widget.GridView;
38import android.widget.ImageView;
39import android.widget.TextView;
40
41import java.io.File;
42import java.io.FileOutputStream;
43import java.io.IOException;
44import java.util.Collections;
45import java.util.HashMap;
46import java.util.Map;
47import java.util.Vector;
48
49import org.json.JSONArray;
50import org.json.JSONException;
The Android Open Source Project765e7c92009-01-09 17:51:25 -080051import org.json.JSONObject;
The Android Open Source Projected217d92008-12-17 18:05:52 -080052
53/**
54 * Gears FilePicker dialog
55 */
56class GearsFilePickerDialog extends GearsBaseDialog
57 implements View.OnTouchListener {
58
59 private static final String TAG = "Gears FilePicker";
60 private static Bitmap mDirectoryIcon;
61 private static Bitmap mDefaultIcon;
62 private static Bitmap mImageIcon;
63 private static Bitmap mBackIcon;
The Android Open Source Project765e7c92009-01-09 17:51:25 -080064
65 private static String MULTIPLE_FILES = "MULTIPLE_FILES";
66 private static String SINGLE_FILE = "SINGLE_FILE";
67
The Android Open Source Projected217d92008-12-17 18:05:52 -080068 private static ImagesLoad mImagesLoader;
69 private FilePickerAdapter mAdapter;
The Android Open Source Project765e7c92009-01-09 17:51:25 -080070 private String mSelectionMode;
71 private boolean mMultipleSelection;
72 private String mCurrentPath;
73
74 // Disable saving thumbnails until this is refactored to fit into
75 // existing schemes.
76 private static final boolean enableSavedThumbnails = false;
The Android Open Source Projected217d92008-12-17 18:05:52 -080077
78 public GearsFilePickerDialog(Activity activity,
79 Handler handler,
80 String arguments) {
81 super (activity, handler, arguments);
82 mAdapter = new FilePickerAdapter(activity);
The Android Open Source Project765e7c92009-01-09 17:51:25 -080083 parseArguments();
84 }
85
86 public void parseArguments() {
87 mSelectionMode = MULTIPLE_FILES;
88 try {
89 JSONObject json = new JSONObject(mDialogArguments);
90
91 if (json.has("mode")) {
92 mSelectionMode = json.getString("mode");
93 }
94 } catch (JSONException e) {
95 Log.e(TAG, "exc: " + e);
96 }
97 if (mSelectionMode.equalsIgnoreCase(SINGLE_FILE)) {
98 mMultipleSelection = false;
99 } else {
100 mMultipleSelection = true;
101 }
The Android Open Source Projected217d92008-12-17 18:05:52 -0800102 }
103
104 public void setup() {
105 inflate(R.layout.gears_dialog_filepicker, R.id.panel_content);
106 setupButtons(0,
107 R.string.filepicker_button_allow,
108 R.string.filepicker_button_deny);
109 setupDialog();
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800110
111 TextView textViewPath = (TextView) findViewById(R.id.path_name);
112 if (textViewPath != null) {
113 textViewPath.setText(R.string.filepicker_path);
114 }
115
The Android Open Source Projected217d92008-12-17 18:05:52 -0800116 GridView view = (GridView) findViewById(R.id.files_list);
117 view.setAdapter(mAdapter);
118 view.setOnTouchListener(this);
119
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800120 setSelectionText();
121
The Android Open Source Projected217d92008-12-17 18:05:52 -0800122 mImagesLoader = new ImagesLoad(mAdapter);
123 mImagesLoader.setAdapterView(view);
124 Thread thread = new Thread(mImagesLoader);
125 thread.start();
126 }
127
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800128 public void setSelectionText() {
129 Vector elements = mAdapter.selectedElements();
130 if (elements == null)
131 return;
132 TextView info = (TextView) findViewById(R.id.selection);
133 int nbElements = elements.size();
134 if (nbElements == 0) {
135 info.setText(R.string.filepicker_no_files_selected);
136 } else if (nbElements == 1) {
137 info.setText(R.string.filepicker_one_file_selected);
138 } else {
139 info.setText(nbElements + " " +
140 mActivity.getString(
141 R.string.filepicker_some_files_selected));
142 }
143 }
144
145 public void setCurrentPath(String path) {
146 if (path != null) {
147 mCurrentPath = path;
148 TextView textViewPath = (TextView) findViewById(R.id.current_path);
149 if (textViewPath != null) {
150 textViewPath.setText(path);
151 }
152 }
153 }
154
The Android Open Source Projected217d92008-12-17 18:05:52 -0800155 public void setupDialog(TextView message, ImageView icon) {
156 message.setText(R.string.filepicker_message);
157 message.setTextSize(24);
The Android Open Source Projectfbb2a3a2009-02-13 12:57:52 -0800158 icon.setImageResource(R.drawable.ic_dialog_menu_generic);
The Android Open Source Projected217d92008-12-17 18:05:52 -0800159 }
160
161 public boolean onTouch(View v, MotionEvent event) {
162 mImagesLoader.pauseIconRequest();
163 return false;
164 }
165
166 /**
167 * Utility class to load and generate thumbnails
168 * for image files
169 */
170 class ImagesLoad implements Runnable {
171 private Map mImagesMap;
172 private Vector mImagesPath;
173 private BaseAdapter mAdapter;
174 private AdapterView mAdapterView;
175 private Vector<FilePickerElement> mElements;
176 private Handler mLoaderHandler;
177
178 ImagesLoad(BaseAdapter adapter) {
179 mAdapter = adapter;
180 }
181
182 public void signalChanges() {
183 Message message = mHandler.obtainMessage(GearsBaseDialog.NEW_ICON,
184 mAdapter);
185 mHandler.sendMessage(message);
186 }
187
188 /**
189 * TODO: use the same thumbnails as the photo app
190 * (bug: http://b/issue?id=1497927)
191 */
192 public String getThumbnailPath(String path) {
193 File f = new File(path);
194 String myPath = f.getParent() + "/.thumbnails";
195 File d = new File(myPath);
196 if (!d.exists()) {
197 d.mkdirs();
198 }
199 return myPath + "/" + f.getName();
200 }
201
202 public boolean saveImage(String path, Bitmap image) {
203 boolean ret = false;
204 try {
205 FileOutputStream outStream = new FileOutputStream(path);
206 ret = image.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
207 } catch (IOException e) {
208 Log.e(TAG, "IOException ", e);
209 }
210 return ret;
211 }
212
213 public Bitmap generateImage(FilePickerElement elem) {
214 String path = elem.getPath();
215 Bitmap finalImage = null;
216 try {
217 String thumbnailPath = getThumbnailPath(path);
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800218 if (enableSavedThumbnails) {
219 File thumbnail = new File(thumbnailPath);
220 if (thumbnail.exists()) {
221 finalImage = BitmapFactory.decodeFile(thumbnailPath);
222 if (finalImage != null) {
223 return finalImage;
224 }
The Android Open Source Projected217d92008-12-17 18:05:52 -0800225 }
226 }
227 BitmapFactory.Options options = new BitmapFactory.Options();
228 options.inJustDecodeBounds = true;
229 BitmapFactory.decodeFile(path, options);
230
231 int width = options.outWidth;
232 int height = options.outHeight;
233 int size = 128;
234 int sampleSize = 1;
235 if (width > size || height > size) {
236 sampleSize = 2;
237 while ((width / sampleSize > size)
238 || (height / sampleSize > size)) {
239 sampleSize += 2;
240 }
241 }
242 options.inJustDecodeBounds = false;
243 options.inSampleSize = sampleSize;
244 Bitmap originalImage = BitmapFactory.decodeFile(path, options);
245 if (originalImage == null) {
246 return null;
247 }
248 finalImage = Bitmap.createScaledBitmap(originalImage, size, size, true);
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800249 if (enableSavedThumbnails) {
250 if (saveImage(thumbnailPath, finalImage)) {
251 if (mDebug) {
252 Log.v(TAG, "Saved thumbnail for file " + path);
253 }
254 } else {
255 Log.e(TAG, "Could NOT Save thumbnail for file " + path);
The Android Open Source Projected217d92008-12-17 18:05:52 -0800256 }
The Android Open Source Projected217d92008-12-17 18:05:52 -0800257 }
258 originalImage.recycle();
259 } catch (java.lang.OutOfMemoryError e) {
260 Log.e(TAG, "Intercepted OOM ", e);
261 }
262 return finalImage;
263 }
264
265 public void pauseIconRequest() {
266 Message message = Message.obtain(mLoaderHandler,
267 GearsBaseDialog.PAUSE_REQUEST_ICON);
268 mLoaderHandler.sendMessageAtFrontOfQueue(message);
269 }
270 public void postIconRequest(FilePickerElement item, int position) {
271 if (item == null) {
272 return;
273 }
274 Message message = mLoaderHandler.obtainMessage(
275 GearsBaseDialog.REQUEST_ICON, position, 0, item);
276 mLoaderHandler.sendMessage(message);
277 }
278
279 public void generateIcon(FilePickerElement elem) {
280 if (elem.isImage()) {
281 if (elem.getThumbnail() == null) {
282 Bitmap image = generateImage(elem);
283 if (image != null) {
284 elem.setThumbnail(image);
285 }
286 }
287 }
288 }
289
290 public void setAdapterView(AdapterView view) {
291 mAdapterView = view;
292 }
293
294 public void run() {
295 Looper.prepare();
296 mLoaderHandler = new Handler() {
297 public void handleMessage(Message msg) {
298 int visibleElements = 10;
299 if (msg.what == GearsBaseDialog.PAUSE_REQUEST_ICON) {
300 try {
301 // We are busy (likely) scrolling the view,
302 // so we just pause the loading.
303 Thread.sleep(1000);
304 mLoaderHandler.removeMessages(
305 GearsBaseDialog.PAUSE_REQUEST_ICON);
306 } catch (InterruptedException e) {
307 Log.e(TAG, "InterruptedException ", e);
308 }
309 } else if (msg.what == GearsBaseDialog.REQUEST_ICON) {
310 try {
311 Thread.sleep(10);
312 } catch (InterruptedException e) {
313 Log.e(TAG, "InterruptedException ", e);
314 }
315 FilePickerElement elem = (FilePickerElement) msg.obj;
316 int firstVisiblePosition = mAdapterView.getFirstVisiblePosition();
317 // If the elements are not visible, we slow down the update
318 // TODO: replace this by a low-priority thread
319 if ((msg.arg1 < firstVisiblePosition - visibleElements)
320 && msg.arg1 > firstVisiblePosition + visibleElements) {
321 try {
322 Thread.sleep(100);
323 } catch (InterruptedException e) {
324 }
325 }
326 generateIcon(elem);
327 signalChanges();
328 }
329 }
330 };
331 Looper.loop();
332 }
333 }
334
335 /**
336 * Utility class representing an element displayed in the
337 * file picker, associated with an icon and/or thumbnail
338 */
339 class FilePickerElement {
340 private File mPath;
341 private String mName;
342 private Bitmap mIcon;
343 private boolean mIsSelected;
344 private Vector mChildren;
345 private FilePickerElement mParent;
346 private boolean mIsParent;
347 private BaseAdapter mAdapter;
348 private String mExtension;
349 private Bitmap mThumbnail;
350 private boolean mIsImage;
351
352 public FilePickerElement(String name, BaseAdapter adapter) {
353 this(name, adapter, null);
354 }
355
356 public FilePickerElement(String path, String name, BaseAdapter adapter) {
357 this(path, name, adapter, null);
358 }
359
360 public FilePickerElement(String name,
361 BaseAdapter adapter,
362 FilePickerElement parent) {
363 mName = name;
364 mAdapter = adapter;
365 mParent = parent;
366 mIsSelected = false;
367 mChildren = null;
368 }
369
370 public FilePickerElement(String path,
371 String name,
372 BaseAdapter adapter,
373 FilePickerElement parent) {
374 mPath = new File(path);
375 mName = name;
376 mIsSelected = false;
377 mChildren = null;
378 mParent = parent;
379 mAdapter = adapter;
380 mExtension = null;
381
382 setIcons();
383 }
384
385 public void setIcons() {
386 if (mPath.isDirectory()) {
387 if (mDirectoryIcon == null) {
388 mDirectoryIcon = BitmapFactory.decodeResource(
389 getResources(), R.drawable.gears_folder);
390 }
391 mIcon = mDirectoryIcon;
392
393 } else {
394 if (isImage()) {
395 if (mImageIcon == null) {
396 mImageIcon = BitmapFactory.decodeResource(
397 getResources(), R.drawable.gears_file_image);
398 }
399 mIcon = mImageIcon;
400 } else if (isAudio()) {
401 mIcon = BitmapFactory.decodeResource(
402 getResources(), R.drawable.gears_file_audio);
403 } else if (isVideo()) {
404 mIcon = BitmapFactory.decodeResource(
405 getResources(), R.drawable.gears_file_video);
406 } else {
407 if (mDefaultIcon == null) {
408 mDefaultIcon = BitmapFactory.decodeResource(
409 getResources(), R.drawable.gears_file_unknown);
410 }
411 mIcon = mDefaultIcon;
412 }
413 }
414 if (mBackIcon == null) {
415 mBackIcon = BitmapFactory.decodeResource(getResources(),
The Android Open Source Project066e9082009-01-20 14:03:59 -0800416 com.android.internal.R.drawable.ic_menu_back);
The Android Open Source Projected217d92008-12-17 18:05:52 -0800417 }
418 }
419
420 public boolean isImage() {
421 if (mIsImage) return mIsImage;
422 String extension = getExtension();
423 if (extension != null) {
424 if (extension.equalsIgnoreCase("jpg") ||
425 extension.equalsIgnoreCase("jpeg") ||
426 extension.equalsIgnoreCase("png") ||
427 extension.equalsIgnoreCase("gif")) {
428 mIsImage = true;
429 return true;
430 }
431 }
432 return false;
433 }
434
435 public boolean isAudio() {
436 String extension = getExtension();
437 if (extension != null) {
438 if (extension.equalsIgnoreCase("mp3") ||
439 extension.equalsIgnoreCase("wav") ||
440 extension.equalsIgnoreCase("aac")) {
441 return true;
442 }
443 }
444 return false;
445 }
446
447 public boolean isVideo() {
448 String extension = getExtension();
449 if (extension != null) {
450 if (extension.equalsIgnoreCase("mpg") ||
451 extension.equalsIgnoreCase("mpeg") ||
452 extension.equalsIgnoreCase("mpe") ||
453 extension.equalsIgnoreCase("divx") ||
454 extension.equalsIgnoreCase("3gpp") ||
455 extension.equalsIgnoreCase("avi")) {
456 return true;
457 }
458 }
459 return false;
460 }
461
462 public void setParent(boolean isParent) {
463 mIsParent = isParent;
464 }
465
466 public boolean isDirectory() {
467 return mPath.isDirectory();
468 }
469
470 public String getExtension() {
471 if (isDirectory()) {
472 return null;
473 }
474 if (mExtension == null) {
475 String path = getPath();
476 int index = path.lastIndexOf(".");
477 if ((index != -1) && (index != path.length() - 1)){
478 // if we find a dot that is not the last character
479 mExtension = path.substring(index+1);
480 return mExtension;
481 }
482 }
483 return mExtension;
484 }
485
486 public void refresh() {
487 mChildren = null;
488 Vector children = getChildren();
489 for (int i = 0; i < children.size(); i++) {
490 FilePickerElement elem = (FilePickerElement) children.get(i);
491 mImagesLoader.postIconRequest(elem, i);
492 }
493 }
494
495 public Vector getChildren() {
496 if (isDirectory()) {
497 if (mChildren == null) {
498 mChildren = new Vector();
499 File[] files = mPath.listFiles();
500 if (mParent != null) {
501 mChildren.add(mParent);
502 mParent.setParent(true);
503 }
504 for (int i = 0; i < files.length; i++) {
505 String name = files[i].getName();
506 String fpath = files[i].getPath();
507 if (!name.startsWith(".")) { // hide dotfiles
508 FilePickerElement elem = new FilePickerElement(fpath, name,
509 mAdapter, this);
510 elem.setParent(false);
511 mChildren.add(elem);
512 }
513 }
514 }
515 }
516 return mChildren;
517 }
518
519 public FilePickerElement getChild(int position) {
520 Vector children = getChildren();
521 if (children != null) {
522 return (FilePickerElement) children.get(position);
523 }
524 return null;
525 }
526
527 public Bitmap getIcon(int position) {
528 if (mIsParent) {
529 return mBackIcon;
530 }
531 if (isImage()) {
532 if (mThumbnail != null) {
533 return mThumbnail;
534 } else {
535 mImagesLoader.postIconRequest(this, position);
536 }
537 }
538 return mIcon;
539 }
540
541 public Bitmap getThumbnail() {
542 return mThumbnail;
543 }
544
545 public void setThumbnail(Bitmap icon) {
546 mThumbnail = icon;
547 }
548
549 public String getName() {
550 return mName;
551 }
552
553 public String getPath() {
554 return mPath.getPath();
555 }
556
557 public void toggleSelection() {
558 mIsSelected = !mIsSelected;
559 }
560
561 public boolean isSelected() {
562 return mIsSelected;
563 }
564
565 }
566
567 /**
568 * Adapter for the GridView
569 */
570 class FilePickerAdapter extends BaseAdapter {
571 private Context mContext;
572 private Map mImagesMap;
573 private Map mImagesSelected;
574
575 private Vector mImages;
576 private Vector<FilePickerElement> mFiles;
577
578 private FilePickerElement mRootElement;
579 private FilePickerElement mCurrentElement;
580
581 public FilePickerAdapter(Context context) {
582 mContext = context;
583 mImages = new Vector();
584 mFiles = new Vector();
585
586 mImagesMap = Collections.synchronizedMap(new HashMap());
587 mImagesSelected = new HashMap();
588
589 Uri requests[] = { MediaStore.Images.Media.INTERNAL_CONTENT_URI,
590 MediaStore.Images.Media.EXTERNAL_CONTENT_URI };
591
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800592 String startingPath = Environment.getExternalStorageDirectory().getPath();
593 mRootElement = new FilePickerElement(startingPath, "SD Card", this);
The Android Open Source Projected217d92008-12-17 18:05:52 -0800594 mCurrentElement = mRootElement;
595 }
596
597 public void addImage(String path) {
598 mImages.add(path);
599 Bitmap image = BitmapFactory.decodeResource(
600 getResources(), R.drawable.gears_file_unknown);
601 mImagesMap.put(path, image);
602 mImagesSelected.put(path, Boolean.FALSE);
603 }
604
605 public int getCount() {
606 Vector elems = mCurrentElement.getChildren();
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800607 setCurrentPath(mCurrentElement.getPath());
The Android Open Source Projected217d92008-12-17 18:05:52 -0800608 return elems.size();
609 }
610
611 public Object getItem(int position) {
612 return position;
613 }
614
615 public long getItemId(int position) {
616 return position;
617 }
618
619 public Vector selectedElements() {
620 if (mCurrentElement == null) {
621 return null;
622 }
623 Vector children = mCurrentElement.getChildren();
624 Vector ret = new Vector();
625 for (int i = 0; i < children.size(); i++) {
626 FilePickerElement elem = (FilePickerElement) children.get(i);
627 if (elem.isSelected()) {
628 ret.add(elem);
629 }
630 }
631 return ret;
632 }
633
634 public View getView(int position, View convertView, ViewGroup parent) {
635 View cell = convertView;
636 if (cell == null) {
637 LayoutInflater inflater = (LayoutInflater) getSystemService(
638 Context.LAYOUT_INFLATER_SERVICE);
639 cell = inflater.inflate(R.layout.gears_dialog_filepicker_cell, null);
640 }
641 ImageView imageView = (ImageView) cell.findViewById(R.id.icon);
642 TextView textView = (TextView) cell.findViewById(R.id.name);
643 FilePickerElement elem = mCurrentElement.getChild(position);
644 if (elem == null) {
645 String message = "Could not get elem " + position;
646 message += " for " + mCurrentElement.getPath();
647 Log.e(TAG, message);
648 return null;
649 }
650 String path = elem.getPath();
651 textView.setText(elem.getName());
652
653 View.OnClickListener listener = new View.OnClickListener() {
654 public void onClick(View view) {
655 int pos = (Integer) view.getTag();
656 FilePickerElement elem = mCurrentElement.getChild(pos);
657 if (elem.isDirectory()) {
658 mCurrentElement = elem;
659 mCurrentElement.refresh();
660 } else {
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800661 if (mMultipleSelection) {
662 elem.toggleSelection();
663 } else {
664 Vector elems = selectedElements();
665 if (elems != null) {
666 if (elems.size() == 0) {
667 elem.toggleSelection();
668 } else if ((elems.size() == 1)
669 && elem.isSelected()) {
670 elem.toggleSelection();
671 }
672 }
673 }
The Android Open Source Projected217d92008-12-17 18:05:52 -0800674 }
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800675 setSelectionText();
The Android Open Source Projected217d92008-12-17 18:05:52 -0800676 notifyDataSetChanged();
677 }
678 };
The Android Open Source Projected217d92008-12-17 18:05:52 -0800679 cell.setLayoutParams(new GridView.LayoutParams(96, 96));
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800680 cell.setOnClickListener(listener);
681 cell.setOnTouchListener(new View.OnTouchListener() {
682 public boolean onTouch(View v, MotionEvent event) {
683 if (event.getAction() == MotionEvent.ACTION_DOWN) {
684 int color = getResources().getColor(R.color.icon_selection);
685 v.setBackgroundColor(color);
686 } else {
The Android Open Source Projectfbb2a3a2009-02-13 12:57:52 -0800687 v.setBackgroundColor(android.R.color.background_dark);
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800688 }
689 return false;
690 }
691 });
The Android Open Source Projected217d92008-12-17 18:05:52 -0800692
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800693 cell.setTag(position);
The Android Open Source Projected217d92008-12-17 18:05:52 -0800694
695 if (elem.isSelected()) {
The Android Open Source Project765e7c92009-01-09 17:51:25 -0800696 int color = getResources().getColor(R.color.icon_selection);
697 cell.setBackgroundColor(color);
The Android Open Source Projected217d92008-12-17 18:05:52 -0800698 } else {
The Android Open Source Projectfbb2a3a2009-02-13 12:57:52 -0800699 cell.setBackgroundColor(android.R.color.background_dark);
The Android Open Source Projected217d92008-12-17 18:05:52 -0800700 }
701 Bitmap bmp = elem.getIcon(position);
702 if (bmp != null) {
703 imageView.setImageBitmap(bmp);
704 }
705
706 return cell;
707 }
708 }
709
710 private String selectedFiles() {
711 Vector selection = mAdapter.selectedElements();
712 JSONArray jsonSelection = new JSONArray();
713 if (selection != null) {
714 for (int i = 0; i < selection.size(); i++) {
715 FilePickerElement elem = (FilePickerElement) selection.get(i);
716 jsonSelection.put(elem.getPath());
717 }
718 }
719 return jsonSelection.toString();
720 }
721
722 public String closeDialog(int closingType) {
723 return selectedFiles();
724 }
725}