Search in sources :

Example 6 with DialogAction

use of com.mucommander.ui.dialog.DialogAction in project mucommander by mucommander.

the class BrowseLocationThread method run.

@Override
public void run() {
    LOGGER.debug("starting folder change...");
    boolean folderChangedSuccessfully = false;
    // Show some progress in the progress bar to give hope
    folderPanel.setProgressValue(10);
    boolean userCancelled = false;
    CredentialsMapping newCredentialsMapping = null;
    // True if Guest authentication was selected in the authentication dialog (guest credentials must not be
    // added to CredentialsManager)
    boolean guestCredentialsSelected = false;
    AuthenticationType authenticationType = folderURL.getAuthenticationType();
    if (credentialsMapping != null) {
        newCredentialsMapping = credentialsMapping;
        CredentialsManager.authenticate(folderURL, newCredentialsMapping);
    } else // avoid waiting for an AuthException to be thrown.
    if (!folderURL.containsCredentials() && ((authenticationType == AuthenticationType.AUTHENTICATION_REQUIRED) || (authenticationType == AuthenticationType.AUTHENTICATION_OPTIONAL && CredentialsManager.getMatchingCredentials(folderURL).length > 0))) {
        AuthDialog authDialog = popAuthDialog(folderURL, false, null);
        newCredentialsMapping = authDialog.getCredentialsMapping();
        guestCredentialsSelected = authDialog.guestCredentialsSelected();
        // User cancelled the authentication dialog, stop
        if (newCredentialsMapping == null)
            userCancelled = true;
        else // Use the provided credentials and invalidate the folder AbstractFile instance (if any) so that
        // it gets recreated with the new credentials
        {
            CredentialsManager.authenticate(folderURL, newCredentialsMapping);
            folder = null;
        }
    }
    if (!userCancelled) {
        boolean canonicalPathFollowed = false;
        do {
            // Set cursor to hourglass/wait
            mainFrame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
            // Render all actions inactive while changing folder
            mainFrame.setNoEventsMode(true);
            try {
                // Thread was created using a FileURL
                if (folder == null) {
                    AbstractFile file = FileFactory.getFile(folderURL, true);
                    synchronized (KILL_LOCK) {
                        if (killed) {
                            LOGGER.debug("this thread has been killed, returning");
                            break;
                        }
                    }
                    // File resolved -> 25% complete
                    folderPanel.setProgressValue(25);
                    // or doesn't exist
                    if (file == null || !file.exists()) {
                        // Restore default cursor
                        mainFrame.setCursor(Cursor.getDefaultCursor());
                        locationChanger.showFolderDoesNotExistDialog();
                        break;
                    }
                    if (!file.canRead()) {
                        // Restore default cursor
                        mainFrame.setCursor(Cursor.getDefaultCursor());
                        showFailedToReadFolderDialog();
                        break;
                    }
                    // File is a regular directory, all good
                    if (file.isDirectory()) {
                    // Just continue
                    } else // File is a browsable file (Zip archive for instance) but not a directory : Browse or Download ? => ask the user
                    if (file.isBrowsable()) {
                        // of the OpenAction (enter pressed on the file). This works well enough in practice.
                        if (!globalHistory.contains(folderURL) && !file.equals(folderPanel.getFileTable().getSelectedFile())) {
                            // Restore default cursor
                            mainFrame.setCursor(Cursor.getDefaultCursor());
                            // Download or browse file ?
                            QuestionDialog dialog = new QuestionDialog(mainFrame, null, Translator.get("table.download_or_browse"), mainFrame, Arrays.asList(BrowseLocationThreadAction.BROWSE, BrowseLocationThreadAction.DOWNLOAD, BrowseLocationThreadAction.CANCEL), 0);
                            DialogAction ret = dialog.getActionValue();
                            if (ret == DIALOG_DISPOSED_ACTION || ret == BrowseLocationThreadAction.CANCEL)
                                break;
                            // Download file
                            if (ret == BrowseLocationThreadAction.DOWNLOAD) {
                                showDownloadDialog(file);
                                break;
                            }
                            // Continue if BROWSE
                            // Set cursor to hourglass/wait
                            mainFrame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
                        }
                    // else just continue and browse file's contents
                    } else // File is a regular file: show download dialog which allows to download (copy) the file
                    // to a directory specified by the user
                    {
                        showDownloadDialog(file);
                        break;
                    }
                    this.folder = file;
                } else // Thread was created using an AbstractFile instance, check file existence
                if (!folder.exists()) {
                    // Find a 'workable' folder if the requested folder doesn't exist anymore
                    if (findWorkableFolder) {
                        AbstractFile newFolder = locationChanger.getWorkableFolder(folder);
                        if (newFolder.equals(folder)) {
                            // If we've already tried the returned folder, give up (avoids a potentially endless loop)
                            locationChanger.showFolderDoesNotExistDialog();
                            break;
                        }
                        // Try again with the new folder
                        folder = newFolder;
                        folderURL = folder.getURL();
                        // Discard the file to select, if any
                        fileToSelect = null;
                        continue;
                    } else {
                        locationChanger.showFolderDoesNotExistDialog();
                        break;
                    }
                } else if (!folder.canRead()) {
                    showFailedToReadFolderDialog();
                    break;
                }
                // resolved again.
                if (!canonicalPathFollowed && followCanonicalPath(folder)) {
                    try {
                        // Recreate the FileURL using the file's canonical path
                        FileURL newURL = FileURL.getFileURL(folder.getCanonicalPath());
                        // Keep the credentials and properties (if any)
                        newURL.setCredentials(folderURL.getCredentials());
                        newURL.importProperties(folderURL);
                        this.folderURL = newURL;
                        // Invalidate the AbstractFile instance
                        this.folder = null;
                        // There won't be any further attempts after this one
                        canonicalPathFollowed = true;
                        // Loop the resolve the file
                        continue;
                    } catch (MalformedURLException e) {
                    // In the unlikely event of the canonical path being malformed, the AbstractFile
                    // and FileURL instances are left untouched
                    }
                }
                synchronized (KILL_LOCK) {
                    if (killed) {
                        LOGGER.debug("this thread has been killed, returning");
                        break;
                    }
                }
                // File tested -> 50% complete
                folderPanel.setProgressValue(50);
                synchronized (KILL_LOCK) {
                    if (killed) {
                        LOGGER.debug("this thread has been killed, returning");
                        break;
                    }
                    // From now on, thread cannot be killed (would comprise table integrity)
                    doNotKill = true;
                }
                // files listed -> 75% complete
                folderPanel.setProgressValue(75);
                LOGGER.trace("calling setCurrentFolder");
                // Change the file table's current folder and select the specified file (if any)
                locationChanger.setCurrentFolder(folder, fileToSelect, changeLockedTab, true);
                // folder set -> 95% complete
                folderPanel.setProgressValue(95);
                // Do not add the credentials if guest credentials were selected by the user.
                if (newCredentialsMapping != null && !guestCredentialsSelected)
                    CredentialsManager.addCredentials(newCredentialsMapping);
                // All good !
                folderChangedSuccessfully = true;
                break;
            } catch (Exception e) {
                LOGGER.debug("Caught exception", e);
                if (killed) {
                    // If #tryKill() called #interrupt(), the exception we just caught was most likely
                    // thrown as a result of the thread being interrupted.
                    // 
                    // The exception can be a java.lang.InterruptedException (Thread throws those),
                    // a java.nio.channels.ClosedByInterruptException (InterruptibleChannel throws those)
                    // or any other exception thrown by some code that swallowed the original exception
                    // and threw a new one.
                    LOGGER.debug("Thread was interrupted, ignoring exception");
                    break;
                }
                // Restore default cursor
                mainFrame.setCursor(Cursor.getDefaultCursor());
                if (e instanceof AuthException) {
                    AuthException authException = (AuthException) e;
                    // Retry (loop) if user provided new credentials, if not stop
                    AuthDialog authDialog = popAuthDialog(authException.getURL(), true, authException.getMessage());
                    newCredentialsMapping = authDialog.getCredentialsMapping();
                    guestCredentialsSelected = authDialog.guestCredentialsSelected();
                    if (newCredentialsMapping != null) {
                        // Invalidate the existing AbstractFile instance
                        folder = null;
                        // Use the provided credentials
                        CredentialsManager.authenticate(folderURL, newCredentialsMapping);
                        continue;
                    }
                } else {
                    // Find a 'workable' folder if the requested folder doesn't exist anymore
                    if (findWorkableFolder) {
                        AbstractFile newFolder = locationChanger.getWorkableFolder(folder);
                        if (newFolder.equals(folder)) {
                            // If we've already tried the returned folder, give up (avoids a potentially endless loop)
                            locationChanger.showFolderDoesNotExistDialog();
                            break;
                        }
                        // Try again with the new folder
                        folder = newFolder;
                        folderURL = folder.getURL();
                        // Discard the file to select, if any
                        fileToSelect = null;
                        continue;
                    }
                    showAccessErrorDialog(e);
                }
                // Stop looping!
                break;
            }
        } while (true);
    }
    synchronized (KILL_LOCK) {
        // Clean things up
        cleanup(folderChangedSuccessfully);
    }
}
Also used : FileURL(com.mucommander.commons.file.FileURL) MalformedURLException(java.net.MalformedURLException) AbstractFile(com.mucommander.commons.file.AbstractFile) QuestionDialog(com.mucommander.ui.dialog.QuestionDialog) DialogAction(com.mucommander.ui.dialog.DialogAction) AuthException(com.mucommander.commons.file.AuthException) AuthDialog(com.mucommander.ui.dialog.auth.AuthDialog) Cursor(java.awt.Cursor) MalformedURLException(java.net.MalformedURLException) AuthException(com.mucommander.commons.file.AuthException) CredentialsMapping(com.mucommander.auth.CredentialsMapping) AuthenticationType(com.mucommander.commons.file.AuthenticationType)

