1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-15 00:02:49 +03:00

Merge branch 'master' into esp8266

* master: (414 commits)
  Don't export sketch if the underlying core does not support it. Fixes #3171
  RSyntaxTextArea: using a modified version, tracked at https://github.com/arduino/RSyntaxTextArea. Fixes #3099
  Updated keywords.txt
  New editor on MacOSX: since CMD+J is known as "jump to selection" and the editor has no such feature, CMD+J is disabled on mac. See #3098
  Old Preferences class remains for backwards compatibility as a delegate for PreferencesData
  New Preferences window: renders fine on every OS and it's easier to adapt using NetBeans as visual editor. Fixes #3140
  Remove spawn from exec command
  Removed redundant call to File.deleteIfExists()
  Removed buggy redundant check in FileUtils.deleteIfExists()
  Restored current line/current selected lines display on lower left of the IDE. Fixes #3134
  Updated cursor.ino
  New editor on MacOSX: restored CMD+E for finding selected text
  New editor on MacOSX: CMD+UP/DOWN moves cursor to start or end of sketch. See #3098
  New editor on MacOSX: CMD+BACKSPACE deletes current line until cursor position, ALT+BACKSPACE deletes previous word. See #3098
  ArduinoIDE is in the default package. Removed
  Fixes  #2969:
  Fix Uncategorized warning message
  New editor: ALT+ BACKSPACE deletes next word (OSX only). See #3098
  New editor: ALT+ UP/DOWN move current line only if "editor.advanced" (hidden pref) is true. Fixes #3101
  New editor: mark occurrences enable when "editor.advanced" (hidden pref) is true. Fixes #3102
  ...

Conflicts:
	.gitignore
	build/build.xml
	hardware/esp8266com/esp8266/libraries/ESP8266WiFi/keywords.txt
	hardware/esp8266com/esp8266/libraries/ESP8266WiFi/library.properties
	hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h
	libraries/WiFi/README.adoc
	libraries/WiFi/src/WiFi.cpp
	libraries/WiFi/src/WiFiClient.cpp
	libraries/WiFi/src/WiFiClient.h
	libraries/WiFi/src/WiFiServer.cpp
	libraries/WiFi/src/WiFiUdp.cpp
This commit is contained in:
Ivan Grokhotkov
2015-05-18 14:54:06 +03:00
644 changed files with 37518 additions and 12166 deletions

View File

@ -10,7 +10,7 @@
<classpathentry kind="lib" path="app/test-lib/junit-4.11.jar"/>
<classpathentry kind="lib" path="app/test-lib/fest-assert-1.2.jar"/>
<classpathentry kind="lib" path="app/test-lib/fest-reflect-1.2.jar"/>
<classpathentry kind="lib" path="app/test-lib/fest-swing-1.2.jar" sourcepath="/home/megabug/git/fest-swing-1.2-sources.jar"/>
<classpathentry kind="lib" path="app/test-lib/fest-swing-1.2.jar"/>
<classpathentry kind="lib" path="app/test-lib/fest-util-1.1.2.jar"/>
<classpathentry kind="lib" path="app/test-lib/jcip-annotations-1.0.jar"/>
<classpathentry kind="lib" path="app/lib/commons-codec-1.7.jar"/>
@ -20,6 +20,13 @@
<classpathentry kind="lib" path="app/lib/jmdns-3.4.1.jar"/>
<classpathentry kind="lib" path="app/lib/jsch-0.1.50.jar"/>
<classpathentry kind="lib" path="app/lib/jssc-2.8.0.jar"/>
<classpathentry kind="lib" path="app/lib/bcpg-jdk15on-152.jar"/>
<classpathentry kind="lib" path="app/lib/bcprov-jdk15on-152.jar"/>
<classpathentry kind="lib" path="app/lib/jackson-core-2.2.3.jar"/>
<classpathentry kind="lib" path="app/lib/jackson-databind-2.2.3.jar"/>
<classpathentry kind="lib" path="app/lib/jackson-module-mrbean-2.2.3.jar"/>
<classpathentry kind="lib" path="app/lib/jackson-annotations-2.2.3.jar"/>
<classpathentry kind="lib" path="app/lib/commons-compress-1.8.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/arduino-core"/>
<classpathentry kind="output" path="app/bin"/>
</classpath>

20
.gitignore vendored
View File

@ -21,32 +21,36 @@ build/windows/libastylej*
build/windows/arduino-*.zip
build/windows/dist/*.tar.gz
build/windows/dist/*.tar.bz2
build/windows/launch4j-*
build/windows/launch4j-*.tgz
build/windows/launch4j-*.zip
build/windows/launcher/launch4j
build/windows/WinAVR-*.zip
build/macosx/arduino-*.zip
build/macosx/dist/*.tar.gz
build/macosx/dist/*.tar.bz2
build/macosx/*.tar.bz2
build/macosx/libastylej*
build/macosx/appbundler*.jar
build/macosx/appbundler*.zip
build/macosx/appbundler
build/macosx/appbundler-1.0ea-arduino2
build/macosx/appbundler-1.0ea-upstream1
build/linux/work/
build/linux/dist/*.tar.gz
build/linux/dist/*.tar.bz2
build/linux/*.tgz
build/linux/*.tar.xz
build/linux/*.tar.bz2
build/linux/*.zip
build/linux/libastylej*
build/shared/reference*.zip
build/shared/Edison*.zip
build/shared/Galileo*.zip
test-bin
*.iml
.idea
.DS_Store
.directory
build/windows/launch4j-*
build/windows/launcher/launch4j
build/windows/WinAVR-*.zip
hardware/arduino/avr/libraries/Bridge/examples/XivelyClient/passwords.h
avr-toolchain-*.zip
/hardware/tools/esp8266/utils/
@ -57,6 +61,14 @@ avr-toolchain-*.zip
/hardware/tools/bossac.exe
/hardware/tools/listComPorts.exe
/app/nbproject/private/
/arduino-core/nbproject/private/
/app/build/
/arduino-core/build/
manifest.mf
nbbuild.xml
nbproject
build/macosx/esptool-*-osx.zip
build/macosx/dist/osx-xtensa-lx106-elf.tgz

View File

@ -1,26 +1,29 @@
#Sat Dec 31 13:42:35 CET 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=18
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=18
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=18
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=82
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=18
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=18
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
@ -40,6 +43,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
@ -56,10 +60,16 @@ org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
@ -70,11 +80,18 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.indentation.size=2
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
@ -122,6 +139,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=inser
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
@ -140,12 +158,14 @@ org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invoca
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
@ -169,6 +189,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invoc
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
@ -196,6 +217,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do n
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
@ -224,6 +246,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invoc
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
@ -233,6 +256,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=inser
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
@ -256,5 +280,8 @@ org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=2
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true

View File

@ -7,10 +7,17 @@
<classpathentry kind="lib" path="lib/jna.jar"/>
<classpathentry kind="lib" path="lib/ecj.jar"/>
<classpathentry kind="lib" path="lib/apple.jar"/>
<classpathentry kind="lib" path="lib/bcpg-jdk15on-152.jar"/>
<classpathentry kind="lib" path="lib/bcprov-jdk15on-152.jar"/>
<classpathentry kind="lib" path="lib/commons-codec-1.7.jar"/>
<classpathentry kind="lib" path="lib/commons-compress-1.8.jar"/>
<classpathentry kind="lib" path="lib/commons-exec-1.1.jar"/>
<classpathentry kind="lib" path="lib/commons-httpclient-3.1.jar"/>
<classpathentry kind="lib" path="lib/commons-logging-1.0.4.jar"/>
<classpathentry kind="lib" path="lib/jackson-annotations-2.2.3.jar"/>
<classpathentry kind="lib" path="lib/jackson-core-2.2.3.jar"/>
<classpathentry kind="lib" path="lib/jackson-databind-2.2.3.jar"/>
<classpathentry kind="lib" path="lib/jackson-module-mrbean-2.2.3.jar"/>
<classpathentry kind="lib" path="lib/jmdns-3.4.1.jar"/>
<classpathentry kind="lib" path="lib/jsch-0.1.50.jar"/>
<classpathentry kind="lib" path="lib/jssc-2.8.0.jar"/>
@ -21,5 +28,9 @@
<classpathentry kind="lib" path="test-lib/fest-util-1.1.2.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/arduino-core"/>
<classpathentry kind="lib" path="test-lib/jcip-annotations-1.0.jar"/>
<classpathentry kind="lib" path="lib/commons-lang3-3.3.2.jar"/>
<classpathentry kind="lib" path="lib/guava-18.0.jar"/>
<classpathentry kind="lib" path="lib/java-semver-0.8.0.jar"/>
<classpathentry kind="lib" path="lib/rsyntaxtextarea-2.5.6.1+arduino.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

16
app/.editorconfig Normal file
View File

@ -0,0 +1,16 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
charset = utf-8
[*.{md,adoc}]
indent_style = space
trim_trailing_whitespace = false

View File

@ -1,4 +1,3 @@
#Wed Jan 11 13:49:57 CET 2012
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
@ -66,6 +65,7 @@ org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=18
@ -76,18 +76,21 @@ org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=82
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=18
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=18
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
@ -104,6 +107,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
@ -120,10 +124,16 @@ org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
@ -136,7 +146,15 @@ org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=2
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
@ -184,6 +202,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=inser
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
@ -202,12 +221,14 @@ org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invoca
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
@ -231,6 +252,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invoc
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
@ -258,6 +280,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do n
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
@ -286,6 +309,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invoc
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
@ -295,6 +319,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=inser
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
@ -304,6 +329,8 @@ org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
@ -316,5 +343,8 @@ org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=2
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true

View File

@ -1,4 +1,3 @@
#Tue Jun 03 17:00:03 EDT 2008
eclipse.preferences.version=1
formatter_profile=_two spaces no tabs
formatter_settings_version=11
formatter_profile=_Arduino
formatter_settings_version=12

View File

@ -48,7 +48,7 @@
<fail if="windows" unless="java_home"
message="The JAVA_HOME variable must be set to the location of a full JDK. For instance, on Windows, this might be c:\jdk1.6.0_18." />
<condition property="work.dir" value="../build/macosx/work/Arduino.app/Contents/Resources/Java/">
<condition property="work.dir" value="../build/macosx/work/Arduino.app/Contents/Java/">
<os family="mac"/>
</condition>
<condition property="java.additional.library.path" value=".">
@ -99,11 +99,14 @@
<fileset dir="test" includes="**/*.txt" />
<fileset dir="test" includes="**/*.properties" />
<fileset dir="test" includes="**/*.ino" />
<fileset dir="test" includes="**/*.json*" />
<fileset dir="test" includes="**/*.key" />
</copy>
<junit printsummary="yes" dir="${work.dir}" fork="true">
<jvmarg value="-Djava.library.path=${java.additional.library.path}"/>
<jvmarg value="-DWORK_DIR=."/>
<jvmarg value="-ea"/>
<classpath>
<pathelement location="bin"/>
<pathelement location="test-bin"/>

View File

@ -45,7 +45,7 @@ import java.io.*;
public void show() {
String originalText = editor.textarea.getText();
int indentSize = Preferences.getInteger("editor.tabs.size");
int indentSize = PreferencesData.getInteger("editor.tabs.size");
//

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

BIN
app/lib/guava-18.0.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

Binary file not shown.

View File

@ -0,0 +1,24 @@
Copyright (c) 2012, Robert Futrell
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,115 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions;
import cc.arduino.contributions.filters.BuiltInPredicate;
import cc.arduino.contributions.filters.InstalledPredicate;
import cc.arduino.contributions.packages.ContributedPackage;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.view.Event;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import processing.app.Base;
import processing.app.BaseNoGui;
import processing.app.I18n;
import processing.app.PreferencesData;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.LinkedList;
import java.util.List;
import static processing.app.I18n._;
public class BuiltInCoreIsNewerCheck implements Runnable {
private final Base base;
public BuiltInCoreIsNewerCheck(Base base) {
this.base = base;
}
@Override
public void run() {
try {
builtInPackageIsNewerCheck();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void builtInPackageIsNewerCheck() throws InterruptedException {
if (PreferencesData.getInteger("builtin_platform_is_newer", -1) >= BaseNoGui.REVISION) {
return;
}
LinkedList<ContributedPlatform> contributedPlatforms = Lists.newLinkedList(Iterables.concat(Collections2.transform(BaseNoGui.indexer.getPackages(), new Function<ContributedPackage, List<ContributedPlatform>>() {
@Override
public List<ContributedPlatform> apply(ContributedPackage input) {
return input.getPlatforms();
}
})));
List<ContributedPlatform> installedBuiltInPlatforms = new LinkedList<ContributedPlatform>(Collections2.filter(contributedPlatforms, Predicates.and(new InstalledPredicate(), new BuiltInPredicate())));
if (installedBuiltInPlatforms.size() != 1) {
return;
}
final ContributedPlatform installedBuiltIn = installedBuiltInPlatforms.get(0);
ContributedPlatform installedNotBuiltIn = BaseNoGui.indexer.getInstalled(installedBuiltIn.getParentPackage().getName(), installedBuiltIn.getArchitecture());
if (installedNotBuiltIn == null) {
return;
}
while (!base.hasActiveEditor()) {
Thread.sleep(100);
}
if (VersionHelper.valueOf(installedBuiltIn.getParsedVersion()).greaterThan(VersionHelper.valueOf(installedNotBuiltIn.getParsedVersion()))) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
PreferencesData.setInteger("builtin_platform_is_newer", BaseNoGui.REVISION);
assert base.hasActiveEditor();
int chosenOption = JOptionPane.showConfirmDialog(base.getActiveEditor(), I18n.format(_("The IDE includes an updated {0} package, but you're using an older one.\nDo you want to upgrade {0}?"), installedBuiltIn.getName()), I18n.format(_("A newer {0} package is available"), installedBuiltIn.getName()), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (chosenOption == JOptionPane.YES_OPTION) {
Action openBoardsManager = base.getOpenBoardsManager();
Event event = new Event(base.getActiveEditor(), ActionEvent.ACTION_PERFORMED, installedBuiltIn.getName());
event.getPayload().put("filterText", installedBuiltIn.getName());
openBoardsManager.actionPerformed(event);
}
}
});
}
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.filters;
import com.google.common.base.Predicate;
public class NoopPredicate<T> implements Predicate<T> {
@Override
public boolean apply(T input) {
return true;
}
@Override
public boolean equals(Object obj) {
return obj instanceof NoopPredicate;
}
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.filters;
import cc.arduino.contributions.libraries.ContributedLibrary;
import com.google.common.base.Predicate;
public class CategoryPredicate implements Predicate<ContributedLibrary> {
private final String category;
public CategoryPredicate(String category) {
this.category = category;
}
@Override
public boolean apply(ContributedLibrary input) {
return input.getCategory() != null && category.equals(input.getCategory());
}
@Override
public boolean equals(Object obj) {
return obj instanceof CategoryPredicate && ((CategoryPredicate) obj).category.equals(category);
}
}

View File

@ -0,0 +1,64 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.filters;
import cc.arduino.contributions.filters.InstalledPredicate;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.LibrariesIndex;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import java.util.Collection;
public class InstalledLibraryPredicate implements Predicate<ContributedLibrary> {
private final LibrariesIndex index;
public InstalledLibraryPredicate(LibrariesIndex index) {
this.index = index;
}
@Override
public boolean apply(ContributedLibrary input) {
if (input.isInstalled()) {
return true;
}
Collection<ContributedLibrary> installed = Collections2.filter(index.find(input.getName()), new InstalledPredicate());
return !installed.isEmpty();
}
@Override
public boolean equals(Object obj) {
return obj instanceof InstalledLibraryPredicate;
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.filters;
import cc.arduino.contributions.libraries.ContributedLibrary;
import com.google.common.base.Predicate;
import processing.app.packages.UserLibrary;
public class OnlyUpstreamReleasePredicate implements Predicate<ContributedLibrary> {
@Override
public boolean apply(ContributedLibrary input) {
return !(input instanceof UserLibrary);
}
@Override
public boolean equals(Object obj) {
return obj instanceof OnlyUpstreamReleasePredicate;
}
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.filters;
import cc.arduino.contributions.libraries.ContributedLibrary;
import com.google.common.base.Predicate;
public class TypePredicate implements Predicate<ContributedLibrary> {
private final String type;
public TypePredicate(String type) {
this.type = type;
}
@Override
public boolean apply(ContributedLibrary input) {
return input.getTypes() != null && input.getTypes().contains(type);
}
@Override
public boolean equals(Object obj) {
return obj instanceof TypePredicate && ((TypePredicate) obj).type.equals(type);
}
}

View File

@ -0,0 +1,441 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.ui;
import cc.arduino.contributions.VersionComparator;
import cc.arduino.contributions.filters.BuiltInPredicate;
import cc.arduino.contributions.filters.InstalledPredicate;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.filters.OnlyUpstreamReleasePredicate;
import cc.arduino.contributions.packages.DownloadableContribution;
import cc.arduino.contributions.DownloadableContributionVersionComparator;
import cc.arduino.contributions.ui.InstallerTableCell;
import cc.arduino.contributions.ui.listeners.DelegatingKeyListener;
import cc.arduino.utils.ReverseComparator;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import processing.app.Base;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.Document;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.StyleSheet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static processing.app.I18n._;
import static processing.app.I18n.format;
@SuppressWarnings("serial")
public class ContributedLibraryTableCell extends InstallerTableCell {
private JPanel panel;
private JButton installButton;
private Component installButtonPlaceholder;
private JComboBox downgradeChooser;
private JComboBox versionToInstallChooser;
private JButton downgradeButton;
private JPanel buttonsPanel;
private JPanel inactiveButtonsPanel;
private JLabel statusLabel;
public ContributedLibraryTableCell() {
{
installButton = new JButton(_("Install"));
installButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
onInstall(editorValue.getSelected(), editorValue.getInstalled());
}
});
int width = installButton.getPreferredSize().width;
installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1));
}
downgradeButton = new JButton(_("Install"));
downgradeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ContributedLibrary selected = (ContributedLibrary) downgradeChooser.getSelectedItem();
onInstall(selected, editorValue.getInstalled());
}
});
downgradeChooser = new JComboBox();
downgradeChooser.addItem("-");
downgradeChooser.setMaximumSize(downgradeChooser.getPreferredSize());
downgradeChooser.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
Object selectVersionItem = downgradeChooser.getItemAt(0);
boolean disableDowngrade = (e.getItem() == selectVersionItem);
downgradeButton.setEnabled(!disableDowngrade);
}
});
versionToInstallChooser = new JComboBox();
versionToInstallChooser.addItem("-");
versionToInstallChooser.setMaximumSize(versionToInstallChooser.getPreferredSize());
versionToInstallChooser.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
editorValue.select((ContributedLibrary) versionToInstallChooser.getSelectedItem());
}
});
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
makeNewDescription(panel);
{
buttonsPanel = new JPanel();
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
buttonsPanel.setOpaque(false);
buttonsPanel.add(Box.createHorizontalStrut(7));
buttonsPanel.add(downgradeChooser);
buttonsPanel.add(Box.createHorizontalStrut(5));
buttonsPanel.add(downgradeButton);
buttonsPanel.add(Box.createHorizontalGlue());
buttonsPanel.add(versionToInstallChooser);
buttonsPanel.add(Box.createHorizontalStrut(5));
buttonsPanel.add(installButton);
buttonsPanel.add(Box.createHorizontalStrut(5));
buttonsPanel.add(Box.createHorizontalStrut(15));
panel.add(buttonsPanel);
}
{
inactiveButtonsPanel = new JPanel();
inactiveButtonsPanel.setLayout(new BoxLayout(inactiveButtonsPanel, BoxLayout.X_AXIS));
inactiveButtonsPanel.setOpaque(false);
int height = installButton.getMinimumSize().height;
inactiveButtonsPanel.add(Box.createVerticalStrut(height));
inactiveButtonsPanel.add(Box.createGlue());
statusLabel = new JLabel(" ");
inactiveButtonsPanel.add(statusLabel);
inactiveButtonsPanel.add(Box.createHorizontalStrut(15));
panel.add(inactiveButtonsPanel);
}
panel.add(Box.createVerticalStrut(15));
}
private JTextPane makeNewDescription(JPanel panel) {
if (panel.getComponentCount() > 0) {
panel.remove(0);
}
JTextPane description = new JTextPane();
description.setInheritsPopupMenu(true);
Insets margin = description.getMargin();
margin.bottom = 0;
description.setMargin(margin);
description.setContentType("text/html");
Document doc = description.getDocument();
if (doc instanceof HTMLDocument) {
HTMLDocument html = (HTMLDocument) doc;
StyleSheet stylesheet = html.getStyleSheet();
stylesheet.addRule("body { margin: 0; padding: 0;"
+ "font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"
+ "font-size: 100%;" + "font-size: 0.95em; }");
}
description.setOpaque(false);
description.setBorder(new EmptyBorder(4, 7, 7, 7));
description.setHighlighter(null);
description.setEditable(false);
description.addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
Base.openURL(e.getDescription());
}
}
});
description.addKeyListener(new DelegatingKeyListener(parentTable));
panel.add(description, 0);
return description;
}
protected void onRemove(ContributedLibrary selected) {
// Empty
}
protected void onInstall(ContributedLibrary selected, ContributedLibrary installed) {
// Empty
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected,
boolean hasFocus, int row,
int column) {
parentTable = table;
setEnabled(false);
Component component = getUpdatedCellComponent(value, isSelected, row, false);
if (row % 2 == 0) {
component.setBackground(new Color(236, 241, 241)); //#ecf1f1
} else {
component.setBackground(new Color(255, 255, 255));
}
int height = new Double(component.getPreferredSize().getHeight()).intValue();
if (table.getRowHeight(row) < height) {
table.setRowHeight(row, height);
}
return component;
}
private LibrariesIndexTableModel.ContributedLibraryReleases editorValue;
private JTable parentTable;
@Override
public Object getCellEditorValue() {
return editorValue;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row,
int column) {
parentTable = table;
editorValue = (LibrariesIndexTableModel.ContributedLibraryReleases) value;
setEnabled(true);
final ContributedLibrary installed = editorValue.getInstalled();
List<ContributedLibrary> releases = new LinkedList<ContributedLibrary>(Collections2.filter(editorValue.releases, new OnlyUpstreamReleasePredicate()));
List<ContributedLibrary> uninstalledReleases = new LinkedList<ContributedLibrary>(Collections2.filter(releases, Predicates.not(new InstalledPredicate())));
List<ContributedLibrary> installedBuiltIn = new LinkedList<ContributedLibrary>(Collections2.filter(releases, Predicates.and(new InstalledPredicate(), new BuiltInPredicate())));
if (installed != null && !installedBuiltIn.contains(installed)) {
uninstalledReleases.addAll(installedBuiltIn);
}
Collections.sort(uninstalledReleases, new ReverseComparator<DownloadableContribution>(new DownloadableContributionVersionComparator()));
downgradeChooser.removeAllItems();
downgradeChooser.addItem(_("Select version"));
final List<ContributedLibrary> uninstalledPreviousReleases = Lists.newLinkedList();
final List<ContributedLibrary> uninstalledNewerReleases = Lists.newLinkedList();
final VersionComparator versionComparator = new VersionComparator();
Lists.newLinkedList(Lists.transform(uninstalledReleases, new Function<ContributedLibrary, ContributedLibrary>() {
@Override
public ContributedLibrary apply(ContributedLibrary input) {
if (installed == null || versionComparator.greaterThan(installed.getParsedVersion(), input.getParsedVersion())) {
uninstalledPreviousReleases.add(input);
} else {
uninstalledNewerReleases.add(input);
}
return input;
}
}));
for (ContributedLibrary release : uninstalledNewerReleases) {
downgradeChooser.addItem(release);
}
for (ContributedLibrary release : uninstalledPreviousReleases) {
downgradeChooser.addItem(release);
}
downgradeChooser.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1));
downgradeButton.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1));
versionToInstallChooser.removeAllItems();
for (ContributedLibrary release : uninstalledReleases) {
versionToInstallChooser.addItem(release);
}
versionToInstallChooser.setVisible(installed == null && uninstalledReleases.size() > 1);
Component component = getUpdatedCellComponent(value, true, row, !installedBuiltIn.isEmpty());
component.setBackground(new Color(218, 227, 227)); //#dae3e3
return component;
}
private Component getUpdatedCellComponent(Object value, boolean isSelected, int row, boolean hasBuiltInRelease) {
LibrariesIndexTableModel.ContributedLibraryReleases releases = (LibrariesIndexTableModel.ContributedLibraryReleases) value;
JTextPane description = makeNewDescription(panel);
//FIXME: happens on macosx, don't know why
if (releases == null) {
return panel;
}
ContributedLibrary selected = releases.getSelected();
ContributedLibrary installed = releases.getInstalled();
boolean removable, installable, upgradable;
if (installed == null) {
installable = true;
removable = false;
upgradable = false;
} else {
installable = false;
removable = !installed.isReadOnly() && !hasBuiltInRelease;
upgradable = new DownloadableContributionVersionComparator().compare(selected, installed) > 0;
}
if (installable) {
installButton.setText(_("Install"));
}
if (upgradable) {
installButton.setText(_("Update"));
}
installButton.setVisible(installable || upgradable);
installButtonPlaceholder.setVisible(!(installable || upgradable));
String name = selected.getName();
String author = selected.getAuthor();
// String maintainer = selectedLib.getMaintainer();
String website = selected.getWebsite();
String sentence = selected.getSentence();
String paragraph = selected.getParagraph();
// String availableVer = selectedLib.getVersion();
// String url = selected.getUrl();
String midcolor = isSelected ? "#000000" : "#888888";
String desc = "<html><body>";
// Library name...
desc += format("<b>{0}</b>", name);
if (installed != null && installed.isReadOnly()) {
desc += " Built-In ";
}
// ...author...
desc += format("<font color=\"{0}\">", midcolor);
if (author != null && !author.isEmpty()) {
desc += format(" by <b>{0}</b>", author);
}
// ...version.
if (installed != null) {
String installedVer = installed.getParsedVersion();
if (installedVer == null) {
desc += " " + _("Version unknown");
} else {
desc += " " + format(_("Version <b>{0}</b>"), installedVer);
}
}
desc += "</font>";
if (installed != null) {
desc += " <strong><font color=\"#00979D\">INSTALLED</font></strong>";
}
desc += "<br/>";
// Description
if (sentence != null) {
desc += format("<b>{0}</b> ", sentence);
if (paragraph != null && !paragraph.isEmpty())
desc += format("{0}", paragraph);
desc += "<br />";
}
if (author != null && !author.isEmpty()) {
desc += format("<a href=\"{0}\">More info</a>", website);
}
desc += "</body></html>";
description.setText(desc);
description.setBackground(Color.WHITE);
// for modelToView to work, the text area has to be sized. It doesn't
// matter if it's visible or not.
// See:
// http://stackoverflow.com/questions/3081210/how-to-set-jtextarea-to-have-height-that-matches-the-size-of-a-text-it-contains
int width = parentTable.getBounds().width;
setJTextPaneDimensionToFitContainedText(description, width);
if (isSelected) {
panel.setBackground(parentTable.getSelectionBackground());
panel.setForeground(parentTable.getSelectionForeground());
} else {
panel.setBackground(parentTable.getBackground());
panel.setForeground(parentTable.getForeground());
}
return panel;
}
private Timer enabler = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
enable(true);
enabler.stop();
}
});
@Override
public void setEnabled(boolean enabled) {
enable(false);
if (enabled) {
enabler.start();
} else {
enabler.stop();
}
buttonsPanel.setVisible(enabled);
inactiveButtonsPanel.setVisible(!enabled);
}
public void enable(boolean enabled) {
installButton.setEnabled(enabled);
}
public void setStatus(String status) {
statusLabel.setText(status);
}
public void invalidate() {
panel.invalidate();
}
}

View File

