diff --git a/plugin/.project b/plugin/.project new file mode 100644 index 00000000..1b18c44d --- /dev/null +++ b/plugin/.project @@ -0,0 +1,17 @@ + + + SQDev + + + + + + org.eclipse.pde.UpdateSiteBuilder + + + + + + org.eclipse.pde.UpdateSiteNature + + diff --git a/plugin/Raven.SQDev.Util/bin/raven/sqdev/util/StringUtils.class b/plugin/Raven.SQDev.Util/bin/raven/sqdev/util/StringUtils.class index d5b7b83b..9a77e2cc 100644 Binary files a/plugin/Raven.SQDev.Util/bin/raven/sqdev/util/StringUtils.class and b/plugin/Raven.SQDev.Util/bin/raven/sqdev/util/StringUtils.class differ diff --git a/plugin/Raven.SQDev.Util/build.properties b/plugin/Raven.SQDev.Util/build.properties index cf574e75..3ca12925 100644 --- a/plugin/Raven.SQDev.Util/build.properties +++ b/plugin/Raven.SQDev.Util/build.properties @@ -3,5 +3,4 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ resources/ -src.includes = resources/,\ - build.properties +src.includes = resources/ diff --git a/plugin/Raven.SQDev.Util/src/raven/sqdev/util/StringUtils.java b/plugin/Raven.SQDev.Util/src/raven/sqdev/util/StringUtils.java index 210e39c8..17553e81 100644 --- a/plugin/Raven.SQDev.Util/src/raven/sqdev/util/StringUtils.java +++ b/plugin/Raven.SQDev.Util/src/raven/sqdev/util/StringUtils.java @@ -1,22 +1,37 @@ package raven.sqdev.util; +import java.util.ArrayList; + /** * A class containing various static String functions + * * @author Raven - * + * */ public class StringUtils { + /** + * An array containing all sort of brackets + */ + public static final char[] BRACKETS = { '(', ')', '[', ']', '{', '}' }; + /** + * An array containing all special characters that are allowed in project names + */ + public static final char[] ALLOWED_SPECIAL_CHARACTER_PROJECTNAME = {'.', ' ', '_'}; + /** * Counts the occurence of a String in another String - * @param str The String to be searched - * @param match The String to be searched for + * + * @param str + * The String to be searched + * @param match + * The String to be searched for * @return How often the searched string has been found */ public static int countMatches(String str, String match) { int counter = 0; - while(str.contains(match)) { + while (str.contains(match)) { counter++; str = str.substring(str.indexOf(match) + match.length()); @@ -25,4 +40,138 @@ public static int countMatches(String str, String match) { return counter; } + /** + * Checks if the given name is valid.
+ * A name is considered valid if it starts with a letter and then continues + * with either letters or digits or any character specified in + * allowedChars.
+ * If you don't want any additional characters to be allowed just pass + * null + * + * @param name + * The name to validate + * @param allowedChars + * A list of additional characters that are allowed for this + * name. May be null + */ + public static boolean isValidName(String name, ArrayList allowedChars) { + if (name.isEmpty() || name == null) { + // an empty name can't be valid + return false; + } + + if (allowedChars == null) { + // initialize empty list + allowedChars = new ArrayList(); + } + + char[] chars = name.toCharArray(); + + if (!Character.isLetter(chars[0])) { + // name has to start with a letter + return false; + } + + for (char currentChar : chars) { + if (!Character.isLetterOrDigit(currentChar)) { + // check if special character is allowed + if (!allowedChars.contains((Character) currentChar)) { + return false; + } + } + } + + return true; + } + + /** + * Checks for the reason the given name is invalid. + * + * @param name + * The invalid name (mustn't be valid) + * @param allowedChars + * A list of additional characters that are allowed for this + * name. May be null + * @return The error message explaining why the given name isn't valid. + */ + public static String whyIsInvalidName(String name, ArrayList allowedChars) { + if (isValidName(name, allowedChars) || name == null) { + // if it is a valid name no error message can be found + return null; + } + + if(name.isEmpty()) { + return "A name must not be empty!"; + } + + if (allowedChars == null) { + // initialize empty list + allowedChars = new ArrayList(); + } + + char[] chars = name.toCharArray(); + + if (!Character.isLetter(chars[0])) { + // name has to start with a letter + return "A name has to start with a letter!"; + } + + for (char currentChar : chars) { + if (!Character.isLetterOrDigit(currentChar)) { + // check if special character is allowed + if (!allowedChars.contains((Character) currentChar)) { + return "Invalid character '" + currentChar + "' in \"" + name + "\"!"; + } + } + } + + // one of the above has to have matched + return null; + } + + /** + * Checks if the given name is a valid project name + * @param name The name to check + * @see #isValidName + */ + public static boolean isValidProjectName(String name) { + ArrayList allowedChars = new ArrayList(); + + for(char currentChar : ALLOWED_SPECIAL_CHARACTER_PROJECTNAME) { + allowedChars.add((Character) currentChar); + } + + return isValidName(name, allowedChars); + } + + /** + * Get the error code for why the name isn't valid + * @param name The name to check (mustn't be valid) + * @see #whyIsInvalidName + */ + public static String whyIsInvalidProjectName(String name) { + ArrayList allowedChars = new ArrayList(); + + for(char currentChar : ALLOWED_SPECIAL_CHARACTER_PROJECTNAME) { + allowedChars.add((Character) currentChar); + } + + return whyIsInvalidName(name, allowedChars); + } + + /** + * Checks if the given character is a bracket + * @param c + * @see #BRACKETS + */ + public static boolean isBracket(char c) { + for(char currentChar : BRACKETS) { + if(currentChar == c) { + return true; + } + } + + return false; + } + } diff --git a/plugin/Raven.SQDev.Wizards/META-INF/MANIFEST.MF b/plugin/Raven.SQDev.Wizards/META-INF/MANIFEST.MF index 65819930..571a904c 100644 --- a/plugin/Raven.SQDev.Wizards/META-INF/MANIFEST.MF +++ b/plugin/Raven.SQDev.Wizards/META-INF/MANIFEST.MF @@ -12,6 +12,8 @@ Require-Bundle: org.eclipse.core.runtime, raven.sqdev.editors, org.eclipse.ui.workbench, org.eclipse.ui.editors, - raven.sqdev.util;bundle-version="0.1.0" + raven.sqdev.util;bundle-version="0.1.0", + org.eclipse.swt, + org.eclipse.jface Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy diff --git a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/exceptions/FailedAtCreatingFileException.class b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/exceptions/FailedAtCreatingFileException.class new file mode 100644 index 00000000..6c7516b5 Binary files /dev/null and b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/exceptions/FailedAtCreatingFileException.class differ diff --git a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/EProjectType.class b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/EProjectType.class new file mode 100644 index 00000000..97fed260 Binary files /dev/null and b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/EProjectType.class differ diff --git a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizard.class b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizard.class new file mode 100644 index 00000000..d0f3ba20 Binary files /dev/null and b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizard.class differ diff --git a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage$1.class b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage$1.class new file mode 100644 index 00000000..b6656970 Binary files /dev/null and b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage$1.class differ diff --git a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage$2.class b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage$2.class new file mode 100644 index 00000000..403d675f Binary files /dev/null and b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage$2.class differ diff --git a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage.class b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage.class new file mode 100644 index 00000000..e9484354 Binary files /dev/null and b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage.class differ diff --git a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.class b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.class index bceca326..cd551479 100644 Binary files a/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.class and b/plugin/Raven.SQDev.Wizards/bin/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.class differ diff --git a/plugin/Raven.SQDev.Wizards/plugin.xml b/plugin/Raven.SQDev.Wizards/plugin.xml index bb605d10..d006b6f1 100644 --- a/plugin/Raven.SQDev.Wizards/plugin.xml +++ b/plugin/Raven.SQDev.Wizards/plugin.xml @@ -8,11 +8,23 @@ name="SQDev"> + name="New SQF file" + project="false"> + + + + diff --git a/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/exceptions/FailedAtCreatingFileException.java b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/exceptions/FailedAtCreatingFileException.java new file mode 100644 index 00000000..15441a5d --- /dev/null +++ b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/exceptions/FailedAtCreatingFileException.java @@ -0,0 +1,31 @@ +package raven.sqdev.wizards.exceptions; + +import raven.sqdev.exceptions.SQDevException; + +public class FailedAtCreatingFileException extends SQDevException { + + /** + * + */ + private static final long serialVersionUID = 3841747047339787544L; + + public FailedAtCreatingFileException() {} + + public FailedAtCreatingFileException(String message) { + super(message); + } + + public FailedAtCreatingFileException(Throwable cause) { + super(cause); + } + + public FailedAtCreatingFileException(String message, Throwable cause) { + super(message, cause); + } + + public FailedAtCreatingFileException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/EProjectType.java b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/EProjectType.java new file mode 100644 index 00000000..be9613fd --- /dev/null +++ b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/EProjectType.java @@ -0,0 +1,198 @@ +package raven.sqdev.wizards.sqdevProject; + +import java.io.ByteArrayInputStream; + +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.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.part.FileEditorInput; + +import raven.sqdev.editors.BasicTextEditor; +import raven.sqdev.wizards.exceptions.FailedAtCreatingFileException; + +public enum EProjectType { + SQF("SQF", "Creates a new SQF-project"), OOS("OOS", "Creates a new OOS-project"), MIXED("Mixed", + "Creates new project that will contain both: SQF and OOS"); + + private String displayName; + private String creationDescription; + + private final String INITIAL_SQF_CONTENT = "scopeName = \"init\";\n\n"; + + private EProjectType(String name, String creationDescription) { + setDisplayName(name); + setCreationDescription(creationDescription); + } + + /** + * Gets the enum for the given index + * + * @param index + * The index of the enum entry + * @return + */ + public static EProjectType getIndex(int index) { + if (index > EProjectType.values().length) { + throw new IllegalArgumentException( + "Can't access index " + index + " for EProjectType!"); + } + + return EProjectType.values()[index]; + } + + /** + * Creates the project with the given name in the given + * IworkspaceRoot
+ * This mehtod assumes that the given location is accessible and the given + * name is valid + * + * @param projectName + * The name of the project to be created + * @param root + * The location where the project should be created + */ + public void create(String projectName, IWorkspaceRoot root) { + IProject project = root.getProject(projectName); + + // create the project; If anything goes wrong return + if (!project.exists()) { + try { + project.create(null); + } catch (CoreException e) { + try { + // rethrow with custom exception + throw new FailedAtCreatingFileException(e); + } catch (FailedAtCreatingFileException e1) { + e1.printStackTrace(); + return; + } + } + } else { + try { + throw new FailedAtCreatingFileException( + "A project with the name \"" + projectName + "\" does already exist!"); + } catch (FailedAtCreatingFileException e) { + e.printStackTrace(); + return; + } + } + + switch (this) { + case MIXED: + break; + case OOS: + break; + case SQF: + createSQFProject(project, root); + break; + default: + break; + } + } + + /** + * Creates an SQF project + * + * @param project + * The project the content should be added to + * @param root + * The root of the project + */ + private void createSQFProject(IProject project, IWorkspaceRoot root) { + IFolder scriptFolder = project.getFolder("scripts"); + IFile initFile = project.getFile("init.sqf"); + + try { + // open the project + project.open(new NullProgressMonitor()); + } catch (CoreException e2) { + e2.printStackTrace(); + } + + if (!scriptFolder.exists()) { + // create scriptFolder + try { + scriptFolder.create(IResource.NONE, true, null); + } catch (CoreException e) { + try { + throw new FailedAtCreatingFileException(e); + } catch (FailedAtCreatingFileException e1) { + e1.printStackTrace(); + } + } + } + + if (!initFile.exists()) { + try { + initFile.create(getSQFInitFileContent(), IResource.NONE, null); + } catch (CoreException e) { + try { + throw new FailedAtCreatingFileException(e); + } catch (FailedAtCreatingFileException e1) { + e1.printStackTrace(); + } + } + } + + // open the init file + IWorkbench wb = PlatformUI.getWorkbench(); + IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); + IWorkbenchPage page = win.getActivePage(); + + IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry() + .getDefaultEditor(initFile.getName()); + + try { + page.openEditor(new FileEditorInput(initFile), desc.getId()); + } catch (PartInitException e) { + e.printStackTrace(); + } + + // set initial caret offset so that it is at the end of the file + try { + BasicTextEditor editor = (BasicTextEditor) IDE.openEditor(page, initFile, true); + + editor.selectAndReveal(INITIAL_SQF_CONTENT.length(), 0); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + + /** + * Creates an InputStream with the initial content of the init.sqf + * + * @return + */ + private ByteArrayInputStream getSQFInitFileContent() { + byte[] content = INITIAL_SQF_CONTENT.getBytes(); + + return new ByteArrayInputStream(content); + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getCreationDescription() { + return creationDescription; + } + + public void setCreationDescription(String creationDescription) { + this.creationDescription = creationDescription; + } +} diff --git a/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/SQDevProjectWizard.java b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/SQDevProjectWizard.java new file mode 100644 index 00000000..044c076f --- /dev/null +++ b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/SQDevProjectWizard.java @@ -0,0 +1,41 @@ +package raven.sqdev.wizards.sqdevProject; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IWorkbench; + +public class SQDevProjectWizard extends Wizard implements INewWizard { + private SQDevProjectWizardPage page; + + public SQDevProjectWizard() { + super(); + } + + public void addPages() { + page = new SQDevProjectWizardPage("SQDevProjectWizardPage"); + addPage(page); + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + + } + + @Override + public boolean performFinish() { + String projectName = page.getProjectName(); + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + + page.getProjectType().create(projectName, root); + + return true; + + } + +} diff --git a/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage.java b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage.java new file mode 100644 index 00000000..8d18943e --- /dev/null +++ b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqdevProject/SQDevProjectWizardPage.java @@ -0,0 +1,163 @@ +package raven.sqdev.wizards.sqdevProject; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import raven.sqdev.util.StringUtils; + +public class SQDevProjectWizardPage extends WizardPage { + + private Text nameText; + private Combo typeCombo; + private EProjectType projectType; + + public SQDevProjectWizardPage(String pageName) { + super(pageName); + setTitle("New SQDev project"); + } + + public SQDevProjectWizardPage(String pageName, String title, ImageDescriptor titleImage) { + super(pageName, title, titleImage); + } + + @Override + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + GridLayout layout = new GridLayout(); + container.setLayout(layout); + layout.numColumns = 2; + layout.verticalSpacing = 9; + + Label nameLabel = new Label(container, SWT.NULL); + nameLabel.setText("&Project name:"); + + setNameText(new Text(container, SWT.BORDER | SWT.SINGLE)); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + getNameText().setLayoutData(gd); + getNameText().addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + dialogChanged(); + } + }); + + Label typeLabel = new Label(container, SWT.NULL); + typeLabel.setText("&Project type:"); + + typeCombo = new Combo(container, SWT.DROP_DOWN | SWT.READ_ONLY); + + for (EProjectType current : EProjectType.values()) { + typeCombo.add(current.getDisplayName()); + } + + if (EProjectType.values().length > 0) { + typeCombo.select(0); + setProjectType(EProjectType.getIndex(0)); + } + + typeCombo.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + setProjectType(EProjectType.getIndex(typeCombo.getSelectionIndex())); + dialogChanged(); + } + }); + + getNameText().setFocus(); + dialogChanged(); + setControl(container); + } + + /** + * Gets notified whenever the dialog has changed + */ + private void dialogChanged() { + validate(); + + setDescription(getProjectType().getCreationDescription()); + + } + + /** + * Validates the given input + */ + private void validate() { + // check if the cosen project type is valid + if (getProjectType() != EProjectType.SQF) { + // any other prject type is not yet implemented + updateStatus("The projectType \"" + getProjectType().getDisplayName() + + "\" is not yet available!"); + return; + } + + // check if the entered project name is valid + if(!StringUtils.isValidProjectName(getProjectName())) { + updateStatus(StringUtils.whyIsInvalidProjectName(getProjectName())); + return; + } + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + IProject project = root.getProject(getProjectName()); + + if(project.exists()) { + updateStatus("A project with the given name does already exist!"); + return; + } + + // remove any error message and make the page finishable + updateStatus(null); + } + + /** + * Sets the error message for this wizard page. It will automatically + * prevent the page from being finished as long as there is a error message. + * If you want to make remove the error message pass null as an + * argument which will make the page finishable again. + * + * @param message + * The message to be displayed + */ + public void updateStatus(String message) { + setErrorMessage(message); + setPageComplete(message == null); + } + + public EProjectType getProjectType() { + return projectType; + } + + private void setProjectType(EProjectType projectType) { + this.projectType = projectType; + } + + private Text getNameText() { + return nameText; + } + + private void setNameText(Text nameText) { + this.nameText = nameText; + } + + /** + * Gets the name the user has chosen for the project to be created + * @return + */ + public String getProjectName() { + return getNameText().getText(); + } + +} diff --git a/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.java b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.java index 5d603555..5329ea6a 100644 --- a/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.java +++ b/plugin/Raven.SQDev.Wizards/src/raven/sqdev/wizards/sqfNewFileWizard/SqfNewFileWizardPage.java @@ -37,7 +37,7 @@ public class SqfNewFileWizardPage extends WizardPage { * @param pageName */ public SqfNewFileWizardPage(ISelection selection) { - super("wizardPage"); + super("newSqfFileWizardPage"); setTitle("New SQF file"); setDescription("This wizard creates a new file with *.sqf extension"); this.selection = selection; diff --git a/plugin/Raven.SQDev/feature.xml b/plugin/Raven.SQDev/feature.xml index 29777a6c..6add4c03 100644 --- a/plugin/Raven.SQDev/feature.xml +++ b/plugin/Raven.SQDev/feature.xml @@ -6,11 +6,23 @@ provider-name="Raven"> - SQDev brings SQF support for eclipse + SQDev provides a set of features to facilitate the development of scripts for ArmA. SQDev is published under the MIT License + + + +The MIT License (MIT) + +Copyright (c) 2015 Raven + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,6 +35,7 @@ + + + + + + +