Example 7 with DialogAction

use of com.mucommander.ui.dialog.DialogAction in project mucommander by mucommander.

the class DeleteJob method processFile.

// //////////////////////////
// FileJob implementation //
// //////////////////////////
/**
 * Deletes recursively the given file or folder.
 *
 * @param file the file or folder to delete
 * @param recurseParams not used
 *
 * @return <code>true</code> if the file has been completely deleted.
 */
@Override
protected boolean processFile(AbstractFile file, Object recurseParams) {
    if (getState() == FileJobState.INTERRUPTED)
        return false;
    // Delete files recursively, only if trash is not used.
    DialogAction ret;
    if (!moveToTrash && file.isDirectory()) {
        String filePath = file.getAbsolutePath();
        filePath = filePath.substring(getBaseSourceFolder().getAbsolutePath(false).length() + 1, filePath.length());
        // Important: symlinks must *not* be followed -- following symlinks could have disastrous effects.
        if (!file.isSymlink()) {
            do {
                // Delete each file in this folder
                try {
                    AbstractFile[] subFiles = file.ls();
                    for (int i = 0; i < subFiles.length && getState() != FileJobState.INTERRUPTED; i++) {
                        // Notify job that we're starting to process this file (needed for recursive calls to processFile)
                        nextFile(subFiles[i]);
                        processFile(subFiles[i], null);
                    }
                    break;
                } catch (IOException e) {
                    LOGGER.debug("IOException caught", e);
                    ret = showErrorDialog(errorDialogTitle, Translator.get("cannot_read_file", filePath));
                    // Retry loops
                    if (ret == FileJobAction.RETRY)
                        continue;
                    // Cancel, skip or close dialog returns false
                    return false;
                }
            } while (true);
        }
    }
    // Return now if the job was interrupted, so that we do not attempt to delete this folder
    if (getState() == FileJobState.INTERRUPTED)
        return false;
    do {
        // Loop for retry
        try {
            deleteFile(file);
            return true;
        } catch (IOException e) {
            LOGGER.debug("IOException caught", e);
            ret = showErrorDialog(errorDialogTitle, Translator.get(file.isDirectory() ? "cannot_delete_folder" : "cannot_delete_file", file.getName()));
            // Retry loops
            if (ret == FileJobAction.RETRY)
                continue;
            // Cancel, skip or close dialog returns false
            return false;
        }
    } while (true);
}
Also used : AbstractFile(com.mucommander.commons.file.AbstractFile) DialogAction(com.mucommander.ui.dialog.DialogAction) IOException(java.io.IOException)