@ -0,0 +1,62 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.ui;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.LibrariesIndex;
import cc.arduino.contributions.libraries.filters.InstalledLibraryPredicate;
import cc.arduino.contributions.ui.DropdownItem;
import com.google.common.base.Predicate;
import static processing.app.I18n._;
public class DropdownInstalledLibraryItem implements DropdownItem<ContributedLibrary> {
private final LibrariesIndex index;
public DropdownInstalledLibraryItem(LibrariesIndex index) {
this.index = index;
}
public String toString() {
return _("Installed");
}
@Override
public Predicate<ContributedLibrary> getFilterPredicate() {
return new InstalledLibraryPredicate(index);
}
@Override
public boolean equals(Object obj) {
return obj instanceof DropdownInstalledLibraryItem;
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.ui;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.filters.CategoryPredicate;
import cc.arduino.contributions.ui.DropdownItem;
import com.google.common.base.Predicate;
public class DropdownLibraryOfCategoryItem implements DropdownItem<ContributedLibrary> {
private final String category;
public DropdownLibraryOfCategoryItem(String category) {
this.category = category;
}
public String toString() {
return category;
}
@Override
public Predicate<ContributedLibrary> getFilterPredicate() {
return new CategoryPredicate(category);
}
@Override
public boolean equals(Object obj) {
return obj instanceof DropdownLibraryOfCategoryItem && ((DropdownLibraryOfCategoryItem) obj).category.equals(category);
}
}

View File

@ -0,0 +1,60 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.ui;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.filters.CategoryPredicate;
import cc.arduino.contributions.libraries.filters.TypePredicate;
import cc.arduino.contributions.ui.DropdownItem;
import com.google.common.base.Predicate;
public class DropdownLibraryOfTypeItem implements DropdownItem<ContributedLibrary> {
private final String type;
public DropdownLibraryOfTypeItem(String type) {
this.type = type;
}
public String toString() {
return type;
}
@Override
public Predicate<ContributedLibrary> getFilterPredicate() {
return new TypePredicate(type);
}
@Override
public boolean equals(Object obj) {
return obj instanceof DropdownLibraryOfTypeItem && ((DropdownLibraryOfTypeItem) obj).type.equals(type);
}
}

View File

@ -0,0 +1,280 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.ui;
import cc.arduino.contributions.DownloadableContributionBuiltInAtTheBottomComparator;
import cc.arduino.contributions.VersionHelper;
import cc.arduino.contributions.filters.InstalledPredicate;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.LibrariesIndexer;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.ui.FilteredAbstractTableModel;
import com.github.zafarkhaja.semver.Version;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings("serial")
public class LibrariesIndexTableModel extends FilteredAbstractTableModel<ContributedLibrary> {
public final static int DESCRIPTION_COL = 0;
public static class ContributedLibraryReleases implements Comparable<ContributedLibraryReleases> {
public final String name;
public final List<ContributedLibrary> releases;
public final List<String> versions;
public ContributedLibrary selected;
public ContributedLibraryReleases(ContributedLibrary library) {
this.name = library.getName();
this.versions = new LinkedList<String>();
this.releases = new LinkedList<ContributedLibrary>();
this.selected = null;
add(library);
}
public boolean shouldContain(ContributedLibrary lib) {
return lib.getName().equals(name);
}
public void add(ContributedLibrary library) {
releases.add(library);
String version = library.getParsedVersion();
if (version != null) {
versions.add(version);
}
selected = getLatest();
}
public ContributedLibrary getInstalled() {
List<ContributedLibrary> installedReleases = new LinkedList<ContributedLibrary>(Collections2.filter(releases, new InstalledPredicate()));
Collections.sort(installedReleases, new DownloadableContributionBuiltInAtTheBottomComparator());
if (installedReleases.isEmpty()) {
return null;
}
return installedReleases.get(0);
}
public ContributedLibrary getLatest() {
return getLatestOf(releases);
}
public ContributedLibrary getSelected() {
return selected;
}
public void select(ContributedLibrary value) {
for (ContributedLibrary plat : releases) {
if (plat == value) {
selected = plat;
return;
}
}
}
@Override
public int compareTo(ContributedLibraryReleases o) {
return name.compareToIgnoreCase(o.name);
}
}
private final List<ContributedLibraryReleases> contributions = new ArrayList<ContributedLibraryReleases>();
private final String[] columnNames = {"Description"};
private final Class<?>[] columnTypes = {ContributedPlatform.class};
private LibrariesIndexer indexer;
public void setIndexer(LibrariesIndexer _index) {
indexer = _index;
}
Predicate<ContributedLibrary> selectedCategoryFilter = null;
String selectedFilters[] = null;
public void updateIndexFilter(String filters[], Predicate<ContributedLibrary>... additionalFilters) {
selectedCategoryFilter = Predicates.and(additionalFilters);
selectedFilters = filters;
update();
}
/**
* Check if <b>string</b> contains all the substrings in <b>set</b>. The
* compare is case insensitive.
*
* @param string
* @param filters
* @return <b>true<b> if all the strings in <b>set</b> are contained in
* <b>string</b>.
*/
private boolean stringContainsAll(String string, String filters[]) {
if (string == null) {
return false;
}
if (filters == null) {
return true;
}
for (String filter : filters) {
if (!string.toLowerCase().contains(filter.toLowerCase())) {
return false;
}
}
return true;
}
private void addContribution(ContributedLibrary lib) {
for (ContributedLibraryReleases contribution : contributions) {
if (!contribution.shouldContain(lib))
continue;
contribution.add(lib);
return;
}
contributions.add(new ContributedLibraryReleases(lib));
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return contributions.size();
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Class<?> getColumnClass(int colum) {
return columnTypes[colum];
}
@Override
public void setValueAt(Object value, int row, int col) {
if (col == DESCRIPTION_COL) {
fireTableCellUpdated(row, col);
}
}
@Override
public Object getValueAt(int row, int col) {
if (row >= contributions.size()) {
return null;
}
ContributedLibraryReleases contribution = contributions.get(row);
if (col == DESCRIPTION_COL) {
return contribution;// .getSelected();
}
return null;
}
@Override
public boolean isCellEditable(int row, int col) {
return col == DESCRIPTION_COL;
}
public ContributedLibraryReleases getReleases(int row) {
return contributions.get(row);
}
public ContributedLibrary getSelectedRelease(int row) {
return contributions.get(row).getSelected();
}
public void update() {
updateContributions();
fireTableDataChanged();
}
private void applyFilterToLibrary(ContributedLibrary lib) {
if (selectedCategoryFilter != null && !selectedCategoryFilter.apply(lib)) {
return;
}
if (!stringContainsAll(lib.getName(), selectedFilters) && !stringContainsAll(lib.getParagraph(), selectedFilters) && !stringContainsAll(lib.getSentence(), selectedFilters)) {
return;
}
addContribution(lib);
}
public void updateLibrary(ContributedLibrary lib) {
// Find the row interested in the change
int row = -1;
for (ContributedLibraryReleases releases : contributions) {
if (releases.shouldContain(lib))
row = contributions.indexOf(releases);
}
updateContributions();
// If the library is found in the list send update event
// or insert event on the specific row...
for (ContributedLibraryReleases releases : contributions) {
if (releases.shouldContain(lib)) {
if (row == -1) {
row = contributions.indexOf(releases);
fireTableRowsInserted(row, row);
} else {
fireTableRowsUpdated(row, row);
}
return;
}
}
// ...otherwise send a row deleted event
fireTableRowsDeleted(row, row);
}
private void updateContributions() {
contributions.clear();
for (ContributedLibrary l : indexer.getIndex().getLibraries()) {
applyFilterToLibrary(l);
}
for (ContributedLibrary l : indexer.getInstalledLibraries()) {
applyFilterToLibrary(l);
}
Collections.sort(contributions);
}
}

View File

@ -0,0 +1,285 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.libraries.ui;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.LibrariesIndexer;
import cc.arduino.contributions.libraries.LibraryInstaller;
import cc.arduino.contributions.packages.DownloadableContribution;
import cc.arduino.contributions.ui.InstallerJDialogUncaughtExceptionHandler;
import cc.arduino.contributions.ui.*;
import cc.arduino.utils.Progress;
import com.google.common.base.Predicate;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import static processing.app.I18n._;
@SuppressWarnings("serial")
public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
private LibrariesIndexer indexer;
private final JComboBox typeChooser;
private Predicate<ContributedLibrary> typeFilter;
@Override
protected FilteredAbstractTableModel createContribModel() {
return new LibrariesIndexTableModel();
}
private LibrariesIndexTableModel getContribModel() {
return (LibrariesIndexTableModel) contribModel;
}
@Override
protected InstallerTableCell createCellRenderer() {
return new ContributedLibraryTableCell();
}
@Override
protected InstallerTableCell createCellEditor() {
return new ContributedLibraryTableCell() {
@Override
protected void onInstall(ContributedLibrary selectedLibrary, ContributedLibrary installedLibrary) {
if (selectedLibrary.isReadOnly()) {
onRemovePressed(installedLibrary);
} else {
onInstallPressed(selectedLibrary, installedLibrary);
}
}
@Override
protected void onRemove(ContributedLibrary library) {
onRemovePressed(library);
}
};
}
public LibraryManagerUI(Frame parent) {
super(parent, "Library Manager", Dialog.ModalityType.APPLICATION_MODAL, _("Unable to reach Arduino.cc due to possible network issues."));
filtersContainer.add(new JLabel(_("Topic")), 1);
filtersContainer.remove(2);
typeChooser = new JComboBox();
typeChooser.setMaximumRowCount(20);
typeChooser.setEnabled(false);
filtersContainer.add(Box.createHorizontalStrut(5), 0);
filtersContainer.add(new JLabel(_("Type")), 1);
filtersContainer.add(Box.createHorizontalStrut(5), 2);
filtersContainer.add(typeChooser, 3);
}
protected final ActionListener typeChooserActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
DropdownItem<ContributedLibrary> selected = (DropdownItem<ContributedLibrary>) typeChooser.getSelectedItem();
if (typeFilter == null || !typeFilter.equals(selected)) {
typeFilter = selected.getFilterPredicate();
if (contribTable.getCellEditor() != null) {
contribTable.getCellEditor().stopCellEditing();
}
updateIndexFilter(filters, categoryFilter, typeFilter);
}
}
};
@Override
public void updateIndexFilter(String[] filters, Predicate<ContributedLibrary>... additionalFilters) {
if (additionalFilters.length == 1) {
additionalFilters = new Predicate[] { additionalFilters[0], typeFilter };
}
super.updateIndexFilter(filters, additionalFilters);
}
public void setIndexer(LibrariesIndexer indexer) {
this.indexer = indexer;
DropdownItem<DownloadableContribution> previouslySelectedCategory = (DropdownItem<DownloadableContribution>) categoryChooser.getSelectedItem();
DropdownItem<DownloadableContribution> previouslySelectedType = (DropdownItem<DownloadableContribution>) typeChooser.getSelectedItem();
categoryChooser.removeActionListener(categoryChooserActionListener);
typeChooser.removeActionListener(typeChooserActionListener);
// TODO: Remove setIndexer and make getContribModel
// return a FilteredAbstractTableModel
getContribModel().setIndexer(indexer);
categoryFilter = null;
categoryChooser.removeAllItems();
// Load categories
categoryChooser.addItem(new DropdownAllItem());
Collection<String> categories = indexer.getIndex().getCategories();
for (String category : categories) {
categoryChooser.addItem(new DropdownLibraryOfCategoryItem(category));
}
categoryChooser.setEnabled(categoryChooser.getItemCount() > 1);
categoryChooser.addActionListener(categoryChooserActionListener);
if (previouslySelectedCategory != null) {
categoryChooser.setSelectedItem(previouslySelectedCategory);
} else {
categoryChooser.setSelectedIndex(0);
}
typeFilter = null;
typeChooser.removeAllItems();
typeChooser.addItem(new DropdownAllItem());
typeChooser.addItem(new DropdownInstalledLibraryItem(indexer.getIndex()));
Collection<String> types = indexer.getIndex().getTypes();
for (String type : types) {
typeChooser.addItem(new DropdownLibraryOfTypeItem(type));
}
typeChooser.setEnabled(typeChooser.getItemCount() > 1);
typeChooser.addActionListener(typeChooserActionListener);
if (previouslySelectedType != null) {
typeChooser.setSelectedItem(previouslySelectedType);
} else {
typeChooser.setSelectedIndex(0);
}
filterField.setEnabled(contribModel.getRowCount() > 0);
// Create LibrariesInstaller tied with the provided index
installer = new LibraryInstaller(indexer) {
@Override
public void onProgress(Progress progress) {
setProgress(progress);
}
};
}
public LibrariesIndexer getIndexer() {
return indexer;
}
public void setProgress(Progress progress) {
progressBar.setValue(progress);
}
/*
* Installer methods follows
*/
private LibraryInstaller installer;
private Thread installerThread = null;
@Override
protected void onCancelPressed() {
super.onUpdatePressed();
if (installerThread != null) {
installerThread.interrupt();
}
}
@Override
protected void onUpdatePressed() {
super.onUpdatePressed();
installerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
setProgressVisible(true, "");
installer.updateIndex();
onIndexesUpdated();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
setProgressVisible(false, "");
}
}
});
installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage));
installerThread.start();
}
public void onInstallPressed(final ContributedLibrary lib, final ContributedLibrary replaced) {
clearErrorMessage();
installerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
setProgressVisible(true, _("Installing..."));
installer.install(lib, replaced);
onIndexesUpdated(); // TODO: Do a better job in refreshing only the needed element
//getContribModel().updateLibrary(lib);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
setProgressVisible(false, "");
}
}
});
installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage));
installerThread.start();
}
public void onRemovePressed(final ContributedLibrary lib) {
boolean managedByIndex = indexer.getIndex().getLibraries().contains(lib);
if (!managedByIndex) {
int chosenOption = JOptionPane.showConfirmDialog(this, _("This library is not listed on Library Manager. You won't be able to resinstall it from here.\nAre you sure you want to delete it?"), _("Please confirm library deletion"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (chosenOption != JOptionPane.YES_OPTION) {
return;
}
}
clearErrorMessage();
installerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
setProgressVisible(true, _("Removing..."));
installer.remove(lib);
onIndexesUpdated(); // TODO: Do a better job in refreshing only the needed element
//getContribModel().updateLibrary(lib);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
setProgressVisible(false, "");
}
}
});
installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage));
installerThread.start();
}
protected void onIndexesUpdated() throws Exception {
// Empty
}
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.packages.filters;
import cc.arduino.contributions.packages.ContributedPlatform;
import com.google.common.base.Predicate;
public class CategoryPredicate implements Predicate<ContributedPlatform> {
private final String category;
public CategoryPredicate(String category) {
this.category = category;
}
@Override
public boolean apply(ContributedPlatform input) {
return input.getCategory() != null && category.equals(input.getCategory());
}
@Override
public boolean equals(Object obj) {
return obj instanceof CategoryPredicate && ((CategoryPredicate) obj).category.equals(category);
}
}

View File

@ -0,0 +1,446 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.packages.ui;
import cc.arduino.contributions.DownloadableContributionVersionComparator;
import cc.arduino.contributions.VersionComparator;
import cc.arduino.contributions.filters.BuiltInPredicate;
import cc.arduino.contributions.filters.InstalledPredicate;
import cc.arduino.contributions.packages.ContributedBoard;
import cc.arduino.contributions.packages.ContributedHelp;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.packages.DownloadableContribution;
import cc.arduino.contributions.ui.InstallerTableCell;
import cc.arduino.contributions.ui.listeners.DelegatingKeyListener;
import cc.arduino.utils.ReverseComparator;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import processing.app.Base;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.Document;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.StyleSheet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Collections;
import java.util.LinkedList;
import static processing.app.I18n._;
import static processing.app.I18n.format;
@SuppressWarnings("serial")
public class ContributedPlatformTableCell extends InstallerTableCell {
private JPanel panel;
private JButton installButton;
private JButton removeButton;
private Component removeButtonPlaceholder;
private Component installButtonPlaceholder;
private JComboBox downgradeChooser;
private JComboBox versionToInstallChooser;
private JButton downgradeButton;
private JPanel buttonsPanel;
private JPanel inactiveButtonsPanel;
private JLabel statusLabel;
public ContributedPlatformTableCell() {
{
installButton = new JButton(_("Install"));
installButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
onInstall(editorValue.getSelected(), editorValue.getInstalled());
}
});
int width = installButton.getPreferredSize().width;
installButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1));
}
{
removeButton = new JButton(_("Remove"));
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
onRemove(editorValue.getInstalled());
}
});
int width = removeButton.getPreferredSize().width;
removeButtonPlaceholder = Box.createRigidArea(new Dimension(width, 1));
}
downgradeButton = new JButton(_("Install"));
downgradeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ContributedPlatform selected = (ContributedPlatform) downgradeChooser.getSelectedItem();
onInstall(selected, editorValue.getInstalled());
}
});
downgradeChooser = new JComboBox();
downgradeChooser.addItem("-");
downgradeChooser.setMaximumSize(downgradeChooser.getPreferredSize());
downgradeChooser.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
Object selectVersionItem = downgradeChooser.getItemAt(0);
boolean disableDowngrade = (e.getItem() == selectVersionItem);
downgradeButton.setEnabled(!disableDowngrade);
}
});
versionToInstallChooser = new JComboBox();
versionToInstallChooser.addItem("-");
versionToInstallChooser.setMaximumSize(versionToInstallChooser.getPreferredSize());
versionToInstallChooser.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
editorValue.select((ContributedPlatform) versionToInstallChooser.getSelectedItem());
}
});
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
makeNewDescription(panel);
{
buttonsPanel = new JPanel();
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
buttonsPanel.setOpaque(false);
buttonsPanel.add(Box.createHorizontalStrut(7));
buttonsPanel.add(downgradeChooser);
buttonsPanel.add(Box.createHorizontalStrut(5));
buttonsPanel.add(downgradeButton);
buttonsPanel.add(Box.createHorizontalGlue());
buttonsPanel.add(versionToInstallChooser);
buttonsPanel.add(Box.createHorizontalStrut(5));
buttonsPanel.add(installButton);
buttonsPanel.add(Box.createHorizontalStrut(5));
buttonsPanel.add(removeButton);
buttonsPanel.add(Box.createHorizontalStrut(5));
buttonsPanel.add(Box.createHorizontalStrut(15));
panel.add(buttonsPanel);
}
{
inactiveButtonsPanel = new JPanel();
inactiveButtonsPanel.setLayout(new BoxLayout(inactiveButtonsPanel, BoxLayout.X_AXIS));
inactiveButtonsPanel.setOpaque(false);
int height = installButton.getMinimumSize().height;
inactiveButtonsPanel.add(Box.createVerticalStrut(height));
inactiveButtonsPanel.add(Box.createGlue());
statusLabel = new JLabel(" ");
inactiveButtonsPanel.add(statusLabel);
inactiveButtonsPanel.add(Box.createHorizontalStrut(15));
panel.add(inactiveButtonsPanel);
}
panel.add(Box.createVerticalStrut(15));
}
private JTextPane makeNewDescription(JPanel panel) {
if (panel.getComponentCount() > 0) {
panel.remove(0);
}
JTextPane description = new JTextPane();
description.setInheritsPopupMenu(true);
Insets margin = description.getMargin();
margin.bottom = 0;
description.setMargin(margin);
description.setContentType("text/html");
Document doc = description.getDocument();
if (doc instanceof HTMLDocument) {
HTMLDocument html = (HTMLDocument) doc;
StyleSheet stylesheet = html.getStyleSheet();
stylesheet.addRule("body { margin: 0; padding: 0;"
+ "font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"
+ "font-size: 100%;" + "font-size: 0.95em; }");
}
description.setOpaque(false);
description.setBorder(new EmptyBorder(4, 7, 7, 7));
description.setHighlighter(null);
description.setEditable(false);
description.addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
Base.openURL(e.getDescription());
}
}
});
description.addKeyListener(new DelegatingKeyListener(parentTable));
panel.add(description, 0);
return description;
}
protected void onRemove(ContributedPlatform contributedPlatform) {
// Empty
}
protected void onInstall(ContributedPlatform contributedPlatform, ContributedPlatform installed) {
// Empty
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected,
boolean hasFocus, int row,
int column) {
parentTable = table;
setEnabled(false);
Component component = getUpdatedCellComponent(value, isSelected, row, false);
if (row % 2 == 0) {
component.setBackground(new Color(236, 241, 241)); //#ecf1f1
} else {
component.setBackground(new Color(255, 255, 255));
}
int height = new Double(component.getPreferredSize().getHeight()).intValue();
if (table.getRowHeight(row) < height) {
table.setRowHeight(row, height);
}
return component;
}
private ContributionIndexTableModel.ContributedPlatformReleases editorValue;
private JTable parentTable;
@Override
public Object getCellEditorValue() {
return editorValue;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row,
int column) {
parentTable = table;
editorValue = (ContributionIndexTableModel.ContributedPlatformReleases) value;
setEnabled(true);
final ContributedPlatform installed = editorValue.getInstalled();
java.util.List<ContributedPlatform> releases = new LinkedList<ContributedPlatform>(editorValue.releases);
java.util.List<ContributedPlatform> uninstalledReleases = new LinkedList<ContributedPlatform>(Collections2.filter(releases, Predicates.not(new InstalledPredicate())));
java.util.List<ContributedPlatform> installedBuiltIn = new LinkedList<ContributedPlatform>(Collections2.filter(releases, Predicates.and(new InstalledPredicate(), new BuiltInPredicate())));
if (installed != null && !installedBuiltIn.contains(installed)) {
uninstalledReleases.addAll(installedBuiltIn);
}
Collections.sort(uninstalledReleases, new ReverseComparator<DownloadableContribution>(new DownloadableContributionVersionComparator()));
downgradeChooser.removeAllItems();
downgradeChooser.addItem(_("Select version"));
final java.util.List<ContributedPlatform> uninstalledPreviousReleases = Lists.newLinkedList();
final java.util.List<ContributedPlatform> uninstalledNewerReleases = Lists.newLinkedList();
final VersionComparator versionComparator = new VersionComparator();
Lists.newLinkedList(Lists.transform(uninstalledReleases, new Function<ContributedPlatform, ContributedPlatform>() {
@Override
public ContributedPlatform apply(ContributedPlatform input) {
if (installed == null || versionComparator.greaterThan(installed.getParsedVersion(), input.getParsedVersion())) {
uninstalledPreviousReleases.add(input);
} else {
uninstalledNewerReleases.add(input);
}
return input;
}
}));
for (ContributedPlatform release : uninstalledNewerReleases) {
downgradeChooser.addItem(release);
}
for (ContributedPlatform release : uninstalledPreviousReleases) {
downgradeChooser.addItem(release);
}
downgradeChooser.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1));
downgradeButton.setVisible(installed != null && (!uninstalledPreviousReleases.isEmpty() || uninstalledNewerReleases.size() > 1));
versionToInstallChooser.removeAllItems();
for (ContributedPlatform release : uninstalledReleases) {
versionToInstallChooser.addItem(release);
}
versionToInstallChooser.setVisible(installed == null && uninstalledReleases.size() > 1);
Component component = getUpdatedCellComponent(value, true, row, !installedBuiltIn.isEmpty());
component.setBackground(new Color(218, 227, 227)); //#dae3e3
return component;
}
private Component getUpdatedCellComponent(Object value, boolean isSelected, int row, boolean hasBuiltInRelease) {
ContributionIndexTableModel.ContributedPlatformReleases releases = (ContributionIndexTableModel.ContributedPlatformReleases) value;
JTextPane description = makeNewDescription(panel);
//FIXME: happens on macosx, don't know why
if (releases == null) {
return panel;
}
ContributedPlatform selected = releases.getSelected();
ContributedPlatform installed = releases.getInstalled();
boolean removable, installable, upgradable;
if (installed == null) {
installable = true;
removable = false;
upgradable = false;
} else {
installable = false;
removable = !installed.isReadOnly() && !hasBuiltInRelease;
upgradable = new DownloadableContributionVersionComparator().compare(selected, installed) > 0;
}
if (installable) {
installButton.setText(_("Install"));
}
if (upgradable) {
installButton.setText(_("Update"));
}
installButton.setVisible(installable || upgradable);
installButtonPlaceholder.setVisible(!(installable || upgradable));
removeButton.setVisible(removable);
removeButtonPlaceholder.setVisible(!removable);
String desc = "<html><body>";
desc += "<b>" + selected.getName() + "</b>";
if (installed != null && installed.isReadOnly()) {
desc += " Built-In ";
}
String author = selected.getParentPackage().getMaintainer();
if (author != null && !author.isEmpty()) {
desc += " " + format("by <b>{0}</b>", author);
}
if (installed != null) {
desc += " " + format(_("version <b>{0}</b>"), installed.getParsedVersion()) + " <strong><font color=\"#00979D\">INSTALLED</font></strong>";
}
desc += "<br />";
desc += _("Boards included in this package:") + "<br />";
for (ContributedBoard board : selected.getBoards()) {
desc += board.getName() + ", ";
}
desc = desc.substring(0, desc.lastIndexOf(',')) + ".<br />";
ContributedHelp help = null;
if (selected.getHelp() != null) {
help = selected.getHelp();
} else if (selected.getParentPackage().getHelp() != null) {
help = selected.getParentPackage().getHelp();
}
if (help != null) {
String url = help.getOnline();
if (url != null && !url.isEmpty()) {
desc += " " + format("<a href=\"{0}\">Online help</a><br/>", url);
}
}
String url = selected.getParentPackage().getWebsiteURL();
if (url != null && !url.isEmpty()) {
desc += " " + format("<a href=\"{0}\">More info</a>", url);
}
desc += "</body></html>";
description.setText(desc);
description.setBackground(Color.WHITE);
// for modelToView to work, the text area has to be sized. It doesn't
// matter if it's visible or not.
// See:
// http://stackoverflow.com/questions/3081210/how-to-set-jtextarea-to-have-height-that-matches-the-size-of-a-text-it-contains
int width = parentTable.getBounds().width;
setJTextPaneDimensionToFitContainedText(description, width);
if (isSelected) {
panel.setBackground(parentTable.getSelectionBackground());
panel.setForeground(parentTable.getSelectionForeground());
} else {
panel.setBackground(parentTable.getBackground());
panel.setForeground(parentTable.getForeground());
}
return panel;
}
private Timer enabler = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
enable(true);
enabler.stop();
}
});
@Override
public void setEnabled(boolean enabled) {
enable(false);
if (enabled) {
enabler.start();
} else {
enabler.stop();
}
buttonsPanel.setVisible(enabled);
inactiveButtonsPanel.setVisible(!enabled);
}
public void enable(boolean enabled) {
installButton.setEnabled(enabled);
removeButton.setEnabled(enabled);
}
public void setStatus(String status) {
statusLabel.setText(status);
}
public void invalidate() {
panel.invalidate();
}
}

View File

@ -0,0 +1,224 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.packages.ui;
import cc.arduino.contributions.DownloadableContributionBuiltInAtTheBottomComparator;
import cc.arduino.contributions.filters.InstalledPredicate;
import cc.arduino.contributions.packages.ContributedPackage;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.packages.ContributionsIndexer;
import cc.arduino.contributions.ui.FilteredAbstractTableModel;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings("serial")
public class ContributionIndexTableModel extends FilteredAbstractTableModel<ContributedPlatform> {
public final static int DESCRIPTION_COL = 0;
public static class ContributedPlatformReleases {
public final ContributedPackage packager;
public final String arch;
public final List<ContributedPlatform> releases;
public final List<String> versions;
public ContributedPlatform selected = null;
public ContributedPlatformReleases(ContributedPlatform platform) {
this.packager = platform.getParentPackage();
this.arch = platform.getArchitecture();
this.releases = new LinkedList<ContributedPlatform>();
this.versions = new LinkedList<String>();
add(platform);
}
public boolean shouldContain(ContributedPlatform platform) {
if (platform.getParentPackage() != packager)
return false;
return platform.getArchitecture().equals(arch);
}
public void add(ContributedPlatform platform) {
releases.add(platform);
String version = platform.getParsedVersion();
if (version != null) {
versions.add(version);
}
selected = getLatest();
}
public ContributedPlatform getInstalled() {
List<ContributedPlatform> installedReleases = new LinkedList<ContributedPlatform>(Collections2.filter(releases, new InstalledPredicate()));
Collections.sort(installedReleases, new DownloadableContributionBuiltInAtTheBottomComparator());
if (installedReleases.isEmpty()) {
return null;
}
return installedReleases.get(0);
}
public ContributedPlatform getLatest() {
return getLatestOf(releases);
}
public ContributedPlatform getSelected() {
return selected;
}
public void select(ContributedPlatform value) {
for (ContributedPlatform plat : releases) {
if (plat == value) {
selected = plat;
return;
}
}
}
}
private List<ContributedPlatformReleases> contributions = new ArrayList<ContributedPlatformReleases>();
private String[] columnNames = {"Description"};
private Class<?>[] columnTypes = {ContributedPlatform.class};
private ContributionsIndexer indexer;
public void setIndexer(ContributionsIndexer indexer) {
this.indexer = indexer;
}
public void updateIndexFilter(String filters[], Predicate<ContributedPlatform>... additionalFilters) {
contributions.clear();
Predicate<ContributedPlatform> filter = Predicates.and(additionalFilters);
for (ContributedPackage pack : indexer.getPackages()) {
for (ContributedPlatform platform : pack.getPlatforms()) {
if (!filter.apply(platform)) {
continue;
}
if (!stringContainsAll(platform.getName(), filters))
continue;
addContribution(platform);
}
}
fireTableDataChanged();
}
/**
* Check if <b>string</b> contains all the substrings in <b>set</b>. The
* compare is case insensitive.
*
* @param string
* @param set
* @return <b>true<b> if all the strings in <b>set</b> are contained in
* <b>string</b>.
*/
private boolean stringContainsAll(String string, String set[]) {
if (set == null)
return true;
for (String s : set) {
if (!string.toLowerCase().contains(s.toLowerCase()))
return false;
}
return true;
}
private void addContribution(ContributedPlatform platform) {
for (ContributedPlatformReleases contribution : contributions) {
if (!contribution.shouldContain(platform))
continue;
contribution.add(platform);
return;
}
contributions.add(new ContributedPlatformReleases(platform));
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return contributions.size();
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Class<?> getColumnClass(int colum) {
return columnTypes[colum];
}
@Override
public void setValueAt(Object value, int row, int col) {
if (col == DESCRIPTION_COL) {
fireTableCellUpdated(row, col);
}
}
@Override
public Object getValueAt(int row, int col) {
if (row >= contributions.size()) {
return null;
}
ContributedPlatformReleases contribution = contributions.get(row);
if (col == DESCRIPTION_COL) {
return contribution;// .getSelected();
}
return null;
}
@Override
public boolean isCellEditable(int row, int col) {
return col == DESCRIPTION_COL;
}
public ContributedPlatformReleases getReleases(int row) {
return contributions.get(row);
}
public ContributedPlatform getSelectedRelease(int row) {
return contributions.get(row).getSelected();
}
public void update() {
fireTableDataChanged();
}
}

View File

@ -0,0 +1,229 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.packages.ui;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.packages.ContributionInstaller;
import cc.arduino.contributions.packages.ContributionsIndexer;
import cc.arduino.contributions.packages.DownloadableContribution;
import cc.arduino.contributions.ui.*;
import cc.arduino.utils.Progress;
import processing.app.I18n;
import javax.swing.*;
import java.awt.*;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import static processing.app.I18n._;
@SuppressWarnings("serial")
public class ContributionManagerUI extends InstallerJDialog {
// private ContributedPlatformTableCell cellEditor;
@Override
protected FilteredAbstractTableModel createContribModel() {
return new ContributionIndexTableModel();
}
private ContributionIndexTableModel getContribModel() {
return (ContributionIndexTableModel) contribModel;
}
@Override
protected InstallerTableCell createCellRenderer() {
return new ContributedPlatformTableCell();
}
@Override
protected InstallerTableCell createCellEditor() {
return new ContributedPlatformTableCell() {
@Override
protected void onInstall(ContributedPlatform selected, ContributedPlatform installed) {
if (selected.isReadOnly()) {
onRemovePressed(installed, false);
} else {
onInstallPressed(selected, installed);
}
}
@Override
protected void onRemove(ContributedPlatform installedPlatform) {
onRemovePressed(installedPlatform, true);
}
};
}
public ContributionManagerUI(Frame parent) {
super(parent, _("Boards Manager"), Dialog.ModalityType.APPLICATION_MODAL, _("Unable to reach Arduino.cc due to possible network issues."));
}
public void setIndexer(ContributionsIndexer indexer) {
DropdownItem<DownloadableContribution> previouslySelectedCategory = (DropdownItem<DownloadableContribution>) categoryChooser.getSelectedItem();
categoryChooser.removeActionListener(categoryChooserActionListener);
getContribModel().setIndexer(indexer);
categoryFilter = null;
categoryChooser.removeAllItems();
filterField.setEnabled(getContribModel().getRowCount() > 0);
categoryChooser.addActionListener(categoryChooserActionListener);
// Enable categories combo only if there are two or more choices
categoryChooser.addItem(new DropdownAllCoresItem());
Collection<String> categories = indexer.getCategories();
for (String s : categories) {
categoryChooser.addItem(new DropdownCoreOfCategoryItem(s));
}
if (previouslySelectedCategory != null) {
categoryChooser.setSelectedItem(previouslySelectedCategory);
} else {
categoryChooser.setSelectedIndex(0);
}
// Create ConstributionInstaller tied with the provided index
installer = new ContributionInstaller(indexer) {
@Override
public void onProgress(Progress progress) {
setProgress(progress);
}
};
}
public void setProgress(Progress progress) {
progressBar.setValue(progress);
}
/*
* Installer methods follows
*/
private ContributionInstaller installer;
private Thread installerThread = null;
@Override
public void onCancelPressed() {
super.onCancelPressed();
if (installerThread != null) {
installerThread.interrupt();
}
}
@Override
public void onUpdatePressed() {
super.onUpdatePressed();
installerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
setProgressVisible(true, "");
List<String> downloadedPackageIndexFiles = installer.updateIndex();
installer.deleteUnknownFiles(downloadedPackageIndexFiles);
onIndexesUpdated();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
setProgressVisible(false, "");
}
}
});
installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage));
installerThread.start();
}
public void onInstallPressed(final ContributedPlatform platformToInstall, final ContributedPlatform platformToRemove) {
clearErrorMessage();
installerThread = new Thread(new Runnable() {
@Override
public void run() {
List<String> errors = new LinkedList<String>();
try {
setProgressVisible(true, _("Installing..."));
errors.addAll(installer.install(platformToInstall));
if (platformToRemove != null && !platformToRemove.isReadOnly()) {
errors.addAll(installer.remove(platformToRemove));
}
onIndexesUpdated();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
setProgressVisible(false, "");
if (!errors.isEmpty()) {
setErrorMessage(errors.get(0));
}
}
}
});
installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage));
installerThread.start();
}
public void onRemovePressed(final ContributedPlatform platform, boolean showWarning) {
clearErrorMessage();
if (showWarning) {
int chosenOption = JOptionPane.showConfirmDialog(this, I18n.format(_("Do you want to remove {0}?\nIf you do so you won't be able to use {0} any more."), platform.getName()), _("Please confirm boards deletion"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (chosenOption != JOptionPane.YES_OPTION) {
return;
}
}
installerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
setProgressVisible(true, _("Removing..."));
installer.remove(platform);
onIndexesUpdated();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
setProgressVisible(false, "");
}
}
});
installerThread.setUncaughtExceptionHandler(new InstallerJDialogUncaughtExceptionHandler(this, noConnectionErrorMessage));
installerThread.start();
}
/**
* Callback invoked when indexes are updated
*
* @throws Exception
*/
protected void onIndexesUpdated() throws Exception {
// Empty
}
}

