/* * $Id$ * * Copyright (c) 2004-2005 by the TeXlapse Team. * 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 */ package net.sourceforge.texlipse.properties; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import net.sourceforge.texlipse.TexlipsePlugin; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; /** * Names and helper methods for project properties. * * @author Kimmo Karlsson */ public class TexlipseProperties { // properties public static final String PACKAGE_NAME = TexlipsePlugin.class.getPackage().getName(); public static final String LATEX_PROJECT_SETTINGS_FILE = ".texlipse"; public static final String MAINFILE_PROPERTY = "mainTexFile"; public static final String OUTPUTFILE_PROPERTY = "outputFile"; public static final String BIBFILE_PROPERTY = "bibFiles"; public static final String BIBSTYLE_PROPERTY = "bibStyle"; public static final String SESSION_BIBLATEXMODE_PROPERTY = "biblatexMode"; public static final String SESSION_BIBLATEXBACKEND_PROPERTY = "biblatexBackend"; public static final String SESSION_BIBLATEXLOCALBIB_PROPERTY = "biblatexLocalBib"; public static final String PREAMBLE_PROPERTY = "preamble"; public static final String PARTIAL_BUILD_PROPERTY = "partialBuild"; public static final String PARTIAL_BUILD_FILE = "partialFile"; public static final String BIBFILES_CHANGED = "bibFilesChanged"; public static final String FORCED_REBUILD = "forcedRebuild"; public static final String OUTPUT_DIR_PROPERTY = "outputDir"; public static final String SOURCE_DIR_PROPERTY = "srcDir"; public static final String TEMP_DIR_PROPERTY = "tempDir"; public static final String BIBREF_DIR_PROPERTY = "bibrefDir"; public static final String MARK_OUTPUT_DERIVED_PROPERTY = "markDer"; public static final String MARK_TEMP_DERIVED_PROPERTY = "markTmpDer"; public static final String LANGUAGE_PROPERTY = "langSpell"; public static final String MAKEINDEX_STYLEFILE_PROPERTY = "makeIndSty"; public static final String BIBCONTAINER_PROPERTY = "bibContainer"; public static final String LABELCONTAINER_PROPERTY = "labelContainer"; public static final String COMCONTAINER_PROPERTY = "commandContainer"; // public static final String LISTENERS_PROPERTY = "changeListeners"; // preferences public static final String BIB_DIR = "bibDir"; public static final String TEMP_FILE_EXTS = "tempFileExts"; public static final String DERIVED_FILES = "derivedFiles"; public static final String FILE_LOCATION_PORT = "fileLocPort"; public static final String BUILD_ENV_SETTINGS = "buildEnvSet"; public static final String VIEWER_ENV_SETTINGS = "viewerEnvSet"; public static final String TEX_COMPLETION = "texCompletion"; public static final String TEX_COMPLETION_DELAY = "texDelay"; public static final String TEX_ITEM_COMPLETION = "texItemCompletion"; public static final String AUTO_PARSING = "autoParsing"; public static final String AUTO_PARSING_DELAY = "autoParsingDelay"; public static final String SECTION_CHECK = "sectionCheck"; public static final String BIB_COMPLETION = "bibCompletion"; public static final String BIB_COMPLETION_DELAY = "bibDelay"; public static final String BIB_FREQSORT = "bibFreqSort"; public static final String BIB_CODE_FOLDING = "bibCodeFolding"; public static final String BIB_FOLD_INITIAL = "bibFoldInitial"; public static final String BIB_STRING = "bibString"; public static final String INDENTATION = "indent"; public static final String INDENTATION_LEVEL = "indentLevel"; public static final String INDENTATION_TABS = "indentTabs"; public static final String INDENTATION_ENVS = "indentEnvs"; public static final String WORDWRAP_TYPE = "wrapType"; public static final String WORDWRAP_LENGTH = "lineLength"; public static final String WORDWRAP_TYPE_NONE = "none"; public static final String WORDWRAP_TYPE_SOFT = "soft"; public static final String WORDWRAP_TYPE_HARD = "hard"; public static final String WORDWRAP_DEFAULT = "wrapDefault"; // B----------------------------------- mmaus public static final String SMART_KEY_ENABLE = "ske"; public static final String STYLE_COMPLETION_SETTINGS = "styleCompletionSet"; // E----------------------------------- mmaus public static final String SMART_BACKSPACE = "smartBackspace"; //public static final String SMART_QUOTES = "smartQuotes"; //public static final String SMART_PARENS = "smartParens"; public static final String SMART_LDOTS = "smartLdots"; public static final String SMART_PARENS = "texBracketCompletion"; public static final String TEX_BRACKET_COMLETION_VALUE = "true"; public static final String SMART_QUOTES = "texReplaceQuotes"; public static final String TEX_REPLACE_QUOTES_VALUE = "true"; public static final String TEX_EDITOR_ANNOTATATIONS = "textEditorAnnotations"; public static final String CODE_FOLDING = "codeFolding"; public static final String CODE_FOLDING_PREAMBLE = "codeFoldingPreamble"; public static final String CODE_FOLDING_PART = "codeFoldingPart"; public static final String CODE_FOLDING_CHAPTER = "codeFoldingChapter"; public static final String CODE_FOLDING_SECTION = "codeFoldingSection"; public static final String CODE_FOLDING_SUBSECTION = "codeFoldingSubSection"; public static final String CODE_FOLDING_SUBSUBSECTION = "codeFoldingSubSubSection"; public static final String CODE_FOLDING_PARAGRAPH = "codeFoldingParagraph"; public static final String CODE_FOLDING_ENVS = "codeFoldingEnvs"; public static final String OUTLINE_PREAMBLE = "outlinePreamble"; public static final String OUTLINE_PART = "outlinePart"; public static final String OUTLINE_CHAPTER = "outlineChapter"; public static final String OUTLINE_SECTION = "outlineSection"; public static final String OUTLINE_SUBSECTION = "outlineSubSection"; public static final String OUTLINE_SUBSUBSECTION = "outlineSubSubSection"; public static final String OUTLINE_PARAGRAPH = "outlineParagraph"; public static final String OUTLINE_ENVS = "outlineEnvs"; public static final String BUILDER_NUMBER = "builderNum"; public static final String BUILDER_CONSOLE_OUTPUT = "builderConsole"; public static final String BUILD_BEFORE_VIEW = "buildBeforeView"; public static final String BUILDER_RETURN_FOCUS = "returnFocusOnPreivew"; public static final String BUILDER_PARSE_AUX_FILES = "builderParseAuxFiles"; public static final String BUILDER_FORCE_RETURN_FOCUS = "forceReturnFocusOnInverseSearch"; public static final String OUTPUT_FORMAT = "outputFormat"; public static final String OUTPUT_FORMAT_AUX = "aux"; public static final String INPUT_FORMAT_BIB = "bib"; public static final String INPUT_FORMAT_IDX = "idx"; public static final String OUTPUT_FORMAT_IDX = "ind"; public static final String INPUT_FORMAT_BCF = "bcf"; public static final String OUTPUT_FORMAT_BBL = "bbl"; public static final String INPUT_FORMAT_NOMENCL = "nlo"; public static final String OUTPUT_FORMAT_NOMENCL = "nls"; public static final String INPUT_FORMAT_TEX = "tex"; public static final String OUTPUT_FORMAT_DVI = "dvi"; public static final String OUTPUT_FORMAT_PS = "ps"; public static final String OUTPUT_FORMAT_PDF = "pdf"; // session variables public static final String SESSION_BIBTEX_RERUN = "rerunBibtex"; public static final String SESSION_LATEX_RERUN = "rerunLatex"; public static final String SESSION_MAKEINDEX_RERUN = "rerunMakeindex"; public static final String SESSION_PROPERTIES_LOAD = "propsLoaded"; // attribute for session properties to hold the viewer process object public static final String SESSION_ATTRIBUTE_VIEWER = "active.viewer"; public static final String SESSION_PROJECT_FULLOUTLINE = "project.fullTexParser"; public static final String ECLIPSE_BUILDIN_SPELLCHECKER = "eclipseBuildInSpellChecker"; public static final String SPELLCHECKER_DICT_DIR = "spellcheckerDictDir"; public static final String SPELLCHECKER_CUSTOM_DICT_DIR = "spellcheckerCustomDictDir"; public static final String SPELLCHECKER_IGNORE_COMMENTS = "spellcheckerIgnoreComments"; public static final String SPELLCHECKER_IGNORE_MATH = "spellcheckerIgnoreMath"; public static final String SPELLCHECKER_IGNORE_MIXED_CASE = "spellcheckerIgnoreMixedCase"; /** * A named preference that controls whether bracket matching highlighting is turned on or off. * <p> * Value is of type <code>Boolean</code>. * </p> */ public final static String MATCHING_BRACKETS = "matchingBrackets"; //$NON-NLS-1$ /** * A named preference that holds the color used to highlight matching brackets. * <p> * Value is of type <code>String</code>. A RGB color value encoded as a string using class <code>PreferenceConverter</code> * </p> * * @see org.eclipse.jface.resource.StringConverter * @see org.eclipse.jface.preference.PreferenceConverter */ public final static String MATCHING_BRACKETS_COLOR = "matchingBracketsColor"; //$NON-NLS-1$ /** * Returns the contents of a file in the project. * * @param resource The file resource to read from * @return Contents of the given file in string form or null if the given resource wasn't a file * @throws IOException if an error occurs */ public static String getFileContents(IResource resource) throws IOException { // IFolder srcDir = getProjectSourceDir(project); // IFile file = srcDir.getFile(filename); if (resource.getType() != IResource.FILE) return null; File f = resource.getLocation().toFile(); FileInputStream in = new FileInputStream(f); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buff = new byte[4096]; int len = 0; while ((len = in.read(buff)) == buff.length) { out.write(buff); } if (len > 0) { out.write(buff, 0, len); } in.close(); String contents = null; try { // cast will succeed, because we have already checked for it to be a file contents = out.toString(((IFile) resource).getCharset()); } catch (UnsupportedEncodingException e) { // if the correct encoding is not supported, try with default contents = out.toString(); } catch (CoreException e) { // should not happen } out.close(); return contents; } /** * Returns an array of file handles to all files in project's source * directory, which have one of the following extensions: * tex,ltx,bib,idx. * This method recursively checks all subdirectories. * * @param project the current project * @return an array of file handles */ public static IResource[] getAllProjectFiles(IProject project) { IContainer sourceDir = getProjectSourceDir(project); return (IResource[]) getAllMemberFiles(sourceDir, new String[] { "tex", "ltx", "bib", "idx" }).toArray(new IResource[0]); } /** * This method returns a list of files under the given directory * or its subdirectories. The directories themselves are not returned. * * @param dir a directory * @return list of IResource objects representing the files under * the given directory and its subdirectories */ public static List<IResource> getAllMemberFiles(IContainer dir, String[] exts) { List<IResource> list = new ArrayList<IResource>(); IResource[] arr = null; try { arr = dir.members(); } catch (CoreException e) { } for (int i = 0; arr != null && i < arr.length; i++) { if (arr[i].getType() == IResource.FOLDER) { list.addAll(getAllMemberFiles((IFolder)arr[i], exts)); } else { for (int j = 0; j < exts.length; j++) { if (exts[j].equals(arr[i].getFileExtension())) { list.add(arr[i]); break; } } } } return list; } /** * Returns the name of the output file, if partial building is turned on, the name of * the partial build file will be returned. * @param project * @return Name of the output file without path */ public static String getOutputFileName (IProject project) { String outputFileName = getProjectProperty(project, TexlipseProperties.OUTPUTFILE_PROPERTY); //Check for partial build Object s = getProjectProperty(project, TexlipseProperties.PARTIAL_BUILD_PROPERTY); if (s != null) { IFile tmpFile = (IFile)getSessionProperty(project, TexlipseProperties.PARTIAL_BUILD_FILE); if (tmpFile != null){ String fmtProp = getProjectProperty(project, TexlipseProperties.OUTPUT_FORMAT); String name = tmpFile.getName(); name = name.substring(0, name.lastIndexOf('.')) + "." + fmtProp; outputFileName = name; } } return outputFileName; } /** * Find the project's main source file. The file may or may not exist. * @param project the current project * @return a handle to the project's main source file, or null if main file not set */ public static IFile getProjectSourceFile(IProject project) { //IContainer folder = getProjectSourceDir(project); String dir = TexlipseProperties.getProjectProperty(project, TexlipseProperties.SOURCE_DIR_PROPERTY); String mainFile = getProjectProperty(project, MAINFILE_PROPERTY); if (mainFile != null) { if (dir != null && dir.length() > 0) { return project.getFolder(dir).getFile(mainFile); } return project.getFile(mainFile); } return null; } /** * Find the project's source directory. * @param project the current project * @return a handle to the project's source directory or null if source directory is * the same as project directory */ public static IContainer getProjectSourceDir(IProject project) { String dir = TexlipseProperties.getProjectProperty(project, TexlipseProperties.SOURCE_DIR_PROPERTY); if (dir != null && dir.length() > 0) { return project.getFolder(dir); } else return project; } /** * Find the project's output file. The file may or may not exist. This is independent * of partial build turned on or off. * @param project the current project * @return a handle to the project's output file or null if output file not set */ public static IFile getProjectOutputFile(IProject project) { IFolder folder = getProjectOutputDir(project); if (folder == null) { return project.getFile(getProjectProperty(project, OUTPUTFILE_PROPERTY)); } return folder.getFile(getProjectProperty(project, OUTPUTFILE_PROPERTY)); } /** * Find the project's output directory. * @param project the current project * @return a handle to the project's output directory or null if output directory is * the same as project's directory */ public static IFolder getProjectOutputDir(IProject project) { String dir = TexlipseProperties.getProjectProperty(project, TexlipseProperties.OUTPUT_DIR_PROPERTY); if (dir != null && dir.length() > 0) { return project.getFolder(dir); } return null; } /** * Find the project's temporary files directory. * @param project the current project * @return a handle to the project's temp directory or null if temp directory is * the same as project's directory */ public static IFolder getProjectTempDir(IProject project) { String dir = TexlipseProperties.getProjectProperty(project, TexlipseProperties.TEMP_DIR_PROPERTY); if (dir != null && dir.length() > 0) { return project.getFolder(dir); } return null; } /** * Loads the project properties from a file. * * @param project current project */ public static void loadProjectProperties(IProject project) { IFile settingsFile = project.getFile(LATEX_PROJECT_SETTINGS_FILE); if (!settingsFile.exists()) { return; } Properties prop = new Properties(); try { prop.load(settingsFile.getContents()); } catch (CoreException e) { TexlipsePlugin.log("Loading project property file", e); return; } catch (IOException e) { TexlipsePlugin.log("Loading project property file", e); return; } setSessionProperty(project, SESSION_PROPERTIES_LOAD, Long.valueOf(System.currentTimeMillis())); setProjectProperty(project, MAINFILE_PROPERTY, prop.getProperty(MAINFILE_PROPERTY, "")); setProjectProperty(project, OUTPUTFILE_PROPERTY, prop.getProperty(OUTPUTFILE_PROPERTY, "")); setProjectProperty(project, SOURCE_DIR_PROPERTY, prop.getProperty(SOURCE_DIR_PROPERTY, "")); setProjectProperty(project, OUTPUT_DIR_PROPERTY, prop.getProperty(OUTPUT_DIR_PROPERTY, "")); setProjectProperty(project, TEMP_DIR_PROPERTY, prop.getProperty(TEMP_DIR_PROPERTY, "")); setProjectProperty(project, BIBREF_DIR_PROPERTY, prop.getProperty(BIBREF_DIR_PROPERTY, "")); setProjectProperty(project, BUILDER_NUMBER, prop.getProperty(BUILDER_NUMBER, "")); setProjectProperty(project, OUTPUT_FORMAT, prop.getProperty(OUTPUT_FORMAT, "")); setProjectProperty(project, MARK_TEMP_DERIVED_PROPERTY, prop.getProperty(MARK_TEMP_DERIVED_PROPERTY, "true")); setProjectProperty(project, MARK_OUTPUT_DERIVED_PROPERTY, prop.getProperty(MARK_OUTPUT_DERIVED_PROPERTY, "true")); setProjectProperty(project, LANGUAGE_PROPERTY, prop.getProperty(LANGUAGE_PROPERTY, "")); setProjectProperty(project, MAKEINDEX_STYLEFILE_PROPERTY, prop.getProperty(MAKEINDEX_STYLEFILE_PROPERTY, "")); } /** * Saves the project properties to a file. * * @param project current project */ public static void saveProjectProperties(IProject project) { IFile settingsFile = project.getFile(LATEX_PROJECT_SETTINGS_FILE); // check if we can write to the properties file if (settingsFile.isReadOnly()) { IWorkbench workbench = PlatformUI.getWorkbench(); workbench.getDisplay().asyncExec(new Runnable() { public void run() { IWorkbench workbench = PlatformUI.getWorkbench(); // show an error message is the file is not writable MessageDialog dialog = new MessageDialog(workbench.getActiveWorkbenchWindow().getShell(), TexlipsePlugin.getResourceString("projectSettingsReadOnlyTitle"), null, TexlipsePlugin.getResourceString("projectSettingsReadOnly"), MessageDialog.ERROR, new String[] { IDialogConstants.OK_LABEL }, 0); dialog.open(); }}); return; } Properties prop = new Properties(); prop.setProperty(MAINFILE_PROPERTY, getProjectProperty(project, MAINFILE_PROPERTY)); prop.setProperty(OUTPUTFILE_PROPERTY, getProjectProperty(project, OUTPUTFILE_PROPERTY)); prop.setProperty(SOURCE_DIR_PROPERTY, getProjectProperty(project, SOURCE_DIR_PROPERTY)); prop.setProperty(OUTPUT_DIR_PROPERTY, getProjectProperty(project, OUTPUT_DIR_PROPERTY)); prop.setProperty(TEMP_DIR_PROPERTY, getProjectProperty(project, TEMP_DIR_PROPERTY)); prop.setProperty(BIBREF_DIR_PROPERTY, getProjectProperty(project, BIBREF_DIR_PROPERTY)); prop.setProperty(BUILDER_NUMBER, getProjectProperty(project, BUILDER_NUMBER)); prop.setProperty(OUTPUT_FORMAT, getProjectProperty(project, OUTPUT_FORMAT)); prop.setProperty(MARK_TEMP_DERIVED_PROPERTY, getProjectProperty(project, MARK_TEMP_DERIVED_PROPERTY)); prop.setProperty(MARK_OUTPUT_DERIVED_PROPERTY, getProjectProperty(project, MARK_OUTPUT_DERIVED_PROPERTY)); prop.setProperty(LANGUAGE_PROPERTY, getProjectProperty(project, LANGUAGE_PROPERTY)); prop.setProperty(MAKEINDEX_STYLEFILE_PROPERTY, getProjectProperty(project, MAKEINDEX_STYLEFILE_PROPERTY)); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { prop.store(baos, "TeXlipse project settings"); } catch (IOException e) {} NullProgressMonitor mon = new NullProgressMonitor(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); try { if (settingsFile.exists()) { settingsFile.setContents(bais, true, false, mon); } else { settingsFile.create(bais, true, mon); } } catch (CoreException e) { TexlipsePlugin.log("Saving project property file", e); } } /** * Check if the project properties should be read from disk. * * @param project current project * @return true, if the project properties should be read from disk */ public static boolean isProjectPropertiesFileChanged(IProject project) { IResource settingsFile = project.findMember(LATEX_PROJECT_SETTINGS_FILE); if (settingsFile == null) { return false; } Long lastLoadTime = (Long) getSessionProperty(project, SESSION_PROPERTIES_LOAD); if (lastLoadTime == null) { return true; } long timeStamp = settingsFile.getLocalTimeStamp(); return timeStamp > lastLoadTime.longValue(); } /** * Read a project property. * * @param project the current project * @param property the name of the property * @return the value of the named project property or null if the property is not found */ public static String getProjectProperty(IResource project, String property) { String value = null; try { value = project.getPersistentProperty(new QualifiedName(TexlipseProperties.PACKAGE_NAME, property)); } catch (CoreException e) { // do nothing } return value; } /** * Write a project property. This value will be stored to the project settings file on disk. * * @param project the current project * @param property the name of the property * @param value new value for the property */ public static void setProjectProperty(IResource project, String property, String value) { try { project.setPersistentProperty(new QualifiedName(TexlipseProperties.PACKAGE_NAME, property), value); } catch (CoreException e) { // do nothing } } /** * Read a session property. * * @param project the current project * @param property the name of the property * @return the value of session property or null if the property is not found */ public static Object getSessionProperty(IResource project, String property) { Object value = null; try { value = project.getSessionProperty(new QualifiedName(TexlipseProperties.PACKAGE_NAME, property)); } catch (CoreException e) { // do nothing } return value; } /** * Write a session property. This value will be stored only in memory as long as Eclipse is still running. * * @param project the current project * @param property the name of the property * @param value new value for the session property */ public static void setSessionProperty(IResource project, String property, Object value) { try { project.setSessionProperty(new QualifiedName(TexlipseProperties.PACKAGE_NAME, property), value); } catch (CoreException e) { // do nothing } } }