Example 8 with DialogAction

use of com.mucommander.ui.dialog.DialogAction in project mucommander by mucommander.

the class MkdirJob method processFile.

// //////////////////////////
// FileJob implementation //
// //////////////////////////
/**
 * Creates the new directory in the destination folder.
 */
@Override
protected boolean processFile(AbstractFile file, Object recurseParams) {
    // Stop if interrupted (although there is no way to stop the job at this time)
    if (getState() == FileJobState.INTERRUPTED)
        return false;
    do {
        try {
            LOGGER.debug("Creating: {}", file);
            // Check for file collisions, i.e. if the file already exists in the destination
            int collision = FileCollisionChecker.checkForCollision(null, file);
            if (collision != FileCollisionChecker.NO_COLLISION) {
                // File already exists in destination, ask the user what to do (cancel, overwrite,...) but
                // do not offer the multiple files' mode options such as 'skip' and 'apply to all'.
                DialogAction choice = waitForUserResponse(new FileCollisionDialog(getMainFrame(), getMainFrame(), collision, null, file, false, false));
                // Overwrite file
                if (choice == FileCollisionDialog.FileCollisionAction.OVERWRITE) {
                    // Delete the file
                    file.delete();
                } else // Cancel or dialog close (return)
                // else if (choice==-1 || choice==FileCollisionDialog.OverwriteAction.CANCEL) {
                {
                    interrupt();
                    return false;
                }
            }
            // Create file
            if (mkfileMode) {
                // Use mkfile
                if (allocateSpace == -1) {
                    file.mkfile();
                } else // Allocate the requested number of bytes
                {
                    OutputStream mkfileOut = null;
                    try {
                        // using RandomAccessOutputStream if we can have one
                        if (file.isFileOperationSupported(FileOperation.RANDOM_WRITE_FILE)) {
                            mkfileOut = file.getRandomAccessOutputStream();
                            ((RandomAccessOutputStream) mkfileOut).setLength(allocateSpace);
                        } else // manually otherwise
                        {
                            mkfileOut = file.getOutputStream();
                            // Use BufferPool to avoid excessive memory allocation and garbage collection
                            byte[] buffer = BufferPool.getByteArray();
                            int bufferSize = buffer.length;
                            try {
                                long remaining = allocateSpace;
                                int nbWrite;
                                while (remaining > 0 && getState() != FileJobState.INTERRUPTED) {
                                    nbWrite = (int) (remaining > bufferSize ? bufferSize : remaining);
                                    mkfileOut.write(buffer, 0, nbWrite);
                                    remaining -= nbWrite;
                                }
                            } finally {
                                BufferPool.releaseByteArray(buffer);
                            }
                        }
                    } finally {
                        if (mkfileOut != null)
                            try {
                                mkfileOut.close();
                            } catch (IOException e) {
                            }
                    }
                }
            } else // Create directory
            {
                file.mkdir();
            }
            // Resolve new file instance now that it exists: remote files do not update file attributes after
            // creation, we need to get an instance that reflects the newly created file attributes
            file = FileFactory.getFile(file.getURL());
            // Select newly created file when job is finished
            selectFileWhenFinished(file);
            // Return Success
            return true;
        } catch (IOException e) {
            // thrown, this is normal behavior
            if (mkfileMode && getState() == FileJobState.INTERRUPTED)
                return false;
            LOGGER.debug("IOException caught", e);
            DialogAction action = showErrorDialog(Translator.get("error"), Translator.get(mkfileMode ? "cannot_write_file" : "cannot_create_folder", file.getAbsolutePath()), Arrays.asList(FileJobAction.RETRY, FileJobAction.CANCEL));
            // Retry (loop)
            if (action == FileJobAction.RETRY)
                continue;
            // Return Failure
            return false;
        }
    } while (true);
}
Also used : FileCollisionDialog(com.mucommander.ui.dialog.file.FileCollisionDialog) DialogAction(com.mucommander.ui.dialog.DialogAction) OutputStream(java.io.OutputStream) RandomAccessOutputStream(com.mucommander.commons.io.RandomAccessOutputStream) RandomAccessOutputStream(com.mucommander.commons.io.RandomAccessOutputStream) IOException(java.io.IOException)