View File

@ -0,0 +1,54 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.packages.ui;
import cc.arduino.contributions.filters.NoopPredicate;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.ui.DropdownItem;
import com.google.common.base.Predicate;
import static processing.app.I18n._;
public class DropdownAllCoresItem implements DropdownItem<ContributedPlatform> {
public String toString() {
return _("All");
}
@Override
public Predicate<ContributedPlatform> getFilterPredicate() {
return new NoopPredicate<ContributedPlatform>();
}
@Override
public boolean equals(Object obj) {
return obj instanceof DropdownAllCoresItem;
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.packages.ui;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.packages.filters.CategoryPredicate;
import cc.arduino.contributions.ui.DropdownItem;
import com.google.common.base.Predicate;
public class DropdownCoreOfCategoryItem implements DropdownItem<ContributedPlatform> {
private final String category;
public DropdownCoreOfCategoryItem(String category) {
this.category = category;
}
public String toString() {
return category;
}
@Override
public Predicate<ContributedPlatform> getFilterPredicate() {
return new CategoryPredicate(category);
}
@Override
public boolean equals(Object obj) {
return obj instanceof DropdownCoreOfCategoryItem && ((DropdownCoreOfCategoryItem) obj).category.equals(category);
}
}

View File

@ -0,0 +1,55 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import cc.arduino.contributions.filters.NoopPredicate;
import cc.arduino.contributions.packages.DownloadableContribution;
import cc.arduino.contributions.ui.DropdownItem;
import com.google.common.base.Predicate;
import static processing.app.I18n._;
public class DropdownAllItem implements DropdownItem<DownloadableContribution> {
public String toString() {
return _("All");
}
@Override
public Predicate<DownloadableContribution> getFilterPredicate() {
return new NoopPredicate<DownloadableContribution>();
}
@Override
public boolean equals(Object obj) {
return obj instanceof DropdownAllItem;
}
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import com.google.common.base.Predicate;
public interface DropdownItem<T> {
Predicate<T> getFilterPredicate();
}

View File

@ -0,0 +1,117 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
@SuppressWarnings("serial")
public class FilterJTextField extends JTextField {
private final String filterHint;
private boolean showingHint;
public FilterJTextField(String hint) {
super(hint);
filterHint = hint;
showingHint = true;
updateStyle();
addFocusListener(new FocusListener() {
public void focusLost(FocusEvent focusEvent) {
if (getText().isEmpty()) {
showingHint = true;
}
updateStyle();
}
public void focusGained(FocusEvent focusEvent) {
if (showingHint) {
showingHint = false;
setText("");
}
updateStyle();
}
});
getDocument().addDocumentListener(new DocumentListener() {
public void removeUpdate(DocumentEvent e) {
applyFilter();
}
public void insertUpdate(DocumentEvent e) {
applyFilter();
}
public void changedUpdate(DocumentEvent e) {
applyFilter();
}
});
}
private String lastFilter = "";
private void applyFilter() {
String filter = showingHint ? "" : getText();
filter = filter.toLowerCase();
// Replace anything but 0-9, a-z, or : with a space
filter = filter.replaceAll("[^\\x30-\\x39^\\x61-\\x7a^\\x3a]", " ");
// Fire event only if the filter is changed
if (filter.equals(lastFilter))
return;
lastFilter = filter;
onFilter(filter.split(" "));
}
protected void onFilter(String[] strings) {
// Empty
}
public void updateStyle() {
if (showingHint) {
setText(filterHint);
setForeground(Color.gray);
setFont(getFont().deriveFont(Font.ITALIC));
} else {
setForeground(UIManager.getColor("TextField.foreground"));
setFont(getFont().deriveFont(Font.PLAIN));
}
}
}

View File

@ -0,0 +1,62 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import cc.arduino.contributions.VersionComparator;
import cc.arduino.contributions.packages.DownloadableContribution;
import com.google.common.base.Predicate;
import javax.swing.table.AbstractTableModel;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public abstract class FilteredAbstractTableModel<T> extends AbstractTableModel {
abstract public void updateIndexFilter(String[] filters, Predicate<T>... additionalFilters);
protected static <T extends DownloadableContribution> T getLatestOf(List<T> contribs) {
contribs = new LinkedList<T>(contribs);
final VersionComparator versionComparator = new VersionComparator();
Collections.sort(contribs, new Comparator<T>() {
@Override
public int compare(T contrib1, T contrib2) {
return versionComparator.compare(contrib1.getParsedVersion(), contrib2.getParsedVersion());
}
});
if (contribs.isEmpty()) {
return null;
}
return contribs.get(contribs.size() - 1);
}
}

View File

@ -0,0 +1,301 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import cc.arduino.contributions.packages.ui.ContributionIndexTableModel;
import cc.arduino.contributions.ui.listeners.AbstractKeyListener;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import processing.app.Base;
import processing.app.Theme;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import static cc.arduino.contributions.packages.ui.ContributionIndexTableModel.DESCRIPTION_COL;
import static processing.app.I18n._;
public abstract class InstallerJDialog<T> extends JDialog {
// Toolbar on top of the window:
// - Categories drop-down menu
protected final JComboBox categoryChooser;
// - Search text-field
protected final FilterJTextField filterField;
protected final JPanel filtersContainer;
// Currently selected category and filters
protected Predicate<T> categoryFilter;
protected String[] filters;
protected final String noConnectionErrorMessage;
// Real contribution table
protected JTable contribTable;
// Model behind the table
protected FilteredAbstractTableModel<T> contribModel;
abstract protected FilteredAbstractTableModel createContribModel();
abstract protected InstallerTableCell createCellRenderer();
abstract protected InstallerTableCell createCellEditor();
// Bottom:
// - Progress bar
protected final ProgressJProgressBar progressBar;
protected final Box progressBox;
protected final Box errorMessageBox;
private final JLabel errorMessage;
public InstallerJDialog(Frame parent, String title, ModalityType applicationModal, String noConnectionErrorMessage) {
super(parent, title, applicationModal);
this.noConnectionErrorMessage = noConnectionErrorMessage;
setResizable(true);
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
{
categoryChooser = new JComboBox();
categoryChooser.setMaximumRowCount(20);
categoryChooser.setEnabled(false);
filterField = new FilterJTextField(_("Filter your search...")) {
@Override
protected void onFilter(String[] _filters) {
filters = _filters;
if (contribTable.getCellEditor() != null) {
contribTable.getCellEditor().stopCellEditing();
}
updateIndexFilter(filters, categoryFilter);
}
};
filtersContainer = new JPanel();
filtersContainer.setLayout(new BoxLayout(filtersContainer, BoxLayout.X_AXIS));
filtersContainer.add(Box.createHorizontalStrut(5));
filtersContainer.add(new JLabel(_("Type")));
filtersContainer.add(Box.createHorizontalStrut(5));
filtersContainer.add(categoryChooser);
filtersContainer.add(Box.createHorizontalStrut(5));
filtersContainer.add(filterField);
filtersContainer.setBorder(new EmptyBorder(7, 7, 7, 7));
pane.add(filtersContainer, BorderLayout.NORTH);
}
contribModel = createContribModel();
contribTable = new JTable(contribModel);
contribTable.setTableHeader(null);
contribTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
contribTable.setColumnSelectionAllowed(false);
contribTable.setDragEnabled(false);
contribTable.setIntercellSpacing(new Dimension(0, 1));
contribTable.setShowVerticalLines(false);
contribTable.setSelectionBackground(Theme.getColor("status.notice.bgcolor"));
contribTable.addKeyListener(new AbstractKeyListener() {
@Override
public void keyReleased(KeyEvent keyEvent) {
if (keyEvent.getKeyCode() != KeyEvent.VK_DOWN && keyEvent.getKeyCode() != KeyEvent.VK_UP) {
return;
}
if (!contribTable.isEnabled()) {
return;
}
contribTable.editCellAt(contribTable.getSelectedRow(), contribTable.getSelectedColumn());
}
});
{
TableColumnModel tcm = contribTable.getColumnModel();
TableColumn col = tcm.getColumn(DESCRIPTION_COL);
col.setCellRenderer(createCellRenderer());
col.setCellEditor(createCellEditor());
col.setResizable(true);
}
{
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(contribTable);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.getVerticalScrollBar().setUnitIncrement(7);
pane.add(scrollPane, BorderLayout.CENTER);
}
pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST);
pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST);
progressBar = new ProgressJProgressBar();
progressBar.setStringPainted(true);
progressBar.setString(" ");
progressBar.setVisible(true);
errorMessage = new JLabel("");
errorMessage.setForeground(Color.RED);
{
JButton cancelButton = new JButton(_("Cancel"));
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
onCancelPressed();
}
});
progressBox = Box.createHorizontalBox();
progressBox.add(progressBar);
progressBox.add(Box.createHorizontalStrut(5));
progressBox.add(cancelButton);
JButton dismissErrorMessageButton = new JButton(_("OK"));
dismissErrorMessageButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
clearErrorMessage();
}
});
errorMessageBox = Box.createHorizontalBox();
errorMessageBox.add(Box.createHorizontalGlue());
errorMessageBox.add(errorMessage);
errorMessageBox.add(Box.createHorizontalGlue());
errorMessageBox.add(dismissErrorMessageButton);
errorMessageBox.setVisible(false);
}
{
JPanel progressPanel = new JPanel();
progressPanel.setBorder(new EmptyBorder(7, 7, 7, 7));
progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS));
progressPanel.add(progressBox);
progressPanel.add(errorMessageBox);
pane.add(progressPanel, BorderLayout.SOUTH);
}
setProgressVisible(false, "");
setMinimumSize(new Dimension(800, 450));
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
Base.registerWindowCloseKeys(getRootPane(), new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
InstallerJDialog.this.dispatchEvent(new WindowEvent(InstallerJDialog.this, WindowEvent.WINDOW_CLOSING));
}
});
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
onUpdatePressed();
}
});
}
public void updateIndexFilter(String[] filters, Predicate<T>... additionalFilters) {
Collection<Predicate<T>> notNullAdditionalFilters = Collections2.filter(Arrays.asList(additionalFilters), Predicates.notNull());
contribModel.updateIndexFilter(filters, notNullAdditionalFilters.toArray(new Predicate[notNullAdditionalFilters.size()]));
}
public void setErrorMessage(String message) {
errorMessage.setText("<html><body>" + message + "</body></html>");
errorMessageBox.setVisible(true);
}
public void clearErrorMessage() {
errorMessage.setText("");
errorMessageBox.setVisible(false);
}
public void setProgressVisible(boolean visible, String status) {
if (visible) {
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
} else {
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
progressBox.setVisible(visible);
filterField.setEnabled(!visible);
categoryChooser.setEnabled(!visible);
contribTable.setEnabled(!visible);
errorMessageBox.setVisible(false);
if (contribTable.getCellEditor() != null) {
((InstallerTableCell) contribTable.getCellEditor()).setEnabled(!visible);
((InstallerTableCell) contribTable.getCellEditor()).setStatus(status);
}
}
protected final ActionListener categoryChooserActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
DropdownItem<T> selected = (DropdownItem<T>) categoryChooser.getSelectedItem();
if (categoryFilter == null || !categoryFilter.equals(selected)) {
categoryFilter = selected.getFilterPredicate();
if (contribTable.getCellEditor() != null) {
contribTable.getCellEditor().stopCellEditing();
}
updateIndexFilter(filters, categoryFilter);
}
}
};
public void setFilterText(String filterText) {
for (FocusListener listener : filterField.getFocusListeners()) {
listener.focusGained(new FocusEvent(filterField, FocusEvent.FOCUS_GAINED));
}
filterField.setText(filterText);
}
/**
* Action performed when the Cancel button is pressed.
*/
protected void onCancelPressed() {
clearErrorMessage();
}
/**
* Action performed when the "Update List" button is pressed.
*/
protected void onUpdatePressed() {
clearErrorMessage();
}
}

View File

@ -0,0 +1,65 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import cc.arduino.contributions.ui.InstallerJDialog;
import javax.swing.*;
import static processing.app.I18n._;
public class InstallerJDialogUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
private final InstallerJDialog parent;
private final String connectionErrorMessage;
public InstallerJDialogUncaughtExceptionHandler(InstallerJDialog parent, String connectionErrorMessage) {
this.parent = parent;
this.connectionErrorMessage = connectionErrorMessage;
}
@Override
public void uncaughtException(Thread t, final Throwable e) {
String errorMessage = _(e.getMessage().substring(e.getMessage().indexOf(":") + 1));
if (errorMessage.startsWith("Error downloading")) {
errorMessage = connectionErrorMessage;
}
final String finalErrorMessage = errorMessage;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.err.println(finalErrorMessage);
e.printStackTrace();
}
});
parent.setErrorMessage(finalErrorMessage);
}
}

View File

