Java tutorial
/******************************************************************************* * Copyright (c) 2009 Andrey Loskutov. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * Contributor: Andrey Loskutov - initial API and implementation *******************************************************************************/ package de.loskutov.anyedit.actions; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.ui.IEditorInput; import de.loskutov.anyedit.AnyEditToolsPlugin; import de.loskutov.anyedit.IAnyEditConstants; import de.loskutov.anyedit.Messages; import de.loskutov.anyedit.util.EclipseUtils; public class SaveToFileAction extends AbstractOpenAction { private static final int CANCEL = -1; private static final int APPEND = 0; private static final int OVERRIDE = 1; private static String lastUsedFile; public SaveToFileAction() { super(); } @Override protected void handleAction(IDocument doc, ISelectionProvider selectionProvider, IEditorInput currentInput) { IPreferenceStore prefs = AnyEditToolsPlugin.getDefault().getPreferenceStore(); boolean shouldAsk = prefs.getBoolean(IAnyEditConstants.SAVE_TO_SHOW_OPTIONS); boolean shouldOpenEditor = prefs.getBoolean(IAnyEditConstants.SAVE_TO_OPEN_EDITOR); boolean ignoreSelection = prefs.getBoolean(IAnyEditConstants.SAVE_TO_IGNORE_SELECTION); ITextSelection selection = (ITextSelection) selectionProvider.getSelection(); boolean hasSelection = false; if (!ignoreSelection && selection != null && selection.getLength() > 0) { hasSelection = true; } else { selection = new TextSelection(doc, 0, doc.getLength()); } /* * Show dialog if prefs is set, asking for open in editor */ if (shouldAsk) { MessageDialogWithToggle dialogWithToggle = MessageDialogWithToggle.openYesNoCancelQuestion( AnyEditToolsPlugin.getShell(), Messages.SaveTo_ShouldOpen, hasSelection ? Messages.SaveTo_MessageSelection : Messages.SaveTo_MessageNoSelection, Messages.SaveTo_MessageToggle, false, prefs, IAnyEditConstants.SAVE_TO_SHOW_OPTIONS); int returnCode = dialogWithToggle.getReturnCode(); if (returnCode != IDialogConstants.YES_ID && returnCode != IDialogConstants.NO_ID) { return; } shouldOpenEditor = returnCode == IDialogConstants.YES_ID; if (!prefs.getBoolean(IAnyEditConstants.SAVE_TO_SHOW_OPTIONS)) { prefs.setValue(IAnyEditConstants.SAVE_TO_OPEN_EDITOR, shouldOpenEditor); } } /* * open file selection dialog (external) */ File file = getFileFromUser(); if (file == null) { return; } /* * if selected file exists, ask for override/append/another file */ int overrideOrAppend = checkForExisting(file); if (overrideOrAppend == CANCEL) { return; } IFile iFile = EclipseUtils.getIFile(new Path(file.getAbsolutePath())); /* * if selected file is in the workspace, checkout it or show error message */ if (iFile == null || !checkout(iFile, overrideOrAppend)) { return; } /* * save it */ doSave(doc, selection, file, overrideOrAppend); /* * and if option is on, open in editor */ if (shouldOpenEditor) { new DefaultOpenEditorParticipant().openEditor(doc, selectionProvider, currentInput, iFile); } } private void doSave(IDocument doc, ITextSelection selection, File file, int overrideOrAppend) { int startSelection = selection.getOffset(); int stopSelection = startSelection + selection.getLength(); int endLine = selection.getEndLine(); FileWriter fw; try { fw = new FileWriter(file, overrideOrAppend == APPEND); } catch (IOException e) { AnyEditToolsPlugin.errorDialog("Couldn't open file for writing: " + file, e); return; } try { for (int i = selection.getStartLine(); i <= endLine; i++) { IRegion lineInfo = doc.getLineInformation(i); boolean useStartLineOffset = lineInfo.getOffset() > startSelection; int startIndex; if (useStartLineOffset) { startIndex = 0; } else { startIndex = startSelection - lineInfo.getOffset(); } int stopIndex; boolean useStopLineOffset = lineInfo.getOffset() + lineInfo.getLength() > stopSelection; if (useStopLineOffset) { stopIndex = stopSelection - lineInfo.getOffset(); } else { stopIndex = lineInfo.getLength(); } String line = doc.get(lineInfo.getOffset() + startIndex, stopIndex - startIndex); if (line == null) { continue; } fw.write(line); String lineDelimiter = doc.getLineDelimiter(doc.getLineOfOffset(stopIndex)); if (lineDelimiter != null) { fw.write(lineDelimiter); } fw.flush(); } } catch (Exception e) { AnyEditToolsPlugin.errorDialog("Error during writing to file: " + file, e); } finally { try { fw.close(); } catch (IOException e) { AnyEditToolsPlugin.logError("Couldn't close file: " + file, e); } } } /** * @param file * non null * @param overrideOrAppend * @return true if file doesn't exist and was created or writable */ private boolean checkout(IFile file, int overrideOrAppend) { if (file.getLocation() == null) { File file2 = new File(file.getFullPath().toOSString()); if (!file2.exists()) { try { file2.createNewFile(); } catch (IOException e) { AnyEditToolsPlugin.errorDialog("Couldn't create file: " + file, e); return false; } } boolean canWrite = file2.canWrite(); if (!canWrite) { AnyEditToolsPlugin.errorDialog("File is read-only: " + file); } return canWrite; } try { if (overrideOrAppend == APPEND && file.exists()) { file.appendContents(new ByteArrayInputStream(new byte[0]), true, true, new NullProgressMonitor()); } else { if (file.exists()) { file.delete(true, new NullProgressMonitor()); } file.create(new ByteArrayInputStream(new byte[0]), true, new NullProgressMonitor()); } } catch (CoreException e) { AnyEditToolsPlugin.errorDialog("File is read-only: " + file, e); return false; } return true; } /** * @param file * non null * @return OVERRIDE if file not exists or exists and may be overriden, APPEND if it * exists and should be reused, CANCEL if action should be cancelled */ private int checkForExisting(File file) { if (file.exists()) { MessageDialog md = new MessageDialog(AnyEditToolsPlugin.getShell(), Messages.SaveTo_ShouldOpen, null, Messages.SaveTo_FileExists, MessageDialog.WARNING, new String[] { Messages.SaveTo_Append, Messages.SaveTo_Override, "Cancel" }, 0); int result = md.open(); switch (result) { case APPEND: // Append btn index return APPEND; case OVERRIDE: // Override btn index return OVERRIDE; default: return CANCEL; } } return OVERRIDE; } private File getFileFromUser() { FileDialog fd = new FileDialog(AnyEditToolsPlugin.getShell(), SWT.SAVE); if (lastUsedFile == null) { String property = System.getProperty("user.home"); fd.setFilterPath(property); } else { fd.setFileName(lastUsedFile); } fd.setFilterExtensions(new String[] { "*.log", "*.txt" }); String fileStr = fd.open(); if (fileStr != null) { lastUsedFile = fileStr; return new File(fileStr); } return null; } }