Example 9 with DialogAction

use of com.mucommander.ui.dialog.DialogAction in project mucommander by mucommander.

the class SearchUpdaterThread method run.

@Override
public void run() {
    LOGGER.debug("starting search updater...");
    boolean searchEndedSuccessfully = false;
    // Show some progress in the progress bar to give hope
    folderPanel.setProgressValue(10);
    try {
        // Set cursor to hourglass/wait
        mainFrame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
        // Render all actions inactive while changing folder
        mainFrame.setNoEventsMode(true);
        search = (SearchFile) FileFactory.getFile(folderURL, true);
        // Initiate the search thread
        search.start(SearchBuilder.newSearch().mainFrame(mainFrame));
        // Retrieve the timestamp of the latest search results
        long date = search.getDate();
        // Update the file table, most likely with empty result set
        setCurrentFolder(false);
        // Search started, advance progress
        folderPanel.setProgressValue(50);
        while (true) {
            if (killed)
                throw new InterruptedException("search-updater thread stopped");
            sleep(1000);
            boolean searchCompleted = COMPLETED_SEARCH_STATUSES.contains(search.getSearchPhase());
            // Retrieve the timestamp of the latest search results
            long currentDate = search.getDate();
            boolean searchResultsChanged = currentDate != date;
            if (searchCompleted) {
                synchronized (KILL_LOCK) {
                    if (killed)
                        throw new InterruptedException("search-updater thread stopped");
                    doNotKill = true;
                }
                if (searchResultsChanged) {
                    folderPanel.setProgressValue(75);
                    setCurrentFolder(true);
                } else {
                    folderPanel.setProgressValue(90);
                    folderPanel.getLocationManager().fireLocationChanged(search.getURL());
                }
                // folder set -> 95% complete
                folderPanel.setProgressValue(95);
                searchEndedSuccessfully = true;
                break;
            }
            if (searchResultsChanged) {
                date = currentDate;
                // Change the file table's current folder and select the specified file (if any)
                setCurrentFolder(false);
                if (search.isPausedToDueMaxResults()) {
                    // Restore default cursor
                    mainFrame.setCursor(Cursor.getDefaultCursor());
                    // Download or browse file ?
                    DialogAction ret = showSearchExceededMaxResults();
                    if (ret == DIALOG_DISPOSED_ACTION || ret == SearchUpdaterThreadAction.STOP) {
                        stoppedDueToMaxResults = true;
                        folderPanel.getLocationManager().fireLocationChanged(search.getURL());
                        break;
                    }
                    // Set cursor to hourglass/wait
                    mainFrame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
                    // continue the paused search
                    search.continueSearch();
                }
            }
        }
    } catch (Exception e) {
        LOGGER.debug("Caught exception", e);
        if (search == null) {
            locationChanger.showFolderDoesNotExistDialog();
        } else {
            search.stop();
            if (killed)
                setCurrentFolderDismissException();
        }
    }
    synchronized (KILL_LOCK) {
        // Clean things up
        cleanup(searchEndedSuccessfully);
    }
}
Also used : DialogAction(com.mucommander.ui.dialog.DialogAction) Cursor(java.awt.Cursor) IOException(java.io.IOException) UnsupportedFileOperationException(com.mucommander.commons.file.UnsupportedFileOperationException)