@ -0,0 +1,61 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.BadLocationException;
import java.awt.*;
public abstract class InstallerTableCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
public void setEnabled(boolean b) {
}
public void setStatus(String s) {
}
protected void setJTextPaneDimensionToFitContainedText(JTextPane jTextPane, int width) {
Dimension minimumDimension = new Dimension(width, 10);
jTextPane.setPreferredSize(minimumDimension);
jTextPane.setSize(minimumDimension);
try {
Rectangle r = jTextPane.modelToView(jTextPane.getDocument().getLength());
//r.height += jTextPane.modelToView(0).y; // add margins
Dimension d = new Dimension(minimumDimension.width, r.y + r.height);
jTextPane.setPreferredSize(d);
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui;
import javax.swing.JProgressBar;
import cc.arduino.utils.Progress;
@SuppressWarnings("serial")
public class ProgressJProgressBar extends JProgressBar {
public void setValue(Progress p) {
setValue((int) p.getProgress());
if (p.getStatus() != null)
setString(p.getStatus());
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui.listeners;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public abstract class AbstractKeyListener implements KeyListener {
@Override
public void keyTyped(KeyEvent keyEvent) {
}
@Override
public void keyPressed(KeyEvent keyEvent) {
}
@Override
public void keyReleased(KeyEvent keyEvent) {
}
}

View File

@ -0,0 +1,76 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.contributions.ui.listeners;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class DelegatingKeyListener implements KeyListener {
private final Component delegate;
public DelegatingKeyListener(Component delegate) {
this.delegate = delegate;
}
@Override
public void keyTyped(final KeyEvent keyEvent) {
if (delegate.getKeyListeners() == null) {
return;
}
for (KeyListener listener : delegate.getKeyListeners()) {
listener.keyTyped(keyEvent);
}
}
@Override
public void keyPressed(KeyEvent keyEvent) {
if (delegate.getKeyListeners() == null) {
return;
}
for (KeyListener listener : delegate.getKeyListeners()) {
listener.keyPressed(keyEvent);
}
}
@Override
public void keyReleased(KeyEvent keyEvent) {
if (delegate.getKeyListeners() == null) {
return;
}
for (KeyListener listener : delegate.getKeyListeners()) {
listener.keyReleased(keyEvent);
}
}
}

View File

@ -1,3 +1,32 @@
/*
* This file is part of Arduino.
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*/
package cc.arduino.packages;
import processing.app.AbstractMonitor;

View File

@ -1,11 +1,43 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* This file is part of Arduino.
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*/
package cc.arduino.packages.formatter;
import processing.app.Base;
import processing.app.Editor;
import processing.app.helpers.FileUtils;
import processing.app.syntax.JEditTextArea;
import processing.app.syntax.SketchTextArea;
import processing.app.tools.Tool;
import javax.swing.text.BadLocationException;
import java.io.File;
import java.io.IOException;
@ -13,7 +45,7 @@ import static processing.app.I18n._;
public class AStyle implements Tool {
private static String FORMATTER_CONF = "formatter.conf";
private static final String FORMATTER_CONF = "formatter.conf";
private final AStyleInterface aStyleInterface;
private final String formatterConfiguration;
@ -35,7 +67,7 @@ public class AStyle implements Tool {
try {
formatterConfiguration = FileUtils.readFileToString(formatterConf);
} catch (IOException e) {
// noop
// ignored
}
this.formatterConfiguration = formatterConfiguration;
}
@ -55,17 +87,50 @@ public class AStyle implements Tool {
return;
}
JEditTextArea textArea = editor.getTextArea();
int line = textArea.getLineOfOffset(textArea.getCaretPosition());
int lineOffset = textArea.getCaretPosition() - textArea.getLineStartOffset(line);
SketchTextArea textArea = editor.getTextArea();
int line = getLineOfOffset(textArea);
int lineOffset = getLineOffset(textArea, line);
editor.getTextArea().getUndoManager().beginInternalAtomicEdit();
editor.setText(formattedText);
editor.getSketch().setModified(true);
textArea.setCaretPosition(Math.min(textArea.getLineStartOffset(line) + lineOffset, textArea.getSafeLineStopOffset(line) - 1));
editor.getTextArea().getUndoManager().endInternalAtomicEdit();
if (line != -1 && lineOffset != -1) {
setCaretPosition(textArea, line, lineOffset);
}
// mark as finished
editor.statusNotice(_("Auto Format finished."));
}
private void setCaretPosition(SketchTextArea textArea, int line, int lineOffset) {
try {
textArea.setCaretPosition(Math.min(textArea.getLineStartOffset(line) + lineOffset, textArea.getLineEndOffset(line) - 1));
} catch (BadLocationException e) {
e.printStackTrace();
}
}
private int getLineOffset(SketchTextArea textArea, int line) {
try {
return textArea.getCaretPosition() - textArea.getLineStartOffset(line);
} catch (BadLocationException e) {
e.printStackTrace();
}
return -1;
}
private int getLineOfOffset(SketchTextArea textArea) {
try {
return textArea.getLineOfOffset(textArea.getCaretPosition());
} catch (BadLocationException e) {
e.printStackTrace();
}
return -1;
}
@Override
public String getMenuTitle() {
return _("Auto Format");

View File

@ -1,3 +1,32 @@
/*
* This file is part of Arduino.
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*/
package cc.arduino.packages.formatter;
import processing.app.Base;

View File

@ -48,10 +48,7 @@ public class Event extends ActionEvent {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString());
sb.append("\n").append(payload.toString());
return sb.toString();
return super.toString() + "\n" + payload.toString();
}
}

View File

@ -0,0 +1,96 @@
/*
* This file is part of Arduino.
*
* Code inspired by this tutorial http://wiki.netbeans.org/Splash_Screen_Beginner_Tutorial. License says "You may modify and use it as you wish."
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.view;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.Map;
public class SplashScreenHelper {
private final Map desktopHints;
private final SplashScreen splash;
private Rectangle2D.Double splashTextArea;
private Graphics2D splashGraphics;
public SplashScreenHelper(SplashScreen splash) {
this.splash = splash;
Toolkit tk = Toolkit.getDefaultToolkit();
desktopHints = (Map) tk.getDesktopProperty("awt.font.desktophints");
}
public void splashText(String str) {
if (splash == null) {
printText(str);
return;
}
if (!splash.isVisible()) {
return;
}
if (splashTextArea == null) {
// stake out some area for our status information
splashTextArea = new Rectangle2D.Double(0, 300, 520, 30);
// create the Graphics environment for drawing status info
splashGraphics = splash.createGraphics();
if (desktopHints != null) {
splashGraphics.addRenderingHints(desktopHints);
}
}
// erase the last status text
splashGraphics.setPaint(new Color(245, 245, 245));
splashGraphics.fill(splashTextArea);
// draw the text
splashGraphics.setPaint(Color.BLACK);
FontMetrics metrics = splashGraphics.getFontMetrics();
splashGraphics.drawString(str, (int) splashTextArea.getX() + 10, (int) splashTextArea.getY() + (30 - metrics.getHeight()) + 4);
// make sure it's displayed
splash.update();
}
public void close() {
if (splash == null) {
return;
}
splash.close();
}
private void printText(String str) {
System.out.println(str);
}
}

View File

@ -1,6 +1,8 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@ -23,37 +25,25 @@
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*/
package cc.arduino.view;
import processing.app.Preferences;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import java.awt.*;
public class StubMenuListener implements MenuListener {
public class ShowUncertifiedBoardWarning implements Runnable {
private final Frame parent;
public ShowUncertifiedBoardWarning(Frame parent) {
this.parent = parent;
@Override
public void menuSelected(MenuEvent e) {
}
@Override
public void run() {
UncertifiedBoardWarning uncertifiedBoardWarning = new UncertifiedBoardWarning(parent, new EventListener() {
@Override
public void eventHappened(cc.arduino.view.Event event) {
if (!"uncertified_board_warning_ok_pressed".equals(event.getActionCommand())) {
return;
}
Preferences.set("uncertifiedBoardWarning_dontShowMeAgain", event.getPayload().get("dontShowMeAgain").toString());
}
});
uncertifiedBoardWarning.setLocationRelativeTo(parent);
uncertifiedBoardWarning.setVisible(true);
public void menuDeselected(MenuEvent e) {
}
@Override
public void menuCanceled(MenuEvent e) {
}
}

View File

@ -1,146 +0,0 @@
/*
* This file is part of Arduino.
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*/
package cc.arduino.view;
import javax.swing.*;
import java.awt.*;
import static processing.app.I18n._;
public class UncertifiedBoardWarning extends javax.swing.JDialog {
private final EventListener listener;
public UncertifiedBoardWarning(Frame parent, EventListener listener) {
super(parent);
initComponents();
this.listener = listener;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
dontShowMeAgain = new javax.swing.JCheckBox();
ok = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(_("Uncertified board"));
setModal(true);
setName("uncertifiedBoardWarning"); // NOI18N
setResizable(false);
jLabel1.setText("<html><body>" + _("This board comes from an uncertified manufacturer.") + "<br>" + _("We won't be able to provide any support if it doesn't work as expected.") + "</body></html>");
jLabel1.setVerticalAlignment(javax.swing.SwingConstants.TOP);
dontShowMeAgain.setText(_("Don't show me again"));
dontShowMeAgain.setName("dontShowMeAgain"); // NOI18N
ok.setText(_("OK"));
ok.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(dontShowMeAgain)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 206, Short.MAX_VALUE)
.addComponent(ok, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(dontShowMeAgain)
.addComponent(ok))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void okActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okActionPerformed
Event event = new Event(evt.getSource(), evt.getID(), "uncertified_board_warning_ok_pressed");
event.getPayload().put("dontShowMeAgain", dontShowMeAgain.isSelected());
listener.eventHappened(event);
this.dispose();
}//GEN-LAST:event_okActionPerformed
/**
* @param args the command line arguments
*/
public static void main(String args[]) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
/* Create and display the dialog */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
UncertifiedBoardWarning dialog = new UncertifiedBoardWarning(new javax.swing.JFrame(), new EventListener() {
@Override
public void eventHappened(Event event) {
System.out.println(event);
}
});
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox dontShowMeAgain;
private javax.swing.JLabel jLabel1;
private javax.swing.JButton ok;
// End of variables declaration//GEN-END:variables
}

View File

@ -3,10 +3,11 @@
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
<Property name="title" type="java.lang.String" value="_(&quot;Not supported board&quot;)"/>
<Property name="title" type="java.lang.String" value="_(&quot;Additional Boards Manager URLs: &quot;)"/>
<Property name="modal" type="boolean" value="true"/>
<Property name="name" type="java.lang.String" value="uncertifiedBoardWarning" noResource="true"/>
<Property name="resizable" type="boolean" value="false"/>
<Property name="modalExclusionType" type="java.awt.Dialog$ModalExclusionType" editor="org.netbeans.modules.form.editors.EnumEditor">
<Value id="APPLICATION_EXCLUDE"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
@ -27,15 +28,16 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel1" pref="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="dontShowMeAgain" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="206" max="32767" attributes="0"/>
<Component id="ok" min="-2" pref="82" max="-2" attributes="0"/>
<EmptySpace min="0" pref="439" max="32767" attributes="0"/>
<Component id="ok" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -45,29 +47,50 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" pref="87" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="141" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="dontShowMeAgain" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ok" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="additionalBoardsManagerURLs">
<Properties>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="18"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="cancel">
<Properties>
<Property name="text" type="java.lang.String" value="&lt;html&gt;&lt;body&gt;This board comes from an non certified manufacturer.&lt;br&gt;We won&apos;t be able to provide any support if it doesn&apos;t work as expected.&lt;/body&gt;&lt;/html&gt;"/>
<Property name="verticalAlignment" type="int" value="1"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="dontShowMeAgain">
<Properties>
<Property name="text" type="java.lang.String" value="Don&apos;t show me again"/>
<Property name="name" type="java.lang.String" value="dontShowMeAgain" noResource="true"/>
<Property name="text" type="java.lang.String" value="Cancel"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="ok">
<Properties>
@ -76,6 +99,10 @@
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,216 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.view.preferences;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import processing.app.Base;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.util.Arrays;
import java.util.Collection;
import static processing.app.I18n._;
public class AdditionalBoardsManagerURLTextArea extends javax.swing.JDialog {
private ActionListener onOkListener;
public AdditionalBoardsManagerURLTextArea(Window parent) {
super(parent);
initComponents();
setLocationRelativeTo(parent);
Base.registerWindowCloseKeys(getRootPane(), new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancelActionPerformed(e);
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
javax.swing.JButton cancel = new javax.swing.JButton();
javax.swing.JButton ok = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(_("Additional Boards Manager URLs"));
setModal(true);
setModalExclusionType(java.awt.Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
additionalBoardsManagerURLs.setColumns(20);
additionalBoardsManagerURLs.setRows(5);
additionalBoardsManagerURLs.setName(""); // NOI18N
jScrollPane1.setViewportView(additionalBoardsManagerURLs);
cancel.setText(_("Cancel"));
cancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelActionPerformed(evt);
}
});
ok.setText(_("OK"));
ok.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 439, Short.MAX_VALUE)
.addComponent(ok)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancel))
.addComponent(jScrollPane1))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cancel)
.addComponent(ok))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelActionPerformed
dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}//GEN-LAST:event_cancelActionPerformed
private void okActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okActionPerformed
ActionEvent actionEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "");
onOkListener.actionPerformed(actionEvent);
cancelActionPerformed(evt);
}//GEN-LAST:event_okActionPerformed
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(AdditionalBoardsManagerURLTextArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(AdditionalBoardsManagerURLTextArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(AdditionalBoardsManagerURLTextArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(AdditionalBoardsManagerURLTextArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the dialog */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
AdditionalBoardsManagerURLTextArea dialog = new AdditionalBoardsManagerURLTextArea(new javax.swing.JFrame());
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
public void setText(String text) {
Collection<String> urls = splitAndTrim(text, ",");
additionalBoardsManagerURLs.setText(Joiner.on("\n").skipNulls().join(urls));
}
private Collection<String> splitAndTrim(String text, String separator) {
Collection<String> urls = Arrays.asList(text.split(separator));
return FluentIterable.from(urls).transform(new Function<String, String>() {
@Override
public String apply(String input) {
return input.trim();
}
}).filter(new Predicate<String>() {
@Override
public boolean apply(String input) {
return !input.isEmpty();
}
}).toList();
}
public String getText() {
Collection<String> urls = splitAndTrim(additionalBoardsManagerURLs.getText(), "\n");
return Joiner.on(",").skipNulls().join(urls);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private final javax.swing.JTextArea additionalBoardsManagerURLs = new javax.swing.JTextArea();
// End of variables declaration//GEN-END:variables
public void onOk(ActionListener listener) {
this.onOkListener = listener;
}
}

View File

@ -0,0 +1,634 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Preferences&quot;)" type="code"/>
</Property>
<Property name="modal" type="boolean" value="true"/>
<Property name="resizable" type="boolean" value="false"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="proxySettingsPanel" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="sketchbookLocationField" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="browseButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="checkboxesContainer" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="arduinoNotRunningLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="sketchbookLocationLabel" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="comboWarningsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="comboWarnings" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="morePreferencesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="showVerboseLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="verboseCompilationBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="verboseUploadBox" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="comboLanguageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fontSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="fontSizeField" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="comboLanguage" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="requiresRestartLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<Component id="preferencesFileLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="additionalBoardsManagerLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="additionalBoardsManagerField" min="-2" pref="494" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="extendedAdditionalUrlFieldWindow" min="-2" pref="36" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="okButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="sketchbookLocationLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="sketchbookLocationField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="browseButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="comboLanguageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comboLanguage" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="requiresRestartLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="fontSizeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fontSizeField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="showVerboseLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="verboseCompilationBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="verboseUploadBox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="comboWarningsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comboWarnings" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="checkboxesContainer" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="proxySettingsPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
<Component id="additionalBoardsManagerLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="additionalBoardsManagerField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="extendedAdditionalUrlFieldWindow" min="-2" pref="27" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="morePreferencesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="preferencesFileLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="arduinoNotRunningLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="sketchbookLocationLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Sketchbook location:&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="sketchbookLocationField">
<Properties>
<Property name="columns" type="int" value="40"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="browseButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="I18n.PROMPT_BROWSE" type="code"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="browseButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="comboLanguageLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Editor language: &quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JComboBox" name="comboLanguage">
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JComboBox(languages)"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="requiresRestartLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot; (requires restart of Arduino)&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="fontSizeLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Editor font size: &quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="fontSizeField">
<Properties>
<Property name="columns" type="int" value="4"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value=""/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="showVerboseLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Show verbose output during: &quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JCheckBox" name="verboseCompilationBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;compilation &quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="verboseUploadBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;upload&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="comboWarningsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Compiler warnings: &quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JComboBox" name="comboWarnings">
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JComboBox(warningItems)"/>
</AuxValues>
</Component>
<Container class="javax.swing.JPanel" name="proxySettingsPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="&lt;User Code&gt;">
<Connection PropertyName="titleX" code="_(&quot;Proxy Settings&quot;)" type="code"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="proxyHTTPSServerLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Component id="proxyHTTPServerLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="proxyUserLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="proxyHTTPServer" max="32767" attributes="0"/>
<Component id="proxyHTTPSServer" max="32767" attributes="0"/>
<Component id="proxyUser" alignment="1" max="32767" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="proxyHTTPSPortLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="proxyPasswordLabel" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="proxyHTTPPortLabel" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="proxyHTTPSPort" alignment="0" max="32767" attributes="0"/>
<Component id="proxyHTTPPort" alignment="0" max="32767" attributes="0"/>
<Component id="proxyPassword" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="proxyHTTPServerLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="proxyHTTPServer" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="proxyHTTPSServerLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="proxyHTTPSServer" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="proxyUser" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="proxyUserLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="proxyHTTPPortLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="proxyHTTPPort" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="proxyHTTPSPort" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="proxyHTTPSPortLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="proxyPasswordLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="proxyPassword" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="proxyHTTPServerLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Server (HTTP):&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="proxyHTTPServer">
<Properties>
<Property name="columns" type="int" value="10"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="proxyHTTPPortLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Port (HTTP):&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="proxyHTTPPort">
<Properties>
<Property name="columns" type="int" value="10"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="proxyHTTPSServerLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Server (HTTPS):&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="proxyHTTPSServer">
<Properties>
<Property name="columns" type="int" value="10"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="proxyHTTPSPortLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Port (HTTPS):&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="proxyHTTPSPort">
<Properties>
<Property name="columns" type="int" value="10"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="proxyUserLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Username:&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="proxyUser">
<Properties>
<Property name="columns" type="int" value="10"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="proxyPasswordLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Password:&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JPasswordField" name="proxyPassword">
<Properties>
<Property name="columns" type="int" value="10"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="additionalBoardsManagerLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Additional Boards Manager URLs: &quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="additionalBoardsManagerField">
</Component>
<Component class="javax.swing.JButton" name="extendedAdditionalUrlFieldWindow">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new ImageIcon(Base.getThemeImage(&quot;newwindow.gif&quot;, this))" type="code"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="extendedAdditionalUrlFieldWindowActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="morePreferencesLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="Color.GRAY" type="code"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;More preferences can be edited directly in the file&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="preferencesFileLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="PreferencesData.getPreferencesFile().getAbsolutePath()" type="code"/>
</Property>
</Properties>
<Events>
<EventHandler event="mousePressed" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="preferencesFileLabelMousePressed"/>
<EventHandler event="mouseExited" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="preferencesFileLabelMouseExited"/>
<EventHandler event="mouseEntered" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="preferencesFileLabelMouseEntered"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="arduinoNotRunningLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="Color.GRAY" type="code"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;(edit only when Arduino is not running)&quot;)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="okButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="I18n.PROMPT_OK" type="code"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="I18n.PROMPT_CANCEL" type="code"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Container class="javax.swing.JPanel" name="checkboxesContainer">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="1"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="displayLineNumbersBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Display line numbers&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="enableCodeFoldingBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Enable Code Folding&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="verifyUploadBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Verify code after upload&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="externalEditorBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Use external editor&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="checkUpdatesBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Check for updates on startup&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="updateExtensionBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Update sketch files to new extension on save (.pde -&gt; .ino)&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="autoAssociateBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Automatically associate .ino files with Arduino&quot;)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="saveVerifyUploadBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="_(&quot;Save when verifying or uploading&quot;)" type="code"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,770 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package cc.arduino.view.preferences;
import processing.app.Base;
import processing.app.Editor;
import processing.app.I18n;
import processing.app.PreferencesData;
import processing.app.helpers.FileUtils;
import processing.app.helpers.OSUtils;
import processing.app.legacy.PApplet;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.File;
import static processing.app.I18n._;
public class Preferences extends javax.swing.JDialog {
private final Language[] languages;
private final Language[] missingLanguages;
private final WarningItem[] warningItems;
private final Base base;
public static class Language {
private final String name;
private final String originalName;
private final String isoCode;
public Language(String name, String originalName, String isoCode) {
this.name = name;
this.originalName = originalName;
this.isoCode = isoCode;
}
public String toString() {
if (originalName.length() == 0) {
return name;
}
return originalName + " (" + name + ")";
}
public String getIsoCode() {
return isoCode;
}
}
private static class WarningItem {
private final String value;
private final String translation;
public WarningItem(String value, String translation) {
this.value = value;
this.translation = translation;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return translation;
}
}
public Preferences(Window parent, Base base) {
super(parent);
this.base = base;
this.languages = new Language[]{
new Language(_("System Default"), "", ""),
new Language(_("Albanian"), "shqip", "sq"),
new Language(_("Arabic"), "العربية", "ar"),
new Language(_("Aragonese"), "Aragonés", "an"),
new Language(_("Belarusian"), "Беларуская мова", "be"),
new Language(_("Bulgarian"), "български", "bg"),
new Language(_("Catalan"), "Català", "ca"),
new Language(_("Chinese Simplified"), "简体中文", "zh_CN"),
new Language(_("Chinese Traditional"), "繁體中文", "zh_TW"),
new Language(_("Croatian"), "Hrvatski", "hr_HR"),
new Language(_("Czech (Czech Republic)"), "český (Czech Republic)", "cs_CZ"),
new Language(_("Danish (Denmark)"), "Dansk (Denmark)", "da_DK"),
new Language(_("Dutch"), "Nederlands", "nl"),
new Language(_("English"), "English", "en"),
new Language(_("English (United Kingdom)"), "English (United Kingdom)", "en_GB"),
new Language(_("Estonian"), "Eesti", "et"),
new Language(_("Estonian (Estonia)"), "Eesti keel", "et_EE"),
new Language(_("Filipino"), "Pilipino", "fil"),
new Language(_("Finnish"), "Suomi", "fi"),
new Language(_("French"), "Français", "fr"),
new Language(_("Canadian French"), "Canadienne-français", "fr_CA"),
new Language(_("Galician"), "Galego", "gl"),
new Language(_("Georgian"), "საქართველოს", "ka_GE"),
new Language(_("German"), "Deutsch", "de_DE"),
new Language(_("Greek"), "ελληνικά", "el_GR"),
new Language(_("Hebrew"), "עברית", "he"),
new Language(_("Hindi"), "हिंदी", "hi"),
new Language(_("Hungarian"), "Magyar", "hu"),
new Language(_("Indonesian"), "Bahasa Indonesia", "id"),
new Language(_("Italian"), "Italiano", "it_IT"),
new Language(_("Japanese"), "日本語", "ja_JP"),
new Language(_("Korean"), "한국어", "ko_KR"),
new Language(_("Latvian"), "Latviešu", "lv_LV"),
new Language(_("Lithuaninan"), "Lietuvių Kalba", "lt_LT"),
new Language(_("Norwegian Bokmål"), "Norsk bokmål", "nb_NO"),
new Language(_("Persian"), "فارسی", "fa"),
new Language(_("Polish"), "Język Polski", "pl"),
new Language(_("Portuguese (Brazil)"), "Português (Brazil)", "pt_BR"),
new Language(_("Portuguese (Portugal)"), "Português (Portugal)", "pt_PT"),
new Language(_("Romanian"), "Română", "ro"),
new Language(_("Russian"), "Русский", "ru"),
new Language(_("Slovenian"), "Slovenščina", "sl_SI"),
new Language(_("Spanish"), "Español", "es"),
new Language(_("Swedish"), "Svenska", "sv"),
new Language(_("Tamil"), "தமிழ்", "ta"),
new Language(_("Turkish"), "Türk", "tr"),
new Language(_("Ukrainian"), "Український", "uk"),
new Language(_("Vietnamese"), "Tiếng Việt", "vi"),
};
this.missingLanguages = new Language[]{
new Language(_("Afrikaans"), "Afrikaans", "af"),
new Language(_("Armenian"), "Հայերեն", "hy"),
new Language(_("Asturian"), "Asturianu", "ast"),
new Language(_("Basque"), "Euskara", "eu"),
new Language(_("Bengali (India)"), "বাংলা (India)", "bn_IN"),
new Language(_("Bosnian"), "Bosanski", "bs"),
new Language(_("Burmese (Myanmar)"), "ဗမာစကား", "my_MM"),
new Language(_("Chinese (China)"), "", "zh_CN"),
new Language(_("Chinese (Hong Kong)"), "", "zh_HK"),
new Language(_("Chinese (Taiwan)"), "", "zh_TW"),
new Language(_("Chinese (Taiwan) (Big5)"), "", "zh_TW.Big5"),
new Language(_("Czech"), "český", "cs"),
new Language(_("Danish"), "Dansk", "da"),
new Language(_("Dutch (Netherlands)"), "Nederlands", "nl_NL"),
new Language(_("Galician (Spain)"), "Galego (Spain)", "gl_ES"),
new Language(_("Nepali"), "नेपाली", "ne"),
new Language(_("N'Ko"), "ߒߞߏ", "nqo"),
new Language(_("Marathi"), "मराठी", "mr"),
new Language(_("Malay (Malaysia)"), "بهاس ملايو (Malaysia)", "ms_MY"),
new Language(_("Norwegian"), "Norsk", "no"),
new Language(_("Norwegian Nynorsk"), "Norsk Nynorsk", "nn"),
new Language(_("Portugese"), "Português", "pt"),
new Language(_("Persian (Iran)"), "فارسی (Iran)", "fa_IR"),
new Language(_("Slovak"), "Slovenčina", "sk"),
new Language(_("Swahili"), "كِسوَهِل", "sw"),
new Language(_("Talossan"), "Talossan", "tzl"),
new Language(_("Urdu (Pakistan)"), "اردو (Pakistan)", "ur_PK"),
new Language(_("Western Frisian"), "Western Frisian", "fy"),
};
this.warningItems = new WarningItem[]{
new WarningItem("none", _("None")),
new WarningItem("default", _("Default")),
new WarningItem("more", _("More")),
new WarningItem("all", _("All"))
};
initComponents();
Base.registerWindowCloseKeys(getRootPane(), new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancelButtonActionPerformed(e);
}
});
if (!OSUtils.isWindows() || base.getPortableFolder() != null) {
autoAssociateBox.setEnabled(false);
autoAssociateBox.getParent().remove(autoAssociateBox);
}
showPrerefencesData();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.JLabel sketchbookLocationLabel = new javax.swing.JLabel();
sketchbookLocationField = new javax.swing.JTextField();
javax.swing.JButton browseButton = new javax.swing.JButton();
javax.swing.JLabel comboLanguageLabel = new javax.swing.JLabel();
comboLanguage = new JComboBox(languages);
javax.swing.JLabel requiresRestartLabel = new javax.swing.JLabel();
javax.swing.JLabel fontSizeLabel = new javax.swing.JLabel();
fontSizeField = new javax.swing.JTextField();
javax.swing.JLabel showVerboseLabel = new javax.swing.JLabel();
verboseCompilationBox = new javax.swing.JCheckBox();
verboseUploadBox = new javax.swing.JCheckBox();
javax.swing.JLabel comboWarningsLabel = new javax.swing.JLabel();
comboWarnings = new JComboBox(warningItems);
javax.swing.JPanel proxySettingsPanel = new javax.swing.JPanel();
javax.swing.JLabel proxyHTTPServerLabel = new javax.swing.JLabel();
proxyHTTPServer = new javax.swing.JTextField();
javax.swing.JLabel proxyHTTPPortLabel = new javax.swing.JLabel();
proxyHTTPPort = new javax.swing.JTextField();
javax.swing.JLabel proxyHTTPSServerLabel = new javax.swing.JLabel();
proxyHTTPSServer = new javax.swing.JTextField();
javax.swing.JLabel proxyHTTPSPortLabel = new javax.swing.JLabel();
proxyHTTPSPort = new javax.swing.JTextField();
javax.swing.JLabel proxyUserLabel = new javax.swing.JLabel();
proxyUser = new javax.swing.JTextField();
javax.swing.JLabel proxyPasswordLabel = new javax.swing.JLabel();
proxyPassword = new javax.swing.JPasswordField();
javax.swing.JLabel additionalBoardsManagerLabel = new javax.swing.JLabel();
additionalBoardsManagerField = new javax.swing.JTextField();
javax.swing.JButton extendedAdditionalUrlFieldWindow = new javax.swing.JButton();
javax.swing.JLabel morePreferencesLabel = new javax.swing.JLabel();
preferencesFileLabel = new javax.swing.JLabel();
javax.swing.JLabel arduinoNotRunningLabel = new javax.swing.JLabel();
javax.swing.JButton okButton = new javax.swing.JButton();
javax.swing.JButton cancelButton = new javax.swing.JButton();
javax.swing.JPanel checkboxesContainer = new javax.swing.JPanel();
displayLineNumbersBox = new javax.swing.JCheckBox();
enableCodeFoldingBox = new javax.swing.JCheckBox();
verifyUploadBox = new javax.swing.JCheckBox();
externalEditorBox = new javax.swing.JCheckBox();
checkUpdatesBox = new javax.swing.JCheckBox();
updateExtensionBox = new javax.swing.JCheckBox();
autoAssociateBox = new javax.swing.JCheckBox();
saveVerifyUploadBox = new javax.swing.JCheckBox();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(_("Preferences"));
setModal(true);
setResizable(false);
sketchbookLocationLabel.setText(_("Sketchbook location:"));
sketchbookLocationField.setColumns(40);
browseButton.setText(I18n.PROMPT_BROWSE);
browseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
browseButtonActionPerformed(evt);
}
});
comboLanguageLabel.setText(_("Editor language: "));
requiresRestartLabel.setText(_(" (requires restart of Arduino)"));
fontSizeLabel.setText(_("Editor font size: "));
fontSizeField.setColumns(4);
showVerboseLabel.setText(_("Show verbose output during: "));
verboseCompilationBox.setText(_("compilation "));
verboseUploadBox.setText(_("upload"));
comboWarningsLabel.setText(_("Compiler warnings: "));
proxySettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(_("Proxy Settings")));
proxyHTTPServerLabel.setText(_("Server (HTTP):"));
proxyHTTPServer.setColumns(10);
proxyHTTPPortLabel.setText(_("Port (HTTP):"));
proxyHTTPPort.setColumns(10);
proxyHTTPSServerLabel.setText(_("Server (HTTPS):"));
proxyHTTPSServer.setColumns(10);
proxyHTTPSPortLabel.setText(_("Port (HTTPS):"));
proxyHTTPSPort.setColumns(10);
proxyUserLabel.setText(_("Username:"));
proxyUser.setColumns(10);
proxyPasswordLabel.setText(_("Password:"));
proxyPassword.setColumns(10);
javax.swing.GroupLayout proxySettingsPanelLayout = new javax.swing.GroupLayout(proxySettingsPanel);
proxySettingsPanel.setLayout(proxySettingsPanelLayout);
proxySettingsPanelLayout.setHorizontalGroup(
proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(proxySettingsPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(proxyHTTPSServerLabel)
.addGroup(proxySettingsPanelLayout.createSequentialGroup()
.addGap(8, 8, 8)
.addComponent(proxyHTTPServerLabel)))
.addComponent(proxyUserLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(proxyHTTPServer)
.addComponent(proxyHTTPSServer)
.addComponent(proxyUser, javax.swing.GroupLayout.Alignment.TRAILING))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(proxyHTTPSPortLabel)
.addComponent(proxyPasswordLabel, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(proxyHTTPPortLabel, javax.swing.GroupLayout.Alignment.TRAILING))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(proxyHTTPSPort, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(proxyHTTPPort, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(proxyPassword, javax.swing.GroupLayout.Alignment.LEADING))
.addContainerGap())
);
proxySettingsPanelLayout.setVerticalGroup(
proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(proxySettingsPanelLayout.createSequentialGroup()
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(proxySettingsPanelLayout.createSequentialGroup()
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(proxyHTTPServerLabel)
.addComponent(proxyHTTPServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(proxyHTTPSServerLabel)
.addComponent(proxyHTTPSServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(proxyUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(proxyUserLabel)))
.addGroup(proxySettingsPanelLayout.createSequentialGroup()
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(proxyHTTPPortLabel)
.addComponent(proxyHTTPPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(proxyHTTPSPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(proxyHTTPSPortLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(proxySettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(proxyPasswordLabel)
.addComponent(proxyPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
additionalBoardsManagerLabel.setText(_("Additional Boards Manager URLs: "));
extendedAdditionalUrlFieldWindow.setIcon(new ImageIcon(Base.getThemeImage("newwindow.gif", this)));
extendedAdditionalUrlFieldWindow.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
extendedAdditionalUrlFieldWindowActionPerformed(evt);
}
});
morePreferencesLabel.setForeground(Color.GRAY);
morePreferencesLabel.setText(_("More preferences can be edited directly in the file"));
preferencesFileLabel.setText(PreferencesData.getPreferencesFile().getAbsolutePath());
preferencesFileLabel.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
preferencesFileLabelMousePressed(evt);
}
public void mouseExited(java.awt.event.MouseEvent evt) {
preferencesFileLabelMouseExited(evt);
}
public void mouseEntered(java.awt.event.MouseEvent evt) {
preferencesFileLabelMouseEntered(evt);
}
});
arduinoNotRunningLabel.setForeground(Color.GRAY);
arduinoNotRunningLabel.setText(_("(edit only when Arduino is not running)"));
okButton.setText(I18n.PROMPT_OK);
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
cancelButton.setText(I18n.PROMPT_CANCEL);
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
checkboxesContainer.setLayout(new javax.swing.BoxLayout(checkboxesContainer, javax.swing.BoxLayout.Y_AXIS));
displayLineNumbersBox.setText(_("Display line numbers"));
checkboxesContainer.add(displayLineNumbersBox);
enableCodeFoldingBox.setText(_("Enable Code Folding"));
checkboxesContainer.add(enableCodeFoldingBox);
verifyUploadBox.setText(_("Verify code after upload"));
checkboxesContainer.add(verifyUploadBox);
externalEditorBox.setText(_("Use external editor"));
checkboxesContainer.add(externalEditorBox);
checkUpdatesBox.setText(_("Check for updates on startup"));
checkboxesContainer.add(checkUpdatesBox);
updateExtensionBox.setText(_("Update sketch files to new extension on save (.pde -> .ino)"));
checkboxesContainer.add(updateExtensionBox);
autoAssociateBox.setText(_("Automatically associate .ino files with Arduino"));
checkboxesContainer.add(autoAssociateBox);
saveVerifyUploadBox.setText(_("Save when verifying or uploading"));
checkboxesContainer.add(saveVerifyUploadBox);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(proxySettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(sketchbookLocationField)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(browseButton))
.addComponent(checkboxesContainer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(arduinoNotRunningLabel)
.addComponent(sketchbookLocationLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(comboWarningsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboWarnings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(morePreferencesLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(showVerboseLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(verboseCompilationBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(verboseUploadBox))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(comboLanguageLabel)
.addComponent(fontSizeLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(fontSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addComponent(comboLanguage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(requiresRestartLabel))))
.addComponent(preferencesFileLabel))
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(additionalBoardsManagerLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(additionalBoardsManagerField, javax.swing.GroupLayout.PREFERRED_SIZE, 494, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(extendedAdditionalUrlFieldWindow, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)))))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(sketchbookLocationLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(sketchbookLocationField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(browseButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(comboLanguageLabel)
.addComponent(comboLanguage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(requiresRestartLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(fontSizeLabel)
.addComponent(fontSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(showVerboseLabel)
.addComponent(verboseCompilationBox)
.addComponent(verboseUploadBox))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(comboWarningsLabel)
.addComponent(comboWarnings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(checkboxesContainer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(proxySettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(additionalBoardsManagerLabel)
.addComponent(additionalBoardsManagerField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(extendedAdditionalUrlFieldWindow, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(morePreferencesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(preferencesFileLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(arduinoNotRunningLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cancelButton)
.addComponent(okButton))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
File dflt = new File(sketchbookLocationField.getText());
File file = Base.selectFolder(_("Select new sketchbook location"), dflt, this);
if (file != null) {
String path = file.getAbsolutePath();
if (Base.getPortableFolder() != null) {
path = FileUtils.relativePath(Base.getPortableFolder().toString(), path);
if (path == null) {
path = Base.getPortableSketchbookFolder();
}
}
sketchbookLocationField.setText(path);
}
}//GEN-LAST:event_browseButtonActionPerformed
private void extendedAdditionalUrlFieldWindowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_extendedAdditionalUrlFieldWindowActionPerformed
final AdditionalBoardsManagerURLTextArea additionalBoardsManagerURLTextArea = new AdditionalBoardsManagerURLTextArea(this);
additionalBoardsManagerURLTextArea.setText(additionalBoardsManagerField.getText());
additionalBoardsManagerURLTextArea.onOk(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
additionalBoardsManagerField.setText(additionalBoardsManagerURLTextArea.getText());
}
});
additionalBoardsManagerURLTextArea.setVisible(true);
}//GEN-LAST:event_extendedAdditionalUrlFieldWindowActionPerformed
private void preferencesFileLabelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_preferencesFileLabelMouseEntered
preferencesFileLabel.setForeground(new Color(0, 0, 140));
}//GEN-LAST:event_preferencesFileLabelMouseEntered
private void preferencesFileLabelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_preferencesFileLabelMousePressed
Base.openFolder(PreferencesData.getPreferencesFile().getParentFile());
}//GEN-LAST:event_preferencesFileLabelMousePressed
private void preferencesFileLabelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_preferencesFileLabelMouseExited
preferencesFileLabel.setForeground(Color.BLACK);
}//GEN-LAST:event_preferencesFileLabelMouseExited
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}//GEN-LAST:event_cancelButtonActionPerformed
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
savePreferencesData();
for (Editor editor : base.getEditors()) {
editor.applyPreferences();
}
cancelButtonActionPerformed(evt);
}//GEN-LAST:event_okButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTextField additionalBoardsManagerField;
private javax.swing.JCheckBox autoAssociateBox;
private javax.swing.JCheckBox checkUpdatesBox;
private javax.swing.JComboBox comboLanguage;
private javax.swing.JComboBox comboWarnings;
private javax.swing.JCheckBox displayLineNumbersBox;
private javax.swing.JCheckBox enableCodeFoldingBox;
private javax.swing.JCheckBox externalEditorBox;
private javax.swing.JTextField fontSizeField;
private javax.swing.JLabel preferencesFileLabel;
private javax.swing.JTextField proxyHTTPPort;
private javax.swing.JTextField proxyHTTPSPort;
private javax.swing.JTextField proxyHTTPSServer;
private javax.swing.JTextField proxyHTTPServer;
private javax.swing.JPasswordField proxyPassword;
private javax.swing.JTextField proxyUser;
private javax.swing.JCheckBox saveVerifyUploadBox;
private javax.swing.JTextField sketchbookLocationField;
private javax.swing.JCheckBox updateExtensionBox;
private javax.swing.JCheckBox verboseCompilationBox;
private javax.swing.JCheckBox verboseUploadBox;
private javax.swing.JCheckBox verifyUploadBox;
// End of variables declaration//GEN-END:variables
private void savePreferencesData() {
String oldPath = PreferencesData.get("sketchbook.path");
String newPath = sketchbookLocationField.getText();
if (newPath.isEmpty()) {
if (base.getPortableFolder() == null) {
newPath = base.getDefaultSketchbookFolderOrPromptForIt().toString();
} else {
newPath = base.getPortableSketchbookFolder();
}
}
if (!newPath.equals(oldPath)) {
base.rebuildSketchbookMenus();
PreferencesData.set("sketchbook.path", newPath);
}
Language newLanguage = (Language) comboLanguage.getSelectedItem();
PreferencesData.set("editor.languages.current", newLanguage.getIsoCode());
String newSizeText = fontSizeField.getText();
try {
int newSize = Integer.parseInt(newSizeText.trim());
String pieces[] = PApplet.split(PreferencesData.get("editor.font"), ',');
pieces[2] = String.valueOf(newSize);
PreferencesData.set("editor.font", PApplet.join(pieces, ','));
} catch (Exception e) {
System.err.println(I18n.format(_("ignoring invalid font size {0}"), newSizeText));
}
// put each of the settings into the table
PreferencesData.setBoolean("build.verbose", verboseCompilationBox.isSelected());
PreferencesData.setBoolean("upload.verbose", verboseUploadBox.isSelected());
WarningItem warningItem = (WarningItem) comboWarnings.getSelectedItem();
PreferencesData.set("compiler.warning_level", warningItem.getValue());
PreferencesData.setBoolean("editor.linenumbers", displayLineNumbersBox.isSelected());
PreferencesData.setBoolean("editor.code_folding", enableCodeFoldingBox.isSelected());
PreferencesData.setBoolean("upload.verify", verifyUploadBox.isSelected());
PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
PreferencesData.setBoolean("editor.external", externalEditorBox.isSelected());
PreferencesData.setBoolean("update.check", checkUpdatesBox.isSelected());
PreferencesData.setBoolean("editor.update_extension", updateExtensionBox.isSelected());
if (autoAssociateBox != null) {
PreferencesData.setBoolean("platform.auto_file_type_associations", autoAssociateBox.isSelected());
}
PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
PreferencesData.set("proxy.http.server", proxyHTTPServer.getText());
try {
PreferencesData.set("proxy.http.port", Integer.valueOf(proxyHTTPPort.getText()).toString());
} catch (NumberFormatException e) {
PreferencesData.remove("proxy.http.port");
}
PreferencesData.set("proxy.https.server", proxyHTTPSServer.getText());
try {
PreferencesData.set("proxy.https.port", Integer.valueOf(proxyHTTPSPort.getText()).toString());
} catch (NumberFormatException e) {
PreferencesData.remove("proxy.https.port");
}
PreferencesData.set("proxy.user", proxyUser.getText());
PreferencesData.set("proxy.password", new String(proxyPassword.getPassword()));
PreferencesData.set("boardsmanager.additional.urls", additionalBoardsManagerField.getText().replace("\r\n", "\n").replace("\r", "\n").replace("\n", ","));
//editor.applyPreferences();
}
private void showPrerefencesData() {
sketchbookLocationField.setText(PreferencesData.get("sketchbook.path"));
String currentLanguageISOCode = PreferencesData.get("editor.languages.current");
for (Language language : languages) {
if (language.getIsoCode().equals(currentLanguageISOCode)) {
comboLanguage.setSelectedItem(language);
}
}
Font editorFont = PreferencesData.getFont("editor.font");
fontSizeField.setText(String.valueOf(editorFont.getSize()));
verboseCompilationBox.setSelected(PreferencesData.getBoolean("build.verbose"));
verboseUploadBox.setSelected(PreferencesData.getBoolean("upload.verbose"));
String currentWarningLevel = PreferencesData.get("compiler.warning_level", "none");
for (WarningItem item : warningItems) {
if (currentWarningLevel.equals(item.getValue())) {
comboWarnings.setSelectedItem(item);
}
}
displayLineNumbersBox.setSelected(PreferencesData.getBoolean("editor.linenumbers"));
enableCodeFoldingBox.setSelected(PreferencesData.getBoolean("editor.code_folding"));
verifyUploadBox.setSelected(PreferencesData.getBoolean("upload.verify"));
externalEditorBox.setSelected(PreferencesData.getBoolean("editor.external"));
checkUpdatesBox.setSelected(PreferencesData.getBoolean("update.check"));
updateExtensionBox.setSelected(PreferencesData.get("editor.update_extension") == null || PreferencesData.getBoolean("editor.update_extension"));
if (autoAssociateBox != null) {
autoAssociateBox.setSelected(PreferencesData.getBoolean("platform.auto_file_type_associations"));
}
saveVerifyUploadBox.setSelected(PreferencesData.getBoolean("editor.save_on_verify"));
proxyHTTPServer.setText(PreferencesData.get("proxy.http.server"));
try {
proxyHTTPPort.setText(Integer.toString(PreferencesData.getInteger("proxy.http.port", 8080)));
} catch (NumberFormatException e) {
proxyHTTPPort.setText("");
}
proxyHTTPSServer.setText(PreferencesData.get("proxy.https.server"));
try {
proxyHTTPSPort.setText(Integer.toString(PreferencesData.getInteger("proxy.https.port", 8443)));
} catch (NumberFormatException e) {
proxyHTTPSPort.setText("");
}
proxyUser.setText(PreferencesData.get("proxy.user"));
proxyPassword.setText(PreferencesData.get("proxy.password"));
additionalBoardsManagerField.setText(PreferencesData.get("boardsmanager.additional.urls"));
}
}

View File

@ -78,7 +78,7 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
getContentPane().setLayout(new BorderLayout());
Font consoleFont = Theme.getFont("console.font");
Font editorFont = Preferences.getFont("editor.font");
Font editorFont = PreferencesData.getFont("editor.font");
Font font = new Font(consoleFont.getName(), consoleFont.getStyle(), editorFont.getSize());
textArea = new TextAreaFIFO(8000000);
@ -124,12 +124,12 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
lineEndings = new JComboBox(new String[]{_("No line ending"), _("Newline"), _("Carriage return"), _("Both NL & CR")});
lineEndings.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Preferences.setInteger("serial.line_ending", lineEndings.getSelectedIndex());
PreferencesData.setInteger("serial.line_ending", lineEndings.getSelectedIndex());
noLineEndingAlert.setForeground(pane.getBackground());
}
});
if (Preferences.get("serial.line_ending") != null) {
lineEndings.setSelectedIndex(Preferences.getInteger("serial.line_ending"));
if (PreferencesData.get("serial.line_ending") != null) {
lineEndings.setSelectedIndex(PreferencesData.getInteger("serial.line_ending"));
}
lineEndings.setMaximumSize(lineEndings.getMinimumSize());
@ -160,13 +160,13 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
pack();
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
if (Preferences.get("last.screen.height") != null) {
if (PreferencesData.get("last.screen.height") != null) {
// if screen size has changed, the window coordinates no longer
// make sense, so don't use them unless they're identical
int screenW = Preferences.getInteger("last.screen.width");
int screenH = Preferences.getInteger("last.screen.height");
int screenW = PreferencesData.getInteger("last.screen.width");
int screenH = PreferencesData.getInteger("last.screen.height");
if ((screen.width == screenW) && (screen.height == screenH)) {
String locationStr = Preferences.get("last.serial.location");
String locationStr = PreferencesData.get("last.serial.location");
if (locationStr != null) {
int[] location = PApplet.parseInt(PApplet.split(locationStr, ','));
setPlacement(location);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
package processing.app;
import processing.app.syntax.JEditTextArea;
import processing.app.syntax.SketchTextArea;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
@ -11,7 +11,7 @@ public class CaretAwareUndoableEdit implements UndoableEdit {
private final UndoableEdit undoableEdit;
private final int caretPosition;
public CaretAwareUndoableEdit(UndoableEdit undoableEdit, JEditTextArea textArea) {
public CaretAwareUndoableEdit(UndoableEdit undoableEdit, SketchTextArea textArea) {
this.undoableEdit = undoableEdit;
this.caretPosition = textArea.getCaretPosition();
}

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,7 @@ public class EditorConsole extends JScrollPane {
public EditorConsole(Editor _editor) {
editor = _editor;
int maxLineCount = Preferences.getInteger("console.length");
int maxLineCount = PreferencesData.getInteger("console.length");
consoleDoc = new BufferedStyledDocument(4000, maxLineCount);
consoleTextPane = new JTextPane(consoleDoc);
@ -84,7 +84,7 @@ public class EditorConsole extends JScrollPane {
Color fgColorOut = Theme.getColor("console.output.color");
Color fgColorErr = Theme.getColor("console.error.color");
Font consoleFont = Theme.getFont("console.font");
Font editorFont = Preferences.getFont("editor.font");
Font editorFont = PreferencesData.getFont("editor.font");
Font font = new Font(consoleFont.getName(), consoleFont.getStyle(), editorFont.getSize());
stdStyle = new SimpleAttributeSet();
@ -112,7 +112,7 @@ public class EditorConsole extends JScrollPane {
// and size window accordingly
FontMetrics metrics = getFontMetrics(font);
int height = metrics.getAscent() + metrics.getDescent();
int lines = Preferences.getInteger("console.lines");
int lines = PreferencesData.getInteger("console.lines");
int sizeFudge = 6; //10; // unclear why this is necessary, but it is
setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge));
setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge));

View File

@ -1,5 +1,7 @@
package processing.app;
import cc.arduino.files.DeleteFilesOnShutdown;
import static processing.app.I18n._;
import java.io.File;
@ -33,19 +35,19 @@ class EditorConsoleStream extends OutputStream {
// The files and folders are not deleted on exit because they may be
// needed for debugging or bug reporting.
tempFolder = Base.createTempFolder("console");
tempFolder.deleteOnExit();
DeleteFilesOnShutdown.add(tempFolder);
try {
String outFileName = Preferences.get("console.output.file");
String outFileName = PreferencesData.get("console.output.file");
if (outFileName != null) {
outFile = new File(tempFolder, outFileName);
outFile.deleteOnExit();
DeleteFilesOnShutdown.add(outFile);
stdoutFile = new FileOutputStream(outFile);
}
String errFileName = Preferences.get("console.error.file");
String errFileName = PreferencesData.get("console.error.file");
if (errFileName != null) {
errFile = new File(tempFolder, errFileName);
errFile.deleteOnExit();
DeleteFilesOnShutdown.add(errFile);
stderrFile = new FileOutputStream(errFile);
}
} catch (IOException e) {
@ -56,7 +58,7 @@ class EditorConsoleStream extends OutputStream {
consoleOut = new PrintStream(new EditorConsoleStream(false));
consoleErr = new PrintStream(new EditorConsoleStream(true));
if (Preferences.getBoolean("console")) {
if (PreferencesData.getBoolean("console")) {
try {
System.setOut(consoleOut);
System.setErr(consoleErr);

View File

@ -1,3 +1,5 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Processing project - http://processing.org
@ -20,26 +22,21 @@
package processing.app;
import processing.app.helpers.OSUtils;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.Map;
import javax.swing.JComponent;
import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesMap;
import processing.app.syntax.JEditTextArea;
import processing.app.syntax.SketchTextArea;
/**
* Li'l status bar fella that shows the line number.
*/
@SuppressWarnings("serial")
public class EditorLineStatus extends JComponent {
JEditTextArea textarea;
int start = -1, stop;
Image resize;
@ -55,10 +52,8 @@ public class EditorLineStatus extends JComponent {
String name = "";
String serialport = "";
public EditorLineStatus(JEditTextArea textarea) {
this.textarea = textarea;
textarea.editorLineStatus = this;
public EditorLineStatus() {
background = Theme.getColor("linestatus.bgcolor");
font = Theme.getFont("linestatus.font");
foreground = Theme.getColor("linestatus.color");
@ -101,7 +96,7 @@ public class EditorLineStatus extends JComponent {
setBoardName(boardPreferences.get("name"));
else
setBoardName("-");
setSerialPort(Preferences.get("serial.port"));
setSerialPort(PreferencesData.get("serial.port"));
}
g.setColor(background);
Dimension size = getSize();

View File

@ -1,636 +1,83 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Processing project - http://processing.org
Copyright (c) 2004-08 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package processing.app;
import processing.app.syntax.*;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.*;
import java.awt.event.*;
import processing.app.syntax.SketchTextArea;
/**
* Filters key events for tab expansion/indent/etc.
* <p/>
* For version 0099, some changes have been made to make the indents
* smarter. There are still issues though:
* + indent happens when it picks up a curly brace on the previous line,
* but not if there's a blank line between them.
* + It also doesn't handle single indent situations where a brace
* isn't used (i.e. an if statement or for loop that's a single line).
* It shouldn't actually be using braces.
* Solving these issues, however, would probably best be done by a
* smarter parser/formatter, rather than continuing to hack this class.
*/
public class EditorListener {
public class EditorListener implements KeyListener {
private Editor editor;
private JEditTextArea textarea;
private boolean externalEditor;
private boolean tabsExpand;
private boolean tabsIndent;
private int tabSize;
private String tabString;
private boolean autoIndent;
// private int selectionStart, selectionEnd;
// private int position;
/** ctrl-alt on windows and linux, cmd-alt on mac os x */
static final int CTRL_ALT = ActionEvent.ALT_MASK |
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
public EditorListener(Editor editor, JEditTextArea textarea) {
public EditorListener(Editor editor) {
super();
this.editor = editor;
this.textarea = textarea;
// let him know that i'm leechin'
textarea.editorListener = this;
applyPreferences();
}
/** ctrl-alt on windows and linux, cmd-alt on mac os x */
static final int CTRL_ALT = ActionEvent.ALT_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
static final int CTRL_SHIFT = ActionEvent.SHIFT_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
static final int CTRL = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
public void applyPreferences() {
tabsExpand = Preferences.getBoolean("editor.tabs.expand");
//tabsIndent = Preferences.getBoolean("editor.tabs.indent");
tabSize = Preferences.getInteger("editor.tabs.size");
tabString = Editor.EMPTY.substring(0, tabSize);
autoIndent = Preferences.getBoolean("editor.indent");
externalEditor = Preferences.getBoolean("editor.external");
}
//public void setExternalEditor(boolean externalEditor) {
//this.externalEditor = externalEditor;
//}
/**
* Intercepts key pressed events for JEditTextArea.
* <p/>
* Called by JEditTextArea inside processKeyEvent(). Note that this
* won't intercept actual characters, because those are fired on
* keyTyped().
* @return true if the event has been handled (to remove it from the queue)
*/
public boolean keyPressed(KeyEvent event) {
// don't do things if the textarea isn't editable
if (externalEditor) return false;
//deselect(); // this is for paren balancing
public void keyTyped(KeyEvent event) {
char c = event.getKeyChar();
int code = event.getKeyCode();
// if (code == KeyEvent.VK_SHIFT) {
// editor.toolbar.setShiftPressed(true);
// }
//System.out.println((int)c + " " + code + " " + event);
//System.out.println();
if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
// The char is not control code when CTRL key pressed? It should be a shortcut.
if (!Character.isISOControl(c)) {
event.consume();
}
}
}
@Override
public void keyPressed(KeyEvent event) {
SketchTextArea textarea = editor.getTextArea();
if (!textarea.isEditable()) return;
Sketch sketch = editor.getSketch();
int code = event.getKeyCode();
// Navigation..
if ((event.getModifiers() & CTRL) == CTRL && code == KeyEvent.VK_TAB) {
sketch.handleNextCode();
}
// Navigation..
// FIXME: not working on LINUX !!!
if (((event.getModifiers() & CTRL_SHIFT) == CTRL_SHIFT)) {
if(code == KeyEvent.VK_TAB)
sketch.handlePrevCode();
}
// Navigation..
if ((event.getModifiers() & CTRL_ALT) == CTRL_ALT) {
if (code == KeyEvent.VK_LEFT) {
sketch.handlePrevCode();
return true;
} else if (code == KeyEvent.VK_RIGHT) {
sketch.handleNextCode();
return true;
}
}
if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
// Consume ctrl-m(carriage return) keypresses
if (code == KeyEvent.VK_M) {
event.consume(); // does nothing
return false;
}
// The char is not control code when CTRL key pressed? It should be a shortcut.
if (!Character.isISOControl(c)) {
return false;
}
}
if ((event.getModifiers() & KeyEvent.META_MASK) != 0) {
//event.consume(); // does nothing
return false;
}
// TODO i don't like these accessors. clean em up later.
if (!editor.getSketch().isModified()) {
if ((code == KeyEvent.VK_BACK_SPACE) || (code == KeyEvent.VK_TAB) ||
(code == KeyEvent.VK_ENTER) || ((c >= 32) && (c < 128))) {
sketch.setModified(true);
}
}
if ((code == KeyEvent.VK_UP) &&
((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
// back up to the last empty line
char contents[] = textarea.getText().toCharArray();
//int origIndex = textarea.getCaretPosition() - 1;
int caretIndex = textarea.getCaretPosition();
int index = calcLineStart(caretIndex - 1, contents);
//System.out.println("line start " + (int) contents[index]);
index -= 2; // step over the newline
//System.out.println((int) contents[index]);
boolean onlySpaces = true;
while (index > 0) {
if (contents[index] == 10) {
if (onlySpaces) {
index++;
break;
} else {
onlySpaces = true; // reset
}
} else if (contents[index] != ' ') {
onlySpaces = false;
}
index--;
}
// if the first char, index will be -2
if (index < 0) index = 0;
if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
textarea.setSelectionStart(caretIndex);
textarea.setSelectionEnd(index);
} else {
textarea.setCaretPosition(index);
}
event.consume();
return true;
} else if ((code == KeyEvent.VK_DOWN) &&
((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
char contents[] = textarea.getText().toCharArray();
int caretIndex = textarea.getCaretPosition();
int index = caretIndex;
int lineStart = 0;
boolean onlySpaces = false; // don't count this line
while (index < contents.length) {
if (contents[index] == 10) {
if (onlySpaces) {
index = lineStart; // this is it
break;
} else {
lineStart = index + 1;
onlySpaces = true; // reset
}
} else if (contents[index] != ' ') {
onlySpaces = false;
}
index++;
}
// if the first char, index will be -2
//if (index < 0) index = 0;
//textarea.setSelectionStart(index);
//textarea.setSelectionEnd(index);
if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
textarea.setSelectionStart(caretIndex);
textarea.setSelectionEnd(index);
} else {
textarea.setCaretPosition(index);
}
event.consume();
return true;
}
switch ((int) c) {
case 9: // TAB
if (textarea.isSelectionActive()) {
boolean outdent = (event.getModifiers() & KeyEvent.SHIFT_MASK) != 0;
editor.handleIndentOutdent(!outdent);
} else if (tabsExpand) { // expand tabs
textarea.setSelectedText(tabString);
event.consume();
return true;
} else if (tabsIndent) {
// this code is incomplete
// if this brace is the only thing on the line, outdent
//char contents[] = getCleanedContents();
char contents[] = textarea.getText().toCharArray();
// index to the character to the left of the caret
int prevCharIndex = textarea.getCaretPosition() - 1;
// now find the start of this line
int lineStart = calcLineStart(prevCharIndex, contents);
int lineEnd = lineStart;
while ((lineEnd < contents.length - 1) &&
(contents[lineEnd] != 10)) {
lineEnd++;
}
// get the number of braces, to determine whether this is an indent
int braceBalance = 0;
int index = lineStart;
while ((index < contents.length) &&
(contents[index] != 10)) {
if (contents[index] == '{') {
braceBalance++;
} else if (contents[index] == '}') {
braceBalance--;
}
index++;
}
// if it's a starting indent, need to ignore it, so lineStart
// will be the counting point. but if there's a closing indent,
// then the lineEnd should be used.
int where = (braceBalance > 0) ? lineStart : lineEnd;
int indent = calcBraceIndent(where, contents);
if (indent == -1) {
// no braces to speak of, do nothing
indent = 0;
} else {
indent += tabSize;
}
// and the number of spaces it has
int spaceCount = calcSpaceCount(prevCharIndex, contents);
textarea.setSelectionStart(lineStart);
textarea.setSelectionEnd(lineStart + spaceCount);
textarea.setSelectedText(Editor.EMPTY.substring(0, indent));
event.consume();
return true;
}
break;
case 10: // auto-indent
case 13:
if (autoIndent) {
char contents[] = textarea.getText().toCharArray();
// this is the previous character
// (i.e. when you hit return, it'll be the last character
// just before where the newline will be inserted)
int origIndex = textarea.getCaretPosition() - 1;
// NOTE all this cursing about CRLF stuff is probably moot
// NOTE since the switch to JEditTextArea, which seems to use
// NOTE only LFs internally (thank god). disabling for 0099.
// walk through the array to the current caret position,
// and count how many weirdo windows line endings there are,
// which would be throwing off the caret position number
/*
int offset = 0;
int realIndex = origIndex;
for (int i = 0; i < realIndex-1; i++) {
if ((contents[i] == 13) && (contents[i+1] == 10)) {
offset++;
realIndex++;
}
}
// back up until \r \r\n or \n.. @#($* cross platform
//System.out.println(origIndex + " offset = " + offset);
origIndex += offset; // ARGH!#(* WINDOWS#@($*
*/
// if the previous thing is a brace (whether prev line or
// up farther) then the correct indent is the number of spaces
// on that line + 'indent'.
// if the previous line is not a brace, then just use the
// identical indentation to the previous line
// calculate the amount of indent on the previous line
// this will be used *only if the prev line is not an indent*
int spaceCount = calcSpaceCount(origIndex, contents);
// If the last character was a left curly brace, then indent.
// For 0122, walk backwards a bit to make sure that the there
// isn't a curly brace several spaces (or lines) back. Also
// moved this before calculating extraCount, since it'll affect
// that as well.
int index2 = origIndex;
while ((index2 >= 0) &&
Character.isWhitespace(contents[index2])) {
index2--;
}
if (index2 != -1) {
// still won't catch a case where prev stuff is a comment
if (contents[index2] == '{') {
// intermediate lines be damned,
// use the indent for this line instead
spaceCount = calcSpaceCount(index2, contents);
spaceCount += tabSize;
}
}
//System.out.println("spaceCount should be " + spaceCount);
// now before inserting this many spaces, walk forward from
// the caret position and count the number of spaces,
// so that the number of spaces aren't duplicated again
int index = origIndex + 1;
int extraCount = 0;
while ((index < contents.length) &&
(contents[index] == ' ')) {
//spaceCount--;
extraCount++;
index++;
}
int braceCount = 0;
while ((index < contents.length) && (contents[index] != '\n')) {
if (contents[index] == '}') {
braceCount++;
}
index++;
}
// hitting return on a line with spaces *after* the caret
// can cause trouble. for 0099, was ignoring the case, but this is
// annoying, so in 0122 we're trying to fix that.
/*
if (spaceCount - extraCount > 0) {
spaceCount -= extraCount;
}
*/
spaceCount -= extraCount;
//if (spaceCount < 0) spaceCount = 0;
//System.out.println("extraCount is " + extraCount);
// now, check to see if the current line contains a } and if so,
// outdent again by indent
//if (braceCount > 0) {
//spaceCount -= 2;
//}
if (spaceCount < 0) {
// for rev 0122, actually delete extra space
//textarea.setSelectionStart(origIndex + 1);
textarea.setSelectionEnd(textarea.getSelectionStop() - spaceCount);
textarea.setSelectedText("\n");
} else {
String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount);
textarea.setSelectedText(insertion);
}
// not gonna bother handling more than one brace
if (braceCount > 0) {
int sel = textarea.getSelectionStart();
// sel - tabSize will be -1 if start/end parens on the same line
// http://dev.processing.org/bugs/show_bug.cgi?id=484
if (sel - tabSize >= 0) {
textarea.select(sel - tabSize, sel);
String s = Editor.EMPTY.substring(0, tabSize);
// if these are spaces that we can delete
if (textarea.getSelectedText().equals(s)) {
textarea.setSelectedText("");
} else {
textarea.select(sel, sel);
}
}
}
} else {
// Enter/Return was being consumed by somehow even if false
// was returned, so this is a band-aid to simply fire the event again.
// http://dev.processing.org/bugs/show_bug.cgi?id=1073
textarea.setSelectedText(String.valueOf(c));
}
// mark this event as already handled (all but ignored)
event.consume();
return true;
case '}':
if (autoIndent) {
// first remove anything that was there (in case this multiple
// characters are selected, so that it's not in the way of the
// spaces for the auto-indent
if (textarea.getSelectionStart() != textarea.getSelectionStop()) {
textarea.setSelectedText("");
}
// if this brace is the only thing on the line, outdent
char contents[] = textarea.getText().toCharArray();
// index to the character to the left of the caret
int prevCharIndex = textarea.getCaretPosition() - 1;
// backup from the current caret position to the last newline,
// checking for anything besides whitespace along the way.
// if there's something besides whitespace, exit without
// messing any sort of indenting.
int index = prevCharIndex;
boolean finished = false;
while ((index != -1) && (!finished)) {
if (contents[index] == 10) {
finished = true;
index++;
} else if (contents[index] != ' ') {
// don't do anything, this line has other stuff on it
return false;
} else {
index--;
}
}
if (!finished) return false; // brace with no start
int lineStartIndex = index;
int pairedSpaceCount = calcBraceIndent(prevCharIndex, contents); //, 1);
if (pairedSpaceCount == -1) return false;
textarea.setSelectionStart(lineStartIndex);
textarea.setSelectedText(Editor.EMPTY.substring(0, pairedSpaceCount));
// mark this event as already handled
event.consume();
return true;
}
break;
}
return false;
}
// public boolean keyReleased(KeyEvent event) {
// if (code == KeyEvent.VK_SHIFT) {
// editor.toolbar.setShiftPressed(false);
// if (event.isAltDown() && code == KeyEvent.VK_T) {
// int line = textarea.getCaretLineNumber();
// textarea.setActiveLineRange(line, line + 3);
// }
// }
public boolean keyTyped(KeyEvent event) {
char c = event.getKeyChar();
if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
// The char is not control code when CTRL key pressed? It should be a shortcut.
if (!Character.isISOControl(c)) {
event.consume();
return true;
}
}
return false;
}
/**
* Return the index for the first character on this line.
*/
protected int calcLineStart(int index, char contents[]) {
// backup from the current caret position to the last newline,
// so that we can figure out how far this line was indented
/*int spaceCount = 0;*/
boolean finished = false;
while ((index != -1) && (!finished)) {
if ((contents[index] == 10) ||
(contents[index] == 13)) {
finished = true;
//index++; // maybe ?
} else {
index--; // new
}
}
// add one because index is either -1 (the start of the document)
// or it's the newline character for the previous line
return index + 1;
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
/**
* Calculate the number of spaces on this line.
*/
protected int calcSpaceCount(int index, char contents[]) {
index = calcLineStart(index, contents);
int spaceCount = 0;
// now walk forward and figure out how many spaces there are
while ((index < contents.length) && (index >= 0) &&
(contents[index++] == ' ')) {
spaceCount++;
}
return spaceCount;
}
/**
* Walk back from 'index' until the brace that seems to be
* the beginning of the current block, and return the number of
* spaces found on that line.
*/
protected int calcBraceIndent(int index, char contents[]) {
// now that we know things are ok to be indented, walk
// backwards to the last { to see how far its line is indented.
// this isn't perfect cuz it'll pick up commented areas,
// but that's not really a big deal and can be fixed when
// this is all given a more complete (proper) solution.
int braceDepth = 1;
boolean finished = false;
while ((index != -1) && (!finished)) {
if (contents[index] == '}') {
// aww crap, this means we're one deeper
// and will have to find one more extra {
braceDepth++;
//if (braceDepth == 0) {
//finished = true;
//}
index--;
} else if (contents[index] == '{') {
braceDepth--;
if (braceDepth == 0) {
finished = true;
}
index--;
} else {
index--;
}
}
// never found a proper brace, be safe and don't do anything
if (!finished) return -1;
// check how many spaces on the line with the matching open brace
//int pairedSpaceCount = calcSpaceCount(index, contents);
//System.out.println(pairedSpaceCount);
return calcSpaceCount(index, contents);
}
/**
* Get the character array and blank out the commented areas.
* This hasn't yet been tested, the plan was to make auto-indent
* less gullible (it gets fooled by braces that are commented out).
*/
protected char[] getCleanedContents() {
char c[] = textarea.getText().toCharArray();
int index = 0;
while (index < c.length - 1) {
if ((c[index] == '/') && (c[index+1] == '*')) {
c[index++] = 0;
c[index++] = 0;
while ((index < c.length - 1) &&
!((c[index] == '*') && (c[index+1] == '/'))) {
c[index++] = 0;
}
} else if ((c[index] == '/') && (c[index+1] == '/')) {
// clear out until the end of the line
while ((index < c.length) && (c[index] != 10)) {
c[index++] = 0;
}
if (index != c.length) {
index++; // skip over the newline
}
}
}
return c;
}
/*
protected char[] getCleanedContents() {
char c[] = textarea.getText().toCharArray();
boolean insideMulti; // multi-line comment
boolean insideSingle; // single line double slash
//for (int i = 0; i < c.length - 1; i++) {
int index = 0;
while (index < c.length - 1) {
if (insideMulti && (c[index] == '*') && (c[index+1] == '/')) {
insideMulti = false;
index += 2;
} else if ((c[index] == '/') && (c[index+1] == '*')) {
insideMulti = true;
index += 2;
} else if ((c[index] == '/') && (c[index+1] == '/')) {
// clear out until the end of the line
while (c[index] != 10) {
c[index++] = 0;
}
index++;
}
}
}
*/
}
}

View File

@ -219,7 +219,7 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
public void unprogress()
{
if (Preferences.getBoolean("editor.beep.compile")) {
if (PreferencesData.getBoolean("editor.beep.compile")) {
Toolkit.getDefaultToolkit().beep();
}
if (progressBar == null) return;
@ -464,10 +464,10 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
copyErrorButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String message = "";
message += _("Arduino: ") + BaseNoGui.VERSION_NAME + " (" + System.getProperty("os.name") + "), ";
message += _("Arduino: ") + BaseNoGui.VERSION_NAME_LONG + " (" + System.getProperty("os.name") + "), ";
message += _("Board: ") + "\"" + Base.getBoardPreferences().get("name") + "\"\n\n";
message += editor.console.consoleTextPane.getText().trim();
if ((Preferences.getBoolean("build.verbose")) == false) {
if ((PreferencesData.getBoolean("build.verbose")) == false) {
message += "\n\n";
message += " " + _("This report would have more information with") + "\n";
message += " \"" + _("Show verbose output during compilation") + "\"\n";

View File

@ -321,7 +321,7 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
switch (sel) {
case RUN:
editor.handleRun(false);
editor.handleRun(false, editor.presentHandler, editor.runHandler);
break;
// case STOP:

View File

@ -2,31 +2,36 @@ package processing.app;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
import javax.swing.undo.UndoableEdit;
@SuppressWarnings("serial")
public class LastUndoableEditAwareUndoManager extends UndoManager {
import org.fife.ui.rtextarea.RUndoManager;
private UndoableEdit lastUndoableEdit;
import processing.app.syntax.SketchTextArea;
public LastUndoableEditAwareUndoManager() {
this.lastUndoableEdit = null;
public class LastUndoableEditAwareUndoManager extends RUndoManager {
private Editor editor;
public LastUndoableEditAwareUndoManager(SketchTextArea textarea, Editor editor) {
super(textarea);
this.editor = editor;
}
@Override
public synchronized void undo() throws CannotUndoException {
lastUndoableEdit = super.editToBeUndone();
super.undo();
}
@Override
public synchronized void redo() throws CannotRedoException {
lastUndoableEdit = super.editToBeRedone();
super.redo();
}
public UndoableEdit getLastUndoableEdit() {
return lastUndoableEdit;
@Override
public void updateActions() {
super.updateActions();
editor.undoAction.updateUndoState();
editor.redoAction.updateRedoState();
}
}

View File

@ -21,58 +21,30 @@
package processing.app;
import static processing.app.I18n._;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import processing.app.helpers.FileUtils;
import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesHelper;
import processing.app.helpers.PreferencesMap;
import processing.app.legacy.PApplet;
import java.awt.*;
import java.io.File;
/**
* Storage class for user preferences and environment settings.
* <P>
* <p/>
* This class no longer uses the Properties class, since
* properties files are iso8859-1, which is highly likely to
* be a problem when trying to save sketch folders and locations.
* <p>
* <p/>
* The GUI portion in here is really ugly, as it uses exact layout. This was
* done in frustration one evening (and pre-Swing), but that's long since past,
* and it should all be moved to a proper swing layout like BoxLayout.
* <p>
* <p/>
* This is very poorly put together, that the preferences panel and the actual
* preferences i/o is part of the same code. But there hasn't yet been a
* compelling reason to bother with the separation aside from concern about
* being lectured by strangers who feel that it doesn't look like what they
* learned in CS class.
* <p>
* <p/>
* Would also be possible to change this to use the Java Preferences API.
* Some useful articles
* <a href="http://www.onjava.com/pub/a/onjava/synd/2001/10/17/j2se.html">here</a> and
@ -85,114 +57,12 @@ import processing.app.legacy.PApplet;
*/
public class Preferences {
static final String PREFS_FILE = PreferencesData.PREFS_FILE;
class Language {
Language(String _name, String _originalName, String _isoCode) {
name = _name;
originalName = _originalName;
isoCode = _isoCode;
}
public String toString() {
if (originalName.length() == 0)
return name;
return originalName + " (" + name + ")";
};
String name;
String originalName;
String isoCode;
}
Language languages[] = {
new Language(_("System Default"), "", ""),
new Language(_("Albanian"), "shqip", "sq"),
new Language(_("Arabic"), "العربية", "ar"),
new Language(_("Aragonese"), "Aragonés", "an"),
new Language(_("Belarusian"), "Беларуская мова", "be"),
new Language(_("Bulgarian"), "български", "bg"),
new Language(_("Catalan"), "Català", "ca"),
new Language(_("Chinese Simplified"), "简体中文", "zh_CN"),
new Language(_("Chinese Traditional"), "繁體中文", "zh_TW"),
new Language(_("Croatian"), "Hrvatski", "hr_HR"),
new Language(_("Czech (Czech Republic)"), "český (Czech Republic)", "cs_CZ"),
new Language(_("Danish (Denmark)"), "Dansk (Denmark)", "da_DK"),
new Language(_("Dutch"), "Nederlands", "nl"),
new Language(_("English"), "English", "en"),
new Language(_("English (United Kingdom)"), "English (United Kingdom)", "en_GB"),
new Language(_("Estonian"), "Eesti", "et"),
new Language(_("Estonian (Estonia)"), "Eesti keel", "et_EE"),
new Language(_("Filipino"), "Pilipino", "fil"),
new Language(_("Finnish"), "Suomi", "fi"),
new Language(_("French"), "Français", "fr"),
new Language(_("Canadian French"), "Canadienne-français", "fr_CA"),
new Language(_("Galician"), "Galego", "gl"),
new Language(_("Georgian"), "საქართველოს", "ka_GE"),
new Language(_("German"), "Deutsch", "de_DE"),
new Language(_("Greek"), "ελληνικά", "el_GR"),
new Language(_("Hebrew"), "עברית", "he"),
new Language(_("Hindi"), "हिंदी", "hi"),
new Language(_("Hungarian"), "Magyar", "hu"),
new Language(_("Indonesian"), "Bahasa Indonesia", "id"),
new Language(_("Italian"), "Italiano", "it_IT"),
new Language(_("Japanese"), "日本語", "ja_JP"),
new Language(_("Korean"), "한국어", "ko_KR"),
new Language(_("Latvian"), "Latviešu", "lv_LV"),
new Language(_("Lithuaninan"), "Lietuvių Kalba", "lt_LT"),
new Language(_("Norwegian Bokmål"), "Norsk bokmål", "nb_NO"),
new Language(_("Persian"), "فارسی", "fa"),
new Language(_("Polish"), "Język Polski", "pl"),
new Language(_("Portuguese (Brazil)"), "Português (Brazil)", "pt_BR"),
new Language(_("Portuguese (Portugal)"), "Português (Portugal)", "pt_PT"),
new Language(_("Romanian"), "Română", "ro"),
new Language(_("Russian"), "Русский", "ru"),
new Language(_("Slovenian"), "Slovenščina", "sl_SI"),
new Language(_("Spanish"), "Español", "es"),
new Language(_("Swedish"), "Svenska", "sv"),
new Language(_("Tamil"), "தமிழ்", "ta"),
new Language(_("Turkish"), "Türk", "tr"),
new Language(_("Ukrainian"), "Український", "uk"),
new Language(_("Vietnamese"), "Tiếng Việt", "vi"),
};
// Incomplete languages
Language missingLanguages[] = {
new Language(_("Afrikaans"), "Afrikaans", "af"),
new Language(_("Armenian"), "Հայերեն", "hy"),
new Language(_("Asturian"), "Asturianu", "ast"),
new Language(_("Basque"), "Euskara", "eu"),
new Language(_("Bengali (India)"), "বাংলা (India)", "bn_IN"),
new Language(_("Bosnian"), "Bosanski", "bs"),
new Language(_("Burmese (Myanmar)"), "ဗမာစကား", "my_MM"),
new Language(_("Chinese (China)"), "", "zh_CN"),
new Language(_("Chinese (Hong Kong)"), "", "zh_HK"),
new Language(_("Chinese (Taiwan)"), "", "zh_TW"),
new Language(_("Chinese (Taiwan) (Big5)"), "", "zh_TW.Big5"),
new Language(_("Czech"), "český", "cs"),
new Language(_("Danish"), "Dansk", "da"),
new Language(_("Dutch (Netherlands)"), "Nederlands", "nl_NL"),
new Language(_("Galician (Spain)"), "Galego (Spain)", "gl_ES"),
new Language(_("Nepali"), "नेपाली", "ne"),
new Language(_("N'Ko"), "ߒߞߏ", "nqo"),
new Language(_("Marathi"), "मराठी", "mr"),
new Language(_("Malay (Malaysia)"), "بهاس ملايو (Malaysia)", "ms_MY"),
new Language(_("Norwegian"), "Norsk", "no"),
new Language(_("Norwegian Nynorsk"), "Norsk Nynorsk", "nn"),
new Language(_("Portugese"), "Português", "pt"),
new Language(_("Persian (Iran)"), "فارسی (Iran)", "fa_IR"),
new Language(_("Slovak"), "Slovenčina", "sk"),
new Language(_("Swahili"), "كِسوَهِل", "sw"),
new Language(_("Talossan"), "Talossan", "tzl"),
new Language(_("Urdu (Pakistan)"), "اردو (Pakistan)", "ur_PK"),
new Language(_("Western Frisian"), "Western Frisian", "fy"),
};
/**
* Standardized width for buttons. Mac OS X 10.3 wants 70 as its default,
* Windows XP needs 66, and my Ubuntu machine needs 80+, so 80 seems proper.
*/
static public int BUTTON_WIDTH = 80;
static public int BUTTON_WIDTH = 80;
/**
* Standardized button height. Mac OS X 10.3 (Java 1.4) wants 29,
@ -205,549 +75,85 @@ public class Preferences {
// value for the size bars, buttons, etc
static final int GRID_SIZE = 33;
static final int GRID_SIZE = 33;
// indents and spacing standards. these probably need to be modified
// per platform as well, since macosx is so huge, windows is smaller,
// and linux is all over the map
static final int GUI_BIG = 13;
static final int GUI_BETWEEN = 10;
static final int GUI_SMALL = 6;
// gui elements
JFrame dialog;
int wide, high;
JTextField sketchbookLocationField;
JCheckBox exportSeparateBox;
JCheckBox verboseCompilationBox;
JCheckBox verboseUploadBox;
JCheckBox displayLineNumbersBox;
JCheckBox verifyUploadBox;
JCheckBox externalEditorBox;
JCheckBox memoryOverrideBox;
JTextField memoryField;
JCheckBox checkUpdatesBox;
JTextField fontSizeField;
JCheckBox updateExtensionBox;
JCheckBox autoAssociateBox;
JComboBox comboLanguage;
JCheckBox saveVerifyUploadBox;
// the calling editor, so updates can be applied
Editor editor;
static final int GUI_SMALL = 6;
static protected void init(File file) {
PreferencesData.init(file);
PreferencesData.init(file);
// other things that have to be set explicitly for the defaults
PreferencesHelper.putColor(PreferencesData.prefs, "run.window.bgcolor", SystemColor.control);
}
public Preferences() {
// setup dialog for the prefs
//dialog = new JDialog(editor, "Preferences", true);
dialog = new JFrame(_("Preferences"));
dialog.setResizable(false);
Container pain = dialog.getContentPane();
pain.setLayout(null);
int top = GUI_BIG;
int left = GUI_BIG;
int right = 0;
JLabel label;
JButton button; //, button2;
//JComboBox combo;
Dimension d, d2; //, d3;
int h, vmax;
// Sketchbook location:
// [...............................] [ Browse ]
label = new JLabel(_("Sketchbook location:"));
pain.add(label);
d = label.getPreferredSize();
label.setBounds(left, top, d.width, d.height);
top += d.height; // + GUI_SMALL;
sketchbookLocationField = new JTextField(40);
pain.add(sketchbookLocationField);
d = sketchbookLocationField.getPreferredSize();
button = new JButton(I18n.PROMPT_BROWSE);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
File dflt = new File(sketchbookLocationField.getText());
File file =
Base.selectFolder(_("Select new sketchbook location"), dflt, dialog);
if (file != null) {
String path = file.getAbsolutePath();
if (Base.getPortableFolder() != null) {
path = FileUtils.relativePath(Base.getPortableFolder().toString(), path);
if (path == null) {
path = Base.getPortableSketchbookFolder();
}
}
sketchbookLocationField.setText(path);
}
}
});
pain.add(button);
d2 = button.getPreferredSize();
// take max height of all components to vertically align em
vmax = Math.max(d.height, d2.height);
sketchbookLocationField.setBounds(left, top + (vmax-d.height)/2,
d.width, d.height);
h = left + d.width + GUI_SMALL;
button.setBounds(h, top + (vmax-d2.height)/2,
d2.width, d2.height);
right = Math.max(right, h + d2.width + GUI_BIG);
top += vmax + GUI_BETWEEN;
// Preferred language: [ ] (requires restart of Arduino)
Container box = Box.createHorizontalBox();
label = new JLabel(_("Editor language: "));
box.add(label);
comboLanguage = new JComboBox(languages);
String currentLanguage = PreferencesData.get("editor.languages.current");
for (Language language : languages) {
if (language.isoCode.equals(currentLanguage))
comboLanguage.setSelectedItem(language);
}
box.add(comboLanguage);
label = new JLabel(_(" (requires restart of Arduino)"));
box.add(label);
pain.add(box);
d = box.getPreferredSize();
box.setForeground(Color.gray);
box.setBounds(left, top, d.width, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// Editor font size [ ]
box = Box.createHorizontalBox();
label = new JLabel(_("Editor font size: "));
box.add(label);
fontSizeField = new JTextField(4);
box.add(fontSizeField);
label = new JLabel(_(" (requires restart of Arduino)"));
box.add(label);
pain.add(box);
d = box.getPreferredSize();
box.setBounds(left, top, d.width, d.height);
Font editorFont = Preferences.getFont("editor.font");
fontSizeField.setText(String.valueOf(editorFont.getSize()));
top += d.height + GUI_BETWEEN;
// Show verbose output during: [ ] compilation [ ] upload
box = Box.createHorizontalBox();
label = new JLabel(_("Show verbose output during: "));
box.add(label);
verboseCompilationBox = new JCheckBox(_("compilation "));
box.add(verboseCompilationBox);
verboseUploadBox = new JCheckBox(_("upload"));
box.add(verboseUploadBox);
pain.add(box);
d = box.getPreferredSize();
box.setBounds(left, top, d.width, d.height);
top += d.height + GUI_BETWEEN;
// [ ] Display line numbers
displayLineNumbersBox = new JCheckBox(_("Display line numbers"));
pain.add(displayLineNumbersBox);
d = displayLineNumbersBox.getPreferredSize();
displayLineNumbersBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// [ ] Verify code after upload
verifyUploadBox = new JCheckBox(_("Verify code after upload"));
pain.add(verifyUploadBox);
d = verifyUploadBox.getPreferredSize();
verifyUploadBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// [ ] Use external editor
externalEditorBox = new JCheckBox(_("Use external editor"));
pain.add(externalEditorBox);
d = externalEditorBox.getPreferredSize();
externalEditorBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// [ ] Check for updates on startup
checkUpdatesBox = new JCheckBox(_("Check for updates on startup"));
pain.add(checkUpdatesBox);
d = checkUpdatesBox.getPreferredSize();
checkUpdatesBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// [ ] Update sketch files to new extension on save (.pde -> .ino)
updateExtensionBox = new JCheckBox(_("Update sketch files to new extension on save (.pde -> .ino)"));
pain.add(updateExtensionBox);
d = updateExtensionBox.getPreferredSize();
updateExtensionBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// [ ] Automatically associate .pde files with Processing
if (OSUtils.isWindows()) {
autoAssociateBox =
new JCheckBox(_("Automatically associate .ino files with Arduino"));
pain.add(autoAssociateBox);
d = autoAssociateBox.getPreferredSize();
autoAssociateBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// If using portable mode, it's bad manner to change PC setting.
if (Base.getPortableFolder() != null)
autoAssociateBox.setEnabled(false);
}
// [ ] save when verifying or uploading
saveVerifyUploadBox = new JCheckBox(_("Save when verifying or uploading"));
pain.add(saveVerifyUploadBox);
d = saveVerifyUploadBox.getPreferredSize();
saveVerifyUploadBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// More preferences are in the ...
label = new JLabel(_("More preferences can be edited directly in the file"));
pain.add(label);
d = label.getPreferredSize();
label.setForeground(Color.gray);
label.setBounds(left, top, d.width, d.height);
right = Math.max(right, left + d.width);
top += d.height; // + GUI_SMALL;
label = new JLabel(PreferencesData.preferencesFile.getAbsolutePath());
final JLabel clickable = label;
label.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
Base.openFolder(PreferencesData.preferencesFile.getParentFile());
}
public void mouseEntered(MouseEvent e) {
clickable.setForeground(new Color(0, 0, 140));
}
public void mouseExited(MouseEvent e) {
clickable.setForeground(Color.BLACK);
}
});
pain.add(label);
d = label.getPreferredSize();
label.setBounds(left, top, d.width, d.height);
right = Math.max(right, left + d.width);
top += d.height;
label = new JLabel(_("(edit only when Arduino is not running)"));
pain.add(label);
d = label.getPreferredSize();
label.setForeground(Color.gray);
label.setBounds(left, top, d.width, d.height);
right = Math.max(right, left + d.width);
top += d.height; // + GUI_SMALL;
// [ OK ] [ Cancel ] maybe these should be next to the message?
button = new JButton(I18n.PROMPT_OK);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
applyFrame();
disposeFrame();
}
});
pain.add(button);
d2 = button.getPreferredSize();
BUTTON_HEIGHT = d2.height;
h = right - (BUTTON_WIDTH + GUI_SMALL + BUTTON_WIDTH);
button.setBounds(h, top, BUTTON_WIDTH, BUTTON_HEIGHT);
h += BUTTON_WIDTH + GUI_SMALL;
button = new JButton(I18n.PROMPT_CANCEL);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
disposeFrame();
}
});
pain.add(button);
button.setBounds(h, top, BUTTON_WIDTH, BUTTON_HEIGHT);
top += BUTTON_HEIGHT + GUI_BETWEEN;
// finish up
wide = right + GUI_BIG;
high = top + GUI_SMALL;
// closing the window is same as hitting cancel button
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
disposeFrame();
}
});
ActionListener disposer = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
disposeFrame();
}
};
Base.registerWindowCloseKeys(dialog.getRootPane(), disposer);
Base.setIcon(dialog);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
dialog.setLocation((screen.width - wide) / 2,
(screen.height - high) / 2);
dialog.pack(); // get insets
Insets insets = dialog.getInsets();
dialog.setSize(wide + insets.left + insets.right,
high + insets.top + insets.bottom);
// handle window closing commands for ctrl/cmd-W or hitting ESC.
pain.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
//System.out.println(e);
KeyStroke wc = Editor.WINDOW_CLOSE_KEYSTROKE;
if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) ||
(KeyStroke.getKeyStrokeForEvent(e).equals(wc))) {
disposeFrame();
}
}
});
}
// .................................................................
/**
* Close the window after an OK or Cancel.
*/
protected void disposeFrame() {
dialog.dispose();
}
/**
* Change internal settings based on what was chosen in the prefs,
* then send a message to the editor saying that it's time to do the same.
*/
protected void applyFrame() {
// put each of the settings into the table
PreferencesData.setBoolean("build.verbose", verboseCompilationBox.isSelected());
PreferencesData.setBoolean("upload.verbose", verboseUploadBox.isSelected());
PreferencesData.setBoolean("editor.linenumbers", displayLineNumbersBox.isSelected());
PreferencesData.setBoolean("upload.verify", verifyUploadBox.isSelected());
PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
// setBoolean("sketchbook.closing_last_window_quits",
// closingLastQuitsBox.isSelected());
//setBoolean("sketchbook.prompt", sketchPromptBox.isSelected());
//setBoolean("sketchbook.auto_clean", sketchCleanBox.isSelected());
// if the sketchbook path has changed, rebuild the menus
String oldPath = PreferencesData.get("sketchbook.path");
String newPath = sketchbookLocationField.getText();
if (newPath.isEmpty()) {
if (Base.getPortableFolder() == null)
newPath = editor.base.getDefaultSketchbookFolderOrPromptForIt().toString();
else
newPath = Base.getPortableSketchbookFolder();
}
if (!newPath.equals(oldPath)) {
editor.base.rebuildSketchbookMenus();
PreferencesData.set("sketchbook.path", newPath);
}
PreferencesData.setBoolean("editor.external", externalEditorBox.isSelected());
PreferencesData.setBoolean("update.check", checkUpdatesBox.isSelected());
PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
/*
// was gonna use this to check memory settings,
// but it quickly gets much too messy
if (getBoolean("run.options.memory")) {
Process process = Runtime.getRuntime().exec(new String[] {
"java", "-Xms" + memoryMin + "m", "-Xmx" + memoryMax + "m"
});
processInput = new SystemOutSiphon(process.getInputStream());
processError = new MessageSiphon(process.getErrorStream(), this);
}
*/
String newSizeText = fontSizeField.getText();
try {
int newSize = Integer.parseInt(newSizeText.trim());
String pieces[] = PApplet.split(PreferencesData.get("editor.font"), ',');
pieces[2] = String.valueOf(newSize);
PreferencesData.set("editor.font", PApplet.join(pieces, ','));
} catch (Exception e) {
System.err.println(I18n.format(_("ignoring invalid font size {0}"), newSizeText));
}
if (autoAssociateBox != null) {
PreferencesData.setBoolean("platform.auto_file_type_associations",
autoAssociateBox.isSelected());
}
PreferencesData.setBoolean("editor.update_extension", updateExtensionBox.isSelected());
// adds the selected language to the preferences file
Language newLanguage = (Language) comboLanguage.getSelectedItem();
PreferencesData.set("editor.languages.current", newLanguage.isoCode);
editor.applyPreferences();
}
protected void showFrame(Editor editor) {
this.editor = editor;
// set all settings entry boxes to their actual status
verboseCompilationBox.setSelected(PreferencesData.getBoolean("build.verbose"));
verboseUploadBox.setSelected(PreferencesData.getBoolean("upload.verbose"));
displayLineNumbersBox.setSelected(PreferencesData.getBoolean("editor.linenumbers"));
verifyUploadBox.setSelected(PreferencesData.getBoolean("upload.verify"));
//closingLastQuitsBox.
// setSelected(getBoolean("sketchbook.closing_last_window_quits"));
//sketchPromptBox.
// setSelected(getBoolean("sketchbook.prompt"));
//sketchCleanBox.
// setSelected(getBoolean("sketchbook.auto_clean"));
sketchbookLocationField.
setText(PreferencesData.get("sketchbook.path"));
externalEditorBox.
setSelected(PreferencesData.getBoolean("editor.external"));
checkUpdatesBox.
setSelected(PreferencesData.getBoolean("update.check"));
saveVerifyUploadBox.
setSelected(PreferencesData.getBoolean("editor.save_on_verify"));
if (autoAssociateBox != null) {
autoAssociateBox.
setSelected(PreferencesData.getBoolean("platform.auto_file_type_associations"));
}
updateExtensionBox.setSelected(PreferencesData.get("editor.update_extension") == null ||
PreferencesData.getBoolean("editor.update_extension"));
dialog.setVisible(true);
}
static protected void save() {
@Deprecated
protected static void save() {
PreferencesData.save();
}
// .................................................................
static public String get(String attribute) {
@Deprecated
public static String get(String attribute) {
return PreferencesData.get(attribute);
}
static public String get(String attribute, String defaultValue) {
@Deprecated
public static String get(String attribute, String defaultValue) {
return PreferencesData.get(attribute, defaultValue);
}
@Deprecated
public static boolean has(String key) {
return PreferencesData.has(key);
}
@Deprecated
public static void remove(String key) {
PreferencesData.remove(key);
}
static public void set(String attribute, String value) {
@Deprecated
public static void set(String attribute, String value) {
PreferencesData.set(attribute, value);
}
static public boolean getBoolean(String attribute) {
@Deprecated
public static boolean getBoolean(String attribute) {
return PreferencesData.getBoolean(attribute);
}
static public void setBoolean(String attribute, boolean value) {
@Deprecated
public static void setBoolean(String attribute, boolean value) {
PreferencesData.setBoolean(attribute, value);
}
static public int getInteger(String attribute) {
@Deprecated
public static int getInteger(String attribute) {
return PreferencesData.getInteger(attribute);
}
@Deprecated
public static int getInteger(String attribute, int defaultValue) {
return PreferencesData.getInteger(attribute, defaultValue);
}
static public void setInteger(String key, int value) {
@Deprecated
public static void setInteger(String key, int value) {
PreferencesData.setInteger(key, value);
}
static public Font getFont(String attr) {
Font font = PreferencesHelper.getFont(PreferencesData.prefs, attr);
if (font == null) {
String value = PreferencesData.defaults.get(attr);
PreferencesData.prefs.put(attr, value);
font = PreferencesHelper.getFont(PreferencesData.prefs, attr);
}
return font;
}
// get a copy of the Preferences
static public PreferencesMap getMap()
{
@Deprecated
public static PreferencesMap getMap() {
return PreferencesData.getMap();
}
// Decide wether changed preferences will be saved. When value is
// false, Preferences.save becomes a no-op.
static public void setDoSave(boolean value)
{
@Deprecated
public static void setDoSave(boolean value) {
PreferencesData.setDoSave(value);
}
}

View File

@ -74,14 +74,14 @@ public class PresentMode {
public void actionPerformed(ActionEvent e) {
int index = selector.getSelectedIndex();
//device = devices[index];
Preferences.setInteger("run.present.display", index + 1);
PreferencesData.setInteger("run.present.display", index + 1);
}
});
}
static public JComboBox getSelector() {
int deviceIndex = Preferences.getInteger("run.present.display") - 1;
int deviceIndex = PreferencesData.getInteger("run.present.display") - 1;
selector.setSelectedIndex(deviceIndex);
return selector;
}

View File

@ -39,14 +39,14 @@ public class SerialMonitor extends AbstractMonitor {
this.port = port.getAddress();
serialRate = Preferences.getInteger("serial.debug_rate");
serialRate = PreferencesData.getInteger("serial.debug_rate");
serialRates.setSelectedItem(serialRate + " " + _("baud"));
onSerialRateChange(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String wholeString = (String) serialRates.getSelectedItem();
String rateString = wholeString.substring(0, wholeString.indexOf(' '));
serialRate = Integer.parseInt(rateString);
Preferences.set("serial.debug_rate", rateString);
PreferencesData.set("serial.debug_rate", rateString);
try {
close();
Thread.sleep(100); // Wait for serial port to properly close
@ -80,9 +80,9 @@ public class SerialMonitor extends AbstractMonitor {
s += "\r\n";
break;
}
if ("".equals(s) && lineEndings.getSelectedIndex() == 0 && !Preferences.has("runtime.line.ending.alert.notified")) {
if ("".equals(s) && lineEndings.getSelectedIndex() == 0 && !PreferencesData.has("runtime.line.ending.alert.notified")) {
noLineEndingAlert.setForeground(Color.RED);
Preferences.set("runtime.line.ending.alert.notified", "true");
PreferencesData.set("runtime.line.ending.alert.notified", "true");
}
serial.write(s);
}
@ -103,7 +103,7 @@ public class SerialMonitor extends AbstractMonitor {
if (serial != null) {
int[] location = getPlacement();
String locationStr = PApplet.join(PApplet.str(location), ",");
Preferences.set("last.serial.location", locationStr);
PreferencesData.set("last.serial.location", locationStr);
textArea.setText("");
serial.dispose();
serial = null;

View File

@ -23,18 +23,15 @@
package processing.app;
import cc.arduino.packages.BoardPort;
import cc.arduino.packages.Uploader;
import cc.arduino.view.*;
import processing.app.debug.Compiler;
import processing.app.debug.Compiler.ProgressListener;
import processing.app.debug.RunnerException;
import processing.app.debug.TargetBoard;
import processing.app.forms.PasswordAuthorizationDialog;
import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesMap;
import processing.app.helpers.PreferencesMapException;
import processing.app.packages.Library;
import processing.app.packages.UserLibrary;
import static processing.app.I18n._;
import javax.swing.*;
import java.awt.*;
@ -45,8 +42,6 @@ import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import static processing.app.I18n._;
/**
* Stores information about files in the current sketch
@ -117,7 +112,7 @@ public class Sketch {
for (SketchCode code : data.getCodes()) {
if (code.getMetadata() == null)
code.setMetadata(new SketchCodeDocument(code));
code.setMetadata(new SketchCodeDocument(this, code));
}
// set the main file to be the current tab
@ -414,7 +409,7 @@ public class Sketch {
return;
}
ensureExistence();
data.addCode((new SketchCodeDocument(newFile)).getCode());
data.addCode((new SketchCodeDocument(this, newFile)).getCode());
}
// sort the entries
@ -580,7 +575,7 @@ public class Sketch {
});
if (pdeFiles != null && pdeFiles.length > 0) {
if (Preferences.get("editor.update_extension") == null) {
if (PreferencesData.get("editor.update_extension") == null) {
Object[] options = { _("OK"), _("Cancel") };
int result = JOptionPane.showOptionDialog(editor,
_("In Arduino 1.0, the default file extension has changed\n" +
@ -599,10 +594,10 @@ public class Sketch {
if (result != JOptionPane.OK_OPTION) return false; // save cancelled
Preferences.setBoolean("editor.update_extension", true);
PreferencesData.setBoolean("editor.update_extension", true);
}
if (Preferences.getBoolean("editor.update_extension")) {
if (PreferencesData.getBoolean("editor.update_extension")) {
// Do rename of all .pde files to new .ino extension
for (File pdeFile : pdeFiles)
renameCodeToInoExtension(pdeFile);
@ -806,7 +801,7 @@ public class Sketch {
if (result) {
editor.statusNotice(_("One file added to the sketch."));
Preferences.set("last.folder", sourceFile.getAbsolutePath());
PreferencesData.set("last.folder", sourceFile.getAbsolutePath());
}
}
@ -910,7 +905,7 @@ public class Sketch {
}
if (codeExtension != null) {
SketchCode newCode = (new SketchCodeDocument(destFile)).getCode();
SketchCode newCode = (new SketchCodeDocument(this, destFile)).getCode();
if (replacement) {
data.replaceCode(newCode);
@ -938,7 +933,7 @@ public class Sketch {
}
public void importLibrary(Library lib) throws IOException {
public void importLibrary(UserLibrary lib) throws IOException {
importLibrary(lib.getSrcFolder());
}
@ -1064,7 +1059,7 @@ public class Sketch {
// if an external editor is being used, need to grab the
// latest version of the code from the file.
if (Preferences.getBoolean("editor.external")) {
if (PreferencesData.getBoolean("editor.external")) {
// history gets screwed by the open..
//String historySaved = history.lastRecorded;
//handleOpen(sketch);
@ -1138,8 +1133,8 @@ public class Sketch {
* @return null if compilation failed, main class name if not
* @throws RunnerException
*/
public String build(boolean verbose) throws RunnerException, PreferencesMapException {
return build(tempBuildFolder.getAbsolutePath(), verbose);
public String build(boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
return build(tempBuildFolder.getAbsolutePath(), verbose, save);
}
/**
@ -1151,9 +1146,7 @@ public class Sketch {
*
* @return null if compilation failed, main class name if not
*/
public String build(String buildPath, boolean verbose) throws RunnerException, PreferencesMapException {
useOriginalVidPidIfUncertified();
public String build(String buildPath, boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
// run the preprocessor
editor.status.progressUpdate(20);
@ -1166,7 +1159,7 @@ public class Sketch {
}
};
return Compiler.build(data, buildPath, tempBuildFolder, pl, verbose);
return Compiler.build(data, buildPath, tempBuildFolder, pl, verbose, save);
}
protected boolean exportApplet(boolean usingProgrammer) throws Exception {
@ -1184,7 +1177,7 @@ public class Sketch {
// build the sketch
editor.status.progressNotice(_("Compiling sketch..."));
String foundName = build(appletPath, false);
String foundName = build(appletPath, false, false);
// (already reported) error during export, exit this function
if (foundName == null) return false;
@ -1203,45 +1196,13 @@ public class Sketch {
return success;
}
private void useOriginalVidPidIfUncertified() {
BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
if (boardPort == null) {
return;
}
TargetBoard targetBoard = BaseNoGui.getTargetBoard();
if (targetBoard == null) {
return;
}
PreferencesMap boardPreferences = targetBoard.getPreferences();
if (boardPreferences.containsKey("build.vid") && boardPreferences.containsKey("build.pid")) {
if (!boardPreferences.containsKey("backup.build.vid")) {
boardPreferences.put("backup.build.vid", boardPreferences.get("build.vid"));
boardPreferences.put("backup.build.pid", boardPreferences.get("build.pid"));
}
if (boardPort.getPrefs().get("warning") != null) {
boardPreferences.put("build.vid", boardPort.getPrefs().get("vid"));
boardPreferences.put("build.pid", boardPort.getPrefs().get("pid"));
} else {
boardPreferences.put("build.vid", boardPreferences.get("backup.build.vid"));
boardPreferences.put("build.pid", boardPreferences.get("backup.build.pid"));
}
}
if (boardPort.getPrefs().get("warning") != null && !Preferences.getBoolean("uncertifiedBoardWarning_dontShowMeAgain")) {
SwingUtilities.invokeLater(new ShowUncertifiedBoardWarning(editor));
}
}
protected boolean upload(String buildPath, String suggestedClassName, boolean usingProgrammer) throws Exception {
Uploader uploader = Compiler.getUploaderByPreferences(false);
boolean success = false;
do {
if (uploader.requiresAuthorization() && !Preferences.has(uploader.getAuthorizationKey())) {
if (uploader.requiresAuthorization() && !PreferencesData.has(uploader.getAuthorizationKey())) {
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor, _("Type board password to upload a new sketch"));
dialog.setLocationRelativeTo(editor);
dialog.setVisible(true);
@ -1251,7 +1212,7 @@ public class Sketch {
return false;
}
Preferences.set(uploader.getAuthorizationKey(), dialog.getPassword());
PreferencesData.set(uploader.getAuthorizationKey(), dialog.getPassword());
}
List<String> warningsAccumulator = new LinkedList<String>();
@ -1259,7 +1220,7 @@ public class Sketch {
success = Compiler.upload(data, uploader, buildPath, suggestedClassName, usingProgrammer, false, warningsAccumulator);
} finally {
if (uploader.requiresAuthorization() && !success) {
Preferences.remove(uploader.getAuthorizationKey());
PreferencesData.remove(uploader.getAuthorizationKey());
}
}

View File

@ -2,37 +2,43 @@ package processing.app;
import java.io.File;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.undo.UndoManager;
public class SketchCodeDocument{
public class SketchCodeDocument implements DocumentListener{
private SketchCode code;
private Sketch sketch;
private Document document;
// Undo Manager for this tab, each tab keeps track of their own Editor.undo
// will be set to this object when this code is the tab that's currently the
// front.
private LastUndoableEditAwareUndoManager undo = new LastUndoableEditAwareUndoManager();
private UndoManager undo;
// saved positions from last time this tab was used
private int selectionStart;
private int selectionStop;
private int scrollPosition;
public SketchCodeDocument(SketchCode code) {
public SketchCodeDocument(Sketch sketch, SketchCode code) {
this.code = code;
this.sketch = sketch;
this.code.setMetadata(this);
}
public SketchCodeDocument(File file) {
public SketchCodeDocument(Sketch sketch, File file) {
this.code = new SketchCode(file, this);
this.sketch = sketch;
}
public LastUndoableEditAwareUndoManager getUndo() {
public UndoManager getUndo() {
return undo;
}
public void setUndo(LastUndoableEditAwareUndoManager undo) {
public void setUndo(UndoManager undo) {
this.undo = undo;
}
@ -74,6 +80,24 @@ public class SketchCodeDocument{
public void setDocument(Document document) {
this.document = document;
document.addDocumentListener(this);
}
@Override
public void insertUpdate(DocumentEvent e) {
if(!code.isModified()) sketch.setModified(true);
}
@Override
public void removeUpdate(DocumentEvent e) {
if(!code.isModified()) sketch.setModified(true);
}
@Override
public void changedUpdate(DocumentEvent e) {
// Callback for when styles in the current document change.
// This method is never called.
}
}

View File

@ -21,15 +21,19 @@
package processing.app;
import static processing.app.I18n._;
import java.awt.Color;
import java.awt.Font;
import java.awt.SystemColor;
import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesHelper;
import processing.app.helpers.PreferencesMap;
import processing.app.syntax.SyntaxStyle;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.io.File;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import static processing.app.I18n._;
/**
* Storage class for theme settings. This was separated from the Preferences
@ -38,17 +42,21 @@ import processing.app.syntax.SyntaxStyle;
*/
public class Theme {
/** Copy of the defaults in case the user mangles a preference. */
/**
* Copy of the defaults in case the user mangles a preference.
*/
static PreferencesMap defaults;
/** Table of attributes/values for the theme. */
/**
* Table of attributes/values for the theme.
*/
static PreferencesMap table = new PreferencesMap();
static protected void init() {
try {
table.load(Base.getLibStream("theme/theme.txt"));
table.load(new File(BaseNoGui.getContentFile("lib"), "theme/theme.txt"));
} catch (Exception te) {
Base.showError(null, _("Could not read color theme settings.\n" +
"You'll need to reinstall Arduino."), te);
"You'll need to reinstall Arduino."), te);
}
// other things that have to be set explicitly for the defaults
@ -104,7 +112,41 @@ public class Theme {
return font;
}
static public SyntaxStyle getStyle(String what) {
/**
* Returns the default font for text areas.
*
* @return The default font.
*/
public static final Font getDefaultFont() {
// Use StyleContext to get a composite font for better Asian language
// support; see Sun bug S282887.
StyleContext sc = StyleContext.getDefaultStyleContext();
Font font = null;
if (OSUtils.isMacOS()) {
// Snow Leopard (1.6) uses Menlo as default monospaced font,
// pre-Snow Leopard used Monaco.
font = sc.getFont("Menlo", Font.PLAIN, 12);
if (!"Menlo".equals(font.getFamily())) {
font = sc.getFont("Monaco", Font.PLAIN, 12);
if (!"Monaco".equals(font.getFamily())) { // Shouldn't happen
font = sc.getFont("Monospaced", Font.PLAIN, 13);
}
}
} else {
// Consolas added in Vista, used by VS2010+.
font = sc.getFont("Consolas", Font.PLAIN, 13);
if (!"Consolas".equals(font.getFamily())) {
font = sc.getFont("Monospaced", Font.PLAIN, 13);
}
}
//System.out.println(font.getFamily() + ", " + font.getName());
return font;
}
public static Map<String, Object> getStyledFont(String what, Font font) {
String split[] = get("editor." + what + ".style").split(",");
Color color = PreferencesHelper.parseColor(split[0]);
@ -114,6 +156,18 @@ public class Theme {
boolean italic = style.contains("italic");
boolean underlined = style.contains("underlined");
return new SyntaxStyle(color, italic, bold, underlined);
Font styledFont = new Font(font.getFamily(), (bold ? Font.BOLD : 0) | (italic ? Font.ITALIC : 0), font.getSize());
if (underlined) {
Map<TextAttribute, Object> attr = new Hashtable<TextAttribute, Object>();
attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
styledFont = styledFont.deriveFont(attr);
}
Map<String, Object> result = new HashMap<String, Object>();
result.put("color", color);
result.put("font", styledFont);
return result;
}
}

View File

@ -22,16 +22,16 @@
package processing.app;
import processing.app.legacy.PApplet;
import javax.swing.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Random;
import javax.swing.JOptionPane;
import processing.app.legacy.PApplet;
import static processing.app.I18n._;
@ -69,11 +69,11 @@ public class UpdateCheck implements Runnable {
Random r = new Random();
long id = r.nextLong();
String idString = Preferences.get("update.id");
String idString = PreferencesData.get("update.id");
if (idString != null) {
id = Long.parseLong(idString);
} else {
Preferences.set("update.id", String.valueOf(id));
PreferencesData.set("update.id", String.valueOf(id));
}
try {
@ -88,7 +88,7 @@ public class UpdateCheck implements Runnable {
int latest = readInt(downloadURL + "?" + info);
String lastString = Preferences.get("update.last");
String lastString = PreferencesData.get("update.last");
long now = System.currentTimeMillis();
if (lastString != null) {
long when = Long.parseLong(lastString);
@ -97,7 +97,7 @@ public class UpdateCheck implements Runnable {
return;
}
}
Preferences.set("update.last", String.valueOf(now));
PreferencesData.set("update.last", String.valueOf(now));
String prompt =
_("A new version of Arduino is available,\n" +
@ -126,11 +126,16 @@ public class UpdateCheck implements Runnable {
}
protected int readInt(String filename) throws Exception {
protected int readInt(String filename) throws IOException {
URL url = new URL(filename);
InputStream stream = url.openStream();
InputStreamReader isr = new InputStreamReader(stream);
BufferedReader reader = new BufferedReader(isr);
return Integer.parseInt(reader.readLine());
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(url.openStream()));
return Integer.parseInt(reader.readLine());
} finally {
if (reader != null) {
reader.close();
}
}
}
}

View File

@ -0,0 +1,38 @@
package processing.app.debug;
import java.util.Collection;
import java.util.Map;
public class TargetPackageStub implements TargetPackage {
private final String id;
public TargetPackageStub(String id) {
this.id = id;
}
@Override
public String getId() {
return id;
}
@Override
public Map<String, TargetPlatform> getPlatforms() {
return null;
}
@Override
public Collection<TargetPlatform> platforms() {
return null;
}
@Override
public TargetPlatform get(String platform) {
return null;
}
@Override
public boolean hasPlatform(TargetPlatform platform) {
return false;
}
}

View File

@ -0,0 +1,60 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
* Copyright 2015 Arduino LLC
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package processing.app.helpers;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.logging.LogRecord;
import java.util.logging.StreamHandler;
public class ConsoleLogger extends StreamHandler {
public ConsoleLogger() {
setOutputStream(new PrintStream(new FileOutputStream(FileDescriptor.out)));
}
public void publish(LogRecord record) {
super.publish(record);
flush();
}
/**
* Override <tt>StreamHandler.close</tt> to do a flush but not
* to close the output stream. That is, we do <b>not</b>
* close <tt>FileDescriptor.out</tt>.
*/
public void close() {
flush();
}
}

View File

@ -0,0 +1,79 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
* Copyright 2015 Arduino LLC
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package processing.app.helpers;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
public class LogFormatter extends Formatter {
public String format;
private final Date dat = new Date();
public LogFormatter(String logformat) {
format = logformat;
}
@Override
public String format(LogRecord record) {
dat.setTime(record.getMillis());
String source;
if (record.getSourceClassName() != null) {
source = record.getSourceClassName().substring(record.getSourceClassName().lastIndexOf('.') + 1);
if (record.getSourceMethodName() != null) {
source += "." + record.getSourceMethodName();
}
} else {
source = record.getLoggerName();
}
String message = formatMessage(record);
String throwable = "";
if (record.getThrown() != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println();
record.getThrown().printStackTrace(pw);
pw.close();
throwable = sw.toString();
}
return String.format(format,
dat,
source,
record.getLoggerName(),
record.getLevel(),
message,
throwable);
}
}

View File

@ -22,113 +22,95 @@
package processing.app.macosx;
import processing.app.Base;
import com.apple.eawt.*;
import processing.app.Base;
import processing.app.Editor;
import java.io.File;
import java.util.List;
/**
* Deal with issues related to thinking different. This handles the basic
* Mac OS X menu commands (and apple events) for open, about, prefs, etc.
*
* <p/>
* Based on OSXAdapter.java from Apple DTS.
*
* As of 0140, this code need not be built on platforms other than OS X,
* <p/>
* As of 0140, this code need not be built on platforms other than OS X,
* because of the new platform structure which isolates through reflection.
*/
public class ThinkDifferent implements ApplicationListener {
public class ThinkDifferent {
// pseudo-singleton model; no point in making multiple instances
// of the EAWT application or our adapter
private static ThinkDifferent adapter;
// http://developer.apple.com/documentation/Java/Reference/1.4.2/appledoc/api/com/apple/eawt/Application.html
private static Application application;
private static final int MAX_WAIT_FOR_BASE = 10000;
// reference to the app where the existing quit, about, prefs code is
private Base base;
static public void init() {
Application application = Application.getApplication();
application.setAboutHandler(new AboutHandler() {
@Override
public void handleAbout(AppEvent.AboutEvent aboutEvent) {
if (waitForBase()) {
Base.INSTANCE.handleAbout();
}
}
});
application.setPreferencesHandler(new PreferencesHandler() {
@Override
public void handlePreferences(AppEvent.PreferencesEvent preferencesEvent) {
if (waitForBase()) {
Base.INSTANCE.handlePrefs();
}
}
});
application.setOpenFileHandler(new OpenFilesHandler() {
@Override
public void openFiles(final AppEvent.OpenFilesEvent openFilesEvent) {
if (waitForBase()) {
for (File file : openFilesEvent.getFiles()) {
try {
Base.INSTANCE.handleOpen(file);
List<Editor> editors = Base.INSTANCE.getEditors();
if (editors.size() == 2 && editors.get(0).getSketch().isUntitled()) {
Base.INSTANCE.handleClose(editors.get(0));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
});
application.setQuitHandler(new QuitHandler() {
@Override
public void handleQuitRequestWith(AppEvent.QuitEvent quitEvent, QuitResponse quitResponse) {
if (waitForBase()) {
if (Base.INSTANCE.handleClose(Base.INSTANCE.getActiveEditor())) {
quitResponse.performQuit();
} else {
quitResponse.cancelQuit();
}
}
}
});
}
static public void init(Base base) {
if (application == null) {
//application = new com.apple.eawt.Application();
application = com.apple.eawt.Application.getApplication();
}
if (adapter == null) {
adapter = new ThinkDifferent(base);
}
application.addApplicationListener(adapter);
application.setEnabledAboutMenu(true);
application.setEnabledPreferencesMenu(true);
}
public ThinkDifferent(Base base) {
this.base = base;
}
// implemented handler methods. These are basically hooks into existing
// functionality from the main app, as if it came over from another platform.
public void handleAbout(ApplicationEvent ae) {
if (base != null) {
ae.setHandled(true);
base.handleAbout();
} else {
throw new IllegalStateException("handleAbout: Base instance detached from listener");
}
}
public void handlePreferences(ApplicationEvent ae) {
if (base != null) {
base.handlePrefs();
ae.setHandled(true);
} else {
throw new IllegalStateException("handlePreferences: Base instance detached from listener");
private static boolean waitForBase() {
int slept = 0;
while (Base.INSTANCE == null) {
if (slept >= MAX_WAIT_FOR_BASE) {
return false;
}
sleep(100);
slept += 100;
}
return true;
}
public void handleOpenApplication(ApplicationEvent ae) {
}
public void handleOpenFile(ApplicationEvent ae) {
// System.out.println("got open file event " + ae.getFilename());
String filename = ae.getFilename();
private static void sleep(int millis) {
try {
base.handleOpen(new File(filename));
} catch (Exception e) {
e.printStackTrace();
}
ae.setHandled(true);
}
public void handlePrintFile(ApplicationEvent ae) {
// TODO implement os x print handler here (open app, call handlePrint, quit)
}
public void handleQuit(ApplicationEvent ae) {
if (base != null) {
/*
/ You MUST setHandled(false) if you want to delay or cancel the quit.
/ This is important for cross-platform development -- have a universal quit
/ routine that chooses whether or not to quit, so the functionality is identical
/ on all platforms. This example simply cancels the AppleEvent-based quit and
/ defers to that universal method.
*/
boolean result = base.handleQuit();
ae.setHandled(result);
} else {
throw new IllegalStateException("handleQuit: Base instance detached from listener");
Thread.sleep(100);
} catch (InterruptedException e) {
//ignore
}
}
public void handleReOpenApplication(ApplicationEvent arg0) {
}
}

View File

@ -0,0 +1,54 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package processing.app.syntax;
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
import org.fife.ui.rsyntaxtextarea.TokenMaker;
public class ArduinoTokenMakerFactory extends AbstractTokenMakerFactory {
private final PdeKeywords pdeKeywords;
public ArduinoTokenMakerFactory(PdeKeywords pdeKeywords) {
this.pdeKeywords = pdeKeywords;
}
@Override
protected TokenMaker getTokenMakerImpl(String key) {
return new SketchTokenMaker(pdeKeywords);
}
@Override
protected void initTokenMakerMap() {
putMapping(RSyntaxDocument.SYNTAX_STYLE_CPLUSPLUS, SketchTokenMaker.class.getName());
}
}

View File

@ -1,273 +0,0 @@
/*
* CTokenMarker.java - C token marker
* Copyright (C) 1998, 1999 Slava Pestov
*
* You may use and modify this package for any purpose. Redistribution is
* permitted, in both source and binary form, provided that this notice
* remains intact in all source distributions of this package.
*/
package processing.app.syntax;
import javax.swing.text.Segment;
/**
* C token marker.
*
* @author Slava Pestov
*/
public class CTokenMarker extends TokenMarker
{
public CTokenMarker()
{
this(true,getKeywords());
}
public CTokenMarker(boolean cpp, KeywordMap keywords)
{
this.cpp = cpp;
this.keywords = keywords;
}
public byte markTokensImpl(byte token, Segment line, int lineIndex)
{
char[] array = line.array;
int offset = line.offset;
lastOffset = offset;
lastKeyword = offset;
int mlength = line.count + offset;
boolean backslash = false;
loop: for(int i = offset; i < mlength; i++)
{
int i1 = (i+1);
char c = array[i];
if(c == '\\')
{
backslash = !backslash;
continue;
}
switch(token)
{
case Token.NULL:
switch(c)
{
case '#':
if(backslash)
backslash = false;
else if(cpp)
{
if(doKeyword(line,i,c))
break;
addToken(i - lastOffset,token);
addToken(mlength - i,Token.KEYWORD2);
lastOffset = lastKeyword = mlength;
break loop;
}
break;
case '"':
doKeyword(line,i,c);
if(backslash)
backslash = false;
else
{
addToken(i - lastOffset,token);
token = Token.LITERAL1;
lastOffset = lastKeyword = i;
}
break;
case '\'':
doKeyword(line,i,c);
if(backslash)
backslash = false;
else
{
addToken(i - lastOffset,token);
token = Token.LITERAL2;
lastOffset = lastKeyword = i;
}
break;
case ':':
if(lastKeyword == offset)
{
if(doKeyword(line,i,c))
break;
backslash = false;
addToken(i1 - lastOffset,Token.LABEL);
lastOffset = lastKeyword = i1;
}
else if(doKeyword(line,i,c))
break;
break;
case '/':
backslash = false;
doKeyword(line,i,c);
if(mlength - i > 1)
{
switch(array[i1])
{
case '*':
addToken(i - lastOffset,token);
lastOffset = lastKeyword = i;
if(mlength - i > 2 && array[i+2] == '*')
token = Token.COMMENT2;
else
token = Token.COMMENT1;
break;
case '/':
addToken(i - lastOffset,token);
addToken(mlength - i,Token.COMMENT1);
lastOffset = lastKeyword = mlength;
break loop;
}
}
break;
default:
backslash = false;
if(!Character.isLetterOrDigit(c)
&& c != '_')
doKeyword(line,i,c);
break;
}
break;
case Token.COMMENT1:
case Token.COMMENT2:
backslash = false;
if(c == '*' && mlength - i > 1)
{
if(array[i1] == '/')
{
i++;
addToken((i+1) - lastOffset,token);
token = Token.NULL;
lastOffset = lastKeyword = i+1;
}
}
break;
case Token.LITERAL1:
if(backslash)
backslash = false;
else if(c == '"')
{
addToken(i1 - lastOffset,token);
token = Token.NULL;
lastOffset = lastKeyword = i1;
}
break;
case Token.LITERAL2:
if(backslash)
backslash = false;
else if(c == '\'')
{
addToken(i1 - lastOffset,Token.LITERAL1);
token = Token.NULL;
lastOffset = lastKeyword = i1;
}
break;
default:
throw new InternalError("Invalid state: "
+ token);
}
}
if(token == Token.NULL)
doKeyword(line,mlength,'\0');
switch(token)
{
case Token.LITERAL1:
case Token.LITERAL2:
addToken(mlength - lastOffset,Token.INVALID);
token = Token.NULL;
break;
case Token.KEYWORD2:
addToken(mlength - lastOffset,token);
if (!backslash) token = Token.NULL;
addToken(mlength - lastOffset,token);
break;
default:
addToken(mlength - lastOffset,token);
break;
}
return token;
}
public static KeywordMap getKeywords()
{
if(cKeywords == null)
{
cKeywords = new KeywordMap(false);
cKeywords.add("char",Token.KEYWORD3);
cKeywords.add("double",Token.KEYWORD3);
cKeywords.add("enum",Token.KEYWORD3);
cKeywords.add("float",Token.KEYWORD3);
cKeywords.add("int",Token.KEYWORD3);
cKeywords.add("long",Token.KEYWORD3);
cKeywords.add("short",Token.KEYWORD3);
cKeywords.add("signed",Token.KEYWORD3);
cKeywords.add("struct",Token.KEYWORD3);
cKeywords.add("typedef",Token.KEYWORD3);
cKeywords.add("union",Token.KEYWORD3);
cKeywords.add("unsigned",Token.KEYWORD3);
cKeywords.add("void",Token.KEYWORD3);
cKeywords.add("auto",Token.KEYWORD1);
cKeywords.add("const",Token.KEYWORD1);
cKeywords.add("extern",Token.KEYWORD1);
cKeywords.add("register",Token.KEYWORD1);
cKeywords.add("static",Token.KEYWORD1);
cKeywords.add("volatile",Token.KEYWORD1);
cKeywords.add("break",Token.KEYWORD1);
cKeywords.add("case",Token.KEYWORD1);
cKeywords.add("continue",Token.KEYWORD1);
cKeywords.add("default",Token.KEYWORD1);
cKeywords.add("do",Token.KEYWORD1);
cKeywords.add("else",Token.KEYWORD1);
cKeywords.add("for",Token.KEYWORD1);
cKeywords.add("goto",Token.KEYWORD1);
cKeywords.add("if",Token.KEYWORD1);
cKeywords.add("return",Token.KEYWORD1);
cKeywords.add("sizeof",Token.KEYWORD1);
cKeywords.add("switch",Token.KEYWORD1);
cKeywords.add("while",Token.KEYWORD1);
cKeywords.add("asm",Token.KEYWORD2);
cKeywords.add("asmlinkage",Token.KEYWORD2);
cKeywords.add("far",Token.KEYWORD2);
cKeywords.add("huge",Token.KEYWORD2);
cKeywords.add("inline",Token.KEYWORD2);
cKeywords.add("near",Token.KEYWORD2);
cKeywords.add("pascal",Token.KEYWORD2);
cKeywords.add("true",Token.LITERAL2);
cKeywords.add("false",Token.LITERAL2);
cKeywords.add("NULL",Token.LITERAL2);
}
return cKeywords;
}
// private members
private static KeywordMap cKeywords;
private boolean cpp;
private KeywordMap keywords;
private int lastOffset;
private int lastKeyword;
private boolean doKeyword(Segment line, int i, char c)
{
int i1 = i+1;
int len = i - lastKeyword;
byte id = keywords.lookup(line,lastKeyword,len);
if(id != Token.NULL)
{
if(lastKeyword != lastOffset)
addToken(lastKeyword - lastOffset,Token.NULL);
addToken(len,id);
lastOffset = i;
}
lastKeyword = i1;
return false;
}
}

View File

@ -1,373 +0,0 @@
/*
* DefaultInputHandler.java - Default implementation of an input handler
* Copyright (C) 1999 Slava Pestov
*
* You may use and modify this package for any purpose. Redistribution is
* permitted, in both source and binary form, provided that this notice
* remains intact in all source distributions of this package.
*/
package processing.app.syntax;
import javax.swing.KeyStroke;
import java.awt.event.*;
import java.awt.Toolkit;
import java.util.Hashtable;
import java.util.StringTokenizer;
/**
* The default input handler. It maps sequences of keystrokes into actions
* and inserts key typed events into the text area.
* @author Slava Pestov
*/
public class DefaultInputHandler extends InputHandler
{
/**
* Creates a new input handler with no key bindings defined.
*/
public DefaultInputHandler()
{
bindings = currentBindings = new Hashtable();
}
/**
* Sets up the default key bindings.
*/
public void addDefaultKeyBindings()
{
addKeyBinding("BACK_SPACE",BACKSPACE);
addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD);
addKeyBinding("DELETE",DELETE);
addKeyBinding("C+DELETE",DELETE_WORD);
addKeyBinding("ENTER",INSERT_BREAK);
addKeyBinding("TAB",INSERT_TAB);
addKeyBinding("INSERT",OVERWRITE);
addKeyBinding("C+\\",TOGGLE_RECT);
addKeyBinding("HOME",HOME);
addKeyBinding("END",END);
addKeyBinding("S+HOME",SELECT_HOME);
addKeyBinding("S+END",SELECT_END);
addKeyBinding("C+HOME",DOCUMENT_HOME);
addKeyBinding("C+END",DOCUMENT_END);
addKeyBinding("CS+HOME",SELECT_DOC_HOME);
addKeyBinding("CS+END",SELECT_DOC_END);
addKeyBinding("PAGE_UP",PREV_PAGE);
addKeyBinding("PAGE_DOWN",NEXT_PAGE);
addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE);
addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE);
addKeyBinding("LEFT",PREV_CHAR);
addKeyBinding("S+LEFT",SELECT_PREV_CHAR);
addKeyBinding("C+LEFT",PREV_WORD);
addKeyBinding("CS+LEFT",SELECT_PREV_WORD);
addKeyBinding("RIGHT",NEXT_CHAR);
addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR);
addKeyBinding("C+RIGHT",NEXT_WORD);
addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD);
addKeyBinding("UP",PREV_LINE);
addKeyBinding("S+UP",SELECT_PREV_LINE);
addKeyBinding("DOWN",NEXT_LINE);
addKeyBinding("S+DOWN",SELECT_NEXT_LINE);
addKeyBinding("C+ENTER",REPEAT);
}
/**
* Adds a key binding to this input handler. The key binding is
* a list of white space separated key strokes of the form
* <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,
* or S for Shift, and key is either a character (a-z) or a field
* name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
* @param keyBinding The key binding
* @param action The action
*/
public void addKeyBinding(String keyBinding, ActionListener action)
{
Hashtable current = bindings;
StringTokenizer st = new StringTokenizer(keyBinding);
while(st.hasMoreTokens())
{
KeyStroke keyStroke = parseKeyStroke(st.nextToken());
if(keyStroke == null)
return;
if(st.hasMoreTokens())
{
Object o = current.get(keyStroke);
if(o instanceof Hashtable)
current = (Hashtable)o;
else
{
o = new Hashtable();
current.put(keyStroke,o);
current = (Hashtable)o;
}
}
else
current.put(keyStroke,action);
}
}
/**
* Removes a key binding from this input handler. This is not yet
* implemented.
* @param keyBinding The key binding
*/
public void removeKeyBinding(String keyBinding)
{
throw new InternalError("Not yet implemented");
}
/**
* Removes all key bindings from this input handler.
*/
public void removeAllKeyBindings()
{
bindings.clear();
}
/**
* Returns a copy of this input handler that shares the same
* key bindings. Setting key bindings in the copy will also
* set them in the original.
*/
public InputHandler copy()
{
return new DefaultInputHandler(this);
}
/**
* Handle a key pressed event. This will look up the binding for
* the key stroke and execute it.
*/
public void keyPressed(KeyEvent evt)
{
int keyCode = evt.getKeyCode();
int modifiers = evt.getModifiers();
// moved this earlier so it doesn't get random meta clicks
if (keyCode == KeyEvent.VK_CONTROL ||
keyCode == KeyEvent.VK_SHIFT ||
keyCode == KeyEvent.VK_ALT ||
keyCode == KeyEvent.VK_META) {
return;
}
// don't get command-s or other menu key equivs on mac
// unless it's something that's specifically bound (cmd-left or right)
//if ((modifiers & KeyEvent.META_MASK) != 0) return;
if ((modifiers & KeyEvent.META_MASK) != 0) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers);
if (currentBindings.get(keyStroke) == null) {
return;
}
}
/*
char keyChar = evt.getKeyChar();
System.out.println("code=" + keyCode + " char=" + keyChar +
" charint=" + ((int)keyChar));
System.out.println("other codes " + KeyEvent.VK_ALT + " " +
KeyEvent.VK_META);
*/
if((modifiers & ~KeyEvent.SHIFT_MASK) != 0
|| evt.isActionKey()
|| keyCode == KeyEvent.VK_BACK_SPACE
|| keyCode == KeyEvent.VK_DELETE
|| keyCode == KeyEvent.VK_ENTER
|| keyCode == KeyEvent.VK_TAB
|| keyCode == KeyEvent.VK_ESCAPE)
{
if(grabAction != null)
{
handleGrabAction(evt);
return;
}
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode,
modifiers);
Object o = currentBindings.get(keyStroke);
if(o == null)
{
// Don't beep if the user presses some
// key we don't know about unless a
// prefix is active. Otherwise it will
// beep when caps lock is pressed, etc.
if(currentBindings != bindings)
{
Toolkit.getDefaultToolkit().beep();
// F10 should be passed on, but C+e F10
// shouldn't
repeatCount = 0;
repeat = false;
evt.consume();
}
currentBindings = bindings;
return;
}
else if(o instanceof ActionListener)
{
currentBindings = bindings;
executeAction(((ActionListener)o),
evt.getSource(),null);
evt.consume();
return;
}
else if(o instanceof Hashtable)
{
currentBindings = (Hashtable)o;
evt.consume();
return;
}
}
}
/**
* Handle a key typed event. This inserts the key into the text area.
*/
public void keyTyped(KeyEvent evt)
{
int modifiers = evt.getModifiers();
char c = evt.getKeyChar();
// this is the apple/cmd key on macosx.. so menu commands
// were being passed through as legit keys.. added this line
// in an attempt to prevent.
if ((modifiers & KeyEvent.META_MASK) != 0) return;
if (c != KeyEvent.CHAR_UNDEFINED) // &&
// (modifiers & KeyEvent.ALT_MASK) == 0)
{
if(c >= 0x20 && c != 0x7f)
{
KeyStroke keyStroke = KeyStroke.getKeyStroke(
Character.toUpperCase(c));
Object o = currentBindings.get(keyStroke);
if(o instanceof Hashtable)
{
currentBindings = (Hashtable)o;
return;
}
else if(o instanceof ActionListener)
{
currentBindings = bindings;
executeAction((ActionListener)o,
evt.getSource(),
String.valueOf(c));
return;
}
currentBindings = bindings;
if(grabAction != null)
{
handleGrabAction(evt);
return;
}
// 0-9 adds another 'digit' to the repeat number
if(repeat && Character.isDigit(c))
{
repeatCount *= 10;
repeatCount += (c - '0');
return;
}
executeAction(INSERT_CHAR,evt.getSource(),
String.valueOf(evt.getKeyChar()));
repeatCount = 0;
repeat = false;
}
}
}
/**
* Converts a string to a keystroke. The string should be of the
* form <i>modifiers</i>+<i>shortcut</i> where <i>modifiers</i>
* is any combination of A for Alt, C for Control, S for Shift
* or M for Meta, and <i>shortcut</i> is either a single character,
* or a keycode name from the <code>KeyEvent</code> class, without
* the <code>VK_</code> prefix.
* @param keyStroke A string description of the key stroke
*/
public static KeyStroke parseKeyStroke(String keyStroke)
{
if(keyStroke == null)
return null;
int modifiers = 0;
int index = keyStroke.indexOf('+');
if(index != -1)
{
for(int i = 0; i < index; i++)
{
switch(Character.toUpperCase(keyStroke
.charAt(i)))
{
case 'A':
modifiers |= InputEvent.ALT_MASK;
break;
case 'C':
modifiers |= InputEvent.CTRL_MASK;
break;
case 'M':
modifiers |= InputEvent.META_MASK;
break;
case 'S':
modifiers |= InputEvent.SHIFT_MASK;
break;
}
}
}
String key = keyStroke.substring(index + 1);
if(key.length() == 1)
{
char ch = Character.toUpperCase(key.charAt(0));
if(modifiers == 0)
return KeyStroke.getKeyStroke(ch);
else
return KeyStroke.getKeyStroke(ch,modifiers);
}
else if(key.length() == 0)
{
System.err.println("Invalid key stroke: " + keyStroke);
return null;
}
else
{
int ch;
try
{
ch = KeyEvent.class.getField("VK_".concat(key))
.getInt(null);
}
catch(Exception e)
{
System.err.println("Invalid key stroke: "
+ keyStroke);
return null;
}
return KeyStroke.getKeyStroke(ch,modifiers);
}
}
// private members
private Hashtable bindings;
private Hashtable currentBindings;
private DefaultInputHandler(DefaultInputHandler copy)
{
bindings = currentBindings = copy.bindings;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,139 +0,0 @@
/*
* KeywordMap.java - Fast keyword->id map
* Copyright (C) 1998, 1999 Slava Pestov
* Copyright (C) 1999 Mike Dillon
*
* You may use and modify this package for any purpose. Redistribution is
* permitted, in both source and binary form, provided that this notice
* remains intact in all source distributions of this package.
*/
package processing.app.syntax;
import javax.swing.text.Segment;
/**
* A <code>KeywordMap</code> is similar to a hashtable in that it maps keys
* to values. However, the `keys' are Swing segments. This allows lookups of
* text substrings without the overhead of creating a new string object.
* <p>
* This class is used by <code>CTokenMarker</code> to map keywords to ids.
*
* @author Slava Pestov, Mike Dillon
*/
public class KeywordMap
{
/**
* Creates a new <code>KeywordMap</code>.
* @param ignoreCase True if keys are case insensitive
*/
public KeywordMap(boolean ignoreCase)
{
this(ignoreCase, 52);
this.ignoreCase = ignoreCase;
}
/**
* Creates a new <code>KeywordMap</code>.
* @param ignoreCase True if the keys are case insensitive
* @param mapLength The number of `buckets' to create.
* A value of 52 will give good performance for most maps.
*/
public KeywordMap(boolean ignoreCase, int mapLength)
{
this.mapLength = mapLength;
this.ignoreCase = ignoreCase;
map = new Keyword[mapLength];
}
/**
* Looks up a key.
* @param text The text segment
* @param offset The offset of the substring within the text segment
* @param length The length of the substring
*/
public byte lookup(Segment text, int offset, int length)
{
if(length == 0)
return Token.NULL;
Keyword k = map[getSegmentMapKey(text, offset, length)];
while(k != null)
{
if(length != k.keyword.length)
{
k = k.next;
continue;
}
if(SyntaxUtilities.regionMatches(ignoreCase,text,offset,
k.keyword))
return k.id;
k = k.next;
}
return Token.NULL;
}
/**
* Adds a key-value mapping.
* @param keyword The key
* @param id The value
*/
public void add(String keyword, byte id)
{
int key = getStringMapKey(keyword);
map[key] = new Keyword(keyword.toCharArray(),id,map[key]);
}
/**
* Returns true if the keyword map is set to be case insensitive,
* false otherwise.
*/
public boolean getIgnoreCase()
{
return ignoreCase;
}
/**
* Sets if the keyword map should be case insensitive.
* @param ignoreCase True if the keyword map should be case
* insensitive, false otherwise
*/
public void setIgnoreCase(boolean ignoreCase)
{
this.ignoreCase = ignoreCase;
}
// protected members
protected int mapLength;
protected int getStringMapKey(String s)
{
return (Character.toUpperCase(s.charAt(0)) +
Character.toUpperCase(s.charAt(s.length()-1)))
% mapLength;
}
protected int getSegmentMapKey(Segment s, int off, int len)
{
return (Character.toUpperCase(s.array[off]) +
Character.toUpperCase(s.array[off + len - 1]))
% mapLength;
}
// private members
class Keyword
{
public Keyword(char[] keyword, byte id, Keyword next)
{
this.keyword = keyword;
this.id = id;
this.next = next;
}
public char[] keyword;
public byte id;
public Keyword next;
}
private Keyword[] map;
private boolean ignoreCase;
}

View File

@ -24,106 +24,158 @@
package processing.app.syntax;
import processing.app.*;
import cc.arduino.contributions.libraries.ContributedLibrary;
import org.fife.ui.rsyntaxtextarea.TokenMap;
import org.fife.ui.rsyntaxtextarea.TokenTypes;
import processing.app.Base;
import processing.app.BaseNoGui;
import processing.app.legacy.PApplet;
import processing.app.packages.Library;
import java.io.*;
import java.util.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
public class PdeKeywords extends CTokenMarker {
public class PdeKeywords {
// lookup table for the TokenMarker subclass, handles coloring
static KeywordMap keywordColoring;
private static final Map<String, Integer> KNOWN_TOKEN_TYPES = new HashMap<String, Integer>();
private static final Pattern ALPHA = Pattern.compile("\\w");
// lookup table that maps keywords to their html reference pages
static Hashtable keywordToReference;
public PdeKeywords() {
super(false, getKeywords());
static {
KNOWN_TOKEN_TYPES.put("RESERVED_WORD", TokenTypes.RESERVED_WORD);
KNOWN_TOKEN_TYPES.put("RESERVED_WORD_2", TokenTypes.RESERVED_WORD_2);
KNOWN_TOKEN_TYPES.put("VARIABLE", TokenTypes.VARIABLE);
KNOWN_TOKEN_TYPES.put("OPERATOR", TokenTypes.OPERATOR);
KNOWN_TOKEN_TYPES.put("DATA_TYPE", TokenTypes.DATA_TYPE);
KNOWN_TOKEN_TYPES.put("LITERAL_BOOLEAN", TokenTypes.LITERAL_BOOLEAN);
KNOWN_TOKEN_TYPES.put("LITERAL_CHAR", TokenTypes.LITERAL_CHAR);
}
// lookup table for the TokenMarker subclass, handles coloring
private final TokenMap keywordTokenType;
private final Map<String, String> keywordOldToken;
private final Map<String, String> keywordTokenTypeAsString;
// lookup table that maps keywords to their html reference pages
private final Map<String, String> keywordToReference;
public PdeKeywords() {
this.keywordTokenType = new TokenMap();
this.keywordOldToken = new HashMap<String, String>();
this.keywordTokenTypeAsString = new HashMap<String, String>();
this.keywordToReference = new HashMap<String, String>();
}
/**
* Handles loading of keywords file.
* <P>
* <p/>
* Uses getKeywords() method because that's part of the
* TokenMarker classes.
* <P>
* <p/>
* It is recommended that a # sign be used for comments
* inside keywords.txt.
*/
static public KeywordMap getKeywords() {
if (keywordColoring == null) {
try {
keywordColoring = new KeywordMap(false);
keywordToReference = new Hashtable();
getKeywords(Base.getLibStream("keywords.txt"));
for (Library lib : Base.getLibraries()) {
File keywords = new File(lib.getFolder(), "keywords.txt");
if (keywords.exists()) getKeywords(new FileInputStream(keywords));
public void reload() {
try {
parseKeywordsTxt(new File(BaseNoGui.getContentFile("lib"), "keywords.txt"));
for (ContributedLibrary lib : Base.getLibraries()) {
File keywords = new File(lib.getInstalledFolder(), "keywords.txt");
if (keywords.exists()) {
parseKeywordsTxt(keywords);
}
} catch (Exception e) {
Base.showError("Problem loading keywords",
"Could not load keywords.txt,\n" +
"please re-install Arduino.", e);
System.exit(1);
}
} catch (Exception e) {
Base.showError("Problem loading keywords", "Could not load keywords.txt,\nplease re-install Arduino.", e);
System.exit(1);
}
return keywordColoring;
}
static private void getKeywords(InputStream input) throws Exception {
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
String line = null;
while ((line = reader.readLine()) != null) {
//System.out.println("line is " + line);
// in case there's any garbage on the line
//if (line.trim().length() == 0) continue;
private void parseKeywordsTxt(File input) throws Exception {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(input)));
String pieces[] = PApplet.split(line, '\t');
if (pieces.length >= 2) {
//int tab = line.indexOf('\t');
// any line with no tab is ignored
// meaning that a comment is any line without a tab
//if (tab == -1) continue;
String line;
while ((line = reader.readLine()) != null) {
//System.out.println("line is " + line);
// in case there's any garbage on the line
line = line.trim();
if (line.length() == 0 || line.startsWith("#")) {
continue;
}
String pieces[] = PApplet.split(line, '\t');
String keyword = pieces[0].trim();
//String keyword = line.substring(0, tab).trim();
//String second = line.substring(tab + 1);
//tab = second.indexOf('\t');
//String coloring = second.substring(0, tab).trim();
//String htmlFilename = second.substring(tab + 1).trim();
String coloring = pieces[1].trim();
if (coloring.length() > 0 && Character.isDigit(coloring.charAt(coloring.length() - 1))) {
// text will be KEYWORD or LITERAL
boolean isKey = (coloring.charAt(0) == 'K');
// KEYWORD1 -> 0, KEYWORD2 -> 1, etc
int num = coloring.charAt(coloring.length() - 1) - '1';
byte id = (byte)
((isKey ? Token.KEYWORD1 : Token.LITERAL1) + num);
//System.out.println("got " + (isKey ? "keyword" : "literal") +
// (num+1) + " for " + keyword);
keywordColoring.add(keyword, id);
if (pieces.length >= 2) {
keywordOldToken.put(keyword, pieces[1]);
}
if (pieces.length >= 3) {
String htmlFilename = pieces[2].trim();
if (htmlFilename.length() > 0) {
keywordToReference.put(keyword, htmlFilename);
}
parseHTMLReferenceFileName(pieces[2], keyword);
}
if (pieces.length >= 4) {
parseRSyntaxTextAreaTokenType(pieces[3], keyword);
}
}
fillMissingTokenType();
} finally {
if (reader != null) {
reader.close();
}
}
}
private void fillMissingTokenType() {
for (Map.Entry<String, String> oldTokenEntry : keywordOldToken.entrySet()) {
String keyword = oldTokenEntry.getKey();
if (!keywordTokenTypeAsString.containsKey(keyword)) {
if ("KEYWORD1".equals(oldTokenEntry.getValue())) {
parseRSyntaxTextAreaTokenType("DATA_TYPE", keyword);
} else {
parseRSyntaxTextAreaTokenType("FUNCTION", keyword);
}
}
}
reader.close();
}
private void parseRSyntaxTextAreaTokenType(String tokenTypeAsString, String keyword) {
if (!ALPHA.matcher(keyword).find()) {
return;
}
static public String getReference(String keyword) {
return (String) keywordToReference.get(keyword);
if (KNOWN_TOKEN_TYPES.containsKey(tokenTypeAsString)) {
keywordTokenType.put(keyword, KNOWN_TOKEN_TYPES.get(tokenTypeAsString));
keywordTokenTypeAsString.put(keyword, tokenTypeAsString);
} else {
keywordTokenType.put(keyword, TokenTypes.FUNCTION);
keywordTokenTypeAsString.put(keyword, "FUNCTION");
}
}
private void parseHTMLReferenceFileName(String piece, String keyword) {
String htmlFilename = piece.trim();
if (htmlFilename.length() > 0) {
keywordToReference.put(keyword, htmlFilename);
}
}
public String getReference(String keyword) {
return keywordToReference.get(keyword);
}
public String getTokenTypeAsString(String keyword) {
return keywordTokenTypeAsString.get(keyword);
}
public int getTokenType(char[] array, int start, int end) {
return keywordTokenType.get(array, start, end);
}
}

View File

@ -1,211 +0,0 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
PdeTextAreaDefaults - grabs font/color settings for the editor
Part of the Processing project - http://processing.org
Copyright (c) 2004-06 Ben Fry and Casey Reas
Copyright (c) 2001-03 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package processing.app.syntax;
import processing.app.*;
import processing.app.helpers.OSUtils;
public class PdeTextAreaDefaults extends TextAreaDefaults {
public PdeTextAreaDefaults() {
inputHandler = new DefaultInputHandler();
//inputHandler.addDefaultKeyBindings(); // 0122
// use option on mac for text edit controls that are ctrl on windows/linux
String mod = OSUtils.isMacOS() ? "A" : "C";
// right now, ctrl-up/down is select up/down, but mod should be
// used instead, because the mac expects it to be option(alt)
inputHandler.addKeyBinding("BACK_SPACE", InputHandler.BACKSPACE);
// for 0122, shift-backspace is delete, for 0176, it's now a preference,
// to prevent holy warriors from attacking me for it.
if (Preferences.getBoolean("editor.keys.shift_backspace_is_delete")) {
inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.DELETE);
} else {
inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.BACKSPACE);
}
inputHandler.addKeyBinding("DELETE", InputHandler.DELETE);
inputHandler.addKeyBinding("S+DELETE", InputHandler.DELETE);
// the following two were changing for 0122 for better mac/pc compatability
inputHandler.addKeyBinding(mod+"+BACK_SPACE", InputHandler.BACKSPACE_WORD);
inputHandler.addKeyBinding(mod+"+DELETE", InputHandler.DELETE_WORD);
// handled by listener, don't bother here
//inputHandler.addKeyBinding("ENTER", InputHandler.INSERT_BREAK);
//inputHandler.addKeyBinding("TAB", InputHandler.INSERT_TAB);
inputHandler.addKeyBinding("INSERT", InputHandler.OVERWRITE);
// http://dev.processing.org/bugs/show_bug.cgi?id=162
// added for 0176, though the bindings do not appear relevant for osx
if (Preferences.getBoolean("editor.keys.alternative_cut_copy_paste")) {
inputHandler.addKeyBinding("C+INSERT", InputHandler.CLIPBOARD_COPY);
inputHandler.addKeyBinding("S+INSERT", InputHandler.CLIPBOARD_PASTE);
inputHandler.addKeyBinding("S+DELETE", InputHandler.CLIPBOARD_CUT);
}
// disabling for 0122, not sure what this does
//inputHandler.addKeyBinding("C+\\", InputHandler.TOGGLE_RECT);
// for 0122, these have been changed for better compatibility
// HOME and END now mean the beginning/end of the document
// for 0176 changed this to a preference so that the Mac OS X people
// can get the "normal" behavior as well if they prefer.
if (Preferences.getBoolean("editor.keys.home_and_end_travel_far")) {
inputHandler.addKeyBinding("HOME", InputHandler.DOCUMENT_HOME);
inputHandler.addKeyBinding("END", InputHandler.DOCUMENT_END);
inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_DOC_HOME);
inputHandler.addKeyBinding("S+END", InputHandler.SELECT_DOC_END);
} else {
// for 0123 added the proper windows defaults
inputHandler.addKeyBinding("HOME", InputHandler.HOME);
inputHandler.addKeyBinding("END", InputHandler.END);
inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_HOME);
inputHandler.addKeyBinding("S+END", InputHandler.SELECT_END);
inputHandler.addKeyBinding("C+HOME", InputHandler.DOCUMENT_HOME);
inputHandler.addKeyBinding("C+END", InputHandler.DOCUMENT_END);
inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_DOC_HOME);
inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_DOC_END);
}
if (OSUtils.isMacOS()) {
inputHandler.addKeyBinding("M+LEFT", InputHandler.HOME);
inputHandler.addKeyBinding("M+RIGHT", InputHandler.END);
inputHandler.addKeyBinding("MS+LEFT", InputHandler.SELECT_HOME); // 0122
inputHandler.addKeyBinding("MS+RIGHT", InputHandler.SELECT_END); // 0122
} else {
inputHandler.addKeyBinding("C+LEFT", InputHandler.HOME); // 0122
inputHandler.addKeyBinding("C+RIGHT", InputHandler.END); // 0122
inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_HOME); // 0122
inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_END); // 0122
}
inputHandler.addKeyBinding("PAGE_UP", InputHandler.PREV_PAGE);
inputHandler.addKeyBinding("PAGE_DOWN", InputHandler.NEXT_PAGE);
inputHandler.addKeyBinding("S+PAGE_UP", InputHandler.SELECT_PREV_PAGE);
inputHandler.addKeyBinding("S+PAGE_DOWN", InputHandler.SELECT_NEXT_PAGE);
inputHandler.addKeyBinding("LEFT", InputHandler.PREV_CHAR);
inputHandler.addKeyBinding("S+LEFT", InputHandler.SELECT_PREV_CHAR);
inputHandler.addKeyBinding(mod + "+LEFT", InputHandler.PREV_WORD);
inputHandler.addKeyBinding(mod + "S+LEFT", InputHandler.SELECT_PREV_WORD);
inputHandler.addKeyBinding("RIGHT", InputHandler.NEXT_CHAR);
inputHandler.addKeyBinding("S+RIGHT", InputHandler.SELECT_NEXT_CHAR);
inputHandler.addKeyBinding(mod + "+RIGHT", InputHandler.NEXT_WORD);
inputHandler.addKeyBinding(mod + "S+RIGHT", InputHandler.SELECT_NEXT_WORD);
inputHandler.addKeyBinding("UP", InputHandler.PREV_LINE);
inputHandler.addKeyBinding(mod + "+UP", InputHandler.PREV_LINE); // p5
inputHandler.addKeyBinding("S+UP", InputHandler.SELECT_PREV_LINE);
inputHandler.addKeyBinding("DOWN", InputHandler.NEXT_LINE);
inputHandler.addKeyBinding(mod + "+DOWN", InputHandler.NEXT_LINE); // p5
inputHandler.addKeyBinding("S+DOWN", InputHandler.SELECT_NEXT_LINE);
inputHandler.addKeyBinding("MS+UP", InputHandler.SELECT_DOC_HOME);
inputHandler.addKeyBinding("CS+UP", InputHandler.SELECT_DOC_HOME);
inputHandler.addKeyBinding("MS+DOWN", InputHandler.SELECT_DOC_END);
inputHandler.addKeyBinding("CS+DOWN", InputHandler.SELECT_DOC_END);
inputHandler.addKeyBinding(mod + "+ENTER", InputHandler.REPEAT);
document = new SyntaxDocument();
editable = true;
electricScroll = 3;
cols = 80;
rows = 15;
// moved from SyntaxUtilities
//DEFAULTS.styles = SyntaxUtilities.getDefaultSyntaxStyles();
styles = new SyntaxStyle[Token.ID_COUNT];
// comments
styles[Token.COMMENT1] = Theme.getStyle("comment1");
styles[Token.COMMENT2] = Theme.getStyle("comment2");
// abstract, final, private
styles[Token.KEYWORD1] = Theme.getStyle("keyword1");
// beginShape, point, line
styles[Token.KEYWORD2] = Theme.getStyle("keyword2");
// byte, char, short, color
styles[Token.KEYWORD3] = Theme.getStyle("keyword3");
// constants: null, true, this, RGB, TWO_PI
styles[Token.LITERAL1] = Theme.getStyle("literal1");
// p5 built in variables: mouseX, width, pixels
styles[Token.LITERAL2] = Theme.getStyle("literal2");
// ??
styles[Token.LABEL] = Theme.getStyle("label");
// http://arduino.cc/
styles[Token.URL] = Theme.getStyle("url");
// + - = /
styles[Token.OPERATOR] = Theme.getStyle("operator");
// area that's not in use by the text (replaced with tildes)
styles[Token.INVALID] = Theme.getStyle("invalid");
// moved from TextAreaPainter
font = Preferences.getFont("editor.font");
fgcolor = Theme.getColor("editor.fgcolor");
bgcolor = Theme.getColor("editor.bgcolor");
caretVisible = true;
caretBlinks = Preferences.getBoolean("editor.caret.blink");
caretColor = Theme.getColor("editor.caret.color");
selectionColor = Theme.getColor("editor.selection.color");
lineHighlight =
Theme.getBoolean("editor.linehighlight");
lineHighlightColor =
Theme.getColor("editor.linehighlight.color");
bracketHighlight =
Theme.getBoolean("editor.brackethighlight");
bracketHighlightColor =
Theme.getColor("editor.brackethighlight.color");
eolMarkers = Theme.getBoolean("editor.eolmarkers");
eolMarkerColor = Theme.getColor("editor.eolmarkers.color");
paintInvalid = Theme.getBoolean("editor.invalid");
}
}

View File

@ -0,0 +1,474 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
* Copyright 2015 Arduino LLC
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package processing.app.syntax;
import org.fife.ui.rsyntaxtextarea.*;
import org.fife.ui.rsyntaxtextarea.Theme;
import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaUI;
import org.fife.ui.rtextarea.RUndoManager;
import processing.app.*;
import javax.swing.*;
import javax.swing.event.EventListenerList;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Segment;
import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
/**
* Arduino Sketch code editor based on RSyntaxTextArea (http://fifesoft.com/rsyntaxtextarea)
*
* @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
* @date 20/04/2015
* @since 1.6.4
*/
public class SketchTextArea extends RSyntaxTextArea {
private final static Logger LOG = Logger.getLogger(SketchTextArea.class.getName());
/**
* The last docTooltip displayed.
*/
private FocusableTip docTooltip;
private EditorListener editorListener;
private final PdeKeywords pdeKeywords;
public SketchTextArea(PdeKeywords pdeKeywords) throws IOException {
this.pdeKeywords = pdeKeywords;
installFeatures();
}
protected void installFeatures() throws IOException {
setTheme(PreferencesData.get("editor.syntax_theme", "default"));
setLinkGenerator(new DocLinkGenerator(pdeKeywords));
fixControlTab();
setSyntaxEditingStyle(SYNTAX_STYLE_CPLUSPLUS);
}
public void setTheme(String name) throws IOException {
FileInputStream defaultXmlInputStream = null;
try {
defaultXmlInputStream = new FileInputStream(new File(BaseNoGui.getContentFile("lib"), "theme/syntax/" + name + ".xml"));
Theme theme = Theme.load(defaultXmlInputStream);
theme.apply(this);
} finally {
if (defaultXmlInputStream != null) {
defaultXmlInputStream.close();
}
}
setForeground(processing.app.Theme.getColor("editor.fgcolor"));
setBackground(processing.app.Theme.getColor("editor.bgcolor"));
setCurrentLineHighlightColor(processing.app.Theme.getColor("editor.linehighlight.color"));
setCaretColor(processing.app.Theme.getColor("editor.caret.color"));
setSelectedTextColor(null);
setUseSelectedTextColor(false);
setSelectionColor(processing.app.Theme.getColor("editor.selection.color"));
setMatchedBracketBorderColor(processing.app.Theme.getColor("editor.brackethighlight.color"));
setHyperlinkForeground((Color) processing.app.Theme.getStyledFont("url", getFont()).get("color"));
setSyntaxTheme(TokenTypes.DATA_TYPE, "data_type");
setSyntaxTheme(TokenTypes.FUNCTION, "function");
setSyntaxTheme(TokenTypes.RESERVED_WORD, "reserved_word");
setSyntaxTheme(TokenTypes.RESERVED_WORD_2, "reserved_word_2");
setSyntaxTheme(TokenTypes.VARIABLE, "variable");
setSyntaxTheme(TokenTypes.OPERATOR, "operator");
setSyntaxTheme(TokenTypes.COMMENT_DOCUMENTATION, "comment1");
setSyntaxTheme(TokenTypes.COMMENT_EOL, "comment1");
setSyntaxTheme(TokenTypes.COMMENT_KEYWORD, "comment1");
setSyntaxTheme(TokenTypes.COMMENT_MARKUP, "comment1");
setSyntaxTheme(TokenTypes.LITERAL_CHAR, "literal_char");
setSyntaxTheme(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, "literal_string_double_quote");
}
private void setSyntaxTheme(int tokenType, String id) {
Style style = getSyntaxScheme().getStyle(tokenType);
Map<String, Object> styledFont = processing.app.Theme.getStyledFont(id, style.font);
style.foreground = (Color) styledFont.get("color");
style.font = (Font) styledFont.get("font");
getSyntaxScheme().setStyle(tokenType, style);
}
// Removing the default focus traversal keys
// This is because the DefaultKeyboardFocusManager handles the keypress and consumes the event
protected void fixControlTab() {
removeCTRLTabFromFocusTraversal();
removeCTRLSHIFTTabFromFocusTraversal();
}
private void removeCTRLSHIFTTabFromFocusTraversal() {
KeyStroke ctrlShiftTab = KeyStroke.getKeyStroke("ctrl shift TAB");
Set<AWTKeyStroke> backwardKeys = new HashSet<AWTKeyStroke>(this.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
backwardKeys.remove(ctrlShiftTab);
}
private void removeCTRLTabFromFocusTraversal() {
KeyStroke ctrlTab = KeyStroke.getKeyStroke("ctrl TAB");
Set<AWTKeyStroke> forwardKeys = new HashSet<AWTKeyStroke>(this.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
forwardKeys.remove(ctrlTab);
this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
}
@Override
public void select(int selectionStart, int selectionEnd) {
super.select(selectionStart, selectionEnd);
}
public boolean isSelectionActive() {
return this.getSelectedText() != null;
}
public void setSelectedText(String text) {
int old = getTextMode();
setTextMode(OVERWRITE_MODE);
replaceSelection(text);
setTextMode(old);
}
public void processKeyEvent(KeyEvent evt) {
// this had to be added because the menu key events weren't making it up to the frame.
switch (evt.getID()) {
case KeyEvent.KEY_TYPED:
if (editorListener != null) editorListener.keyTyped(evt);
break;
case KeyEvent.KEY_PRESSED:
if (editorListener != null) editorListener.keyPressed(evt);
break;
case KeyEvent.KEY_RELEASED:
// inputHandler.keyReleased(evt);
break;
}
if (!evt.isConsumed()) {
super.processKeyEvent(evt);
}
}
public void switchDocument(Document document, UndoManager newUndo) {
// HACK: Dont discard changes on curret UndoManager.
// BUG: https://github.com/bobbylight/RSyntaxTextArea/issues/84
setUndoManager(null); // bypass reset current undo manager...
super.setDocument(document);
setUndoManager((RUndoManager) newUndo);
// HACK: Complement previous hack (hide code folding on switch) | Drawback: Lose folding state
// if(sketch.getCodeCount() > 1 && textarea.isCodeFoldingEnabled()){
// textarea.setCodeFoldingEnabled(false);
// textarea.setCodeFoldingEnabled(true);
// }
}
@Override
protected JPopupMenu createPopupMenu() {
JPopupMenu menu = super.createPopupMenu();
return menu;
}
@Override
protected void configurePopupMenu(JPopupMenu popupMenu) {
super.configurePopupMenu(popupMenu);
}
@Override
protected RTAMouseListener createMouseListener() {
return new SketchTextAreaMouseListener(this);
}
public void getTextLine(int line, Segment segment) {
try {
int offset = getLineStartOffset(line);
int end = getLineEndOffset(line);
getDocument().getText(offset, end - offset, segment);
} catch (BadLocationException e) {
}
}
public String getTextLine(int line) {
try {
int offset = getLineStartOffset(line);
int end = getLineEndOffset(line);
return getDocument().getText(offset, end - offset);
} catch (BadLocationException e) {
return null;
}
}
public void setEditorListener(EditorListener editorListener) {
this.editorListener = editorListener;
}
private static class DocLinkGenerator implements LinkGenerator {
private final PdeKeywords pdeKeywords;
public DocLinkGenerator(PdeKeywords pdeKeywords) {
this.pdeKeywords = pdeKeywords;
}
@Override
public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, final int offs) {
final Token token = textArea.modelToToken(offs);
final String reference = pdeKeywords.getReference(token.getLexeme());
// LOG.fine("reference: " + reference + ", match: " + (token.getType() == TokenTypes.DATA_TYPE || token.getType() == TokenTypes.VARIABLE || token.getType() == TokenTypes.FUNCTION));
if (token != null && (reference != null || (token.getType() == TokenTypes.DATA_TYPE || token.getType() == TokenTypes.VARIABLE || token.getType() == TokenTypes.FUNCTION))) {
LinkGeneratorResult generatorResult = new LinkGeneratorResult() {
@Override
public int getSourceOffset() {
return offs;
}
@Override
public HyperlinkEvent execute() {
LOG.fine("Open Reference: " + reference);
Base.showReference("Reference/" + reference);
return null;
}
};
return generatorResult;
}
return null;
}
}
/**
* Handles http hyperlinks.
* NOTE (@Ricardo JL Rufino): Workaround to enable hyperlinks by default: https://github.com/bobbylight/RSyntaxTextArea/issues/119
*/
private class SketchTextAreaMouseListener extends RTextAreaMutableCaretEvent {
private Insets insets;
private boolean isScanningForLinks;
private int hoveredOverLinkOffset = -1;
protected SketchTextAreaMouseListener(RTextArea textArea) {
super(textArea);
insets = new Insets(0, 0, 0, 0);
}
/**
* Notifies all listeners that have registered interest for notification
* on this event type. The listener list is processed last to first.
*
* @param e The event to fire.
* @see EventListenerList
*/
private void fireHyperlinkUpdate(HyperlinkEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == HyperlinkListener.class) {
((HyperlinkListener) listeners[i + 1]).hyperlinkUpdate(e);
}
}
}
private HyperlinkEvent createHyperlinkEvent(MouseEvent e) {
HyperlinkEvent he = null;
Token t = viewToToken(e.getPoint());
if (t != null) {
// Copy token, viewToModel() unfortunately modifies Token
t = new TokenImpl(t);
}
if (t != null && t.isHyperlink()) {
URL url = null;
String desc = null;
try {
String temp = t.getLexeme();
// URI's need "http://" prefix for web URL's to work.
if (temp.startsWith("www.")) {
temp = "http://" + temp;
}
url = new URL(temp);
} catch (MalformedURLException mue) {
desc = mue.getMessage();
}
he = new HyperlinkEvent(SketchTextArea.this, HyperlinkEvent.EventType.ACTIVATED, url, desc);
}
return he;
}
@Override
public void mouseClicked(MouseEvent e) {
if (getHyperlinksEnabled()) {
HyperlinkEvent he = createHyperlinkEvent(e);
if (he != null) {
fireHyperlinkUpdate(he);
}
}
}
@Override
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
if (!getHyperlinksEnabled()) {
return;
}
// LinkGenerator linkGenerator = getLinkGenerator();
// GitHub issue RSyntaxTextArea/#25 - links identified at "edges" of editor
// should not be activated if mouse is in margin insets.
insets = getInsets(insets);
if (insets != null) {
int x = e.getX();
int y = e.getY();
if (x <= insets.left || y < insets.top) {
if (isScanningForLinks) {
stopScanningForLinks();
}
return;
}
}
isScanningForLinks = true;
Token t = viewToToken(e.getPoint());
if (t != null) {
// Copy token, viewToModel() unfortunately modifies Token
t = new TokenImpl(t);
}
Cursor c2 = null;
if (t != null && t.isHyperlink()) {
if (hoveredOverLinkOffset == -1 ||
hoveredOverLinkOffset != t.getOffset()) {
hoveredOverLinkOffset = t.getOffset();
repaint();
}
c2 = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
}
// else if (t!=null && linkGenerator!=null) {
// int offs = viewToModel(e.getPoint());
// LinkGeneratorResult newResult = linkGenerator.
// isLinkAtOffset(SketchTextArea.this, offs);
// if (newResult!=null) {
// // Repaint if we're at a new link now.
// if (linkGeneratorResult==null ||
// !equal(newResult, linkGeneratorResult)) {
// repaint();
// }
// linkGeneratorResult = newResult;
// hoveredOverLinkOffset = t.getOffset();
// c2 = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
// }
// else {
// // Repaint if we've moved off of a link.
// if (linkGeneratorResult!=null) {
// repaint();
// }
// c2 = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
// hoveredOverLinkOffset = -1;
// linkGeneratorResult = null;
// }
// }
else {
c2 = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
hoveredOverLinkOffset = -1;
// linkGeneratorResult = null;
}
if (getCursor() != c2) {
setCursor(c2);
// TODO: Repaint just the affected line(s).
repaint(); // Link either left or went into.
}
}
private void stopScanningForLinks() {
if (isScanningForLinks) {
Cursor c = getCursor();
isScanningForLinks = false;
if (c != null && c.getType() == Cursor.HAND_CURSOR) {
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
repaint(); // TODO: Repaint just the affected line.
}
}
}
}
@Override
protected RTextAreaUI createRTextAreaUI() {
return new SketchTextAreaUI(this);
}
}

View File

@ -0,0 +1,43 @@
package processing.app.syntax;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaDefaultInputMap;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaEditorKit;
import processing.app.PreferencesData;
import javax.swing.*;
import javax.swing.text.DefaultEditorKit;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class SketchTextAreaDefaultInputMap extends RSyntaxTextAreaDefaultInputMap {
public SketchTextAreaDefaultInputMap() {
int defaultModifier = getDefaultModifier();
int alt = InputEvent.ALT_MASK;
boolean isOSX = RTextArea.isOSX();
int moveByWordMod = isOSX ? alt : defaultModifier;
remove(KeyStroke.getKeyStroke(KeyEvent.VK_K, defaultModifier));
if (PreferencesData.getBoolean("editor.advanced")) {
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, alt), RTextAreaEditorKit.rtaLineDownAction);
put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, alt), RTextAreaEditorKit.rtaLineUpAction);
} else {
remove(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, alt));
remove(KeyStroke.getKeyStroke(KeyEvent.VK_UP, alt));
}
remove(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, defaultModifier));
put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, moveByWordMod), RTextAreaEditorKit.rtaDeletePrevWordAction);
if (isOSX) {
put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, defaultModifier), SketchTextAreaEditorKit.rtaDeleteLineToCursorAction);
put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, defaultModifier), DefaultEditorKit.beginAction);
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, defaultModifier), DefaultEditorKit.endAction);
remove(KeyStroke.getKeyStroke(KeyEvent.VK_J, defaultModifier));
}
}
}

View File

@ -0,0 +1,103 @@
package processing.app.syntax;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RecordableTextAction;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.ActionEvent;
public class SketchTextAreaEditorKit extends RSyntaxTextAreaEditorKit {
public static final String rtaDeleteNextWordAction = "RTA.DeleteNextWordAction";
public static final String rtaDeleteLineToCursorAction = "RTA.DeleteLineToCursorAction";
private static final Action[] defaultActions = {
new DeleteNextWordAction(),
new DeleteLineToCursorAction()
};
@Override
public Action[] getActions() {
return TextAction.augmentList(super.getActions(), SketchTextAreaEditorKit.defaultActions);
}
public static class DeleteNextWordAction extends RecordableTextAction {
public DeleteNextWordAction() {
super(rtaDeleteNextWordAction);
}
@Override
public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
if (!textArea.isEditable() || !textArea.isEnabled()) {
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
return;
}
try {
int start = textArea.getSelectionStart();
int end = getNextWordStart(textArea, start);
if (end > start) {
textArea.getDocument().remove(start, end - start);
}
} catch (BadLocationException ex) {
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
}
}
@Override
public String getMacroID() {
return rtaDeleteNextWordAction;
}
/**
* Returns the starting offset to delete. Exists so subclasses can
* override.
*/
protected int getNextWordStart(RTextArea textArea, int end)
throws BadLocationException {
return Utilities.getNextWord(textArea, end);
}
}
public static class DeleteLineToCursorAction extends RecordableTextAction {
public DeleteLineToCursorAction() {
super(rtaDeleteLineToCursorAction);
}
@Override
public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
if (!textArea.isEditable() || !textArea.isEnabled()) {
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
return;
}
try {
// We use the elements instead of calling getLineOfOffset(),
// etc. to speed things up just a tad (i.e. micro-optimize).
Document document = textArea.getDocument();
int caretPosition = textArea.getCaretPosition();
Element map = document.getDefaultRootElement();
int currentLineNum = map.getElementIndex(caretPosition);
Element currentLineElement = map.getElement(currentLineNum);
int currentLineStart = currentLineElement.getStartOffset();
if (caretPosition > currentLineStart) {
document.remove(currentLineStart, caretPosition - currentLineStart);
}
} catch (BadLocationException ble) {
ble.printStackTrace();
}
}
@Override
public String getMacroID() {
return rtaDeleteLineToCursorAction;
}
}
}

View File

@ -0,0 +1,21 @@
package processing.app.syntax;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI;
import javax.swing.*;
import javax.swing.text.EditorKit;
import javax.swing.text.JTextComponent;
public class SketchTextAreaUI extends RSyntaxTextAreaUI {
private static final EditorKit defaultKit = new SketchTextAreaEditorKit();
public SketchTextAreaUI(JComponent rSyntaxTextArea) {
super(rSyntaxTextArea);
}
@Override
public EditorKit getEditorKit(JTextComponent tc) {
return defaultKit;
}
}

View File

@ -0,0 +1,62 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
* Copyright 2015 Arduino LLC
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package processing.app.syntax;
import org.fife.ui.rsyntaxtextarea.modes.CPlusPlusTokenMaker;
import java.util.Arrays;
/**
* Controls the syntax highlighting of {@link SketchTextArea} based on the {@link PdeKeywords}
*
* @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
* @date 20/04/2015
* @since 1.6.4
*/
public class SketchTokenMaker extends CPlusPlusTokenMaker {
private final PdeKeywords pdeKeywords;
public SketchTokenMaker(PdeKeywords pdeKeywords) {
this.pdeKeywords = pdeKeywords;
}
@Override
public void addToken(char[] array, int start, int end, int tokenType, int startOffset, boolean hyperlink) {
// This assumes all of your extra tokens would normally be scanned as IDENTIFIER.
int newType = pdeKeywords.getTokenType(array, start, end);
if (newType > -1) {
tokenType = newType;
}
super.addToken(array, start, end, tokenType, startOffset, hyperlink);
}
}

Some files were not shown because too many files have changed in this diff Show More