0

I am trying to open a file dialog with file.browseForOpen. Most of the time it works but on the very rare occasion (such as in meetings) the file browser simply does not appear and does not block (as a modal should).

If I press the button calling the code at this point then I get an error which states "there can only be one".

There are no sub-windows and I can't find to file dialog, even after minimizing the main window, yet the error insists that it is open. I wrote some code which disabled the button when the code above is called and then enables it on any of the events but when this error occurs the button is then permanently disabled.

There are another 10,000 lines of code, some which keep running even while the file browser is open. None of them seem related to the file browser so I moved the following code into a new project, to test, and could not replicate the bug.

var filter:FileFilter = new FileFilter("Image/Video", "*.jpg;*.png;*.mp4;");
var imagesFilter:FileFilter = new FileFilter("jpg/png", "*.jpg;*.png");
var docFilter:FileFilter = new FileFilter("mp4", "*.mp4;");
var filters:Array = [filter, imagesFilter, docFilter];

var fileBrowser:File = File.userDirectory;
fileBrowser.addEventListener(FileListEvent.SELECT_MULTIPLE, onFileSelected);
fileBrowser.addEventListener(Event.CANCEL, clean);
fileBrowser.addEventListener(IOErrorEvent.IO_ERROR, clean);
fileBrowser.browseForOpen("Select Slides", filters);

Does anyone know anything which could save me from a 'needle in a haystack' exhaustive search? Has anyone else ever experienced this same problem? I couldn't find any solutions when searching "File dialog opens but isn't visible" or more than 30 variations of that search including "File dialog doesn't open".

Lastly, is there a way to force the file dialog to close if I detect that the user is interacting with the main window whilst it should be blocked? Just as a bandage fix should the problem not be solved (breaks modal flow, I know, but modal flow is already broken at that point).

UPDATE:

After removing a class and replacing it with a less efficient urlMonitor the problem seems to have gone away. If anyone can work out what went wrong then I will mark your answer as complete. The class I removed seemed completely unrelated but I will show the code:

package reuse.Network
{
    import flash.desktop.NativeApplication;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.StatusEvent;
    import flash.events.TimerEvent;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.utils.Timer;

    import air.net.URLMonitor;

    [Event(name="networkStatusChanged", type="reuse.Network.CheckInternetEvent")]
    public class NetStatusMonitor extends EventDispatcher
    {
        private var url:String;
        private var urlMonitor:URLMonitor;

        public function NetStatusMonitor(url:String = 'http://www.adobe.com')
        {
            super();
            this.url = url;
        }

        protected function onNetwork_ChangeHandler(event:Event):void
        {
            checkWebsite(url, dispatchStatus);
        }

        /**
         * Checks a specific website for connectivity.
         * @param uri URI of the website to check for a response from
         * @param result Function which accepts a bool as a response.
         * @param idleTimeout How many milliseconds to wait before timing out
         */
        public function checkWebsite(uri:String, result:Function, idleTimeout:Number = NaN):void
        {
            var timeout:Timer;
            var request:URLRequest = new URLRequest(uri);

            if(!isNaN(idleTimeout))
            {
                request.idleTimeout = idleTimeout;

                timeout = new Timer(request.idleTimeout + 1000, 1);
                timeout.addEventListener(TimerEvent.TIMER_COMPLETE, failed);
                timeout.start();
            }

            var loader:URLLoader = new URLLoader();
            loader.dataFormat = URLLoaderDataFormat.TEXT;
            loader.addEventListener(Event.COMPLETE, complete);
            loader.addEventListener(IOErrorEvent.IO_ERROR, failed);
            loader.load(request);

            function complete():void
            {
                result(true);
                cleanup();
            }

            function failed(e:*):void
            {
                result(false);
                cleanup();
            }

            function cleanup():void
            {
                if(timeout)
                {
                    timeout.stop();
                    timeout.removeEventListener(TimerEvent.TIMER_COMPLETE, failed);
                    timeout = null;
                }

                loader.close();
                loader.removeEventListener(Event.COMPLETE, complete);
                loader.removeEventListener(IOErrorEvent.IO_ERROR, failed);
                loader = null;
            }
        }

        public function start():void
        {
            checkWebsite(url, dispatchStatus, 5000);

            if(!NativeApplication.nativeApplication.hasEventListener(Event.NETWORK_CHANGE))
                NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetwork_ChangeHandler);

            if(urlMonitor == null)
            {
                var request:URLRequest = new URLRequest(url);
                urlMonitor = new URLMonitor(request);
                urlMonitor.pollInterval = 30;
            }

            if(!urlMonitor.hasEventListener(StatusEvent.STATUS))
                urlMonitor.addEventListener(StatusEvent.STATUS, onNetStatus_ChangeHandler);

            if(!urlMonitor.running)
                urlMonitor.start();
        }

        public function stop():void
        {
            if(urlMonitor)
            {
                if(urlMonitor.running)
                    urlMonitor.stop();

                if(urlMonitor.hasEventListener(StatusEvent.STATUS))
                    urlMonitor.removeEventListener(StatusEvent.STATUS, onNetStatus_ChangeHandler);

                urlMonitor = null;
            }
        }

        private function onNetStatus_ChangeHandler(event:StatusEvent):void
        {
            dispatchStatus(urlMonitor.available);
        }

        private function dispatchStatus(status:Boolean):void
        {
            dispatchEvent(new CheckInternetEvent(CheckInternetEvent.NETWORK_STATUS_CHANGED, status));
        }
    }
}

Anyone familiar with Raja Jaganathan might recognize this class from Adobe Air - Check for internet connection

Community
  • 1
  • 1
Dark Snowy
  • 43
  • 3

1 Answers1

0

I posted this as a bug to Adobe and the following note was added to it:

Alex Rekish

11:06:11 PM GMT+00:00 Apr 12, 2016

I have seen this problem and found workaround. You need remove listeners, force cancel and null pervious file object that you you for browseForOpen method.

previousBrowseFile.removeEventListener(Event.SELECT, fileSelected); previousBrowseFile.removeEventListener(Event.CANCEL, fileCancelled); previousBrowseFile.cancel(); previousBrowseFile= null;

Dark Snowy
  • 43
  • 3