Example 10 with DialogAction

use of com.mucommander.ui.dialog.DialogAction in project mucommander by mucommander.

the class FileJob method showErrorDialog.

/**
 * Displays an error dialog with the specified title and message and returns the selection action's value.
 */
protected DialogAction showErrorDialog(String title, String message, List<DialogAction> actionChoices) {
    // Return SKIP_ACTION if 'skip all' has previously been selected and 'skip' is in the list of actions.
    if (autoSkipErrors) {
        for (DialogAction action : actionChoices) if (action == FileJobAction.SKIP)
            return FileJobAction.SKIP;
    }
    // Send a system notification if a notifier is available and enabled
    if (NotifierProvider.isAvailable() && NotifierProvider.getNotifier().isEnabled())
        NotifierProvider.displayBackgroundNotification(NotificationType.JOB_ERROR, title, message);
    QuestionDialog dialog;
    if (getProgressDialog() == null)
        dialog = new QuestionDialog(getMainFrame(), title, message, getMainFrame(), actionChoices, 0);
    else
        dialog = new QuestionDialog(getProgressDialog(), title, message, getMainFrame(), actionChoices, 0);
    // Cancel or close dialog stops this job
    DialogAction userChoice = waitForUserResponse(dialog);
    if (userChoice == QuestionDialog.DIALOG_DISPOSED_ACTION || userChoice == FileJobAction.CANCEL)
        interrupt();
    else // Keep 'skip all' choice for further error and return SKIP
    if (userChoice == FileJobAction.SKIP_ALL) {
        autoSkipErrors = true;
        return FileJobAction.SKIP;
    }
    return userChoice;
}
Also used : DialogAction(com.mucommander.ui.dialog.DialogAction) QuestionDialog(com.mucommander.ui.dialog.QuestionDialog)

Aggregations

DialogAction (com.mucommander.ui.dialog.DialogAction)22 IOException (java.io.IOException)13 AbstractFile (com.mucommander.commons.file.AbstractFile)10 FileCollisionDialog (com.mucommander.ui.dialog.file.FileCollisionDialog)7 QuestionDialog (com.mucommander.ui.dialog.QuestionDialog)6 JFileChooser (javax.swing.JFileChooser)3 InformationPane (com.mucommander.ui.layout.InformationPane)2 MainFrame (com.mucommander.ui.main.MainFrame)2 WarnUserException (com.mucommander.viewer.WarnUserException)2 Cursor (java.awt.Cursor)2 Frame (java.awt.Frame)2 InputStream (java.io.InputStream)2 ArrayList (java.util.ArrayList)2 JCheckBox (javax.swing.JCheckBox)2 VersionChecker (com.mucommander.VersionChecker)1 CredentialsMapping (com.mucommander.auth.CredentialsMapping)1 AuthException (com.mucommander.commons.file.AuthException)1 AuthenticationType (com.mucommander.commons.file.AuthenticationType)1 FileURL (com.mucommander.commons.file.FileURL)1 UnsupportedFileOperationException (com.mucommander.commons.file.UnsupportedFileOperationException)1