diff options
448 files changed, 11515 insertions, 1642 deletions
diff --git a/anttasks/src/com/android/ant/LintExecTask.java b/anttasks/src/com/android/ant/LintExecTask.java index 64a6c00..3d687cb 100644 --- a/anttasks/src/com/android/ant/LintExecTask.java +++ b/anttasks/src/com/android/ant/LintExecTask.java @@ -28,6 +28,8 @@ public class LintExecTask extends ExecTask { private String mExecutable; private String mHtml; private String mXml; + private Path mSourcePath; + private Path mClassPath; /** * Sets the value of the "executable" attribute. @@ -37,6 +39,16 @@ public class LintExecTask extends ExecTask { mExecutable = TaskHelper.checkSinglePath("executable", executable); } + /** Sets the path where Java source code should be found */ + public void setSrc(Path path) { + mSourcePath = path; + } + + /** Sets the path where class files should be found */ + public void setClasspath(Path path) { + mClassPath = path; + } + /** * Sets the value of the "html" attribute: a path to a file or directory name * where the HTML report should be written. @@ -80,6 +92,16 @@ public class LintExecTask extends ExecTask { task.createArg().setValue(mXml); } + if (mSourcePath != null) { + task.createArg().setValue("--sources"); + task.createArg().setValue(mSourcePath.toString()); + } + + if (mClassPath != null) { + task.createArg().setValue("--classpath"); + task.createArg().setValue(mClassPath.toString()); + } + task.createArg().setValue(getProject().getBaseDir().getAbsolutePath()); task.execute(); } diff --git a/assetstudio/src/images/clipart/big/1-navigation-accept.png b/assetstudio/src/images/clipart/big/1-navigation-accept.png Binary files differnew file mode 100644 index 0000000..121b347 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-accept.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-back.png b/assetstudio/src/images/clipart/big/1-navigation-back.png Binary files differnew file mode 100644 index 0000000..863074c --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-back.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-cancel.png b/assetstudio/src/images/clipart/big/1-navigation-cancel.png Binary files differnew file mode 100644 index 0000000..d968d34 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-cancel.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-collapse.png b/assetstudio/src/images/clipart/big/1-navigation-collapse.png Binary files differnew file mode 100644 index 0000000..e525983 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-collapse.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-expand.png b/assetstudio/src/images/clipart/big/1-navigation-expand.png Binary files differnew file mode 100644 index 0000000..f5b0728 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-expand.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-forward.png b/assetstudio/src/images/clipart/big/1-navigation-forward.png Binary files differnew file mode 100644 index 0000000..4cae802 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-forward.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-next-item.png b/assetstudio/src/images/clipart/big/1-navigation-next-item.png Binary files differnew file mode 100644 index 0000000..a1b8b83 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-next-item.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-previous-item.png b/assetstudio/src/images/clipart/big/1-navigation-previous-item.png Binary files differnew file mode 100644 index 0000000..9312bf6 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-previous-item.png diff --git a/assetstudio/src/images/clipart/big/1-navigation-refresh.png b/assetstudio/src/images/clipart/big/1-navigation-refresh.png Binary files differnew file mode 100644 index 0000000..b5202f9 --- /dev/null +++ b/assetstudio/src/images/clipart/big/1-navigation-refresh.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-accounts.png b/assetstudio/src/images/clipart/big/10-device-access-accounts.png Binary files differnew file mode 100644 index 0000000..64544c5 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-accounts.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-add-alarm.png b/assetstudio/src/images/clipart/big/10-device-access-add-alarm.png Binary files differnew file mode 100644 index 0000000..bd4bcc3 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-add-alarm.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-alarms.png b/assetstudio/src/images/clipart/big/10-device-access-alarms.png Binary files differnew file mode 100644 index 0000000..a5b1ead --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-alarms.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-battery.png b/assetstudio/src/images/clipart/big/10-device-access-battery.png Binary files differnew file mode 100644 index 0000000..d86b2c1 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-battery.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-bightness-low.png b/assetstudio/src/images/clipart/big/10-device-access-bightness-low.png Binary files differnew file mode 100644 index 0000000..738f203 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-bightness-low.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-bluetooth-connected.png b/assetstudio/src/images/clipart/big/10-device-access-bluetooth-connected.png Binary files differnew file mode 100644 index 0000000..403a0b5 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-bluetooth-connected.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-bluetooth-searching.png b/assetstudio/src/images/clipart/big/10-device-access-bluetooth-searching.png Binary files differnew file mode 100644 index 0000000..a99f65a --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-bluetooth-searching.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-bluetooth.png b/assetstudio/src/images/clipart/big/10-device-access-bluetooth.png Binary files differnew file mode 100644 index 0000000..556499d --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-bluetooth.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-brightness-auto.png b/assetstudio/src/images/clipart/big/10-device-access-brightness-auto.png Binary files differnew file mode 100644 index 0000000..46d2b8a --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-brightness-auto.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-brightness-high.png b/assetstudio/src/images/clipart/big/10-device-access-brightness-high.png Binary files differnew file mode 100644 index 0000000..97e3f19 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-brightness-high.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-brightness-medium.png b/assetstudio/src/images/clipart/big/10-device-access-brightness-medium.png Binary files differnew file mode 100644 index 0000000..5e361cb --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-brightness-medium.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-call.png b/assetstudio/src/images/clipart/big/10-device-access-call.png Binary files differnew file mode 100644 index 0000000..940bcb6 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-call.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-camera.png b/assetstudio/src/images/clipart/big/10-device-access-camera.png Binary files differnew file mode 100644 index 0000000..ad8857a --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-camera.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-data-usage.png b/assetstudio/src/images/clipart/big/10-device-access-data-usage.png Binary files differnew file mode 100644 index 0000000..9fa73a5 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-data-usage.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-dial-pad.png b/assetstudio/src/images/clipart/big/10-device-access-dial-pad.png Binary files differnew file mode 100644 index 0000000..81da080 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-dial-pad.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-end-call.png b/assetstudio/src/images/clipart/big/10-device-access-end-call.png Binary files differnew file mode 100644 index 0000000..c28f284 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-end-call.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-flash-automatic.png b/assetstudio/src/images/clipart/big/10-device-access-flash-automatic.png Binary files differnew file mode 100644 index 0000000..e5c2c03 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-flash-automatic.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-flash-off.png b/assetstudio/src/images/clipart/big/10-device-access-flash-off.png Binary files differnew file mode 100644 index 0000000..dfcb747 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-flash-off.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-flash-on.png b/assetstudio/src/images/clipart/big/10-device-access-flash-on.png Binary files differnew file mode 100644 index 0000000..1109aa0 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-flash-on.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-location-found.png b/assetstudio/src/images/clipart/big/10-device-access-location-found.png Binary files differnew file mode 100644 index 0000000..d829a3c --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-location-found.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-location-off.png b/assetstudio/src/images/clipart/big/10-device-access-location-off.png Binary files differnew file mode 100644 index 0000000..e58c258 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-location-off.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-location-searching.png b/assetstudio/src/images/clipart/big/10-device-access-location-searching.png Binary files differnew file mode 100644 index 0000000..3de2f26 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-location-searching.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-mic-muted.png b/assetstudio/src/images/clipart/big/10-device-access-mic-muted.png Binary files differnew file mode 100644 index 0000000..65b4ae6 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-mic-muted.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-mic.png b/assetstudio/src/images/clipart/big/10-device-access-mic.png Binary files differnew file mode 100644 index 0000000..02c1ee8 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-mic.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-network-cell.png b/assetstudio/src/images/clipart/big/10-device-access-network-cell.png Binary files differnew file mode 100644 index 0000000..9d60dbd --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-network-cell.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-network-wifi.png b/assetstudio/src/images/clipart/big/10-device-access-network-wifi.png Binary files differnew file mode 100644 index 0000000..577abdb --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-network-wifi.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-new-account.png b/assetstudio/src/images/clipart/big/10-device-access-new-account.png Binary files differnew file mode 100644 index 0000000..d9707d8 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-new-account.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-not-secure.png b/assetstudio/src/images/clipart/big/10-device-access-not-secure.png Binary files differnew file mode 100644 index 0000000..2ea293a --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-not-secure.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-ring-volume.png b/assetstudio/src/images/clipart/big/10-device-access-ring-volume.png Binary files differnew file mode 100644 index 0000000..9d19f89 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-ring-volume.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-screen-locked-to-landscape.png b/assetstudio/src/images/clipart/big/10-device-access-screen-locked-to-landscape.png Binary files differnew file mode 100644 index 0000000..c702480 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-screen-locked-to-landscape.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-screen-locked-to-portrait.png b/assetstudio/src/images/clipart/big/10-device-access-screen-locked-to-portrait.png Binary files differnew file mode 100644 index 0000000..f66923c --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-screen-locked-to-portrait.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-screen-rotation.png b/assetstudio/src/images/clipart/big/10-device-access-screen-rotation.png Binary files differnew file mode 100644 index 0000000..22e0fcb --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-screen-rotation.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-sd-storage.png b/assetstudio/src/images/clipart/big/10-device-access-sd-storage.png Binary files differnew file mode 100644 index 0000000..cbde363 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-sd-storage.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-secure.png b/assetstudio/src/images/clipart/big/10-device-access-secure.png Binary files differnew file mode 100644 index 0000000..83f4f7d --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-secure.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-storage.png b/assetstudio/src/images/clipart/big/10-device-access-storage.png Binary files differnew file mode 100644 index 0000000..5addbad --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-storage.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-switch-camera.png b/assetstudio/src/images/clipart/big/10-device-access-switch-camera.png Binary files differnew file mode 100644 index 0000000..8b2a2e3 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-switch-camera.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-switch-video.png b/assetstudio/src/images/clipart/big/10-device-access-switch-video.png Binary files differnew file mode 100644 index 0000000..a2919f1 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-switch-video.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-time.png b/assetstudio/src/images/clipart/big/10-device-access-time.png Binary files differnew file mode 100644 index 0000000..aa21482 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-time.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-usb.png b/assetstudio/src/images/clipart/big/10-device-access-usb.png Binary files differnew file mode 100644 index 0000000..ba01983 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-usb.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-video.png b/assetstudio/src/images/clipart/big/10-device-access-video.png Binary files differnew file mode 100644 index 0000000..e18c6bd --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-video.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-volume-muted.png b/assetstudio/src/images/clipart/big/10-device-access-volume-muted.png Binary files differnew file mode 100644 index 0000000..10433a7 --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-volume-muted.png diff --git a/assetstudio/src/images/clipart/big/10-device-access-volume-on.png b/assetstudio/src/images/clipart/big/10-device-access-volume-on.png Binary files differnew file mode 100644 index 0000000..bc86a7b --- /dev/null +++ b/assetstudio/src/images/clipart/big/10-device-access-volume-on.png diff --git a/assetstudio/src/images/clipart/big/11-alerts-and-states-airplane-mode-off.png b/assetstudio/src/images/clipart/big/11-alerts-and-states-airplane-mode-off.png Binary files differnew file mode 100644 index 0000000..f7db5e8 --- /dev/null +++ b/assetstudio/src/images/clipart/big/11-alerts-and-states-airplane-mode-off.png diff --git a/assetstudio/src/images/clipart/big/11-alerts-and-states-airplane-mode-on.png b/assetstudio/src/images/clipart/big/11-alerts-and-states-airplane-mode-on.png Binary files differnew file mode 100644 index 0000000..7e8bf73 --- /dev/null +++ b/assetstudio/src/images/clipart/big/11-alerts-and-states-airplane-mode-on.png diff --git a/assetstudio/src/images/clipart/big/11-alerts-and-states-error.png b/assetstudio/src/images/clipart/big/11-alerts-and-states-error.png Binary files differnew file mode 100644 index 0000000..24335f9 --- /dev/null +++ b/assetstudio/src/images/clipart/big/11-alerts-and-states-error.png diff --git a/assetstudio/src/images/clipart/big/11-alerts-and-states-warning.png b/assetstudio/src/images/clipart/big/11-alerts-and-states-warning.png Binary files differnew file mode 100644 index 0000000..be321f4 --- /dev/null +++ b/assetstudio/src/images/clipart/big/11-alerts-and-states-warning.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-computer.png b/assetstudio/src/images/clipart/big/12-hardware-computer.png Binary files differnew file mode 100644 index 0000000..6170018 --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-computer.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-dock.png b/assetstudio/src/images/clipart/big/12-hardware-dock.png Binary files differnew file mode 100644 index 0000000..c2fc8c8 --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-dock.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-gamepad.png b/assetstudio/src/images/clipart/big/12-hardware-gamepad.png Binary files differnew file mode 100644 index 0000000..3ddc322 --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-gamepad.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-headphones.png b/assetstudio/src/images/clipart/big/12-hardware-headphones.png Binary files differnew file mode 100644 index 0000000..e7bce69 --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-headphones.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-headset.png b/assetstudio/src/images/clipart/big/12-hardware-headset.png Binary files differnew file mode 100644 index 0000000..29f659b --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-headset.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-keyboard.png b/assetstudio/src/images/clipart/big/12-hardware-keyboard.png Binary files differnew file mode 100644 index 0000000..4a2bf70 --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-keyboard.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-mouse.png b/assetstudio/src/images/clipart/big/12-hardware-mouse.png Binary files differnew file mode 100644 index 0000000..2bf8c05 --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-mouse.png diff --git a/assetstudio/src/images/clipart/big/12-hardware-phone.png b/assetstudio/src/images/clipart/big/12-hardware-phone.png Binary files differnew file mode 100644 index 0000000..423fe65 --- /dev/null +++ b/assetstudio/src/images/clipart/big/12-hardware-phone.png diff --git a/assetstudio/src/images/clipart/big/2-action-about.png b/assetstudio/src/images/clipart/big/2-action-about.png Binary files differnew file mode 100644 index 0000000..6d43316 --- /dev/null +++ b/assetstudio/src/images/clipart/big/2-action-about.png diff --git a/assetstudio/src/images/clipart/big/2-action-help.png b/assetstudio/src/images/clipart/big/2-action-help.png Binary files differnew file mode 100644 index 0000000..16eb8ef --- /dev/null +++ b/assetstudio/src/images/clipart/big/2-action-help.png diff --git a/assetstudio/src/images/clipart/big/2-action-search.png b/assetstudio/src/images/clipart/big/2-action-search.png Binary files differnew file mode 100644 index 0000000..9345a06 --- /dev/null +++ b/assetstudio/src/images/clipart/big/2-action-search.png diff --git a/assetstudio/src/images/clipart/big/2-action-settings.png b/assetstudio/src/images/clipart/big/2-action-settings.png Binary files differnew file mode 100644 index 0000000..a049ca0 --- /dev/null +++ b/assetstudio/src/images/clipart/big/2-action-settings.png diff --git a/assetstudio/src/images/clipart/big/3-rating-bad.png b/assetstudio/src/images/clipart/big/3-rating-bad.png Binary files differnew file mode 100644 index 0000000..1ab8c5b --- /dev/null +++ b/assetstudio/src/images/clipart/big/3-rating-bad.png diff --git a/assetstudio/src/images/clipart/big/3-rating-favorite.png b/assetstudio/src/images/clipart/big/3-rating-favorite.png Binary files differnew file mode 100644 index 0000000..9b68720 --- /dev/null +++ b/assetstudio/src/images/clipart/big/3-rating-favorite.png diff --git a/assetstudio/src/images/clipart/big/3-rating-good.png b/assetstudio/src/images/clipart/big/3-rating-good.png Binary files differnew file mode 100644 index 0000000..c72826b --- /dev/null +++ b/assetstudio/src/images/clipart/big/3-rating-good.png diff --git a/assetstudio/src/images/clipart/big/3-rating-half-important.png b/assetstudio/src/images/clipart/big/3-rating-half-important.png Binary files differnew file mode 100644 index 0000000..2110a0f --- /dev/null +++ b/assetstudio/src/images/clipart/big/3-rating-half-important.png diff --git a/assetstudio/src/images/clipart/big/3-rating-important.png b/assetstudio/src/images/clipart/big/3-rating-important.png Binary files differnew file mode 100644 index 0000000..dbad544 --- /dev/null +++ b/assetstudio/src/images/clipart/big/3-rating-important.png diff --git a/assetstudio/src/images/clipart/big/3-rating-not-important.png b/assetstudio/src/images/clipart/big/3-rating-not-important.png Binary files differnew file mode 100644 index 0000000..f7cf26f --- /dev/null +++ b/assetstudio/src/images/clipart/big/3-rating-not-important.png diff --git a/assetstudio/src/images/clipart/big/4-collections-cloud.png b/assetstudio/src/images/clipart/big/4-collections-cloud.png Binary files differnew file mode 100644 index 0000000..a2cedbf --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-cloud.png diff --git a/assetstudio/src/images/clipart/big/4-collections-collection.png b/assetstudio/src/images/clipart/big/4-collections-collection.png Binary files differnew file mode 100644 index 0000000..dfb2508 --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-collection.png diff --git a/assetstudio/src/images/clipart/big/4-collections-go-to-today.png b/assetstudio/src/images/clipart/big/4-collections-go-to-today.png Binary files differnew file mode 100644 index 0000000..b4971ca --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-go-to-today.png diff --git a/assetstudio/src/images/clipart/big/4-collections-labels.png b/assetstudio/src/images/clipart/big/4-collections-labels.png Binary files differnew file mode 100644 index 0000000..16f35a8 --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-labels.png diff --git a/assetstudio/src/images/clipart/big/4-collections-new-label.png b/assetstudio/src/images/clipart/big/4-collections-new-label.png Binary files differnew file mode 100644 index 0000000..cbf02af --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-new-label.png diff --git a/assetstudio/src/images/clipart/big/4-collections-sort-by-size.png b/assetstudio/src/images/clipart/big/4-collections-sort-by-size.png Binary files differnew file mode 100644 index 0000000..10aec0d --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-sort-by-size.png diff --git a/assetstudio/src/images/clipart/big/4-collections-view-as-grid.png b/assetstudio/src/images/clipart/big/4-collections-view-as-grid.png Binary files differnew file mode 100644 index 0000000..10a8fe3 --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-view-as-grid.png diff --git a/assetstudio/src/images/clipart/big/4-collections-view-as-list.png b/assetstudio/src/images/clipart/big/4-collections-view-as-list.png Binary files differnew file mode 100644 index 0000000..5cf08e4 --- /dev/null +++ b/assetstudio/src/images/clipart/big/4-collections-view-as-list.png diff --git a/assetstudio/src/images/clipart/big/5-content-attachment.png b/assetstudio/src/images/clipart/big/5-content-attachment.png Binary files differnew file mode 100644 index 0000000..92e6726 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-attachment.png diff --git a/assetstudio/src/images/clipart/big/5-content-backspace.png b/assetstudio/src/images/clipart/big/5-content-backspace.png Binary files differnew file mode 100644 index 0000000..9a7e456 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-backspace.png diff --git a/assetstudio/src/images/clipart/big/5-content-copy.png b/assetstudio/src/images/clipart/big/5-content-copy.png Binary files differnew file mode 100644 index 0000000..284a5ce --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-copy.png diff --git a/assetstudio/src/images/clipart/big/5-content-cut.png b/assetstudio/src/images/clipart/big/5-content-cut.png Binary files differnew file mode 100644 index 0000000..18d1763 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-cut.png diff --git a/assetstudio/src/images/clipart/big/5-content-discard.png b/assetstudio/src/images/clipart/big/5-content-discard.png Binary files differnew file mode 100644 index 0000000..e40e1fe --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-discard.png diff --git a/assetstudio/src/images/clipart/big/5-content-edit.png b/assetstudio/src/images/clipart/big/5-content-edit.png Binary files differnew file mode 100644 index 0000000..f75157c --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-edit.png diff --git a/assetstudio/src/images/clipart/big/5-content-email.png b/assetstudio/src/images/clipart/big/5-content-email.png Binary files differnew file mode 100644 index 0000000..6bec626 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-email.png diff --git a/assetstudio/src/images/clipart/big/5-content-event.png b/assetstudio/src/images/clipart/big/5-content-event.png Binary files differnew file mode 100644 index 0000000..dc4ed94 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-event.png diff --git a/assetstudio/src/images/clipart/big/5-content-import-export.png b/assetstudio/src/images/clipart/big/5-content-import-export.png Binary files differnew file mode 100644 index 0000000..7dcd6b0 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-import-export.png diff --git a/assetstudio/src/images/clipart/big/5-content-merge.png b/assetstudio/src/images/clipart/big/5-content-merge.png Binary files differnew file mode 100644 index 0000000..45ca498 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-merge.png diff --git a/assetstudio/src/images/clipart/big/5-content-new-attachment.png b/assetstudio/src/images/clipart/big/5-content-new-attachment.png Binary files differnew file mode 100644 index 0000000..3e441d8 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-new-attachment.png diff --git a/assetstudio/src/images/clipart/big/5-content-new-email.png b/assetstudio/src/images/clipart/big/5-content-new-email.png Binary files differnew file mode 100644 index 0000000..fdcd64b --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-new-email.png diff --git a/assetstudio/src/images/clipart/big/5-content-new-event.png b/assetstudio/src/images/clipart/big/5-content-new-event.png Binary files differnew file mode 100644 index 0000000..29ef513 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-new-event.png diff --git a/assetstudio/src/images/clipart/big/5-content-new-picture.png b/assetstudio/src/images/clipart/big/5-content-new-picture.png Binary files differnew file mode 100644 index 0000000..1975219 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-new-picture.png diff --git a/assetstudio/src/images/clipart/big/5-content-new.png b/assetstudio/src/images/clipart/big/5-content-new.png Binary files differnew file mode 100644 index 0000000..9bb4337 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-new.png diff --git a/assetstudio/src/images/clipart/big/5-content-paste.png b/assetstudio/src/images/clipart/big/5-content-paste.png Binary files differnew file mode 100644 index 0000000..f9393c0 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-paste.png diff --git a/assetstudio/src/images/clipart/big/5-content-picture.png b/assetstudio/src/images/clipart/big/5-content-picture.png Binary files differnew file mode 100644 index 0000000..dc3251b --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-picture.png diff --git a/assetstudio/src/images/clipart/big/5-content-read.png b/assetstudio/src/images/clipart/big/5-content-read.png Binary files differnew file mode 100644 index 0000000..0a48d75 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-read.png diff --git a/assetstudio/src/images/clipart/big/5-content-remove.png b/assetstudio/src/images/clipart/big/5-content-remove.png Binary files differnew file mode 100644 index 0000000..d968d34 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-remove.png diff --git a/assetstudio/src/images/clipart/big/5-content-save.png b/assetstudio/src/images/clipart/big/5-content-save.png Binary files differnew file mode 100644 index 0000000..befe49a --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-save.png diff --git a/assetstudio/src/images/clipart/big/5-content-select-all.png b/assetstudio/src/images/clipart/big/5-content-select-all.png Binary files differnew file mode 100644 index 0000000..572b2b5 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-select-all.png diff --git a/assetstudio/src/images/clipart/big/5-content-split.png b/assetstudio/src/images/clipart/big/5-content-split.png Binary files differnew file mode 100644 index 0000000..7e5d059 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-split.png diff --git a/assetstudio/src/images/clipart/big/5-content-undo.png b/assetstudio/src/images/clipart/big/5-content-undo.png Binary files differnew file mode 100644 index 0000000..07fc7d8 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-undo.png diff --git a/assetstudio/src/images/clipart/big/5-content-unread.png b/assetstudio/src/images/clipart/big/5-content-unread.png Binary files differnew file mode 100644 index 0000000..41ba9e2 --- /dev/null +++ b/assetstudio/src/images/clipart/big/5-content-unread.png diff --git a/assetstudio/src/images/clipart/big/6-social-add-group.png b/assetstudio/src/images/clipart/big/6-social-add-group.png Binary files differnew file mode 100644 index 0000000..7822f4f --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-add-group.png diff --git a/assetstudio/src/images/clipart/big/6-social-add-person.png b/assetstudio/src/images/clipart/big/6-social-add-person.png Binary files differnew file mode 100644 index 0000000..b335788 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-add-person.png diff --git a/assetstudio/src/images/clipart/big/6-social-cc-bcc.png b/assetstudio/src/images/clipart/big/6-social-cc-bcc.png Binary files differnew file mode 100644 index 0000000..4db30a7 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-cc-bcc.png diff --git a/assetstudio/src/images/clipart/big/6-social-chat.png b/assetstudio/src/images/clipart/big/6-social-chat.png Binary files differnew file mode 100644 index 0000000..b0cccb3 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-chat.png diff --git a/assetstudio/src/images/clipart/big/6-social-forward.png b/assetstudio/src/images/clipart/big/6-social-forward.png Binary files differnew file mode 100644 index 0000000..a5abbfc --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-forward.png diff --git a/assetstudio/src/images/clipart/big/6-social-group.png b/assetstudio/src/images/clipart/big/6-social-group.png Binary files differnew file mode 100644 index 0000000..1b18678 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-group.png diff --git a/assetstudio/src/images/clipart/big/6-social-person.png b/assetstudio/src/images/clipart/big/6-social-person.png Binary files differnew file mode 100644 index 0000000..27ade22 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-person.png diff --git a/assetstudio/src/images/clipart/big/6-social-reply-all.png b/assetstudio/src/images/clipart/big/6-social-reply-all.png Binary files differnew file mode 100644 index 0000000..c2a87c6 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-reply-all.png diff --git a/assetstudio/src/images/clipart/big/6-social-reply.png b/assetstudio/src/images/clipart/big/6-social-reply.png Binary files differnew file mode 100644 index 0000000..550aa80 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-reply.png diff --git a/assetstudio/src/images/clipart/big/6-social-send-now.png b/assetstudio/src/images/clipart/big/6-social-send-now.png Binary files differnew file mode 100644 index 0000000..c3dad3c --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-send-now.png diff --git a/assetstudio/src/images/clipart/big/6-social-share.png b/assetstudio/src/images/clipart/big/6-social-share.png Binary files differnew file mode 100644 index 0000000..b664970 --- /dev/null +++ b/assetstudio/src/images/clipart/big/6-social-share.png diff --git a/assetstudio/src/images/clipart/big/7-location-directions.png b/assetstudio/src/images/clipart/big/7-location-directions.png Binary files differnew file mode 100644 index 0000000..c0e67e4 --- /dev/null +++ b/assetstudio/src/images/clipart/big/7-location-directions.png diff --git a/assetstudio/src/images/clipart/big/7-location-map.png b/assetstudio/src/images/clipart/big/7-location-map.png Binary files differnew file mode 100644 index 0000000..e32dc26 --- /dev/null +++ b/assetstudio/src/images/clipart/big/7-location-map.png diff --git a/assetstudio/src/images/clipart/big/7-location-place.png b/assetstudio/src/images/clipart/big/7-location-place.png Binary files differnew file mode 100644 index 0000000..fec173c --- /dev/null +++ b/assetstudio/src/images/clipart/big/7-location-place.png diff --git a/assetstudio/src/images/clipart/big/7-location-web-site.png b/assetstudio/src/images/clipart/big/7-location-web-site.png Binary files differnew file mode 100644 index 0000000..4ef24a3 --- /dev/null +++ b/assetstudio/src/images/clipart/big/7-location-web-site.png diff --git a/assetstudio/src/images/clipart/big/8-images-crop.png b/assetstudio/src/images/clipart/big/8-images-crop.png Binary files differnew file mode 100644 index 0000000..bd44bf9 --- /dev/null +++ b/assetstudio/src/images/clipart/big/8-images-crop.png diff --git a/assetstudio/src/images/clipart/big/8-images-rotate-left.png b/assetstudio/src/images/clipart/big/8-images-rotate-left.png Binary files differnew file mode 100644 index 0000000..0410adb --- /dev/null +++ b/assetstudio/src/images/clipart/big/8-images-rotate-left.png diff --git a/assetstudio/src/images/clipart/big/8-images-rotate-right.png b/assetstudio/src/images/clipart/big/8-images-rotate-right.png Binary files differnew file mode 100644 index 0000000..abcff9c --- /dev/null +++ b/assetstudio/src/images/clipart/big/8-images-rotate-right.png diff --git a/assetstudio/src/images/clipart/big/8-images-slideshow.png b/assetstudio/src/images/clipart/big/8-images-slideshow.png Binary files differnew file mode 100644 index 0000000..94e47b4 --- /dev/null +++ b/assetstudio/src/images/clipart/big/8-images-slideshow.png diff --git a/assetstudio/src/images/clipart/big/9-av-add-to-queue.png b/assetstudio/src/images/clipart/big/9-av-add-to-queue.png Binary files differnew file mode 100644 index 0000000..57b2e61 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-add-to-queue.png diff --git a/assetstudio/src/images/clipart/big/9-av-download.png b/assetstudio/src/images/clipart/big/9-av-download.png Binary files differnew file mode 100644 index 0000000..46a1919 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-download.png diff --git a/assetstudio/src/images/clipart/big/9-av-fast-forward.png b/assetstudio/src/images/clipart/big/9-av-fast-forward.png Binary files differnew file mode 100644 index 0000000..f820f5a --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-fast-forward.png diff --git a/assetstudio/src/images/clipart/big/9-av-full-screen.png b/assetstudio/src/images/clipart/big/9-av-full-screen.png Binary files differnew file mode 100644 index 0000000..1dfd01a --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-full-screen.png diff --git a/assetstudio/src/images/clipart/big/9-av-make-available-offline.png b/assetstudio/src/images/clipart/big/9-av-make-available-offline.png Binary files differnew file mode 100644 index 0000000..2efcb11 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-make-available-offline.png diff --git a/assetstudio/src/images/clipart/big/9-av-next.png b/assetstudio/src/images/clipart/big/9-av-next.png Binary files differnew file mode 100644 index 0000000..871587c --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-next.png diff --git a/assetstudio/src/images/clipart/big/9-av-pause-over-video.png b/assetstudio/src/images/clipart/big/9-av-pause-over-video.png Binary files differnew file mode 100644 index 0000000..a2665f2 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-pause-over-video.png diff --git a/assetstudio/src/images/clipart/big/9-av-pause.png b/assetstudio/src/images/clipart/big/9-av-pause.png Binary files differnew file mode 100644 index 0000000..506b1d4 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-pause.png diff --git a/assetstudio/src/images/clipart/big/9-av-play-over-video.png b/assetstudio/src/images/clipart/big/9-av-play-over-video.png Binary files differnew file mode 100644 index 0000000..3db3a1a --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-play-over-video.png diff --git a/assetstudio/src/images/clipart/big/9-av-play.png b/assetstudio/src/images/clipart/big/9-av-play.png Binary files differnew file mode 100644 index 0000000..0c12f86 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-play.png diff --git a/assetstudio/src/images/clipart/big/9-av-previous.png b/assetstudio/src/images/clipart/big/9-av-previous.png Binary files differnew file mode 100644 index 0000000..28f2596 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-previous.png diff --git a/assetstudio/src/images/clipart/big/9-av-repeat.png b/assetstudio/src/images/clipart/big/9-av-repeat.png Binary files differnew file mode 100644 index 0000000..9a7a79a --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-repeat.png diff --git a/assetstudio/src/images/clipart/big/9-av-replay.png b/assetstudio/src/images/clipart/big/9-av-replay.png Binary files differnew file mode 100644 index 0000000..ce9df7f --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-replay.png diff --git a/assetstudio/src/images/clipart/big/9-av-return-from-full-screen.png b/assetstudio/src/images/clipart/big/9-av-return-from-full-screen.png Binary files differnew file mode 100644 index 0000000..24725c0 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-return-from-full-screen.png diff --git a/assetstudio/src/images/clipart/big/9-av-rewind.png b/assetstudio/src/images/clipart/big/9-av-rewind.png Binary files differnew file mode 100644 index 0000000..b09f61a --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-rewind.png diff --git a/assetstudio/src/images/clipart/big/9-av-shuffle.png b/assetstudio/src/images/clipart/big/9-av-shuffle.png Binary files differnew file mode 100644 index 0000000..6e90f7c --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-shuffle.png diff --git a/assetstudio/src/images/clipart/big/9-av-stop.png b/assetstudio/src/images/clipart/big/9-av-stop.png Binary files differnew file mode 100644 index 0000000..9ba88ee --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-stop.png diff --git a/assetstudio/src/images/clipart/big/9-av-upload.png b/assetstudio/src/images/clipart/big/9-av-upload.png Binary files differnew file mode 100644 index 0000000..41da601 --- /dev/null +++ b/assetstudio/src/images/clipart/big/9-av-upload.png diff --git a/assetstudio/src/images/clipart/big/attach.png b/assetstudio/src/images/clipart/big/attach.png Binary files differdeleted file mode 100644 index cfadc2b..0000000 --- a/assetstudio/src/images/clipart/big/attach.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/call.png b/assetstudio/src/images/clipart/big/call.png Binary files differdeleted file mode 100644 index b642c81..0000000 --- a/assetstudio/src/images/clipart/big/call.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/copy.png b/assetstudio/src/images/clipart/big/copy.png Binary files differdeleted file mode 100644 index a018ff3..0000000 --- a/assetstudio/src/images/clipart/big/copy.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/cut.png b/assetstudio/src/images/clipart/big/cut.png Binary files differdeleted file mode 100644 index 29034d1..0000000 --- a/assetstudio/src/images/clipart/big/cut.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/delete.png b/assetstudio/src/images/clipart/big/delete.png Binary files differdeleted file mode 100644 index ea82cc7..0000000 --- a/assetstudio/src/images/clipart/big/delete.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/done.png b/assetstudio/src/images/clipart/big/done.png Binary files differdeleted file mode 100644 index 56e57b9..0000000 --- a/assetstudio/src/images/clipart/big/done.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/edit.png b/assetstudio/src/images/clipart/big/edit.png Binary files differdeleted file mode 100644 index 5a98da6..0000000 --- a/assetstudio/src/images/clipart/big/edit.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/locate.png b/assetstudio/src/images/clipart/big/locate.png Binary files differdeleted file mode 100644 index 222f25c..0000000 --- a/assetstudio/src/images/clipart/big/locate.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/mail.png b/assetstudio/src/images/clipart/big/mail.png Binary files differdeleted file mode 100644 index 5f66d14..0000000 --- a/assetstudio/src/images/clipart/big/mail.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/microphone.png b/assetstudio/src/images/clipart/big/microphone.png Binary files differdeleted file mode 100644 index 0ede452..0000000 --- a/assetstudio/src/images/clipart/big/microphone.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/overflow.png b/assetstudio/src/images/clipart/big/overflow.png Binary files differdeleted file mode 100644 index e88a95a..0000000 --- a/assetstudio/src/images/clipart/big/overflow.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/paste.png b/assetstudio/src/images/clipart/big/paste.png Binary files differdeleted file mode 100644 index 5a9a59d..0000000 --- a/assetstudio/src/images/clipart/big/paste.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/photo.png b/assetstudio/src/images/clipart/big/photo.png Binary files differdeleted file mode 100644 index 9e52bfb..0000000 --- a/assetstudio/src/images/clipart/big/photo.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/refresh.png b/assetstudio/src/images/clipart/big/refresh.png Binary files differdeleted file mode 100644 index 4c4e7cf..0000000 --- a/assetstudio/src/images/clipart/big/refresh.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/search.png b/assetstudio/src/images/clipart/big/search.png Binary files differdeleted file mode 100644 index b5a3572..0000000 --- a/assetstudio/src/images/clipart/big/search.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/select_all.png b/assetstudio/src/images/clipart/big/select_all.png Binary files differdeleted file mode 100644 index b962a04..0000000 --- a/assetstudio/src/images/clipart/big/select_all.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/send.png b/assetstudio/src/images/clipart/big/send.png Binary files differdeleted file mode 100644 index e7644cf..0000000 --- a/assetstudio/src/images/clipart/big/send.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/share.png b/assetstudio/src/images/clipart/big/share.png Binary files differdeleted file mode 100644 index 95185d5..0000000 --- a/assetstudio/src/images/clipart/big/share.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/star.png b/assetstudio/src/images/clipart/big/star.png Binary files differdeleted file mode 100644 index 0a245ce..0000000 --- a/assetstudio/src/images/clipart/big/star.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/user.png b/assetstudio/src/images/clipart/big/user.png Binary files differdeleted file mode 100644 index bc1d946..0000000 --- a/assetstudio/src/images/clipart/big/user.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/big/video.png b/assetstudio/src/images/clipart/big/video.png Binary files differdeleted file mode 100644 index 473076f..0000000 --- a/assetstudio/src/images/clipart/big/video.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/1-navigation-accept.png b/assetstudio/src/images/clipart/small/1-navigation-accept.png Binary files differnew file mode 100644 index 0000000..f5069d9 --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-accept.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-back.png b/assetstudio/src/images/clipart/small/1-navigation-back.png Binary files differnew file mode 100644 index 0000000..f35aec5 --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-back.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-cancel.png b/assetstudio/src/images/clipart/small/1-navigation-cancel.png Binary files differnew file mode 100644 index 0000000..4302320 --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-cancel.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-collapse.png b/assetstudio/src/images/clipart/small/1-navigation-collapse.png Binary files differnew file mode 100644 index 0000000..9c40e2c --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-collapse.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-expand.png b/assetstudio/src/images/clipart/small/1-navigation-expand.png Binary files differnew file mode 100644 index 0000000..684fc5a --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-expand.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-forward.png b/assetstudio/src/images/clipart/small/1-navigation-forward.png Binary files differnew file mode 100644 index 0000000..beb6cf7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-forward.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-next-item.png b/assetstudio/src/images/clipart/small/1-navigation-next-item.png Binary files differnew file mode 100644 index 0000000..932d787 --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-next-item.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-previous-item.png b/assetstudio/src/images/clipart/small/1-navigation-previous-item.png Binary files differnew file mode 100644 index 0000000..679b586 --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-previous-item.png diff --git a/assetstudio/src/images/clipart/small/1-navigation-refresh.png b/assetstudio/src/images/clipart/small/1-navigation-refresh.png Binary files differnew file mode 100644 index 0000000..b946402 --- /dev/null +++ b/assetstudio/src/images/clipart/small/1-navigation-refresh.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-accounts.png b/assetstudio/src/images/clipart/small/10-device-access-accounts.png Binary files differnew file mode 100644 index 0000000..34b4d6a --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-accounts.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-add-alarm.png b/assetstudio/src/images/clipart/small/10-device-access-add-alarm.png Binary files differnew file mode 100644 index 0000000..27c528a --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-add-alarm.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-alarms.png b/assetstudio/src/images/clipart/small/10-device-access-alarms.png Binary files differnew file mode 100644 index 0000000..545a8fa --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-alarms.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-battery.png b/assetstudio/src/images/clipart/small/10-device-access-battery.png Binary files differnew file mode 100644 index 0000000..52e08bf --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-battery.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-bightness-low.png b/assetstudio/src/images/clipart/small/10-device-access-bightness-low.png Binary files differnew file mode 100644 index 0000000..a34cdea --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-bightness-low.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-bluetooth-connected.png b/assetstudio/src/images/clipart/small/10-device-access-bluetooth-connected.png Binary files differnew file mode 100644 index 0000000..d04e9f4 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-bluetooth-connected.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-bluetooth-searching.png b/assetstudio/src/images/clipart/small/10-device-access-bluetooth-searching.png Binary files differnew file mode 100644 index 0000000..06d69ae --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-bluetooth-searching.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-bluetooth.png b/assetstudio/src/images/clipart/small/10-device-access-bluetooth.png Binary files differnew file mode 100644 index 0000000..11ad6b3 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-bluetooth.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-brightness-auto.png b/assetstudio/src/images/clipart/small/10-device-access-brightness-auto.png Binary files differnew file mode 100644 index 0000000..cd50b9d --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-brightness-auto.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-brightness-high.png b/assetstudio/src/images/clipart/small/10-device-access-brightness-high.png Binary files differnew file mode 100644 index 0000000..b9d8501 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-brightness-high.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-brightness-medium.png b/assetstudio/src/images/clipart/small/10-device-access-brightness-medium.png Binary files differnew file mode 100644 index 0000000..7145eee --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-brightness-medium.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-call.png b/assetstudio/src/images/clipart/small/10-device-access-call.png Binary files differnew file mode 100644 index 0000000..732e551 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-call.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-camera.png b/assetstudio/src/images/clipart/small/10-device-access-camera.png Binary files differnew file mode 100644 index 0000000..f61ab27 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-camera.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-data-usage.png b/assetstudio/src/images/clipart/small/10-device-access-data-usage.png Binary files differnew file mode 100644 index 0000000..a78127f --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-data-usage.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-dial-pad.png b/assetstudio/src/images/clipart/small/10-device-access-dial-pad.png Binary files differnew file mode 100644 index 0000000..cfbee88 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-dial-pad.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-end-call.png b/assetstudio/src/images/clipart/small/10-device-access-end-call.png Binary files differnew file mode 100644 index 0000000..2562d0d --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-end-call.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-flash-automatic.png b/assetstudio/src/images/clipart/small/10-device-access-flash-automatic.png Binary files differnew file mode 100644 index 0000000..574219c --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-flash-automatic.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-flash-off.png b/assetstudio/src/images/clipart/small/10-device-access-flash-off.png Binary files differnew file mode 100644 index 0000000..80e3d06 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-flash-off.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-flash-on.png b/assetstudio/src/images/clipart/small/10-device-access-flash-on.png Binary files differnew file mode 100644 index 0000000..c9c2fff --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-flash-on.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-location-found.png b/assetstudio/src/images/clipart/small/10-device-access-location-found.png Binary files differnew file mode 100644 index 0000000..4221d83 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-location-found.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-location-off.png b/assetstudio/src/images/clipart/small/10-device-access-location-off.png Binary files differnew file mode 100644 index 0000000..ea0511d --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-location-off.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-location-searching.png b/assetstudio/src/images/clipart/small/10-device-access-location-searching.png Binary files differnew file mode 100644 index 0000000..ef9dc2e --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-location-searching.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-mic-muted.png b/assetstudio/src/images/clipart/small/10-device-access-mic-muted.png Binary files differnew file mode 100644 index 0000000..87bc6b3 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-mic-muted.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-mic.png b/assetstudio/src/images/clipart/small/10-device-access-mic.png Binary files differnew file mode 100644 index 0000000..7569d6a --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-mic.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-network-cell.png b/assetstudio/src/images/clipart/small/10-device-access-network-cell.png Binary files differnew file mode 100644 index 0000000..7a2c443 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-network-cell.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-network-wifi.png b/assetstudio/src/images/clipart/small/10-device-access-network-wifi.png Binary files differnew file mode 100644 index 0000000..e25cc64 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-network-wifi.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-new-account.png b/assetstudio/src/images/clipart/small/10-device-access-new-account.png Binary files differnew file mode 100644 index 0000000..c537899 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-new-account.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-not-secure.png b/assetstudio/src/images/clipart/small/10-device-access-not-secure.png Binary files differnew file mode 100644 index 0000000..89c732e --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-not-secure.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-ring-volume.png b/assetstudio/src/images/clipart/small/10-device-access-ring-volume.png Binary files differnew file mode 100644 index 0000000..5bfe27a --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-ring-volume.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-screen-locked-to-landscape.png b/assetstudio/src/images/clipart/small/10-device-access-screen-locked-to-landscape.png Binary files differnew file mode 100644 index 0000000..a3b2bbb --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-screen-locked-to-landscape.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-screen-locked-to-portrait.png b/assetstudio/src/images/clipart/small/10-device-access-screen-locked-to-portrait.png Binary files differnew file mode 100644 index 0000000..270c069 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-screen-locked-to-portrait.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-screen-rotation.png b/assetstudio/src/images/clipart/small/10-device-access-screen-rotation.png Binary files differnew file mode 100644 index 0000000..a5337e9 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-screen-rotation.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-sd-storage.png b/assetstudio/src/images/clipart/small/10-device-access-sd-storage.png Binary files differnew file mode 100644 index 0000000..fe09aca --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-sd-storage.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-secure.png b/assetstudio/src/images/clipart/small/10-device-access-secure.png Binary files differnew file mode 100644 index 0000000..9bf3627 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-secure.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-storage.png b/assetstudio/src/images/clipart/small/10-device-access-storage.png Binary files differnew file mode 100644 index 0000000..1d38109 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-storage.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-switch-camera.png b/assetstudio/src/images/clipart/small/10-device-access-switch-camera.png Binary files differnew file mode 100644 index 0000000..972e3b3 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-switch-camera.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-switch-video.png b/assetstudio/src/images/clipart/small/10-device-access-switch-video.png Binary files differnew file mode 100644 index 0000000..2ae54f4 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-switch-video.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-time.png b/assetstudio/src/images/clipart/small/10-device-access-time.png Binary files differnew file mode 100644 index 0000000..f3d932e --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-time.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-usb.png b/assetstudio/src/images/clipart/small/10-device-access-usb.png Binary files differnew file mode 100644 index 0000000..490d286 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-usb.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-video.png b/assetstudio/src/images/clipart/small/10-device-access-video.png Binary files differnew file mode 100644 index 0000000..d069de4 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-video.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-volume-muted.png b/assetstudio/src/images/clipart/small/10-device-access-volume-muted.png Binary files differnew file mode 100644 index 0000000..283d621 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-volume-muted.png diff --git a/assetstudio/src/images/clipart/small/10-device-access-volume-on.png b/assetstudio/src/images/clipart/small/10-device-access-volume-on.png Binary files differnew file mode 100644 index 0000000..a1d6670 --- /dev/null +++ b/assetstudio/src/images/clipart/small/10-device-access-volume-on.png diff --git a/assetstudio/src/images/clipart/small/11-alerts-and-states-airplane-mode-off.png b/assetstudio/src/images/clipart/small/11-alerts-and-states-airplane-mode-off.png Binary files differnew file mode 100644 index 0000000..bfce2ee --- /dev/null +++ b/assetstudio/src/images/clipart/small/11-alerts-and-states-airplane-mode-off.png diff --git a/assetstudio/src/images/clipart/small/11-alerts-and-states-airplane-mode-on.png b/assetstudio/src/images/clipart/small/11-alerts-and-states-airplane-mode-on.png Binary files differnew file mode 100644 index 0000000..fba67ae --- /dev/null +++ b/assetstudio/src/images/clipart/small/11-alerts-and-states-airplane-mode-on.png diff --git a/assetstudio/src/images/clipart/small/11-alerts-and-states-error.png b/assetstudio/src/images/clipart/small/11-alerts-and-states-error.png Binary files differnew file mode 100644 index 0000000..a32766b --- /dev/null +++ b/assetstudio/src/images/clipart/small/11-alerts-and-states-error.png diff --git a/assetstudio/src/images/clipart/small/11-alerts-and-states-warning.png b/assetstudio/src/images/clipart/small/11-alerts-and-states-warning.png Binary files differnew file mode 100644 index 0000000..37af134 --- /dev/null +++ b/assetstudio/src/images/clipart/small/11-alerts-and-states-warning.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-computer.png b/assetstudio/src/images/clipart/small/12-hardware-computer.png Binary files differnew file mode 100644 index 0000000..91c7cdf --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-computer.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-dock.png b/assetstudio/src/images/clipart/small/12-hardware-dock.png Binary files differnew file mode 100644 index 0000000..c4a20ae --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-dock.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-gamepad.png b/assetstudio/src/images/clipart/small/12-hardware-gamepad.png Binary files differnew file mode 100644 index 0000000..db62572 --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-gamepad.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-headphones.png b/assetstudio/src/images/clipart/small/12-hardware-headphones.png Binary files differnew file mode 100644 index 0000000..9d3b020 --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-headphones.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-headset.png b/assetstudio/src/images/clipart/small/12-hardware-headset.png Binary files differnew file mode 100644 index 0000000..d4efdf3 --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-headset.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-keyboard.png b/assetstudio/src/images/clipart/small/12-hardware-keyboard.png Binary files differnew file mode 100644 index 0000000..7b143d2 --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-keyboard.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-mouse.png b/assetstudio/src/images/clipart/small/12-hardware-mouse.png Binary files differnew file mode 100644 index 0000000..4f8d2df --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-mouse.png diff --git a/assetstudio/src/images/clipart/small/12-hardware-phone.png b/assetstudio/src/images/clipart/small/12-hardware-phone.png Binary files differnew file mode 100644 index 0000000..b5f78e1 --- /dev/null +++ b/assetstudio/src/images/clipart/small/12-hardware-phone.png diff --git a/assetstudio/src/images/clipart/small/2-action-about.png b/assetstudio/src/images/clipart/small/2-action-about.png Binary files differnew file mode 100644 index 0000000..56a3a55 --- /dev/null +++ b/assetstudio/src/images/clipart/small/2-action-about.png diff --git a/assetstudio/src/images/clipart/small/2-action-help.png b/assetstudio/src/images/clipart/small/2-action-help.png Binary files differnew file mode 100644 index 0000000..9104862 --- /dev/null +++ b/assetstudio/src/images/clipart/small/2-action-help.png diff --git a/assetstudio/src/images/clipart/small/2-action-search.png b/assetstudio/src/images/clipart/small/2-action-search.png Binary files differnew file mode 100644 index 0000000..1d3f206 --- /dev/null +++ b/assetstudio/src/images/clipart/small/2-action-search.png diff --git a/assetstudio/src/images/clipart/small/2-action-settings.png b/assetstudio/src/images/clipart/small/2-action-settings.png Binary files differnew file mode 100644 index 0000000..1dd6bbb --- /dev/null +++ b/assetstudio/src/images/clipart/small/2-action-settings.png diff --git a/assetstudio/src/images/clipart/small/3-rating-bad.png b/assetstudio/src/images/clipart/small/3-rating-bad.png Binary files differnew file mode 100644 index 0000000..76060f7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/3-rating-bad.png diff --git a/assetstudio/src/images/clipart/small/3-rating-favorite.png b/assetstudio/src/images/clipart/small/3-rating-favorite.png Binary files differnew file mode 100644 index 0000000..b6ab63f --- /dev/null +++ b/assetstudio/src/images/clipart/small/3-rating-favorite.png diff --git a/assetstudio/src/images/clipart/small/3-rating-good.png b/assetstudio/src/images/clipart/small/3-rating-good.png Binary files differnew file mode 100644 index 0000000..0e6f861 --- /dev/null +++ b/assetstudio/src/images/clipart/small/3-rating-good.png diff --git a/assetstudio/src/images/clipart/small/3-rating-half-important.png b/assetstudio/src/images/clipart/small/3-rating-half-important.png Binary files differnew file mode 100644 index 0000000..d9aa154 --- /dev/null +++ b/assetstudio/src/images/clipart/small/3-rating-half-important.png diff --git a/assetstudio/src/images/clipart/small/3-rating-important.png b/assetstudio/src/images/clipart/small/3-rating-important.png Binary files differnew file mode 100644 index 0000000..0bc5c54 --- /dev/null +++ b/assetstudio/src/images/clipart/small/3-rating-important.png diff --git a/assetstudio/src/images/clipart/small/3-rating-not-important.png b/assetstudio/src/images/clipart/small/3-rating-not-important.png Binary files differnew file mode 100644 index 0000000..6ea5892 --- /dev/null +++ b/assetstudio/src/images/clipart/small/3-rating-not-important.png diff --git a/assetstudio/src/images/clipart/small/4-collections-cloud.png b/assetstudio/src/images/clipart/small/4-collections-cloud.png Binary files differnew file mode 100644 index 0000000..5d80291 --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-cloud.png diff --git a/assetstudio/src/images/clipart/small/4-collections-collection.png b/assetstudio/src/images/clipart/small/4-collections-collection.png Binary files differnew file mode 100644 index 0000000..d4a7dcb --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-collection.png diff --git a/assetstudio/src/images/clipart/small/4-collections-go-to-today.png b/assetstudio/src/images/clipart/small/4-collections-go-to-today.png Binary files differnew file mode 100644 index 0000000..3326ead --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-go-to-today.png diff --git a/assetstudio/src/images/clipart/small/4-collections-labels.png b/assetstudio/src/images/clipart/small/4-collections-labels.png Binary files differnew file mode 100644 index 0000000..e647488 --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-labels.png diff --git a/assetstudio/src/images/clipart/small/4-collections-new-label.png b/assetstudio/src/images/clipart/small/4-collections-new-label.png Binary files differnew file mode 100644 index 0000000..f822806 --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-new-label.png diff --git a/assetstudio/src/images/clipart/small/4-collections-sort-by-size.png b/assetstudio/src/images/clipart/small/4-collections-sort-by-size.png Binary files differnew file mode 100644 index 0000000..b097f67 --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-sort-by-size.png diff --git a/assetstudio/src/images/clipart/small/4-collections-view-as-grid.png b/assetstudio/src/images/clipart/small/4-collections-view-as-grid.png Binary files differnew file mode 100644 index 0000000..9f9e0c1 --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-view-as-grid.png diff --git a/assetstudio/src/images/clipart/small/4-collections-view-as-list.png b/assetstudio/src/images/clipart/small/4-collections-view-as-list.png Binary files differnew file mode 100644 index 0000000..39a2f1f --- /dev/null +++ b/assetstudio/src/images/clipart/small/4-collections-view-as-list.png diff --git a/assetstudio/src/images/clipart/small/5-content-attachment.png b/assetstudio/src/images/clipart/small/5-content-attachment.png Binary files differnew file mode 100644 index 0000000..ae5dac4 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-attachment.png diff --git a/assetstudio/src/images/clipart/small/5-content-backspace.png b/assetstudio/src/images/clipart/small/5-content-backspace.png Binary files differnew file mode 100644 index 0000000..f2743fe --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-backspace.png diff --git a/assetstudio/src/images/clipart/small/5-content-copy.png b/assetstudio/src/images/clipart/small/5-content-copy.png Binary files differnew file mode 100644 index 0000000..7efa0ec --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-copy.png diff --git a/assetstudio/src/images/clipart/small/5-content-cut.png b/assetstudio/src/images/clipart/small/5-content-cut.png Binary files differnew file mode 100644 index 0000000..4f113d6 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-cut.png diff --git a/assetstudio/src/images/clipart/small/5-content-discard.png b/assetstudio/src/images/clipart/small/5-content-discard.png Binary files differnew file mode 100644 index 0000000..9bbe70c --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-discard.png diff --git a/assetstudio/src/images/clipart/small/5-content-edit.png b/assetstudio/src/images/clipart/small/5-content-edit.png Binary files differnew file mode 100644 index 0000000..dfef46d --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-edit.png diff --git a/assetstudio/src/images/clipart/small/5-content-email.png b/assetstudio/src/images/clipart/small/5-content-email.png Binary files differnew file mode 100644 index 0000000..0698571 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-email.png diff --git a/assetstudio/src/images/clipart/small/5-content-event.png b/assetstudio/src/images/clipart/small/5-content-event.png Binary files differnew file mode 100644 index 0000000..4fea671 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-event.png diff --git a/assetstudio/src/images/clipart/small/5-content-import-export.png b/assetstudio/src/images/clipart/small/5-content-import-export.png Binary files differnew file mode 100644 index 0000000..1b4ed11 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-import-export.png diff --git a/assetstudio/src/images/clipart/small/5-content-merge.png b/assetstudio/src/images/clipart/small/5-content-merge.png Binary files differnew file mode 100644 index 0000000..4f7451e --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-merge.png diff --git a/assetstudio/src/images/clipart/small/5-content-new-attachment.png b/assetstudio/src/images/clipart/small/5-content-new-attachment.png Binary files differnew file mode 100644 index 0000000..8028ea7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-new-attachment.png diff --git a/assetstudio/src/images/clipart/small/5-content-new-email.png b/assetstudio/src/images/clipart/small/5-content-new-email.png Binary files differnew file mode 100644 index 0000000..699dca9 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-new-email.png diff --git a/assetstudio/src/images/clipart/small/5-content-new-event.png b/assetstudio/src/images/clipart/small/5-content-new-event.png Binary files differnew file mode 100644 index 0000000..4c4f674 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-new-event.png diff --git a/assetstudio/src/images/clipart/small/5-content-new-picture.png b/assetstudio/src/images/clipart/small/5-content-new-picture.png Binary files differnew file mode 100644 index 0000000..6b7b7ea --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-new-picture.png diff --git a/assetstudio/src/images/clipart/small/5-content-new.png b/assetstudio/src/images/clipart/small/5-content-new.png Binary files differnew file mode 100644 index 0000000..7ccce5b --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-new.png diff --git a/assetstudio/src/images/clipart/small/5-content-paste.png b/assetstudio/src/images/clipart/small/5-content-paste.png Binary files differnew file mode 100644 index 0000000..9c3d906 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-paste.png diff --git a/assetstudio/src/images/clipart/small/5-content-picture.png b/assetstudio/src/images/clipart/small/5-content-picture.png Binary files differnew file mode 100644 index 0000000..0676181 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-picture.png diff --git a/assetstudio/src/images/clipart/small/5-content-read.png b/assetstudio/src/images/clipart/small/5-content-read.png Binary files differnew file mode 100644 index 0000000..7c7186f --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-read.png diff --git a/assetstudio/src/images/clipart/small/5-content-remove.png b/assetstudio/src/images/clipart/small/5-content-remove.png Binary files differnew file mode 100644 index 0000000..97f11f7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-remove.png diff --git a/assetstudio/src/images/clipart/small/5-content-save.png b/assetstudio/src/images/clipart/small/5-content-save.png Binary files differnew file mode 100644 index 0000000..4b38e6c --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-save.png diff --git a/assetstudio/src/images/clipart/small/5-content-select-all.png b/assetstudio/src/images/clipart/small/5-content-select-all.png Binary files differnew file mode 100644 index 0000000..cfb2282 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-select-all.png diff --git a/assetstudio/src/images/clipart/small/5-content-split.png b/assetstudio/src/images/clipart/small/5-content-split.png Binary files differnew file mode 100644 index 0000000..779f650 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-split.png diff --git a/assetstudio/src/images/clipart/small/5-content-undo.png b/assetstudio/src/images/clipart/small/5-content-undo.png Binary files differnew file mode 100644 index 0000000..87b0129 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-undo.png diff --git a/assetstudio/src/images/clipart/small/5-content-unread.png b/assetstudio/src/images/clipart/small/5-content-unread.png Binary files differnew file mode 100644 index 0000000..69cb276 --- /dev/null +++ b/assetstudio/src/images/clipart/small/5-content-unread.png diff --git a/assetstudio/src/images/clipart/small/6-social-add-group.png b/assetstudio/src/images/clipart/small/6-social-add-group.png Binary files differnew file mode 100644 index 0000000..cae89bb --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-add-group.png diff --git a/assetstudio/src/images/clipart/small/6-social-add-person.png b/assetstudio/src/images/clipart/small/6-social-add-person.png Binary files differnew file mode 100644 index 0000000..ec95691 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-add-person.png diff --git a/assetstudio/src/images/clipart/small/6-social-cc-bcc.png b/assetstudio/src/images/clipart/small/6-social-cc-bcc.png Binary files differnew file mode 100644 index 0000000..92772f7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-cc-bcc.png diff --git a/assetstudio/src/images/clipart/small/6-social-chat.png b/assetstudio/src/images/clipart/small/6-social-chat.png Binary files differnew file mode 100644 index 0000000..675c7e3 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-chat.png diff --git a/assetstudio/src/images/clipart/small/6-social-forward.png b/assetstudio/src/images/clipart/small/6-social-forward.png Binary files differnew file mode 100644 index 0000000..f533b34 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-forward.png diff --git a/assetstudio/src/images/clipart/small/6-social-group.png b/assetstudio/src/images/clipart/small/6-social-group.png Binary files differnew file mode 100644 index 0000000..ee027a7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-group.png diff --git a/assetstudio/src/images/clipart/small/6-social-person.png b/assetstudio/src/images/clipart/small/6-social-person.png Binary files differnew file mode 100644 index 0000000..bb685c7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-person.png diff --git a/assetstudio/src/images/clipart/small/6-social-reply-all.png b/assetstudio/src/images/clipart/small/6-social-reply-all.png Binary files differnew file mode 100644 index 0000000..fc94679 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-reply-all.png diff --git a/assetstudio/src/images/clipart/small/6-social-reply.png b/assetstudio/src/images/clipart/small/6-social-reply.png Binary files differnew file mode 100644 index 0000000..e413c9a --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-reply.png diff --git a/assetstudio/src/images/clipart/small/6-social-send-now.png b/assetstudio/src/images/clipart/small/6-social-send-now.png Binary files differnew file mode 100644 index 0000000..6fa79f0 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-send-now.png diff --git a/assetstudio/src/images/clipart/small/6-social-share.png b/assetstudio/src/images/clipart/small/6-social-share.png Binary files differnew file mode 100644 index 0000000..fb74121 --- /dev/null +++ b/assetstudio/src/images/clipart/small/6-social-share.png diff --git a/assetstudio/src/images/clipart/small/7-location-directions.png b/assetstudio/src/images/clipart/small/7-location-directions.png Binary files differnew file mode 100644 index 0000000..c3e821d --- /dev/null +++ b/assetstudio/src/images/clipart/small/7-location-directions.png diff --git a/assetstudio/src/images/clipart/small/7-location-map.png b/assetstudio/src/images/clipart/small/7-location-map.png Binary files differnew file mode 100644 index 0000000..4893657 --- /dev/null +++ b/assetstudio/src/images/clipart/small/7-location-map.png diff --git a/assetstudio/src/images/clipart/small/7-location-place.png b/assetstudio/src/images/clipart/small/7-location-place.png Binary files differnew file mode 100644 index 0000000..2d41b57 --- /dev/null +++ b/assetstudio/src/images/clipart/small/7-location-place.png diff --git a/assetstudio/src/images/clipart/small/7-location-web-site.png b/assetstudio/src/images/clipart/small/7-location-web-site.png Binary files differnew file mode 100644 index 0000000..fe15c10 --- /dev/null +++ b/assetstudio/src/images/clipart/small/7-location-web-site.png diff --git a/assetstudio/src/images/clipart/small/8-images-crop.png b/assetstudio/src/images/clipart/small/8-images-crop.png Binary files differnew file mode 100644 index 0000000..ddca47f --- /dev/null +++ b/assetstudio/src/images/clipart/small/8-images-crop.png diff --git a/assetstudio/src/images/clipart/small/8-images-rotate-left.png b/assetstudio/src/images/clipart/small/8-images-rotate-left.png Binary files differnew file mode 100644 index 0000000..0450f2b --- /dev/null +++ b/assetstudio/src/images/clipart/small/8-images-rotate-left.png diff --git a/assetstudio/src/images/clipart/small/8-images-rotate-right.png b/assetstudio/src/images/clipart/small/8-images-rotate-right.png Binary files differnew file mode 100644 index 0000000..a34d957 --- /dev/null +++ b/assetstudio/src/images/clipart/small/8-images-rotate-right.png diff --git a/assetstudio/src/images/clipart/small/8-images-slideshow.png b/assetstudio/src/images/clipart/small/8-images-slideshow.png Binary files differnew file mode 100644 index 0000000..5317cf7 --- /dev/null +++ b/assetstudio/src/images/clipart/small/8-images-slideshow.png diff --git a/assetstudio/src/images/clipart/small/9-av-add-to-queue.png b/assetstudio/src/images/clipart/small/9-av-add-to-queue.png Binary files differnew file mode 100644 index 0000000..544b8fc --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-add-to-queue.png diff --git a/assetstudio/src/images/clipart/small/9-av-download.png b/assetstudio/src/images/clipart/small/9-av-download.png Binary files differnew file mode 100644 index 0000000..bbf910c --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-download.png diff --git a/assetstudio/src/images/clipart/small/9-av-fast-forward.png b/assetstudio/src/images/clipart/small/9-av-fast-forward.png Binary files differnew file mode 100644 index 0000000..dc7e11f --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-fast-forward.png diff --git a/assetstudio/src/images/clipart/small/9-av-full-screen.png b/assetstudio/src/images/clipart/small/9-av-full-screen.png Binary files differnew file mode 100644 index 0000000..c1dd576 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-full-screen.png diff --git a/assetstudio/src/images/clipart/small/9-av-make-available-offline.png b/assetstudio/src/images/clipart/small/9-av-make-available-offline.png Binary files differnew file mode 100644 index 0000000..8e9459c --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-make-available-offline.png diff --git a/assetstudio/src/images/clipart/small/9-av-next.png b/assetstudio/src/images/clipart/small/9-av-next.png Binary files differnew file mode 100644 index 0000000..01e6543 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-next.png diff --git a/assetstudio/src/images/clipart/small/9-av-pause-over-video.png b/assetstudio/src/images/clipart/small/9-av-pause-over-video.png Binary files differnew file mode 100644 index 0000000..bac9ce4 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-pause-over-video.png diff --git a/assetstudio/src/images/clipart/small/9-av-pause.png b/assetstudio/src/images/clipart/small/9-av-pause.png Binary files differnew file mode 100644 index 0000000..6a17d65 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-pause.png diff --git a/assetstudio/src/images/clipart/small/9-av-play-over-video.png b/assetstudio/src/images/clipart/small/9-av-play-over-video.png Binary files differnew file mode 100644 index 0000000..a3a68fc --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-play-over-video.png diff --git a/assetstudio/src/images/clipart/small/9-av-play.png b/assetstudio/src/images/clipart/small/9-av-play.png Binary files differnew file mode 100644 index 0000000..2092eca --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-play.png diff --git a/assetstudio/src/images/clipart/small/9-av-previous.png b/assetstudio/src/images/clipart/small/9-av-previous.png Binary files differnew file mode 100644 index 0000000..cf10fbf --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-previous.png diff --git a/assetstudio/src/images/clipart/small/9-av-repeat.png b/assetstudio/src/images/clipart/small/9-av-repeat.png Binary files differnew file mode 100644 index 0000000..7638bea --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-repeat.png diff --git a/assetstudio/src/images/clipart/small/9-av-replay.png b/assetstudio/src/images/clipart/small/9-av-replay.png Binary files differnew file mode 100644 index 0000000..8f1dae0 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-replay.png diff --git a/assetstudio/src/images/clipart/small/9-av-return-from-full-screen.png b/assetstudio/src/images/clipart/small/9-av-return-from-full-screen.png Binary files differnew file mode 100644 index 0000000..96949cb --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-return-from-full-screen.png diff --git a/assetstudio/src/images/clipart/small/9-av-rewind.png b/assetstudio/src/images/clipart/small/9-av-rewind.png Binary files differnew file mode 100644 index 0000000..1811cd9 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-rewind.png diff --git a/assetstudio/src/images/clipart/small/9-av-shuffle.png b/assetstudio/src/images/clipart/small/9-av-shuffle.png Binary files differnew file mode 100644 index 0000000..6075afb --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-shuffle.png diff --git a/assetstudio/src/images/clipart/small/9-av-stop.png b/assetstudio/src/images/clipart/small/9-av-stop.png Binary files differnew file mode 100644 index 0000000..3c95c99 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-stop.png diff --git a/assetstudio/src/images/clipart/small/9-av-upload.png b/assetstudio/src/images/clipart/small/9-av-upload.png Binary files differnew file mode 100644 index 0000000..af9b895 --- /dev/null +++ b/assetstudio/src/images/clipart/small/9-av-upload.png diff --git a/assetstudio/src/images/clipart/small/attach.png b/assetstudio/src/images/clipart/small/attach.png Binary files differdeleted file mode 100644 index 6bfc535..0000000 --- a/assetstudio/src/images/clipart/small/attach.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/call.png b/assetstudio/src/images/clipart/small/call.png Binary files differdeleted file mode 100644 index 9ea8e0f..0000000 --- a/assetstudio/src/images/clipart/small/call.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/copy.png b/assetstudio/src/images/clipart/small/copy.png Binary files differdeleted file mode 100644 index 68d31d8..0000000 --- a/assetstudio/src/images/clipart/small/copy.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/cut.png b/assetstudio/src/images/clipart/small/cut.png Binary files differdeleted file mode 100644 index b94e50b..0000000 --- a/assetstudio/src/images/clipart/small/cut.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/delete.png b/assetstudio/src/images/clipart/small/delete.png Binary files differdeleted file mode 100644 index 638c9c8..0000000 --- a/assetstudio/src/images/clipart/small/delete.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/done.png b/assetstudio/src/images/clipart/small/done.png Binary files differdeleted file mode 100644 index aed3f0c..0000000 --- a/assetstudio/src/images/clipart/small/done.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/edit.png b/assetstudio/src/images/clipart/small/edit.png Binary files differdeleted file mode 100644 index b677a6a..0000000 --- a/assetstudio/src/images/clipart/small/edit.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/locate.png b/assetstudio/src/images/clipart/small/locate.png Binary files differdeleted file mode 100644 index cd16ada..0000000 --- a/assetstudio/src/images/clipart/small/locate.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/mail.png b/assetstudio/src/images/clipart/small/mail.png Binary files differdeleted file mode 100644 index 8ae1cde..0000000 --- a/assetstudio/src/images/clipart/small/mail.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/microphone.png b/assetstudio/src/images/clipart/small/microphone.png Binary files differdeleted file mode 100644 index bd58fb3..0000000 --- a/assetstudio/src/images/clipart/small/microphone.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/overflow.png b/assetstudio/src/images/clipart/small/overflow.png Binary files differdeleted file mode 100644 index d3cd16c..0000000 --- a/assetstudio/src/images/clipart/small/overflow.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/paste.png b/assetstudio/src/images/clipart/small/paste.png Binary files differdeleted file mode 100644 index b022176..0000000 --- a/assetstudio/src/images/clipart/small/paste.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/photo.png b/assetstudio/src/images/clipart/small/photo.png Binary files differdeleted file mode 100644 index 906db99..0000000 --- a/assetstudio/src/images/clipart/small/photo.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/refresh.png b/assetstudio/src/images/clipart/small/refresh.png Binary files differdeleted file mode 100644 index 6482017..0000000 --- a/assetstudio/src/images/clipart/small/refresh.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/search.png b/assetstudio/src/images/clipart/small/search.png Binary files differdeleted file mode 100644 index fef5270..0000000 --- a/assetstudio/src/images/clipart/small/search.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/select_all.png b/assetstudio/src/images/clipart/small/select_all.png Binary files differdeleted file mode 100644 index b32de7d..0000000 --- a/assetstudio/src/images/clipart/small/select_all.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/send.png b/assetstudio/src/images/clipart/small/send.png Binary files differdeleted file mode 100644 index b2c768b..0000000 --- a/assetstudio/src/images/clipart/small/send.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/share.png b/assetstudio/src/images/clipart/small/share.png Binary files differdeleted file mode 100644 index 11da57d..0000000 --- a/assetstudio/src/images/clipart/small/share.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/star.png b/assetstudio/src/images/clipart/small/star.png Binary files differdeleted file mode 100644 index 847937e..0000000 --- a/assetstudio/src/images/clipart/small/star.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/user.png b/assetstudio/src/images/clipart/small/user.png Binary files differdeleted file mode 100644 index 9c7a585..0000000 --- a/assetstudio/src/images/clipart/small/user.png +++ /dev/null diff --git a/assetstudio/src/images/clipart/small/video.png b/assetstudio/src/images/clipart/small/video.png Binary files differdeleted file mode 100644 index 9766009..0000000 --- a/assetstudio/src/images/clipart/small/video.png +++ /dev/null diff --git a/build/tools.atree b/build/tools.atree index 4777bee..893bd2a 100644 --- a/build/tools.atree +++ b/build/tools.atree @@ -176,9 +176,8 @@ external/chromium-trace/style.css tools/systrace/style.css external/chromium-trace/LICENSE tools/systrace/LICENSE external/chromium-trace/AUTHORS tools/systrace/AUTHORS -# Misspelling databases for tools such as lint -sdk/files/typos-en.txt tools/support/typos-en.txt -sdk/files/typos-nb.txt tools/support/typos-nb.txt +# Misspelling databases for lint +sdk/files/typos tools/support ############################################################################## # Tests Component diff --git a/chimpchat/src/com/android/chimpchat/adb/AdbChimpDevice.java b/chimpchat/src/com/android/chimpchat/adb/AdbChimpDevice.java index d4513d1..7c4b62a 100644 --- a/chimpchat/src/com/android/chimpchat/adb/AdbChimpDevice.java +++ b/chimpchat/src/com/android/chimpchat/adb/AdbChimpDevice.java @@ -481,7 +481,17 @@ public class AdbChimpDevice implements IChimpDevice { @Override public Map<String, Object> instrument(String packageName, Map<String, Object> args) { - List<String> shellCmd = Lists.newArrayList("am", "instrument", "-w", "-r", packageName); + List<String> shellCmd = Lists.newArrayList("am", "instrument", "-w", "-r"); + for (Entry<String, Object> entry: args.entrySet()) { + final String key = entry.getKey(); + final Object value = entry.getValue(); + if (key != null && value != null) { + shellCmd.add("-e"); + shellCmd.add(key); + shellCmd.add(value.toString()); + } + } + shellCmd.add(packageName); String result = shell(shellCmd.toArray(ZERO_LENGTH_STRING_ARRAY)); return convertInstrumentResult(result); } diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/CollectingOutputReceiver.java b/ddms/libs/ddmlib/src/com/android/ddmlib/CollectingOutputReceiver.java index cb4612f..80aa8e1 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/CollectingOutputReceiver.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/CollectingOutputReceiver.java @@ -17,16 +17,24 @@ package com.android.ddmlib; import java.io.UnsupportedEncodingException; +import java.util.concurrent.CountDownLatch; /** * A {@link IShellOutputReceiver} which collects the whole shell output into one * {@link String}. */ public class CollectingOutputReceiver implements IShellOutputReceiver { - + private CountDownLatch mCompletionLatch; private StringBuffer mOutputBuffer = new StringBuffer(); private boolean mIsCanceled = false; + public CollectingOutputReceiver() { + } + + public CollectingOutputReceiver(CountDownLatch commandCompleteLatch) { + mCompletionLatch = commandCompleteLatch; + } + public String getOutput() { return mOutputBuffer.toString(); } @@ -68,6 +76,8 @@ public class CollectingOutputReceiver implements IShellOutputReceiver { */ @Override public void flush() { - // ignore + if (mCompletionLatch != null) { + mCompletionLatch.countDown(); + } } } diff --git a/device_validator/app/src/com/android/validator/DeviceValidator.java b/device_validator/app/src/com/android/validator/DeviceValidator.java index e4038bc..8ca6afe 100644 --- a/device_validator/app/src/com/android/validator/DeviceValidator.java +++ b/device_validator/app/src/com/android/validator/DeviceValidator.java @@ -16,12 +16,12 @@ package com.android.validator; +import com.android.dvlib.DeviceSchema; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import com.android.dvlib.DeviceSchema; - public class DeviceValidator { public static void main(String[] args) { diff --git a/device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java b/device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java index 6c45401..b02471b 100644 --- a/device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java +++ b/device_validator/dvlib/src/com/android/dvlib/DeviceSchema.java @@ -90,6 +90,8 @@ public class DeviceSchema { public static final String NODE_LIVE_WALLPAPER_SUPPORT = "live-wallpaper-support"; + public static final String NODE_STATUS_BAR = "status-bar"; + public static final String NODE_BUTTONS = "buttons"; public static final String NODE_CAMERA = "camera"; diff --git a/device_validator/dvlib/src/com/android/dvlib/devices.xsd b/device_validator/dvlib/src/com/android/dvlib/devices.xsd index 0cc9411..d4678da 100644 --- a/device_validator/dvlib/src/com/android/dvlib/devices.xsd +++ b/device_validator/dvlib/src/com/android/dvlib/devices.xsd @@ -206,6 +206,14 @@ <xsd:list itemType="xsd:NMTOKEN" /> </xsd:simpleType> </xsd:element> + <xsd:element name="status-bar" type="xsd:boolean"> + <xsd:annotation> + <xsd:documentation xml:lang="en"> + Specifies whether the device has a status bar in this + software configuration. + </xsd:documentation> + </xsd:annotation> + </xsd:element> </xsd:sequence> </xsd:complexType> diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices.xml index b626012..6662099 100644 --- a/device_validator/dvlib/tests/src/com/android/dvlib/devices.xml +++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices.xml @@ -123,6 +123,7 @@ GL_OES_vertex_array_object GL_OES_vertex_half_float </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> <d:description>The phone in portrait view</d:description> @@ -248,6 +249,7 @@ GL_IMG_texture_stream GL_IMG_vertex_program </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> <d:description>The phone in portrait view</d:description> diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml index 20d501f..e063fd1 100644 --- a/device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml +++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_minimal.xml @@ -117,6 +117,7 @@ GL_OES_vertex_array_object GL_OES_vertex_half_float </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> <d:description>The phone in portrait view</d:description> diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml index 1247a45..605a6c1 100644 --- a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml +++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_default.xml @@ -122,6 +122,7 @@ GL_OES_vertex_array_object GL_OES_vertex_half_float </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait"> <d:description>The phone in portrait view</d:description> diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml index 8f189a4..fb133ad 100644 --- a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml +++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_hardware.xml @@ -63,6 +63,7 @@ GL_OES_vertex_array_object GL_OES_vertex_half_float </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> <d:description>The phone in portrait view</d:description> diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml index 89519cf..8685e3b 100644 --- a/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml +++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_no_states.xml @@ -123,6 +123,7 @@ GL_OES_vertex_array_object GL_OES_vertex_half_float </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> </d:device> </d:devices> diff --git a/device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml b/device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml index 5409d32..c720a7a 100644 --- a/device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml +++ b/device_validator/dvlib/tests/src/com/android/dvlib/devices_too_many_defaults.xml @@ -123,6 +123,7 @@ GL_OES_vertex_array_object GL_OES_vertex_half_float </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> <d:description>The phone in portrait view</d:description> diff --git a/eclipse/dictionary.txt b/eclipse/dictionary.txt index f29994a..ae582d3 100644 --- a/eclipse/dictionary.txt +++ b/eclipse/dictionary.txt @@ -107,6 +107,8 @@ froyo gen gif git +glob +globbing groovy guava guillemets @@ -166,6 +168,7 @@ macs malformed markup marquee +maven mdpi memento metadata diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/resources/platform/AttrsXmlParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/resources/platform/AttrsXmlParser.java index a0a5ad8..a7bc53b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/resources/platform/AttrsXmlParser.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/resources/platform/AttrsXmlParser.java @@ -17,6 +17,7 @@ package com.android.ide.common.resources.platform; import static com.android.ide.common.layout.LayoutConstants.DOT_LAYOUT_PARAMS; +import static com.android.ide.eclipse.adt.AdtConstants.DOC_HIDE; import com.android.ide.common.api.IAttributeInfo.Format; import com.android.ide.common.log.ILogger; @@ -291,7 +292,12 @@ public final class AttrsXmlParser { mStyleMap.put(name, style); unknownParents.remove(name); if (lastComment != null) { - style.setJavaDoc(parseJavadoc(lastComment.getNodeValue())); + String nodeValue = lastComment.getNodeValue(); + if (nodeValue.contains(DOC_HIDE)) { + mStyleMap.remove(name); + } else { + style.setJavaDoc(parseJavadoc(nodeValue)); + } } } } @@ -416,8 +422,12 @@ public final class AttrsXmlParser { } if (info != null) { if (lastComment != null) { - info.setJavaDoc(parseJavadoc(lastComment.getNodeValue())); - info.setDeprecatedDoc(parseDeprecatedDoc(lastComment.getNodeValue())); + String nodeValue = lastComment.getNodeValue(); + if (nodeValue.contains(DOC_HIDE)) { + return null; + } + info.setJavaDoc(parseJavadoc(nodeValue)); + info.setDeprecatedDoc(parseDeprecatedDoc(nodeValue)); } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java index 8ac1012..670dd20 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java @@ -289,4 +289,7 @@ public class AdtConstants { public static final String CODESITE_BASE_URL = "http://code.google.com/android"; //$NON-NLS-1$ public static final String LIBRARY_TEST_RUNNER = "android.test.runner"; //$NON-NLS-1$ + + /** Documentation marker for elements, attributes etc that should be hidden */ + public static final String DOC_HIDE = "@hide"; //$NON-NLS-1$ } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java index 4cf4a00..d6ca12a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java @@ -30,8 +30,6 @@ import com.android.sdklib.AndroidVersion; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.repository.PkgProps; import com.android.util.XmlUtils; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; import com.google.common.io.ByteStreams; import com.google.common.io.Closeables; @@ -860,7 +858,7 @@ public class AdtUtils { * @return the highest known API number */ public static int getHighestKnownApiLevel() { - return 15; + return 16; } /** @@ -981,41 +979,6 @@ public class AdtUtils { } /** - * Splits the given path into its individual parts, attempting to be - * tolerant about path separators (: or ;). It can handle possibly ambiguous - * paths, such as {@code c:\foo\bar:\other}, though of course these are to - * be avoided if possible. - * - * @param path the path variable to split, which can use both : and ; as - * path separators. - * @return the individual path components as an iterable of strings - */ - public static Iterable<String> splitPath(String path) { - if (path.indexOf(';') != -1) { - return Splitter.on(';').omitEmptyStrings().trimResults().split(path); - } - - List<String> combined = new ArrayList<String>(); - Iterables.addAll(combined, Splitter.on(':').omitEmptyStrings().trimResults().split(path)); - for (int i = 0, n = combined.size(); i < n; i++) { - String p = combined.get(i); - if (p.length() == 1 && i < n - 1 && Character.isLetter(p.charAt(0)) - // Technically, Windows paths do not have to have a \ after the :, - // which means it would be using the current directory on that drive, - // but that's unlikely to be the case in a path since it would have - // unpredictable results - && !combined.get(i+1).isEmpty() && combined.get(i+1).charAt(0) == '\\') { - combined.set(i, p + ':' + combined.get(i+1)); - combined.remove(i+1); - n--; - continue; - } - } - - return combined; - } - - /** * Reads the contents of an {@link IFile} and return it as a byte array * * @param file the file to be read diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java index 0237769..172b7a4 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java @@ -67,6 +67,7 @@ import com.android.resources.UiMode; import com.android.sdklib.AndroidVersion; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.devices.Device; +import com.android.sdklib.devices.DeviceManager; import com.android.sdklib.devices.State; import com.android.sdklib.internal.avd.AvdInfo; import com.android.sdklib.internal.avd.AvdManager; @@ -204,6 +205,9 @@ public class ConfigurationComposite extends Composite implements SelectionListen /** The config listener given to the constructor. Never null. */ private final IConfigListener mListener; + /** The device menu listener, so we can remove it when the device lists are updated */ + private Listener mDeviceListener; + /** The {@link FolderConfiguration} representing the state of the UI controls */ private final FolderConfiguration mCurrentConfig = new FolderConfiguration(); @@ -1906,6 +1910,11 @@ public class ConfigurationComposite extends Composite implements SelectionListen menu.setVisible(true); } }; + + if (mDeviceListener != null) { + combo.removeListener(SWT.Selection, mDeviceListener); + } + mDeviceListener = menuListener; combo.addListener(SWT.Selection, menuListener); } @@ -2656,9 +2665,17 @@ public class ConfigurationComposite extends Composite implements SelectionListen * Loads the list of {@link Device}s and inits the UI with it. */ private void initDevices() { - Sdk sdk = Sdk.getCurrent(); + final Sdk sdk = Sdk.getCurrent(); if (sdk != null) { mDeviceList = sdk.getDevices(); + DeviceManager manager = sdk.getDeviceManager(); + manager.registerListener(new DeviceManager.DevicesChangeListener() { + @Override + public void onDevicesChange() { + mDeviceList = sdk.getDevices(); + addDeviceMenuListener(mDeviceCombo); + } + }); } else { mDeviceList = new ArrayList<Device>(); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java index 9fa5018..1ab02c3 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java @@ -28,6 +28,7 @@ import com.android.tools.lint.checks.PxUsageDetector; import com.android.tools.lint.checks.ScrollViewChildDetector; import com.android.tools.lint.checks.SecurityDetector; import com.android.tools.lint.checks.TextFieldDetector; +import com.android.tools.lint.checks.TranslationDetector; import com.android.tools.lint.checks.TypoDetector; import com.android.tools.lint.checks.TypographyDetector; import com.android.tools.lint.checks.UseCompoundDrawableDetector; @@ -153,6 +154,7 @@ abstract class LintFix implements ICompletionProposal { sFixes.put(PxUsageDetector.PX_ISSUE.getId(), ConvertToDpFix.class); sFixes.put(TextFieldDetector.ISSUE.getId(), SetAttributeFix.class); sFixes.put(SecurityDetector.EXPORTED_SERVICE.getId(), SetAttributeFix.class); + sFixes.put(TranslationDetector.MISSING.getId(), SetAttributeFix.class); sFixes.put(DetectMissingPrefix.MISSING_NAMESPACE.getId(), AddPrefixFix.class); sFixes.put(ScrollViewChildDetector.ISSUE.getId(), SetScrollViewSizeFix.class); sFixes.put(ObsoleteLayoutParamsDetector.ISSUE.getId(), ObsoleteLayoutParamsFix.class); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java index a07101f..5d38df2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java @@ -98,6 +98,7 @@ import java.util.List; * in the Problems view; perhaps we should use a custom view for these. That would also * make marker management more obvious. */ +@SuppressWarnings("restriction") // DOM model public class LintFixGenerator implements IMarkerResolutionGenerator2, IQuickAssistProcessor { /** Constructs a new {@link LintFixGenerator} */ public LintFixGenerator() { @@ -248,7 +249,6 @@ public class LintFixGenerator implements IMarkerResolutionGenerator2, IQuickAssi * * @param marker the marker pointing to the error to be suppressed */ - @SuppressWarnings("restriction") // XML model public static void addSuppressAnnotation(IMarker marker) { String id = EclipseLintClient.getId(marker); if (id != null) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetAttributeFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetAttributeFix.java index 896966e..a860c69 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetAttributeFix.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetAttributeFix.java @@ -18,17 +18,18 @@ package com.android.ide.eclipse.adt.internal.lint; import static com.android.ide.common.layout.LayoutConstants.ATTR_CONTENT_DESCRIPTION; import static com.android.ide.common.layout.LayoutConstants.ATTR_INPUT_TYPE; import static com.android.ide.common.layout.LayoutConstants.VALUE_FALSE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_TRANSLATABLE; import com.android.tools.lint.checks.AccessibilityDetector; import com.android.tools.lint.checks.InefficientWeightDetector; import com.android.tools.lint.checks.SecurityDetector; import com.android.tools.lint.checks.TextFieldDetector; +import com.android.tools.lint.checks.TranslationDetector; import com.android.tools.lint.detector.api.LintConstants; import org.eclipse.core.resources.IMarker; /** Shared fix class for various builtin attributes */ -@SuppressWarnings("restriction") // DOM model final class SetAttributeFix extends SetPropertyFix { private SetAttributeFix(String id, IMarker marker) { super(id, marker); @@ -44,6 +45,8 @@ final class SetAttributeFix extends SetPropertyFix { return LintConstants.ATTR_PERMISSION; } else if (mId.equals(TextFieldDetector.ISSUE.getId())) { return ATTR_INPUT_TYPE; + } else if (mId.equals(TranslationDetector.MISSING.getId())) { + return ATTR_TRANSLATABLE; } else { assert false : mId; return ""; @@ -51,6 +54,15 @@ final class SetAttributeFix extends SetPropertyFix { } @Override + protected boolean isAndroidAttribute() { + if (mId.equals(TranslationDetector.MISSING.getId())) { + return false; + } + + return true; + } + + @Override public String getDisplayString() { if (mId.equals(AccessibilityDetector.ISSUE.getId())) { return "Add content description attribute"; @@ -60,6 +72,8 @@ final class SetAttributeFix extends SetPropertyFix { return "Set input type"; } else if (mId.equals(SecurityDetector.EXPORTED_SERVICE.getId())) { return "Add permission attribute"; + } else if (mId.equals(TranslationDetector.MISSING.getId())) { + return "Mark this as a non-translatable resource"; } else { assert false : mId; return ""; @@ -67,15 +81,37 @@ final class SetAttributeFix extends SetPropertyFix { } @Override + public String getAdditionalProposalInfo() { + String help = super.getAdditionalProposalInfo(); + + if (mId.equals(TranslationDetector.MISSING.getId())) { + help = "<b>Adds translatable=\"false\" to this <string>.</b><br><br>" + help; + } + + return help; + } + + @Override protected boolean invokeCodeCompletion() { return mId.equals(SecurityDetector.EXPORTED_SERVICE.getId()) || mId.equals(TextFieldDetector.ISSUE.getId()); } @Override + public boolean selectValue() { + if (mId.equals(TranslationDetector.MISSING.getId())) { + return false; + } else { + return super.selectValue(); + } + } + + @Override protected String getProposal() { if (mId.equals(InefficientWeightDetector.BASELINE_WEIGHTS.getId())) { return VALUE_FALSE; + } else if (mId.equals(TranslationDetector.MISSING.getId())) { + return VALUE_FALSE; } return super.getProposal(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetPropertyFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetPropertyFix.java index 2bfe5e8..8b32734 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetPropertyFix.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/SetPropertyFix.java @@ -48,6 +48,9 @@ abstract class SetPropertyFix extends DocumentFix { /** Attribute to be added */ protected abstract String getAttribute(); + /** Whether it's in the android: namespace */ + protected abstract boolean isAndroidAttribute(); + protected String getProposal() { return invokeCodeCompletion() ? "" : "TODO"; //$NON-NLS-1$ } @@ -70,7 +73,10 @@ abstract class SetPropertyFix extends DocumentFix { Element element = (Element) node; String proposal = getProposal(); String localAttribute = getAttribute(); - String prefix = XmlUtils.lookupNamespacePrefix(node, ANDROID_URI); + String prefix = null; + if (isAndroidAttribute()) { + prefix = XmlUtils.lookupNamespacePrefix(node, ANDROID_URI); + } String attribute = prefix != null ? prefix + ':' + localAttribute : localAttribute; // This does not work even though it should: it does not include the prefix @@ -78,18 +84,29 @@ abstract class SetPropertyFix extends DocumentFix { // So workaround instead: element.setAttribute(attribute, proposal); - Attr attr = element.getAttributeNodeNS(ANDROID_URI, localAttribute); + Attr attr = null; + if (isAndroidAttribute()) { + attr = element.getAttributeNodeNS(ANDROID_URI, localAttribute); + } else { + attr = element.getAttributeNode(localAttribute); + } if (attr instanceof IndexedRegion) { IndexedRegion region = (IndexedRegion) attr; int offset = region.getStartOffset(); // We only want to select the value part inside the quotes, // so skip the attribute and =" parts added by WST: offset += attribute.length() + 2; - mSelect = new Region(offset, proposal.length()); + if (selectValue()) { + mSelect = new Region(offset, proposal.length()); + } } } } + protected boolean selectValue() { + return true; + } + @Override public void apply(IDocument document) { try { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/TypoFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/TypoFix.java index 7c34e3e..4358410 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/TypoFix.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/TypoFix.java @@ -63,7 +63,7 @@ final class TypoFix extends DocumentFix { return; } List<String> replacements = TypoDetector.getSuggestions(message); - if (replacements.size() == 0) { + if (replacements == null || replacements.isEmpty()) { return; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java index 467602f..022857e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java @@ -20,7 +20,6 @@ import static com.android.sdklib.internal.project.ProjectProperties.PROPERTY_SDK import com.android.ide.eclipse.adt.AdtConstants; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; import com.android.ide.eclipse.adt.AndroidPrintStream; import com.android.ide.eclipse.adt.internal.build.BuildHelper; import com.android.ide.eclipse.adt.internal.build.DexException; @@ -36,6 +35,7 @@ import com.android.sdklib.build.ApkCreationException; import com.android.sdklib.build.DuplicateFileException; import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdklib.xml.AndroidManifest; +import com.android.tools.lint.detector.api.LintUtils; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -177,7 +177,7 @@ public final class ExportHelper { proguardConfig = proguardConfig.replace('/', File.separatorChar); } - Iterable<String> paths = AdtUtils.splitPath(proguardConfig); + Iterable<String> paths = LintUtils.splitPath(proguardConfig); for (String path : paths) { if (path.startsWith(SDK_PROPERTY_REF)) { path = AdtPrefs.getPrefs().getOsSdkFolder() + diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java index 0a62c8b..5f10ce0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java @@ -239,9 +239,9 @@ public class NewTemplatePage extends WizardPage String id = parameter.id; assert id != null && !id.isEmpty() : ATTR_ID; - String value = defaults.get(id); + Object value = defaults.get(id); if (value == null) { - value = parameter.initial; + value = parameter.value; } String name = parameter.name; @@ -289,8 +289,8 @@ public class NewTemplatePage extends WizardPage 2, 1)); } - if (value != null && !value.isEmpty()){ - text.setText(value); + if (value instanceof String) { + text.setText((String) value); mValues.parameters.put(id, value); } @@ -319,8 +319,8 @@ public class NewTemplatePage extends WizardPage checkBox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); - if (value != null && !value.isEmpty()){ - Boolean selected = Boolean.valueOf(value); + if (value instanceof Boolean) { + Boolean selected = (Boolean) value; checkBox.setSelection(selected); mValues.parameters.put(id, value); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java index 00183d2..6101161 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java @@ -29,6 +29,8 @@ import com.android.annotations.Nullable; import com.android.ide.eclipse.adt.internal.assetstudio.ConfigureAssetSetPage; import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState; import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; +import com.android.ide.eclipse.adt.internal.sdk.Sdk; +import com.android.sdklib.IAndroidTarget; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -124,13 +126,17 @@ public class NewTemplateWizardState { return manifest.getMinSdkVersion(); } - /** Returns the min SDK version to use */ + /** Returns the build API version to use */ int getBuildApi() { if (project == null) { return -1; } - ManifestInfo manifest = ManifestInfo.get(project); - return manifest.getMinSdkVersion(); + IAndroidTarget target = Sdk.getCurrent().getTarget(project); + if (target != null) { + return target.getVersion().getApiLevel(); + } + + return getMinSdk(); } /** Computes the changes this wizard will make */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java index 9c31033..a9a3f33 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java @@ -237,7 +237,11 @@ class Parameter { constraints = EnumSet.noneOf(Constraint.class); } - value = initial; + if (initial != null && !initial.isEmpty() && type == Type.BOOLEAN) { + value = Boolean.valueOf(initial); + } else { + value = initial; + } } Parameter(@NonNull Type type, @NonNull String id, @NonNull String initialValue) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java index 1c3b862..e214788 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java @@ -98,8 +98,16 @@ import javax.xml.parsers.SAXParserFactory; * and merging into existing files */ class TemplateHandler { - /** Highest supported format; templates with a higher number will be skipped */ - static final int CURRENT_FORMAT = 1; + /** Highest supported format; templates with a higher number will be skipped + * <p> + * <ul> + * <li> 1: Initial format, supported by ADT 20 and up. + * <li> 2: ADT 21 and up. Boolean variables that have a default value and are not + * edited by the user would end up as strings in ADT 20; now they are always + * proper Booleans. Templates which rely on this should specify format >= 2. + * </ul> + */ + static final int CURRENT_FORMAT = 2; /** * Special marker indicating that this path refers to the special shared @@ -396,7 +404,14 @@ class TemplateHandler { String id = attributes.getValue(ATTR_ID); if (!paramMap.containsKey(id)) { String value = attributes.getValue(ATTR_DEFAULT); - paramMap.put(id, value); + Object mapValue = value; + if (value != null && !value.isEmpty()) { + String type = attributes.getValue(ATTR_TYPE); + if ("boolean".equals(type)) { //$NON-NLS-1$ + mapValue = Boolean.valueOf(value); + } + } + paramMap.put(id, mapValue); } } else if (TAG_GLOBAL.equals(name)) { String id = attributes.getValue(ATTR_ID); diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/.classpath b/eclipse/plugins/com.android.ide.eclipse.monitor/.classpath index 9642053..1be4b68 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/.classpath +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/.classpath @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> + <classpathentry exported="true" kind="lib" path="libs/sdkuilib.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF index 2a2a405..047072b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/META-INF/MANIFEST.MF @@ -11,6 +11,7 @@ Require-Bundle: org.eclipse.ui, com.android.ide.eclipse.base Bundle-ActivationPolicy: lazy Bundle-Vendor: %Bundle-Vendor -Bundle-ClassPath: . +Bundle-ClassPath: ., + libs/sdkuilib.jar Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/build.properties b/eclipse/plugins/com.android.ide.eclipse.monitor/build.properties index 44471de..a2a2a99 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/build.properties +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/build.properties @@ -7,4 +7,5 @@ bin.includes = META-INF/,\ plugin_customization.ini,\ plugin.properties,\ images/,\ - splash.bmp + splash.bmp,\ + libs/sdkuilib.jar diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java index 27fcdd9..5f87813 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/MonitorApplication.java @@ -18,7 +18,11 @@ package com.android.ide.eclipse.monitor; import com.android.ide.eclipse.monitor.SdkToolsLocator.SdkInstallStatus; import com.android.prefs.AndroidLocation; +import com.android.sdklib.ISdkLog; +import com.android.sdklib.NullSdkLog; +import com.android.sdklib.SdkManager; import com.android.sdkstats.SdkStatsService; +import com.android.sdkuilib.internal.repository.sdkman2.AdtUpdateDialog; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -55,6 +59,14 @@ public class MonitorApplication implements IApplication { } MonitorPlugin.getDefault().setSdkPath(sdkPath); + // install platform tools if necessary + ISdkLog sdkLog = new NullSdkLog(); + SdkManager manager = SdkManager.createManager(sdkPath, sdkLog); + if (manager.getPlatformToolsVersion() == null) { + AdtUpdateDialog window = new AdtUpdateDialog(new Shell(display), sdkLog, sdkPath); + window.installPlatformTools(); + } + // If this is the first time using ddms or adt, open up the stats service // opt out dialog, and request user for permissions. // Note that the actual ping is performed in MonitorStartup diff --git a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java index ba87c7b..19e1a43 100644 --- a/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java +++ b/eclipse/plugins/com.android.ide.eclipse.monitor/src/com/android/ide/eclipse/monitor/SdkToolsLocator.java @@ -73,7 +73,7 @@ public class SdkToolsLocator { } public SdkInstallStatus isValidInstallation() { - List<String> executables = Arrays.asList(getAdbLocation(), + List<String> executables = Arrays.asList( getTraceViewLocation(), getHprofConvLocation()); diff --git a/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/NdkGdbLaunchDelegate.java b/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/NdkGdbLaunchDelegate.java index 57d96d7..818a5c1 100644 --- a/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/NdkGdbLaunchDelegate.java +++ b/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/NdkGdbLaunchDelegate.java @@ -19,9 +19,9 @@ package com.android.ide.eclipse.ndk.internal.launch; import com.android.ddmlib.AdbCommandRejectedException; import com.android.ddmlib.AndroidDebugBridge; import com.android.ddmlib.Client; +import com.android.ddmlib.CollectingOutputReceiver; import com.android.ddmlib.IDevice; import com.android.ddmlib.IDevice.DeviceUnixSocketNamespace; -import com.android.ddmlib.IShellOutputReceiver; import com.android.ddmlib.InstallException; import com.android.ddmlib.ShellCommandUnresponsiveException; import com.android.ddmlib.SyncException; @@ -233,7 +233,7 @@ public class NdkGdbLaunchDelegate extends GdbLaunchDelegate { activityName); try { CountDownLatch launchedLatch = new CountDownLatch(1); - ShellOutputReceiver receiver = new ShellOutputReceiver(launchedLatch); + CollectingOutputReceiver receiver = new CollectingOutputReceiver(launchedLatch); device.executeShellCommand(command, receiver); launchedLatch.await(5, TimeUnit.SECONDS); String shellOutput = receiver.getOutput(); @@ -479,39 +479,9 @@ public class NdkGdbLaunchDelegate extends GdbLaunchDelegate { String command = String.format("run-as %s /system/bin/sh -c pwd", app); //$NON-NLS-1$ CountDownLatch commandCompleteLatch = new CountDownLatch(1); - ShellOutputReceiver receiver = new ShellOutputReceiver(commandCompleteLatch); + CollectingOutputReceiver receiver = new CollectingOutputReceiver(commandCompleteLatch); device.executeShellCommand(command, receiver); commandCompleteLatch.await(timeout, timeoutUnit); return receiver.getOutput().trim(); } - - private static class ShellOutputReceiver implements IShellOutputReceiver { - private StringBuffer sb = new StringBuffer(); - private CountDownLatch mCompleteLatch; - - public ShellOutputReceiver(CountDownLatch commandCompleteLatch) { - mCompleteLatch = commandCompleteLatch; - } - - @Override - public void addOutput(byte[] data, int offset, int length) { - sb.append(new String(data, offset, length)); - } - - @Override - public void flush() { - if (mCompleteLatch != null) { - mCompleteLatch.countDown(); - } - } - - @Override - public boolean isCancelled() { - return false; - } - - public String getOutput() { - return sb.toString(); - } - } } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion11-expected-completion73.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion11-expected-completion73.txt index 21baad8..a2feb13 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion11-expected-completion73.txt +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion11-expected-completion73.txt @@ -1,5 +1,5 @@ Code completion in completion11.xml for ?android:attr/Textapp^: -?android:attr/textAppearance +?android:attr/textAppearance : Base text color, typeface, size, and style. ?android:attr/textAppearanceButton ?android:attr/textAppearanceInverse ?android:attr/textAppearanceLarge diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues1-expected-completion32.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues1-expected-completion32.txt index 7e27fa6..30e6c31 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues1-expected-completion32.txt +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues1-expected-completion32.txt @@ -88,7 +88,6 @@ android:fillViewport : Defines whether the scrollview should stretch its content android:filterTouchesWhenObscured : Specifies whether to filter touches when the view's window is obscured by another visible window. [boolean] android:firstDayOfWeek : The first day of week according to java.util.Calendar. [integer] android:fitsSystemWindows : Boolean internal attribute to adjust view layout based on system windows such as the status bar. [boolean] -android:flingable : @hide Whether the number picker supports fligning. [boolean] android:flipInterval : [integer] android:focusable : Boolean that controls whether a view can take focus. [boolean] android:focusableInTouchMode : Boolean that controls whether a view can take focus while in touch mode. [boolean] @@ -221,8 +220,6 @@ android:secondaryProgress : Defines the secondary progress value, between 0 and android:selectAllOnFocus : If the text is selectable, select it all when the view takes focus instead of moving the cursor to the start or end. [boolean] android:selectedDateVerticalBar : Drawable for the vertical bar shown at the beggining and at the end of a selected date. [reference] android:selectedWeekBackgroundColor : The background color for the selected week. [color, reference] -android:selectionDivider : @hide The divider for making the selection area. [reference] -android:selectionDividerHeight : @hide The height of the selection divider. [dimension] android:shadowColor : Place a shadow of the specified color behind the text. [color] android:shadowDx : Horizontal offset of the shadow. [float] android:shadowDy : Vertical offset of the shadow. [float] @@ -233,7 +230,6 @@ android:shownWeekCount : The number of weeks to be shown. [integer] android:shrinkColumns : The zero-based index of the columns to shrink. [string] android:singleLine : Constrains the text to a single horizontally scrolling line instead of letting it wrap onto multiple lines, and advances focus instead of inserting a newline when you press the enter key. * Deprecated: This attribute is deprecated and is replaced by the textMultiLine flag in the inputType attribute. Use caution when altering existing layouts, as the default value of singeLine is false (multi-line mode), but if you specify any value for inputType, the default is single-line mode. (If both singleLine and inputType attributes are found, the inputType flags will override the value of singleLine.). [boolean] android:smoothScrollbar : When set to true, the list will use a more refined calculation method based on the pixels height of the items visible on screen. [boolean] -android:solidColor : @hide Color for the solid color background if such for optimized rendering. [color, reference] android:soundEffectsEnabled : Boolean that controls whether a view should have sound effects enabled for events such as clicking and touching. [boolean] android:spacing : [dimension] android:spinnerMode : Display mode for spinner options. [enum] diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt index 641cddb..c491fea 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completionvalues2-expected-completion71.txt @@ -1,3 +1,2 @@ Code completion in completionvalues2.xml for <item name="main_layout5" type="string">@string/^app_name</item>: @string/app_name -@string/hello diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion18.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion18.txt index 21bb2fa..853d9a5 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion18.txt +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion18.txt @@ -1,5 +1,5 @@ Code completion in manifest.xml for <activity android:^name=".TestActivity": -android:name : Required name of the class implementing the activity, deriving from android.app.Activity. [string] +android:name : Required name of the class implementing the activity, deriving from android.app.Activity. [string]. * Required. android:theme : The overall theme to use for an activity. [reference] android:label : A user-legible name for the given item. [string, reference] android:description : Descriptive text for the associated data. [reference] diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion69.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion69.txt index 627ff01..c60a305 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion69.txt +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion69.txt @@ -1,4 +1,5 @@ Code completion in manifest.xml for <uses-sdk android:minSdkVersion="^11" />: +16 : API 16: Android 4.1 (JellyBean) 15 : API 15: Android 4.0.3 (IceCreamSandwich) 14 : API 14: Android 4.0 (IceCreamSandwich) 13 : API 13: Android 3.2 (Honeycomb) diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/AdtUtilsTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/AdtUtilsTest.java index b2b6787..e0ebdbc 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/AdtUtilsTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/AdtUtilsTest.java @@ -15,9 +15,6 @@ */ package com.android.ide.eclipse.adt; -import com.google.common.collect.Iterables; - -import java.util.Arrays; import java.util.Locale; import junit.framework.TestCase; @@ -148,31 +145,6 @@ public class AdtUtilsTest extends TestCase { assertEquals("Foo", AdtUtils.stripSuffix("Foo", "Bar")); } - public void testSplitPath() throws Exception { - assertTrue(Arrays.equals(new String[] { "/foo", "/bar", "/baz" }, - Iterables.toArray(AdtUtils.splitPath("/foo:/bar:/baz"), String.class))); - - assertTrue(Arrays.equals(new String[] { "/foo", "/bar" }, - Iterables.toArray(AdtUtils.splitPath("/foo;/bar"), String.class))); - - assertTrue(Arrays.equals(new String[] { "/foo", "/bar:baz" }, - Iterables.toArray(AdtUtils.splitPath("/foo;/bar:baz"), String.class))); - - assertTrue(Arrays.equals(new String[] { "\\foo\\bar", "\\bar\\foo" }, - Iterables.toArray(AdtUtils.splitPath("\\foo\\bar;\\bar\\foo"), String.class))); - - assertTrue(Arrays.equals(new String[] { "${sdk.dir}\\foo\\bar", "\\bar\\foo" }, - Iterables.toArray(AdtUtils.splitPath("${sdk.dir}\\foo\\bar;\\bar\\foo"), - String.class))); - - assertTrue(Arrays.equals(new String[] { "${sdk.dir}/foo/bar", "/bar/foo" }, - Iterables.toArray(AdtUtils.splitPath("${sdk.dir}/foo/bar:/bar/foo"), - String.class))); - - assertTrue(Arrays.equals(new String[] { "C:\\foo", "/bar" }, - Iterables.toArray(AdtUtils.splitPath("C:\\foo:/bar"), String.class))); - } - public void testFormatFloatValue() throws Exception { assertEquals("1", AdtUtils.formatFloatAttribute(1.0f)); assertEquals("2", AdtUtils.formatFloatAttribute(2.0f)); diff --git a/eclipse/scripts/create_all_symlinks.sh b/eclipse/scripts/create_all_symlinks.sh index 1bfa946..134a1b8 100755 --- a/eclipse/scripts/create_all_symlinks.sh +++ b/eclipse/scripts/create_all_symlinks.sh @@ -188,6 +188,13 @@ TV_LIBS="traceview" LIBS="$LIBS $TV_LIBS" CP_FILES="$CP_FILES @:$TV_DEST $TV_LIBS" +### MONITOR ### + +MONITOR_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.monitor/libs" +MONITOR_LIBS="sdkuilib" + +LIBS="$LIBS $MONITOR_LIBS" +CP_FILES="$CP_FILES @:$MONITOR_DEST $MONITOR_LIBS" ### SDKMANAGER ### diff --git a/files/ant/build.xml b/files/ant/build.xml index 769889c..0c486e6 100644 --- a/files/ant/build.xml +++ b/files/ant/build.xml @@ -1295,7 +1295,9 @@ description="Runs lint on the project to look for potential bugs" > <lint executable="${lint}" html="${lint.out.html}" - xml="${lint.out.xml}" /> + xml="${lint.out.xml}" + src="${source.absolute.dir}:${gen.absolute.dir}" + classpath="${out.classes.absolute.dir}" /> </target> <!-- ******************************************************* --> diff --git a/files/typos/typos-de.txt b/files/typos/typos-de.txt new file mode 100644 index 0000000..5bcdffc --- /dev/null +++ b/files/typos/typos-de.txt @@ -0,0 +1,2219 @@ +# This file contains a number of common German typos: +andriod->android + +# The remainder of this file contains misspellings from +# http://de.m.wikipedia.org/wiki/Wikipedia:Liste_von_Tippfehlern/F%C3%BCr_Maschinen +# plus some post-processing to fix invalid entries, remove duplicates, etc. +# +# The content is available under the +# "Creative Commons Attribution-ShareAlike License" +# http://creativecommons.org/licenses/by-sa/3.0/ +# +# THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +# COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +# COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +# AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. +# +# BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +# TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +# BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +# CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +# CONDITIONS. +# +# *1. Definitions* +# +# 1. *"Adaptation"* means a work based upon the Work, or upon the Work +# and other pre-existing works, such as a translation, adaptation, +# derivative work, arrangement of music or other alterations of a +# literary or artistic work, or phonogram or performance and includes +# cinematographic adaptations or any other form in which the Work may +# be recast, transformed, or adapted including in any form +# recognizably derived from the original, except that a work that +# constitutes a Collection will not be considered an Adaptation for +# the purpose of this License. For the avoidance of doubt, where the +# Work is a musical work, performance or phonogram, the +# synchronization of the Work in timed-relation with a moving image +# ("synching") will be considered an Adaptation for the purpose of +# this License. +# 2. *"Collection"* means a collection of literary or artistic works, +# such as encyclopedias and anthologies, or performances, phonograms +# or broadcasts, or other works or subject matter other than works +# listed in Section 1(f) below, which, by reason of the selection and +# arrangement of their contents, constitute intellectual creations, in +# which the Work is included in its entirety in unmodified form along +# with one or more other contributions, each constituting separate and +# independent works in themselves, which together are assembled into a +# collective whole. A work that constitutes a Collection will not be +# considered an Adaptation (as defined below) for the purposes of this +# License. +# 3. *"Creative Commons Compatible License"* means a license that is +# listed at http://creativecommons.org/compatiblelicenses that has +# been approved by Creative Commons as being essentially equivalent to +# this License, including, at a minimum, because that license: (i) +# contains terms that have the same purpose, meaning and effect as the +# License Elements of this License; and, (ii) explicitly permits the +# relicensing of adaptations of works made available under that +# license under this License or a Creative Commons jurisdiction +# license with the same License Elements as this License. +# 4. *"Distribute"* means to make available to the public the original +# and copies of the Work or Adaptation, as appropriate, through sale +# or other transfer of ownership. +# 5. *"License Elements"* means the following high-level license +# attributes as selected by Licensor and indicated in the title of +# this License: Attribution, ShareAlike. +# 6. *"Licensor"* means the individual, individuals, entity or entities +# that offer(s) the Work under the terms of this License. +# 7. *"Original Author"* means, in the case of a literary or artistic +# work, the individual, individuals, entity or entities who created +# the Work or if no individual or entity can be identified, the +# publisher; and in addition (i) in the case of a performance the +# actors, singers, musicians, dancers, and other persons who act, +# sing, deliver, declaim, play in, interpret or otherwise perform +# literary or artistic works or expressions of folklore; (ii) in the +# case of a phonogram the producer being the person or legal entity +# who first fixes the sounds of a performance or other sounds; and, +# (iii) in the case of broadcasts, the organization that transmits the +# broadcast. +# 8. *"Work"* means the literary and/or artistic work offered under the +# terms of this License including without limitation any production in +# the literary, scientific and artistic domain, whatever may be the +# mode or form of its expression including digital form, such as a +# book, pamphlet and other writing; a lecture, address, sermon or +# other work of the same nature; a dramatic or dramatico-musical work; +# a choreographic work or entertainment in dumb show; a musical +# composition with or without words; a cinematographic work to which +# are assimilated works expressed by a process analogous to +# cinematography; a work of drawing, painting, architecture, +# sculpture, engraving or lithography; a photographic work to which +# are assimilated works expressed by a process analogous to +# photography; a work of applied art; an illustration, map, plan, +# sketch or three-dimensional work relative to geography, topography, +# architecture or science; a performance; a broadcast; a phonogram; a +# compilation of data to the extent it is protected as a copyrightable +# work; or a work performed by a variety or circus performer to the +# extent it is not otherwise considered a literary or artistic work. +# 9. *"You"* means an individual or entity exercising rights under this +# License who has not previously violated the terms of this License +# with respect to the Work, or who has received express permission +# from the Licensor to exercise rights under this License despite a +# previous violation. +# 10. *"Publicly Perform"* means to perform public recitations of the Work +# and to communicate to the public those public recitations, by any +# means or process, including by wire or wireless means or public +# digital performances; to make available to the public Works in such +# a way that members of the public may access these Works from a place +# and at a place individually chosen by them; to perform the Work to +# the public by any means or process and the communication to the +# public of the performances of the Work, including by public digital +# performance; to broadcast and rebroadcast the Work by any means +# including signs, sounds or images. +# 11. *"Reproduce"* means to make copies of the Work by any means +# including without limitation by sound or visual recordings and the +# right of fixation and reproducing fixations of the Work, including +# storage of a protected performance or phonogram in digital form or +# other electronic medium. +# +# *2. Fair Dealing Rights.* Nothing in this License is intended to reduce, +# limit, or restrict any uses free from copyright or rights arising from +# limitations or exceptions that are provided for in connection with the +# copyright protection under copyright law or other applicable laws. +# +# *3. License Grant.* Subject to the terms and conditions of this License, +# Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +# perpetual (for the duration of the applicable copyright) license to +# exercise the rights in the Work as stated below: +# +# 1. to Reproduce the Work, to incorporate the Work into one or more +# Collections, and to Reproduce the Work as incorporated in the +# Collections; +# 2. to create and Reproduce Adaptations provided that any such +# Adaptation, including any translation in any medium, takes +# reasonable steps to clearly label, demarcate or otherwise identify +# that changes were made to the original Work. For example, a +# translation could be marked "The original work was translated from +# English to Spanish," or a modification could indicate "The original +# work has been modified."; +# 3. to Distribute and Publicly Perform the Work including as +# incorporated in Collections; and, +# 4. to Distribute and Publicly Perform Adaptations. +# 5. +# +# For the avoidance of doubt: +# +# 1. *Non-waivable Compulsory License Schemes*. In those +# jurisdictions in which the right to collect royalties through +# any statutory or compulsory licensing scheme cannot be waived, +# the Licensor reserves the exclusive right to collect such +# royalties for any exercise by You of the rights granted under +# this License; +# 2. *Waivable Compulsory License Schemes*. In those jurisdictions in +# which the right to collect royalties through any statutory or +# compulsory licensing scheme can be waived, the Licensor waives +# the exclusive right to collect such royalties for any exercise +# by You of the rights granted under this License; and, +# 3. *Voluntary License Schemes*. The Licensor waives the right to +# collect royalties, whether individually or, in the event that +# the Licensor is a member of a collecting society that +# administers voluntary licensing schemes, via that society, from +# any exercise by You of the rights granted under this License. +# +# The above rights may be exercised in all media and formats whether now +# known or hereafter devised. The above rights include the right to make +# such modifications as are technically necessary to exercise the rights +# in other media and formats. Subject to Section 8(f), all rights not +# expressly granted by Licensor are hereby reserved. +# +# *4. Restrictions.* The license granted in Section 3 above is expressly +# made subject to and limited by the following restrictions: +# +# 1. You may Distribute or Publicly Perform the Work only under the terms +# of this License. You must include a copy of, or the Uniform Resource +# Identifier (URI) for, this License with every copy of the Work You +# Distribute or Publicly Perform. You may not offer or impose any +# terms on the Work that restrict the terms of this License or the +# ability of the recipient of the Work to exercise the rights granted +# to that recipient under the terms of the License. You may not +# sublicense the Work. You must keep intact all notices that refer to +# this License and to the disclaimer of warranties with every copy of +# the Work You Distribute or Publicly Perform. When You Distribute or +# Publicly Perform the Work, You may not impose any effective +# technological measures on the Work that restrict the ability of a +# recipient of the Work from You to exercise the rights granted to +# that recipient under the terms of the License. This Section 4(a) +# applies to the Work as incorporated in a Collection, but this does +# not require the Collection apart from the Work itself to be made +# subject to the terms of this License. If You create a Collection, +# upon notice from any Licensor You must, to the extent practicable, +# remove from the Collection any credit as required by Section 4(c), +# as requested. If You create an Adaptation, upon notice from any +# Licensor You must, to the extent practicable, remove from the +# Adaptation any credit as required by Section 4(c), as requested. +# 2. You may Distribute or Publicly Perform an Adaptation only under the +# terms of: (i) this License; (ii) a later version of this License +# with the same License Elements as this License; (iii) a Creative +# Commons jurisdiction license (either this or a later license +# version) that contains the same License Elements as this License +# (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons +# Compatible License. If you license the Adaptation under one of the +# licenses mentioned in (iv), you must comply with the terms of that +# license. If you license the Adaptation under the terms of any of the +# licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), +# you must comply with the terms of the Applicable License generally +# and the following provisions: (I) You must include a copy of, or the +# URI for, the Applicable License with every copy of each Adaptation +# You Distribute or Publicly Perform; (II) You may not offer or impose +# any terms on the Adaptation that restrict the terms of the +# Applicable License or the ability of the recipient of the Adaptation +# to exercise the rights granted to that recipient under the terms of +# the Applicable License; (III) You must keep intact all notices that +# refer to the Applicable License and to the disclaimer of warranties +# with every copy of the Work as included in the Adaptation You +# Distribute or Publicly Perform; (IV) when You Distribute or Publicly +# Perform the Adaptation, You may not impose any effective +# technological measures on the Adaptation that restrict the ability +# of a recipient of the Adaptation from You to exercise the rights +# granted to that recipient under the terms of the Applicable License. +# This Section 4(b) applies to the Adaptation as incorporated in a +# Collection, but this does not require the Collection apart from the +# Adaptation itself to be made subject to the terms of the Applicable +# License. +# 3. If You Distribute, or Publicly Perform the Work or any Adaptations +# or Collections, You must, unless a request has been made pursuant to +# Section 4(a), keep intact all copyright notices for the Work and +# provide, reasonable to the medium or means You are utilizing: (i) +# the name of the Original Author (or pseudonym, if applicable) if +# supplied, and/or if the Original Author and/or Licensor designate +# another party or parties (e.g., a sponsor institute, publishing +# entity, journal) for attribution ("Attribution Parties") in +# Licensor's copyright notice, terms of service or by other reasonable +# means, the name of such party or parties; (ii) the title of the Work +# if supplied; (iii) to the extent reasonably practicable, the URI, if +# any, that Licensor specifies to be associated with the Work, unless +# such URI does not refer to the copyright notice or licensing +# information for the Work; and (iv) , consistent with Ssection 3(b), +# in the case of an Adaptation, a credit identifying the use of the +# Work in the Adaptation (e.g., "French translation of the Work by +# Original Author," or "Screenplay based on original Work by Original +# Author"). The credit required by this Section 4(c) may be +# implemented in any reasonable manner; provided, however, that in the +# case of a Adaptation or Collection, at a minimum such credit will +# appear, if a credit for all contributing authors of the Adaptation +# or Collection appears, then as part of these credits and in a manner +# at least as prominent as the credits for the other contributing +# authors. For the avoidance of doubt, You may only use the credit +# required by this Section for the purpose of attribution in the +# manner set out above and, by exercising Your rights under this +# License, You may not implicitly or explicitly assert or imply any +# connection with, sponsorship or endorsement by the Original Author, +# Licensor and/or Attribution Parties, as appropriate, of You or Your +# use of the Work, without the separate, express prior written +# permission of the Original Author, Licensor and/or Attribution Parties. +# 4. Except as otherwise agreed in writing by the Licensor or as may be +# otherwise permitted by applicable law, if You Reproduce, Distribute +# or Publicly Perform the Work either by itself or as part of any +# Adaptations or Collections, You must not distort, mutilate, modify +# or take other derogatory action in relation to the Work which would +# be prejudicial to the Original Author's honor or reputation. +# Licensor agrees that in those jurisdictions (e.g. Japan), in which +# any exercise of the right granted in Section 3(b) of this License +# (the right to make Adaptations) would be deemed to be a distortion, +# mutilation, modification or other derogatory action prejudicial to +# the Original Author's honor and reputation, the Licensor will waive +# or not assert, as appropriate, this Section, to the fullest extent +# permitted by the applicable national law, to enable You to +# reasonably exercise Your right under Section 3(b) of this License +# (right to make Adaptations) but not otherwise. +# +# *5. Representations, Warranties and Disclaimer* +# +# UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +# OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +# KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +# INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +# FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +# LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +# WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE +# EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. +# +# *6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY +# APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL +# THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY +# DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF +# LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +# +# *7. Termination* +# +# 1. This License and the rights granted hereunder will terminate +# automatically upon any breach by You of the terms of this License. +# Individuals or entities who have received Adaptations or Collections +# from You under this License, however, will not have their licenses +# terminated provided such individuals or entities remain in full +# compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will +# survive any termination of this License. +# 2. Subject to the above terms and conditions, the license granted here +# is perpetual (for the duration of the applicable copyright in the +# Work). Notwithstanding the above, Licensor reserves the right to +# release the Work under different license terms or to stop +# distributing the Work at any time; provided, however that any such +# election will not serve to withdraw this License (or any other +# license that has been, or is required to be, granted under the terms +# of this License), and this License will continue in full force and +# effect unless terminated as stated above. +# +# *8. Miscellaneous* +# +# 1. Each time You Distribute or Publicly Perform the Work or a +# Collection, the Licensor offers to the recipient a license to the +# Work on the same terms and conditions as the license granted to You +# under this License. +# 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor +# offers to the recipient a license to the original Work on the same +# terms and conditions as the license granted to You under this License. +# 3. If any provision of this License is invalid or unenforceable under +# applicable law, it shall not affect the validity or enforceability +# of the remainder of the terms of this License, and without further +# action by the parties to this agreement, such provision shall be +# reformed to the minimum extent necessary to make such provision +# valid and enforceable. +# 4. No term or provision of this License shall be deemed waived and no +# breach consented to unless such waiver or consent shall be in +# writing and signed by the party to be charged with such waiver or +# consent. +# 5. This License constitutes the entire agreement between the parties +# with respect to the Work licensed here. There are no understandings, +# agreements or representations with respect to the Work not specified +# here. Licensor shall not be bound by any additional provisions that +# may appear in any communication from You. This License may not be +# modified without the mutual written agreement of the Licensor and You. +# 6. The rights granted under, and the subject matter referenced, in this +# License were drafted utilizing the terminology of the Berne +# Convention for the Protection of Literary and Artistic Works (as +# amended on September 28, 1979), the Rome Convention of 1961, the +# WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms +# Treaty of 1996 and the Universal Copyright Convention (as revised on +# July 24, 1971). These rights and subject matter take effect in the +# relevant jurisdiction in which the License terms are sought to be +# enforced according to the corresponding provisions of the +# implementation of those treaty provisions in the applicable national +# law. If the standard suite of rights granted under applicable +# copyright law includes additional rights not granted under this +# License, such additional rights are deemed to be included in the +# License; this License is not intended to restrict the license of any +# rights under applicable law. +Aaachen->Aachen +aberufen->abgerufen +abgekürtzt->abgekürzt +abgeschloßen->abgeschlossen +Abhängikeit->Abhängigkeit +Abhängkeit->Abhängigkeit +abolvieren->absolvieren +abolviert->absolviert +abschliessen->abschließen +abschliessend->abschließend +abschliessende->abschließende +abschliessenden->abschließenden +abschliessender->abschließender +abschliesst->abschließt +Absorbtion->Absorption +abzuschliessen->abzuschließen +achsial*->axial* +achzig->achtzig +Addresse->Adresse +addressiert->adressiert +Adjudant->Adjutant +Aeropag->Areopag +Aeropagos->Areopag +afrz->afrz. +agberufen->abgerufen +Agendas->Agenden +agerufen->abgerufen +agraisch->agrarisch +agressiv->aggressiv +akkomodieren->akkommodieren +Akkustik->Akustik +akreditiert->akkreditiert +Aktivitiäten->Aktivitäten +Aktzeptanz->Akzeptanz +alamiert->alarmiert +aler->aller +alerdings->allerdings +Algorhitmus->Algorithmus +Algoritmus->Algorithmus +aliiert->alliiert +allerding->allerdings +allgmein->allgemein +alliert->alliiert +allredings->allerdings +all zu->allzu +Alstadt->Altstadt +am einem->an einem,am einen +amerikanich->amerikanisch +amerikansch->amerikanisch +amerkanisch->amerikanisch +am seinem->an seinem +Amtsitz->Amtssitz +Amtsprache->Amtssprache +Amtsprachen->Amtssprachen +Anaesthesie->Anästhesie +Analen->Annalen +anderere->andere +andereren->anderen +andererer->anderer +andereseits->andererseits +anders herum->andersherum +andersrum->besser: andersherum +angelsächisch->angelsächsisch +angelsächsiche->angelsächsische +angelsächsichen->angelsächsischen +angesehendsten->angesehensten +anlaesslich->anlässlich +anlaeßlich->anlässlich +änlich->ähnlich +annährend->annähernd +Annährung->Annäherung +Annektion->Annexion +annerkannt->anerkannt +annerkannte->anerkannte +Annerkennung->Anerkennung +annuliert->annulliert +Annulierung->Annullierung +Anordung->Anordnung +Anschaung->Anschauung +anschliessen->anschließen +anschliessend->anschließend +anschliessende->anschließende +anschliessenden->anschließenden +anschliessender->anschließender +anschliessendes->anschließendes +anschliesst->anschließt +Anstoss->Anstoß +anvisiert->angekündigt,avisiert +Anwendund->Anwendung +Anwort->Antwort +Appartment*->Apartment*,Appartement* +aquirieren->akquirieren +Aquisition->Akquisition +archälogische->archäologische +archälogischen->archäologischen +Archeologe->Archäologe +Argentur*->Agentur* +Arikel->Artikel +arithmetrisch->arithmetisch +Artzt->Arzt +assozial->asozial +asymetrisch*->asymmetrisch* +Atacke->Attacke +atackieren->attackieren +atakieren->attackieren +Athleth*->Athlet* +Athmosphäre*->Atmosphäre* +athmosphärisch*->atmosphärisch* +Atrappe->Attrappe +attakieren->attackieren +Aufällig->Auffällig +Aufassung->Auffassung +Aufassungen->Auffassungen +auf dem ersten Blick->auf den ersten Blick +auf eigenem Wunsch->auf eigenen Wunsch,aus eigenem Wunsch +Aufenhalt->Aufenthalt +Aufname->Aufnahme +Auforderung->Aufforderung +aufrecht erhält->aufrechterhält +aufrecht erhalten->aufrechterhalten +aufrecht erhielt->aufrechterhielt +aufrecht zu erhalten->aufrechtzuerhalten +Aufsteig->Aufstieg +Auftieg->Aufstieg +auftretenen->auftretenden +auftretten->auftreten +Augenlied->Augenlid +augenommen->aufgenommen,ausgenommen +auml->Ä,ä +Ausage->Aussage +Ausagen->Aussagen +auschliesslich->ausschließlich +auschließlich->ausschließlich +auschliessliche->ausschließliche +auschliesslichen->ausschließlichen +Auseinadersetzung->Auseinandersetzung +Auseindersetzung->Auseinandersetzung +auserdem->außerdem +auserhalb->außerhalb +Ausgangpunkt->Ausgangspunkt +ausgeschalten->ausgeschaltet +Ausicht->Aussicht +Ausmass->Ausmaß +Ausprache->Aussprache +Auspruch->Ausspruch +ausschliessen->ausschließen +ausschliesslich->ausschließlich +ausschliesst->ausschließt +Ausschwitz->Auschwitz +aussen->außen +Aussenminister->Außenminister +ausser->außer +ausserdem->außerdem +äussere->äußere +äusseren->äußeren +äusserer->äußerer +äusseres->äußeres +aussergewöhnlich->außergewöhnlich +aussergewöhnlichen->außergewöhnlichen +ausserhalb->außerhalb +ausserirdisch->außerirdisch +ausserirdische->außerirdische +ausserirdischen->außerirdischen +äussern->äußern +ausserordentlich->außerordentlich +ausserordentliche->außerordentliche +ausserordentlichem->außerordentlichem +ausserordentlichen->außerordentlichen +ausserordentlicher->außerordentlicher +ausserordentliches->außerordentliches +äusserst->äußerst +äusserste->äußerste +äussersten->äußersten +äusserte->äußerte +äusserten->äußerten +Äusserung->Äußerung +Äusserungen->Äußerungen +aussschliesslich->ausschließlich +aussschließlich->ausschließlich +außschließlich->ausschließlich +Austattung->Ausstattung +Austellung->Ausstellung +Austellungen->Ausstellungen +Austerben->Aussterben +Auszeichung->Auszeichnung +Auszeichungen->Auszeichnungen +auszuschliessen->auszuschließen +Author des->Autor des +authorisieren->autorisieren +authorisiert->autorisiert +Authorisierung*->Autorisierung* +Authorität->Autorität +dem Autoren->dem Autor +des Autoren->des Autors +vom Autoren->vom Autor +Babies->Babys +bafand->befand +Balett->Ballett +bassierend->basierend +Batallion->Bataillon +Battaillon->Bataillon +Battallion->Bataillon +Bauerhof->Bauernhof +Bauerhöfe->Bauernhöfe +bedeudend->bedeutend +bedeudende->bedeutende +bedeudenden->bedeutenden +bedeudender->bedeutender +bedeudendes->bedeutendes +bedeudet->bedeutet +bedeudete->bedeutete +bedeutendeste->bedeutendste +bedeutenste->bedeutendste +bedeutensten->bedeutendsten +bedeutenster->bedeutendster +bedeutenstes->bedeutendstes +bedeutesten->bedeutendsten +Bedinung->Bedingung/Bedienung +Bedürfniss->Bedürfnis +beeinflußen->beeinflussen +Beeinflußung->Beeinflussung +beeinhalten->beinhalten +beeinhaltet->beinhaltet +befindet auf->befindet sich auf +befindet ein*->befindet sich ein* +befindet in->befindet sich in +begang->beging,begann +beherrbergt->beherbergt +beherschen->beherrschen +beherscht->beherrscht +beherschte->beherrschte +beidemale->beide Male +beim dem->bei dem,beim +beim der->bei der,beim,bei dem +beindrucken->beeindrucken +beinflussen->beeinflussen +beinflusst*->beeinflusst* +Beipiel*->Beispiel* +Beispeil*->Beispiel* +beispielswiese->beispielsweise +beispielweise->beispielsweise +Beitag->Beitrag +bekammen->bekamen +Bekenntniss->Bekenntnis +Benefitz->Benefiz +bennant->benannt +Bennenung->Benennung +Berechung->Berechnung +bereit gehalten->bereitgehalten +bereit gestellt->bereitgestellt +bereit hält->bereithält +bereit stand->bereitstand +bereit stehen->bereitstehen +bereit steht->bereitsteht +bereit stellt->bereitstellt +bereit zu halten->bereitzuhalten +bereit zu stellen->bereitzustellen +Berfung->Berufung +Berreich->Bereich +berücksichtig->berücksichtigt +berümt->berühmt +berümte->berühmte +besass->besaß +besassen->besaßen +besitzten->besitzen +Bespiel->Beispiel +Bestandsteil->Bestandteil +Bestandtteil->Bestandteil +bestbezahltest*->bestbezahlt* +bestimmmt->bestimmt +bestreitete->bestritt +Betreung->Betreuung +Betriebsystem*->Betriebssystem* +Bevökerung->Bevölkerung +Beweiß->Beweis +bezeichent->bezeichnet +bezeichet->bezeichnet +Bezeichung*->Bezeichnung* +Biograpfie->Biografie +bischen->bisschen +Bischofsitz->Bischofssitz +Bisquit->Biskuit +bloss->bloß +blosse->bloße +blossen->bloßen +blosser->bloßer +blosses->bloßes +an Board->an Bord +on Bord->an Bord +bombadieren->bombardieren +bombadiert->bombardiert +Bombadierung->Bombardierung +boolsch->boolesch +brilliant->brillant +britsch->britisch +britsche->britische +britschen->britischen +britscher->britischer +britsches->britisches +Bronzemedaillie*->Bronzemedaille* +Bronzemedallie*->Bronzemedaille* +Bügermeister->Bürgermeister +Bundesaussenminister->Bundesaußenminister +Bundesstrasse->Bundesstraße +Bundestaat*->Bundesstaat* +Bundestraße->Bundesstraße +Bundsandstein*->Buntsandstein* +byzantisch*->byzantinisch* +chinesiche->chinesische +chinesichen->chinesischen +chinesicher->chinesischer +Chirugie->Chirurgie +Chonik->Chronik +Chonist->Chronist +chonologisch->chronologisch +cirka->zirka,circa +dadruch->dadurch +daduch->dadurch +danaben->daneben +danch->danach +dannach->danach +deuten daraufhin->deuten darauf hin +deutet daraufhin->deutet darauf hin +weisen daraufhin->weisen darauf hin +weist daraufhin->weist darauf hin +darüberhinaus->darüber hinaus +daruf->darauf +darufhin->daraufhin +das es sich bei->dass es sich bei +das es sich um->dass es sich um +so das der->so dass der +so das die->so dass die +so das er->so dass er +so das sie->so dass sie +dass heißt->das heißt +dastellt->darstellt +dazu gehörige*->dazugehörige* +Debutalbum->Debütalbum +Definiton->Definition +definitv->definitiv +Defintion->Definition +deligiert->delegiert +dem selben->demselben +denoch->dennoch +den selben->denselben +derem->deren +der Niederlanden->der Niederlande,den Niederlanden +der selbe->derselbe +der selben->derselben +in der USA->in den USA +des des->des +des eines->eines,des,der eines,dem eines +des selben->desselben +dessem->dessen +desshalb->deshalb +desweiteren->des Weiteren +desweitern->des Weiteren +des Weitern->des Weiteren +detailiert*->detailliert* +detalliert->detailliert +dezeit->derzeit +Dezmber->Dezember +die selbe->dieselbe +die selben->dieselben +Differentation->Differentiation +Dikator->Diktator +Dikatur->Diktatur +Diphterie->Diphtherie +Diphtong->Diphthong +Dirgent->Dirigent +Discografie->Diskografie +Discographie->Diskographie +diskreminieren->diskriminieren +diskrimierend*->diskriminierend* +Diskrimierung*->Diskriminierung* +Diskusion->Diskussion +Disseration->Dissertation +Divison*->Division* +Divsion*->Division* +Diziplin*->Disziplin* +Dollmetscher->Dolmetscher +dort hin->dorthin +draufhin->daraufhin +draussen->draußen +Dreick->Dreieck +dreissig->dreißig +dreissiger->dreißiger +druch->durch +druchgeführt->durchgeführt +duch->durch +duchführen->durchführen +Duchführung->Durchführung +duchgeführt->durchgeführt +Duchschnitt->Durchschnitt +durch geführt->durchgeführt +Durchschlagkraft->Durchschlagskraft +Durchsetztung->Durchsetzung +durchstossen->durchstoßen +Durschnitt->Durchschnitt +durschnittlich->durchschnittlich +durschnittliche->durchschnittliche +durschnittlichen->durchschnittlichen +ebefalls->ebenfalls +eben dies->ebendies +eben diese->ebendiese +eben diesem->ebendiesem +eben diesen->ebendiesen +eben dieser->ebendieser +eben dieses->ebendieses +ebendso->ebenso +ebenfall->ebenfalls +ebenfals->ebenfalls +Editon->Edition +Edtion->Edition +einem eigenem->einem eigenen +ihrem eigenem->ihrem eigenen +seinem eigenem->seinem eigenen +eigenen sich->eignen sich +mit einen->mit einem +eines des->eines der +Einflüße->Einflüsse +Einfuss->Einfluss +einge->einige +eingen->einigen +eingentlich->eigentlich +einger->einiger +einges->einiges +eingesetz->eingesetzt +eingesetzen->eingesetzten +einigemal->einige Mal +einklich->eigentlich +Einordung->Einordnung +einschliessen->einschließen +einschliesslich->einschließlich +einschliesst->einschließt +einzelen->einzelne +einzigste->einzige +einzigster->einziger +einzigstes->einziges +ekklektizistisch->eklektizistisch +ekstasisch->ekstatisch +elekrisch->elektrisch +elekronisch->elektronisch +eleminieren->eliminieren +eleminiert->eliminiert +emigiert->emigriert +emigiriert->emigriert +Emmigrant->Emigrant +Emmigration->Emigration +emmigriert->emigriert +emprisch->empirisch +Emsemble->Ensemble +endeckt->entdeckt +endeckte->entdeckte +Endeckung*->Entdeckung* +enfernt->entfernt +enfernte->entfernte +Enfernung->Entfernung +Enfernungen->Entfernungen +Engeneering->Engineering +englsich->englisch +engültig->endgültig +enhält->enthält +enhalten->enthalten +Enscheidung->Entscheidung +enstand->entstand +enstanden->entstanden +enstehen->entstehen +ensteht->entsteht +Enstehung->Entstehung +entgegen gebracht*->entgegengebracht* +entgegen gesetzt*->entgegengesetzt* +entgegen kam->entgegenkam +entgegen nahm->entgegennahm +entgegen zu gehen->entgegenzugehen +entgegen zu kommen->entgegenzukommen +entgegen zu nehmen->entgegenzunehmen +entgegen zu schleudern->entgegenzuschleudern +entgegen zu setzen->entgegenzusetzen +entgegen zu stellen->entgegenzustellen +entgegen zu treten->entgegenzutreten +entgegen zu wirken->entgegenzuwirken +Entgeld->Entgelt +entgültig*->endgültig* +entlang führt*->entlangführt* +entlang geführt*->entlanggeführt* +entprechend->entsprechend +entprechende->entsprechende +entprechender->entsprechender +entsant->entsandt +entscheidene*->entscheidende* +entscheident->entscheidend +entschloß->entschloss +entspechen*->entsprechen* +entsprechene->entsprechende +entsprechenen->entsprechenden +entstandt->entstand +enwickelt->entwickelt +enwickelte->entwickelte +enwickelten->entwickelten +enwickelter->entwickelter +enwickeltes->entwickeltes +Enwicklung->Entwicklung +Enwicklungen->Entwicklungen +ereichen->erreichen +ereicht->erreicht +ereichte->erreichte +Ereignise->Ereignisse +Ereignisen->Ereignissen +Ereigniss->Ereignis +Erfog->Erfolg +erfogreich->erfolgreich +erfolgslos->erfolglos +erfolgsversprechend->erfolgversprechend +Erfurcht->Ehrfurcht +Ergebniss->Ergebnis +Erkentnis->Erkenntnis +Erkentnisse->Erkenntnisse +erklährt->erklärt +ermöglich->ermöglicht,ermöglichen +erorbert->erobert +errinnern->erinnern +errinnert->erinnert +errreichen->erreichen +errreicht->erreicht +errreichte->erreichte +errrichtet->errichtet +ersmals->erstmals +dem erstem->dem ersten +im erstem->im ersten +erzeilt->erzielt +erzeilte->erzielte +erziehlen->erzielen +erziehlt->erzielt +estisch->estnisch +Ettikett*->Etikett* +dem europäischem->dem europäischen +im europäischem->im europäischen +Examplar->Exemplar +examplarisch->exemplarisch +exellent->exzellent +exisitiert->existiert +Existens->Existenz +Expediton->Expedition +experimentiell->experimentell +Extase->Ekstase +Fahradtour->Fahrradtour +fälschlicher Weise->fälschlicherweise +familär*->familiär* +Famile->Familie +Familen*->Familien* +Famlie*->Familie* +Februrar->Februar +Feburar->Februar +fern geblieben->ferngeblieben +fern gehalten->ferngehalten +fern zu halten->fernzuhalten +Fersehen->Fernsehen +Ferseh*->Fernseh* +fertigestellt->fertiggestellt +festellen->feststellen +Festellung->Feststellung +fidet->findet +Fiedrich->Friedrich +Flagschiff->Flaggschiff +Flektion->Flexion +fliessen->fließen +fliesst->fließt +des Flughafen->des Flughafens +Fluß->Fluss +Flüße->Flüsse +fokusieren->fokussieren +fokusiert->fokussiert +Fokusierung->Fokussierung +Foschung->Forschung +Fotographie->Fotografie,Photographie +Fotographien->Fotografien,Photographien +fotographiert->fotografiert +franösisch*->französisch* +frantösisch*->französisch* +franzöisch*->französisch* +französich*->französisch* +dem französischem->dem französischen +einem französischem->einem französischen +im französischem->im französischen +Freidrich->Friedrich +frei gestellt->freigestellt +Freimauerei->Freimaurerei +Fremsprache->Fremdsprache +Friedenschluss->Friedensschluss +Friedich->Friedrich +Frima->Firma +fröhnen->frönen +Frühjar->Frühjahr +frühre->frühere +fuer->für +füher*->früher*,Führer* +Fuktion*->Funktion* +Funier*->Furnier* +für für->für +Fuss->Fuß +Fussball->Fußball +Fussballer->Fußballer +Fussballerin->Fußballerin +Fussballspieler->Fußballspieler +Fussballspielerin->Fußballspielerin +Fußballstadium->Fußballstadion +Fusse->Fuße +Füsse->Füße +Füst->Fürst +gabe es->gab es +Gallerie->Galerie +Gallerien->Galerien +Gallionsfigur->Galionsfigur +garnicht->gar nicht +Garnision->Garnison +Garnision*->Garnison* +Gebäde->Gebäude +Gebahren->Gebaren +gebähren->gebären +Gebaüde->Gebäude +Gebaude->Gebäude +Gebäuder->Gebäude +gebornen->geborenen +Gedult->Geduld +Gedänk*->Gedenk* +einem geeignetem->einem geeigneten +Gefäss->Gefäß +gegebenfalls->gegebenenfalls +gegen einander->gegeneinander +gegenüber gestellt->gegenübergestellt +gegn->gegen +gegnüber->gegenüber +gehöhren->gehören +gehöhrt*->gehört* +gekührt->gekürt +gelanden->geladen +gemäss->gemäß +gemeinsammen->gemeinsamen +gemeisam->gemeinsam +genant->genannt +genanten->genannten +Genaral*->General* +geniessen->genießen +gennant*->genannt* +gennannt*->genannt* +Gerneral*->General* +gesäht->gesät +gesammt->gesamt +gesammten->gesamten +gesammter->gesamter +Gesandschaft*->Gesandtschaft* +Geschichtschreiber->Geschichtsschreiber +Geschichtschreibung->Geschichtsschreibung +geschiet->geschieht +geschlosssen->geschlossen +gesetztlich->gesetzlich +Gesichtpunkt->Gesichtspunkt +gesponsort->gesponsert +gesteift->gestreift +gewan->gewann +gewissermassen->gewissermaßen +gewunken->gewinkt +Ghandi->Gandhi +giebt->gibt +Giessen->Gießen +gleichbleiben->gleich bleiben +gleich zu tun->gleichzutun +Gogle->Google +Goldmedaillie*->Goldmedaille* +Goldmedallie*->Goldmedaille* +Gothik->Gotik +gothisch->gotisch +Grabmahl->Grabmal +Gradwanderung->Gratwanderung +Graftschaft*->Grafschaft* +groesse->größe +groeße->größe +gröhlen->grölen +Grossaufgebot->Großaufgebot +Grossbritanien->Großbritannien +Großbritanien->Großbritannien +Grossbritannien->Großbritannien +Grossbrittanien->Großbritannien +Großbrittanien->Großbritannien +Grossbrittannien->Großbritannien +Großbrittannien->Großbritannien +grosse->große +grösse->größe +grossem->großem +einem großem->einem großen +grossen->großen +grossenteils->großenteils +größenteils->größtenteils +grosser->großer +grösser->größer +grössere->größere +grösserem->größerem +grösseren->größeren +grösserer->größerer +grösseres->größeres +grosses->großes +grösste->größte +Grossteil->Großteil +grossteils->großteils +grössten->größten +grösstenteils->größtenteils +grösster->größter +grösstes->größtes +Gründstück*->Grundstück* +einem grünem->einem grünen +Guerrillakampf->Guerillakampf +Guiness->Guinness +Guiseppe->Giuseppe +einem gutem->einem guten +Güterloh*->Gütersloh* +Häckchen->Häkchen +haetten->hätten +Handelschiff->Handelsschiff +Handies->Handys +hahnebüchen->hanebüchen +hattte->hatte,hatten +Haupstadt->Hauptstadt +haupsächlich->hauptsächlich +Haupstädte->Hauptstädte +des Haus->des Hauses +heiratetet->heiratet +heiss->heiß +heisser->heißer +heisst->heißt +heraus gebracht->herausgebracht +herausragenste->herausragendste +Herausvorderung->Herausforderung +herraus->heraus +herrausragend->herausragend +Herrrschaft->Herrschaft +Herrrscher->Herrscher +Herschaft->Herrschaft +Herscher->Herrscher +hervoragen->hervorragen +hervoragend->hervorragend +hervor gegangen*->hervorgegangen* +hervor ging->hervorging +hervorragenste->hervorragendste +Hierachie->Hierarchie +hierachisch->hierarchisch +hiess->hieß +hinaus gehende*->hinausgehende* +hingegegen->hingegen +Hintegrund->Hintergrund +Hintergund->Hintergrund +hinterliess->hinterließ +hinterliessen->hinterließen +hinweg täuschen->hinwegtäuschen +hinzu gefügt*->hinzugefügt* +hinzu gekommen*->hinzugekommen* +Hobbies->Hobbys +Hochaus->Hochhaus +Hochäuser->Hochhäuser +höchst gelegene*->höchstgelegene* +Hofffnung->Hoffnung +Hoffung->Hoffnung +höherere*->höhere* +höherwertigere*->höherwertige* +höhren->hören,höheren +höhrt->hört +Homage->Hommage +hunderste*->hundertste* +idendifiziert->identifiziert +idenfiziert->identifiziert +idiopatisch->idiopathisch +im besonderen Maße->in besonderem Maße +im Bezug auf->in Bezug auf +Imbus->Inbus +im dem->in dem,im +im den->in den,in dem,ihm den +im der->in der,im,ihm der +im deutschsprachigem->im deutschsprachigen +im einem->in einem +im großem->in großem,im großen +im großen Umfang->in großem Umfang +im hohen Maße->in hohem Maße +immernoch->immer noch +immmer->immer +Impendanz->Impedanz +im seinem->in seinem +im selbem->im selben +inbesondere->insbesondere +inclusive->inklusive +Independet->Independent +indeß->indes +individiuell->individuell +Industie->Industrie +Industriealisierung->Industrialisierung +in englisch->in Englisch +inerhalb->innerhalb +Infantrie->Infanterie +infiszieren->infizieren +in Folge->infolge +in Folge der->infolge der +in Folge des->infolge des +in Folge einer->infolge einer +in Folge eines->infolge eines +in Folge von->infolge von +in Folge dessen->infolgedessen,infolge dessen,in dessen Folge +Ingeneur->Ingenieur +ingesamt->insgesamt +Ingredenzien->Ingredienzien +Inhaltstoff->Inhaltsstoff +Initation->Initiation,Imitation +Initative->Initiative +Initator->Initiator +Initialie->Initiale +Initialien->Initialen +initieren->initiieren +initiert->initiiert +Inititative->Initiative +Iniziative->Initiative +in mitten->inmitten +inne gehabt->innegehabt +inne haben->innehaben +inne hat->innehat +inne hatte->innehatte +inne hatten->innehatten +Innenaustattung->Innenausstattung +innnerhalb->innerhalb +Insbruck->Innsbruck +in selben Jahr->im selben Jahr +insgeamt->insgesamt +insgesammt->insgesamt +Insitut->Institut +Insitution->Institution +in so fern->insofern +in sofern->insofern +instandgehalten->instand gehalten,in Stand gehalten +instandgesetzt->instand gesetzt,in Stand gesetzt +instandhalten->instand halten,in Stand halten +instandsetzen->instand setzen,in Stand setzen +instandzusetzen->instand zu setzen,in Stand zu setzen +Instituion->Institution +Instiut->Institut +Instiution->Institution +Instutition*->Institution* +inszinieren->inszenieren +Inszinierung->Inszenierung +integiert->integriert +intelektuell*->intellektuell* +intenational->international +intepretiert->interpretiert +Interese->Interesse +interesiert->interessiert +Intergration->Integration +intergriert->integriert +Internetpräsens->Internetpräsenz +interresiert->interessiert +Interresse->Interesse +interressiert->interessiert +Intiative->Initiative +intressiert->interessiert +Intrument*->Instrument* +Inverstor->Investor +in wie weit->inwieweit +in wieweit->inwieweit +inwischen->inzwischen +irgend ein->irgendein +irgend eine->irgendeine +irgend einem->irgendeinem +irgend einen->irgendeinen +irgend einer->irgendeiner +irgend eines->irgendeines +irgentwie->irgendwie +irrtümlicher Weise->irrtümlicherweise +ist meis->ist meist +ist meisten->ist meistens +italenisch->italienisch +italiensch->italienisch +italiensich->italienisch +Jägerbatallion->Jägerbataillon +Jahhundert->Jahrhundert +Jahhunderte->Jahrhunderte +Jahhunderts->Jahrhunderts +des Jahre->des Jahres +Jahrhudert->Jahrhundert +Jahrhunder->Jahrhundert +Jahrundert->Jahrhundert +Jahrunderte->Jahrhunderte +Jahrunderts->Jahrhunderts +Jahrzent->Jahrzehnt +Jahrzente->Jahrzehnte +Jahundert->Jahrhundert +Jahunderte->Jahrhunderte +Jahunderts->Jahrhunderts +Jäner->Jänner +Janur->Januar +Jarh->Jahr +Jarhundert->Jahrhundert +Jarhunderte->Jahrhunderte +Jarhunderts->Jahrhunderts +jdoch->jedoch +jedch->jedoch +jeoch->jedoch +jeodch->jedoch +jeweil->jeweils +jeweis->jeweils +Jounalist->Journalist +Jubiliäum->Jubiläum +Jungend*->Jugend* +Justitz->Justiz +Kabaret->Kabarett +Kaiserlautern->Kaiserslautern +Kandidad->Kandidat +Kanditat->Kandidat +Kappelle->Kapelle +Karierre->Karriere +Karrikaturist->Karikaturist +karrikieren->karikieren +Kasette*->Kassette* +kathegorisch->kategorisch +Kenntnise->Kenntnis +Kenntniss->Kenntnis +Kennzeichnug->Kennzeichnung +Kentnis->Kenntnis +Kentnisse->Kenntnisse +Kirchtum->Kirchturm +klassich->klassisch +klassiche->klassische +klassichen->klassischen +klassicher->klassischer +Klink->Klinik +des Kloster->des Klosters +km2->km² +kmh->km/h +Kofession*->Konfession* +Kollission*->Kollision* +Kollonade->Kolonnade +Komandant->Kommandant +Komandanten->Kommandanten +Komando->Kommando +Komandos->Kommandos +komerziell->kommerziell +Komissar->Kommissar +Komissariat->Kommissariat +komissarisch->kommissarisch +Komission->Kommission +komlett->komplett +Kommilitionen->Kommilitonen +Kommision->Kommission +Kommitee->Komitee +Kommittee->Komitee +kommmen->kommen +Kommunkation->Kommunikation +Kompentenz->Kompetenz +Könföderierte->Konföderierte +Konförderierte->Konföderierte +könglich->königlich +Köngreich->Königreich +Königsreich->Königreich +Königstum->Königtum +Konkurenz*->Konkurrenz* +konkurieren*->konkurrieren* +konkuriert*->konkurriert* +könnnen->können,Können +Konservationslexikon->Konversationslexikon +Kontak->Kontakt +konte->konnte +Kontigent*->Kontingent* +konventionnell->konventionell +korregieren->korrigieren +korregiert->korrigiert +Krankeit*->Krankheit* +Krankenaus->Krankenhaus +Kreuzug*->Kreuzung*,Kreuzzug* +Kriche->Kirche +Kriegschiff->Kriegsschiff +kummulieren->kumulieren +Kunsstoff*->Kunststoff* +Kunstaustellung*->Kunstausstellung* +Kunstoff->Kunststoff +Kunstoffe->Kunststoffe +Kurfüst*->Kurfürst* +kurzeitig*->kurzzeitig* +läd->lädt +Landesaustellung->Landesausstellung +Landesprache->Landessprache +Landwirschaft->Landwirtschaft +landwirschaftlich->landwirtschaftlich +langläufig->landläufig +Lapalie->Lappalie +Lassithi->Lasithi +läst->lässt +lateinsch->lateinisch +lateinsche->lateinische +lateinschen->lateinischen +lateinscher->lateinischer +lateinsches->lateinisches +Lebenstil->Lebensstil +Lebenweise->Lebensweise +legänder->legendär +Leibzig->Leipzig +Leichathlet*->Leichtathlet* +Leichnahm->Leichnam +letze->letzte +letzem->letztem +letzen->letzten +letzendlich->letztendlich +letzer->letzter +letzere->letztere +letzerem->letzterem +letzeren->letzteren +letzerer->letzterer +letzeres->letzteres +letzes->letztes +letzlich->letztlich +letztenendes->letzten Endes +Lexikas->Lexika +Liason->Liaison +liess->ließ +liesse->ließe +liessen->ließen +ließt->er/sie/es liest; ließ; fließt +Lilliputaner->Liliputaner +literaisch->literarisch +literatisch->literarisch +lizensieren->lizenzieren +lizensiert->lizenziert +lizensierte->lizenzierte +lizensiertem->lizenziertem +lizensierten->lizenzierten +lizensierter->lizenzierter +lizensiertes->lizenziertes +Lizensierung->Lizenzierung +los zu werden->loszuwerden +Louisana->Louisiana +Lousiana->Louisiana +Luwig->Ludwig +Lybien->Libyen +lybisch->libysch +lybische->libysche +lybischem->libyschem +lybischen->libyschen +lybischer->libyscher +lybisches->libysches +machmal->manchmal +Manhatan->Manhattan +Manhatta->Manhattan +Manhatten->Manhattan +Manhetten->Manhattan +Manschaft->Mannschaft +Manmschaft->Mannschaft +Mannhattan->Manhattan +Mannöver->Manöver +Mannschaf->Mannschaft +Mannschaftt->Mannschaft +Mannshcaft->Mannschaft +Mansardach->Mansarddach +Mansardendach->Mansarddach +Mansnchaften->Mannschaft +Manssarddach->Mansarddach +marrokanisch*->marokkanisch* +marrokkanisch*->marokkanisch* +Marrokko->Marokko +Marroko->Marokko +Marylin->meist Marilyn +Marytrium->Martyrium +Märtyrium->Martyrium +Maschiene->Maschine +Maschienen->Maschinen +mässig->mäßig +mässige->mäßige +mässigem->mäßigem +mässigen->mäßigen +mässiger->mäßiger +mässiges->mäßiges +Mass->Maß +Massgabe->Maßgabe +Massgaben->Maßgaben +massgebend->maßgebend +massgebende->maßgebende +massgebendem->maßgebendem +massgebenden->maßgebenden +massgebender->maßgebender +massgebendes->maßgebendes +massgeblich->maßgeblich +massgebliche->maßgebliche +massgeblichem->maßgeblichem +massgeblichen->maßgeblichen +massgeblicher->maßgeblicher +massgebliches->maßgebliches +masslos->maßlos +masslose->maßlose +masslosen->maßlosen +massloser->maßloser +massloses->maßloses +Massnahme->Maßnahme +Massnahmen->Maßnahmen +Matraze->Matratze +Matritze->Matrize,Matrix +Maximillian->meist Maximilian +Medailie->Medaille +Medaillie->Medaille +Medailliengewinner->Medaillengewinner +Medailliengewinnerin->Medaillengewinnerin +Medallie->Medaille +Medalliengewinner->Medaillengewinner +Medalliengewinnerin->Medaillengewinnerin +medizinsch->medizinisch +medizisch->medizinisch +medizische->medizinische +medizischem->medizinischem +medizischen->medizinischen +medizischer->medizinischer +medizisches->medizinisches +Meerespiegel->Meeresspiegel +Meeresspegel->Meeresspiegel +mehere->mehrere +meheren->mehreren +meherer->mehrerer +mehre->meist mehrere +mehren->gelegentlich mehreren +mehrer->häufig mehrerer,mehrere +mehrerere->mehrere +mehrtätige->mehrtägige +meisst->meist +meißt->meist +meißten->meisten +meißtens->meistens +meistbesuchtesten->meistbesuchten +meist gelesene*->meistgelesene* +meist gesehene*->meistgesehene* +meist gesuchte*->meistgesuchte* +meits->meist +mengemässig->mengenmäßig +mengenmässig->mengenmäßig +Mensche->Menschen +Menscheit->Menschheit +Menschens->Menschen +Meßgerät->Messgerät +Meßgeräte->Messgeräte +Messystem->Messsystem +Meßsystem->Messsystem +Metallegierung->Metalllegierung +Metereologe->Meteorologe +Metereologie->Meteorologie +metereologisch->meteorologisch +Meterologie->Meteorologie +meterologisch->meteorologisch +Mettal->Metall +mhd->mittelhochdeutsch +Micheal->meist Michael +Miglied->Mitglied +Milionen->Millionen +Militärdikatur->Militärdiktatur +Millarde->Milliarde +Millarden*->Milliarden* +Millenium->Millennium +Millione->Millionen +Millitär->Militär +millitärisch->militärisch +eine Millionen->eine Million +Millon->Million +Millonen->Millionen +Miltär->Militär +miltärisch->militärisch +Miltitär->Militär +miltitärisch->militärisch +minimalste->minimale +minimalster->minimaler +minimalstes->minimales +Ministerpäsident->Ministerpräsident +mit einander->miteinander +Mitgleid->Mitglied +mitlerweile->mittlerweile +mittlerweilen->mittlerweile +Mitlgiled->Mitglied +Mitlied->Mitglied +mit samt->mitsamt +Mittelater->Mittelalter +mittelaterlich->mittelalterlich +mittelständige->mittelständische +mittelständigen->mittelständischen +mittelständiger->mittelständischer +mittelständiges->mittelständisches +Mitteralter->Mittelalter +mitteralterlich->mittelalterlich +Mitterand->Mitterrand +Mittglied->Mitglied +Mittschnitt->Mitschnitt +mnachmal->manchmal +Mobiletelefon->Mobiltelefon +moeglich->möglich +moegliche->mögliche +moeglichen->möglichen +moeglicher->möglicher +moegliches->mögliches +möglicht->möglich,möglichst +mordern->modern +morderne->moderne +mordernen->modernen +morderner->moderner +mordernes->modernes +morgentlich*->morgendlich* +morgends->morgens +muß->muss +mußte->musste +mußten->mussten +Museeum->Museum +mutmasslich->mutmaßlich +mutmassliche->mutmaßliche +mutmasslichem->mutmaßlichem +mutmasslichen->mutmaßlichen +mutmasslicher->mutmaßlicher +mutmassliches->mutmaßliches +nachdem Krieg->nach dem Krieg +Nachkommens->Nachkommen +nächst gelegene*->nächstgelegene* +nächst größere*->nächstgrößere* +nächst höhere*->nächsthöhere* +nächst kleinere*->nächstkleinere* +nächst niedrigere*->nächstniedrigere* +nächst tiefere*->nächsttiefere* +Nahaufname->Nahaufnahme +nahegelegenste->nächstgelegene +naheste->nächste +nahesten->nächsten +nähmlich->nämlich +namenlich->namentlich +namenslos->namenlos +des Names->des Namens +Namne->Namen +narzistisch->narzisstisch +Natiomnal*->National* +Nazionalsoz*->Nationalsoz* +nciht->nicht +Nervösität->Nervosität +nich->nicht +die Niederlanden->die Niederlande +niedersächisch->niedersächsisch +niedersächsiche->niedersächsische +niedersächsichen->niedersächsischen +niedrieg->niedrig +Niesche->Nische +nihct->nicht +nix->nichts +nocheinmal->noch einmal +nordeutsch->norddeutsch +Nordeutschland->Norddeutschland +nordlich->nördlich +nördöstlich*->nordöstlich* +nördwestlich*->nordwestlich* +normanisch*->normannisch* +notwenig*->notwendig* +numehr->nunmehr +Numerus Clausus->Numerus clausus +objekiv->objektiv +obrige->obige +obrigen->obigen +obriger->obiger +offizell*->offiziell* +Offizer->Offizier +offiziel->offiziell +offiziele*->offizielle* +offziell->offiziell +offzielle->offizielle +ofiziell->offiziell +Olympiamedaillie*->Olympiamedaille* +Olympiamedallie*->Olympiamedaille* +Olympische Bronzemedaille->olympische Bronzemedaille +Olympische Goldmedaille->olympische Goldmedaille +Olympische Silbermedaille->olympische Silbermedaille +Omlett->Omelett +optimalste->optimale +optimalster->optimaler +optimalstes->optimales +Ordnug->Ordnung +Ordung->Ordnung +Orgeon->Oregon +Organistion->Organisation +Organsiation->Organisation +organsich->organisch +Organsisation->Organisation +organisert->organisiert +orginal->original +orginale->originale +orginalen->originalen +orginell->originell +orignal->original +orignell->originell +Orsteil->Ortsteil +Orsteile->Ortsteile +Ortteil->Ortsteil +ouml->Ö/ö +Overtüre->Ouvertüre +öffenlich->öffentlich +Ökö->Öko +Östereich->Österreich +Österrreich->Österreich +Österreisch->Österreich +östereichisch*->österreichisch* +österreichich->österreichisch +Packet->Paket +palästinesisch->palästinensisch +Palete->Palette +Paleten->Paletten +Pallete->Palette +Palleten->Paletten +Pallette->Palette +Palletten->Paletten +paralell->parallel +Parcour->Parcours +parralel->parallel +parrallel->parallel +Päsident->Präsident +patroullieren->patrouillieren +patroulliert->patrouilliert +Pavillion->Pavillon +Peleponnes*->Peloponnes* +Pepperoni->Peperoni +Perlmut->Perlmutt +perönlich*->persönlich* +persöhnlich*->persönlich* +Persönlichleit->Persönlichkeit +Philantrop*->Philanthrop* +Philipinen->Philippinen +Philipinisch->Philippinisch +philipinischer->philippinischer +Philippienen->Philippinen +Philisoph->Philosoph +Philisophie->Philosophie +philisophisch->philosophisch +Phillipinen->Philippinen +Philosopie->Philosophie +Philosph->Philosoph +Philosphie->Philosophie +philosphisch->philosophisch +Philsophie->Philosophie +philsophisch->philosophisch +photografiert->fotografiert,photographiert +piktoresk->pittoresk +Planze->Pflanze +Planzen*->Pflanzen* +Politk->Politik +Politker->Politiker +politsch->politisch +politsche->politische +politschen->politischen +politscher->politischer +politsches->politisches +poltisch*->politisch* +portugiesich*->portugiesisch* +Positon->Position +postiv->positiv +prinzipell*->prinzipiell* +Prinzipen->Prinzipien +Priveleg->Privileg +priveligiert->privilegiert +Priviligien*->Privilegien* +priviligiert->privilegiert +Progrom->Pogrom +projezieren->projizieren +projeziert->projiziert +Prophezeihung*->Prophezeiung* +Provinzhaupstadt->Provinzhauptstadt +Prozeße->Prozesse +Psychatrie->Psychiatrie +pysikalisch->physikalisch +Quattrologie->Tetralogie +Ralley->Rallye +Ralleyfahrer->Rallyefahrer +rechlich->rechtlich +Rechtsprache->Rechtssprache +Rechtspruch->Rechtsspruch +Rechtssprechung->Rechtsprechung +Rechtstaat->Rechtsstaat +rechtstaatlich->rechtsstaatlich +rechtwinklich->rechtwinklig +rechtwinkling->rechtwinklig +rechzeitig->rechtzeitig +Reeling->Reling +Reflektion->Reflexion +regelmässig->regelmäßig +regelmässige->regelmäßige +regelmässigen->regelmäßigen +regelmässiger->regelmäßiger +regelmässiges->regelmäßiges +Reichtags*->Reichstags* +Relgion*->Religion* +relgiös->religiös +Religiösität->Religiosität +Religon->Religion +Religonen->Religionen +religös->religiös +religösen->religiösen +Relion->Religion +reliösen->religiösen +Remineszenz->Reminiszenz +Rendevous->Rendezvous +Rennaisance->Renaissance +Rennaissance->Renaissance +des Rennes->des Rennens +Renomee->Renommee +renomiert->renommiert +Renomme->Renommee +repäsentieren->repräsentieren +repäsentiert->repräsentiert +Reperatur->Reparatur +Resourcen->Ressourcen +Rhytmen->Rhythmen +rhytmisch->rhythmisch +rhytmische->rhythmische +Rhytmus->Rhythmus +Richtline->Richtlinie +Richung->Richtung +rigde->ridge +rihgt->right +Riskio->Risiko +Risko->Risiko +Rossevelt->Roosevelt +Rückgrad->Rückgrat +Rückrad->Rückgrat +Rückrat->Rückgrat +russich->russisch +russiche->russische +russichen->russischen +russicher->russischer +russsich->russisch +russsisch->russisch +russsische->russische +russsischen->russischen +Rythmen->Rhythmen +rythmisch->rhythmisch +rythmische->rhythmische +Rythmus->Rhythmus +sächisch->sächsisch +sächsich->sächsisch +sächsiche->sächsische +sächsichen->sächsischen +Santiago de Compostella->Santiago de Compostela +Sarkopharg->Sarkophag +sassen->saßen +satzungsgemäss->satzungsgemäß +S-Bahnstation->S-Bahn-Station +schafte->schaffte +Schaupiel*->Schauspiel* +Scheiz->Schweiz +schillernste*->schillerndste* +schliessen->schließen +schliesslich->schließlich +schliesst->schließt +Schrifsteller*->Schriftsteller* +Schriftseller->Schriftsteller +schweizer->Schweizer +Seeman->Seemann +seemänisch->seemännisch +sehenwert->sehenswert +Sehenwürdigkeit->Sehenswürdigkeit +Sehenwürdigkeiten->Sehenswürdigkeiten +seit dem->seitdem +seit dem die->seitdem die +seit dem ein->seitdem ein +seit dem hat->seitdem hat +seit dem ist->seitdem ist +seit dem war->seitdem war +seperat->separat +seperate->separate +seperatem->separatem +seperaten->separaten +Seperation->Separation +Seperatist*->Separatist* +Septmber->September +Septmeber->September +Seriösität->Seriosität +sicher gestellt->sichergestellt +sich er sich->er sich +sicher stellen->sicherstellen +sicher stellt*->sicherstellt* +sicher zu stellen->sicherzustellen +Silbermedaillie*->Silbermedaille* +Silbermedallie*->Silbermedaille* +Siluette->Silhouette +sinvoll->sinnvoll +Situtation->Situation +Skagerak->Skagerrak +sobald wie möglich->so bald wie möglich +sobald als möglich->so bald als möglich +sodas->sodass,so dass +sodaß->sodass,so dass +sogenante->sogenannte +sogenanten->sogenannten +sonder->sondern +Souveranität->Souveränität +soweit wie->so weit wie +Sowietunion->Sowjetunion +spezialiseren->spezialisieren +spezialisert*->spezialisiert* +speziel->speziell +sponsorte->sponserte +Spritualität->Spiritualität +sprituell->spirituell +Staatstreich->Staatsstreich +Stadbild->Stadtbild +Staddteil->Stadtteil +Stadteil->Stadtteil +Stadteile->Stadtteile +Stadteilen->Stadtteilen +Stadteils->Stadtteils +Standart->Standard +Standarts->Standards +statt fand->stattfand +statt finden->stattfinden +statt findet->stattfindet +statt gegeben->stattgegeben +Stehgreif->Stegreif +stellverteten->stellvertreten +Stellverteter->Stellvertreter +stiess->stieß +Stimmulation->Stimulation +Stömung->Strömung +Stoss->Stoß +stossen->stoßen +Stossfänger->Stoßfänger +Stossstange->Stoßstange +stösst->stößt +Strasse->Straße +strukur*->struktur* +subsummieren->subsumieren +subsummiert->subsumiert +sumieren->summieren +sumiert->summiert +svw->svw., bzw., so viel wie +symetrisch->symmetrisch +symphatisiert->sympathisiert +Synomym->Synonym +Synomyn->Synonym +Syphon->Siphon +Sytem->System +Sytematik->Systematik +sytematisch->systematisch +Tag- und Nachtgleiche->Tagundnachtgleiche,Tag-und-Nacht-Gleiche +Taiwanese->Taiwaner +Taiwanesen->Taiwaner +tasächlich->tatsächlich +tatächlich->tatsächlich +Teakwondo->Taekwondo +teiweise->teilweise +Temparatur->Temperatur +tendentiell*->tendenziell* +Terasse->Terrasse +Terassen->Terrassen +Terrabyte->Terabyte +Tocher->Tochter +Tolleranz->Toleranz +tollerieren->tolerieren +tolleriert->toleriert +Tradion*->Tradition* +traditionel->traditionell +Traditon*->Tradition* +Tradtion*->Tradition* +Trainig*->Training* +Transskript->Transkript +Triologie->Trilogie +Triumpf->Triumph +trotzdessen->trotzdem +trozdem->trotzdem +Tryptichon->Triptychon +Triptichon->Triptychon +Tryptychon->Triptychon +Tunier->Turnier +Turismus->Tourismus +Turist->Tourist +U-Bahnnetz->U-Bahn-Netz +U-Bahnstation->U-Bahn-Station +U-Bahntunnel->U-Bahn-Tunnel +überarbeitetet->überarbeitet +überlegende->überlegene +überlegenden->überlegenen +überlicherweise->üblicherweise +Überwachungstaat->Überwachungsstaat +U-Bootkrieg->U-Boot-Krieg +umbennen->umbenennen +umbennenen->umbenennen +umbennennen->umbenennen +umbennant->umbenannt +Umbennennung->Umbenennung +Umbennenung->Umbenennung +Umbennung->Umbenennung,Umnennung +umd->und,um +Umgangsprache->Umgangssprache +umgangsprachlich->umgangssprachlich +umgangsprachliche->umgangssprachliche +umgangsprachlicher->umgangssprachlicher +umgenannt->umbenannt +umittelbar->unmittelbar +umstrittend*->umstritten* +umzubennen->umzubenennen,umzunennen +Unabhängikeit->Unabhängigkeit +Unabhängkeit->Unabhängigkeit +unabhänig->unabhängig +Unabhänigkeit->Unabhängigkeit +unauthorisiert->unautorisiert +unbenannt wurde->umbenannt wurde +und sowie->und/sowie +und und->und +Unfang->Umfang +ungekehrt->umgekehrt +Univerität->Universität +Universiät->Universität +Universtät->Universität +Universtität->Universität +unsymetrisch->unsymmetrisch +unteranderem->unter anderem +Untergund->Untergrund +Untericht->Unterricht +unterichtet->unterrichtet +unteriridisch->unterirdisch +Unternehmes*->Unternehmens* +Unternehms*->Unternehmens* +unterstüzt->unterstützt +Unterstüzung->Unterstützung +Unversität->Universität +unwegbar->unwägbar,unwegsam +Urprung->Ursprung +urprünglich*->ursprünglich* +ürsprünglich*->ursprünglich* +urspünglich*->ursprünglich* +Ursurpator->Usurpator +us-amerikanischen->US-amerikanischen,amerikanischen +usprünglich*->ursprünglich* +variert->variiert +varrieren->variieren +Vehrkehr*->Verkehr* +Vekehr*->Verkehr* +venezuelanisch*->venezolanisch* +venizianisch*->venezianisch* +verabeitet->verarbeitet +Verabeitung*->Verarbeitung* +veraltert*->veraltet* +verantworlich*->verantwortlich* +Veranwtortung->Verantwortung +Verbauch*->Verbrauch* +verbeitet*->verbreitet* +Verbeitung*->Verbreitung* +verbreiteste*->verbreitetste* +verbreiteteste*->verbreitetste* +vereingt*->vereinigt* +vereiningt->vereinigt +vergleichweise->vergleichsweise +vergößert*->vergrößert* +Vergößerung->Vergrößerung +vergrössern->vergrößern +vergrössert->vergrößert +vergrösserte->vergrößerte +vergrösserten->vergrößerten +vergrösserter->vergrößerter +Vergrösserung->Vergrößerung +verhaeltnismaessig->verhältnismäßig +verhältnismässig->verhältnismäßig +verheiratetet->verheiratet +verkündetet->verkündet +verliess->verließ +veröffendlicht->veröffentlicht +Veröffendlichung->Veröffentlichung +veröffentlich->veröffentlicht +verplichtet->verpflichtet +verschiedende*->verschiedene* +verschiedendste*->verschiedenste* +Verschleiss->Verschleiß +verschohnen->verschonen +verspühren->verspüren +verspührt->verspürt +Verständis->Verständnis +Vertäge->Verträge +vertaglich->vertraglich +Verteidung->Verteidigung +Verwaltungsitz->Verwaltungssitz +Verwandschaft->Verwandtschaft +verwandschaftlich*->verwandtschaftlich* +Vetrag->Vertrag +Veträge->Verträge +vetraglich->vertraglich +vetraut->vertraut +vieleicht->vielleicht +vom dem->von dem,vom +vom der->von der,vom,der +von einander->voneinander +getrennt von einander->getrennt voneinander +unabhängig von einander->unabhängig voneinander +von einander entfernt->voneinander entfernt +von einander getrennt->voneinander getrennt +von einander unterscheiden->voneinander unterscheiden +von einander unterschieden->voneinander unterschieden +von einander zu->voneinander zu +von nöten->vonnöten,z. B. vonnöten sein +von statten->vonstatten +von von->von +vorallem->vor allem +vorallen->vor allem +vor allen in->vor allem in +voran bringen->voranbringen +Vorang->Vorrang +voran gegangen*->vorangegangen* +vorangig->vorrangig +voran zu bringen->voranzubringen +voran zu treiben->voranzutreiben +Vorausetzung->Voraussetzung +Vorausetzungen->Voraussetzungen +voraus gegangen*->vorausgegangen* +vorausichtlich->voraussichtlich +Vorfahrens->Vorfahren +Vorgesetze->Vorgesetzte +vorkommene->vorkommende +Vormachtsstellung->Vormachtstellung +vorranging->vorrangig +vorraus*->voraus* +vorrüber*->vorüber* +vorweg genommen*->vorweggenommen* +Wachholder->Wacholder +wachesen->wachsen +währe->wäre +währendessen->währenddessen +wahr genommen->wahrgenommen +Walfahrer->Wallfahrer +Walfahrt->Wallfahrt +Walfahrtskirche->Wallfahrtskirche +Walfahrtsort->Wallfahrtsort +wärend->während +Warheit->Wahrheit +warscheinlich->wahrscheinlich +Webblog*->Weblog* +Webpräsens->Webpräsenz +Wehrmutstropfen->Wermutstropfen +weiss->weiß +Weisswein->Weißwein +einem weiterem->einem weiteren +im weiterem->im weiteren +weiterere->weitere +weitereren->weiteren +weitesgehend->weitestgehend +Weltanschaung->Weltanschauung +Wepräsenz->Webpräsenz +wesendlich->wesentlich +im Wesentlichem->im Wesentlichen +wichig->wichtig +wichtigeste->wichtigste +Widerstandkämpfer->Widerstandskämpfer +widerum->wiederum +Wiedererichtung->Wiedererrichtung +wieder kehrend*->wiederkehrend* +Wiedersacher->Widersacher +wiedersetzen->widersetzen +wiederspiegeln->widerspiegeln +wiederspiegelt->widerspiegelt +wiederspiegelte->widerspiegelte +wiederspiegelten->widerspiegelten +wiedersprechen->widersprechen +wiedersprechend->widersprechend +wiedersprechende->widersprechende +Wiederspruch->Widerspruch +Wiedersprüche->Widersprüche +wiedersprüchlich->widersprüchlich +wiedersprüchliche->widersprüchliche +wiedersprüchlichen->widersprüchlichen +Wiederstand->Widerstand +Wiederstandskampf->Widerstandskampf +wiederstehen->widerstehen +wiederzuspiegeln->widerzuspiegeln +Wihelm->Wilhelm +Wikipeda->Wikipedia +Wikpedia->Wikipedia +wirtschaflich->wirtschaftlich +wissenschaflich->wissenschaftlich +wissenschafltich->wissenschaftlich +Wissentschaft->Wissenschaft +wissentschaftlich->wissenschaftlich +Wochende->Wochenende +woduch->wodurch +Wolfang->Wolfgang +wurd->wurde +wurde wurde->wurde +Würtemberg->Württemberg +würtembergische->württembergische +zahreich->zahlreich +zeimlich->ziemlich +der Zeit seines Lebens->der zeit seines Lebens +er Zeit seines Lebens->er zeit seines Lebens +sie Zeit ihres Lebens->sie zeit ihres Lebens +war Zeit ihres Lebens->war zeit ihres Lebens +war Zeit seines Lebens->war zeit seines Lebens +zeitgenösisch->zeitgenössisch +zeitgenössich->zeitgenössisch +zerissen->zerrissen +Ziffernblatt->Zifferblatt +Zohne->Zone +zu allererst->zuallererst +zuammen->zusammen +Zuammenhang->Zusammenhang +zueigen->zu eigen +zuende->zu Ende +zu Folge->zufolge,zur Folge +zufrieden geben->zufriedengeben +zugrundeliegen->zugrunde liegen,zu Grunde liegen +zugrundeliegt->zugrunde liegt,zu Grunde liegt +zu letzt->zuletzt +zum dem->zu dem,zum +zum den->zu den,zu dem,zum +zum erstem->zum ersten +zumindestens->zumindest +in zunehmenden Maße->in zunehmendem Maße +mit zunehmenden Alter->mit zunehmendem Alter +zunehmends->zunehmend +zur der->zu der,zur +zur dieser->zu dieser +zur einem->zu einem +zur einer->zu einer,zur +zur ihr->zu ihr +zur ihrem->zu ihrem +zur ihren->zu ihren +zur ihrer->zu ihrer,zur +zur seiner->zu seiner,zur +zurecht->zurecht +zurecht finden->zurechtfinden +zurecht kam->zurechtkam +zurecht kommen->zurechtkommen +zurecht kommt->zurechtkommt +zurecht zu finden->zurechtzufinden +zurecht zu kommen->zurechtzukommen +zurfolge->zur Folge,zufolge +zurück ge*->zurückge* +zurück gegangen*->zurückgegangen* +zurück blicken->zurückblicken +zurück erobert->zurückerobert +zurück ging->zurückging +zurück greif*->zurückgreif* +zurück kehrte->zurückkehrte +zurück trat->zurücktrat +zurück verfolgen->zurückverfolgen +zurück verfolgt->zurückverfolgt +zurück ziehen->zurückziehen +zurück zog->zurückzog +zurück zu bekommen->zurückzubekommen +zurück zu bringen->zurückzubringen +zurück zu drängen->zurückzudrängen +zurück zu erobern->zurückzuerobern +zurück zu führen->zurückzuführen +zurück zuführen->zurückzuführen +zurück zu gewinnen->zurückzugewinnen +zurück zu holen->zurückzuholen +zurück zu kehren->zurückzukehren +zurück zu ziehen->zurückzuziehen +zusamen->zusammen +Zusamenhang->Zusammenhang +zusammen arbeiten->zusammenarbeiten +zusammen arbeitete->zusammenarbeitete +zusammen arbeiteten->zusammenarbeiteten +zusammen gearbeitet->zusammengearbeitet +zusammen gefasst->zusammengefasst +zusammen geschlossen*->zusammengeschlossen* +zusammen schloss*->zusammenschloss* +zusammen zu arbeiten->zusammenzuarbeiten +zusammen zu schließen->zusammenzuschließen +zusammmen->zusammen +zusätlich->zusätzlich +zusehens->zusehends +zustandegekommen->zustande gekommen,zu Stande gekommen +zustandekam->zustande kam,zu Stande kam +zustandekommt->zustande kommt,zu Stande kommt +zustätzlich->zusätzlich +zu teil werden->zuteilwerden +zu teil wird->zuteilwird +zu teil wurde->zuteilwurde +zu zu->zu,zuzu +zu zuordnen*->zuzuordnen* +zu zuwenden*->zuzuwenden* +Zweidrittel->zwei Drittel +Zweidrittel-Mehrheit->Zweidrittelmehrheit +Zweiliga*->Zweitliga* +dem zweitem->dem zweiten +im zweitem->im zweiten diff --git a/files/typos-en.txt b/files/typos/typos-en.txt index 85c72ce..74fbd08 100644 --- a/files/typos-en.txt +++ b/files/typos/typos-en.txt @@ -3,6 +3,7 @@ andriod->android # The remainder of this file contains misspellings from # http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines +# plus some post-processing to fix invalid entries, remove duplicates, etc. # # The content is available under the # "Creative Commons Attribution-ShareAlike License" @@ -2774,8 +2775,7 @@ modle->model moent->moment moeny->money mohammedans->muslims -moil->mohel -moil->soil +moil->mohel,soil moleclues->molecules momento->memento monestaries->monasteries @@ -3543,8 +3543,7 @@ refereneced->referenced refereneces->references referiang->referring refering->referring -refernce->reference -refernce->references +refernce->reference,references refernces->references referrence->reference referrences->references diff --git a/files/typos/typos-es.txt b/files/typos/typos-es.txt new file mode 100644 index 0000000..af2bccb --- /dev/null +++ b/files/typos/typos-es.txt @@ -0,0 +1,733 @@ +# This file contains a number of common Spanish typos: +andriod->android + +# The remainder of this file contains misspellings from +# http://es.wikipedia.org/wiki/Wikipedia:Lista_de_errores_ortogr%C3%A1ficos_comunes/M%C3%A1quinas +# plus some post-processing to fix invalid entries, remove duplicates, etc. +# +# The content is available under the +# "Creative Commons Attribution-ShareAlike License" +# http://creativecommons.org/licenses/by-sa/3.0/ +# +# THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +# COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +# COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +# AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. +# +# BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +# TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +# BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +# CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +# CONDITIONS. +# +# *1. Definitions* +# +# 1. *"Adaptation"* means a work based upon the Work, or upon the Work +# and other pre-existing works, such as a translation, adaptation, +# derivative work, arrangement of music or other alterations of a +# literary or artistic work, or phonogram or performance and includes +# cinematographic adaptations or any other form in which the Work may +# be recast, transformed, or adapted including in any form +# recognizably derived from the original, except that a work that +# constitutes a Collection will not be considered an Adaptation for +# the purpose of this License. For the avoidance of doubt, where the +# Work is a musical work, performance or phonogram, the +# synchronization of the Work in timed-relation with a moving image +# ("synching") will be considered an Adaptation for the purpose of +# this License. +# 2. *"Collection"* means a collection of literary or artistic works, +# such as encyclopedias and anthologies, or performances, phonograms +# or broadcasts, or other works or subject matter other than works +# listed in Section 1(f) below, which, by reason of the selection and +# arrangement of their contents, constitute intellectual creations, in +# which the Work is included in its entirety in unmodified form along +# with one or more other contributions, each constituting separate and +# independent works in themselves, which together are assembled into a +# collective whole. A work that constitutes a Collection will not be +# considered an Adaptation (as defined below) for the purposes of this +# License. +# 3. *"Creative Commons Compatible License"* means a license that is +# listed at http://creativecommons.org/compatiblelicenses that has +# been approved by Creative Commons as being essentially equivalent to +# this License, including, at a minimum, because that license: (i) +# contains terms that have the same purpose, meaning and effect as the +# License Elements of this License; and, (ii) explicitly permits the +# relicensing of adaptations of works made available under that +# license under this License or a Creative Commons jurisdiction +# license with the same License Elements as this License. +# 4. *"Distribute"* means to make available to the public the original +# and copies of the Work or Adaptation, as appropriate, through sale +# or other transfer of ownership. +# 5. *"License Elements"* means the following high-level license +# attributes as selected by Licensor and indicated in the title of +# this License: Attribution, ShareAlike. +# 6. *"Licensor"* means the individual, individuals, entity or entities +# that offer(s) the Work under the terms of this License. +# 7. *"Original Author"* means, in the case of a literary or artistic +# work, the individual, individuals, entity or entities who created +# the Work or if no individual or entity can be identified, the +# publisher; and in addition (i) in the case of a performance the +# actors, singers, musicians, dancers, and other persons who act, +# sing, deliver, declaim, play in, interpret or otherwise perform +# literary or artistic works or expressions of folklore; (ii) in the +# case of a phonogram the producer being the person or legal entity +# who first fixes the sounds of a performance or other sounds; and, +# (iii) in the case of broadcasts, the organization that transmits the +# broadcast. +# 8. *"Work"* means the literary and/or artistic work offered under the +# terms of this License including without limitation any production in +# the literary, scientific and artistic domain, whatever may be the +# mode or form of its expression including digital form, such as a +# book, pamphlet and other writing; a lecture, address, sermon or +# other work of the same nature; a dramatic or dramatico-musical work; +# a choreographic work or entertainment in dumb show; a musical +# composition with or without words; a cinematographic work to which +# are assimilated works expressed by a process analogous to +# cinematography; a work of drawing, painting, architecture, +# sculpture, engraving or lithography; a photographic work to which +# are assimilated works expressed by a process analogous to +# photography; a work of applied art; an illustration, map, plan, +# sketch or three-dimensional work relative to geography, topography, +# architecture or science; a performance; a broadcast; a phonogram; a +# compilation of data to the extent it is protected as a copyrightable +# work; or a work performed by a variety or circus performer to the +# extent it is not otherwise considered a literary or artistic work. +# 9. *"You"* means an individual or entity exercising rights under this +# License who has not previously violated the terms of this License +# with respect to the Work, or who has received express permission +# from the Licensor to exercise rights under this License despite a +# previous violation. +# 10. *"Publicly Perform"* means to perform public recitations of the Work +# and to communicate to the public those public recitations, by any +# means or process, including by wire or wireless means or public +# digital performances; to make available to the public Works in such +# a way that members of the public may access these Works from a place +# and at a place individually chosen by them; to perform the Work to +# the public by any means or process and the communication to the +# public of the performances of the Work, including by public digital +# performance; to broadcast and rebroadcast the Work by any means +# including signs, sounds or images. +# 11. *"Reproduce"* means to make copies of the Work by any means +# including without limitation by sound or visual recordings and the +# right of fixation and reproducing fixations of the Work, including +# storage of a protected performance or phonogram in digital form or +# other electronic medium. +# +# *2. Fair Dealing Rights.* Nothing in this License is intended to reduce, +# limit, or restrict any uses free from copyright or rights arising from +# limitations or exceptions that are provided for in connection with the +# copyright protection under copyright law or other applicable laws. +# +# *3. License Grant.* Subject to the terms and conditions of this License, +# Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +# perpetual (for the duration of the applicable copyright) license to +# exercise the rights in the Work as stated below: +# +# 1. to Reproduce the Work, to incorporate the Work into one or more +# Collections, and to Reproduce the Work as incorporated in the +# Collections; +# 2. to create and Reproduce Adaptations provided that any such +# Adaptation, including any translation in any medium, takes +# reasonable steps to clearly label, demarcate or otherwise identify +# that changes were made to the original Work. For example, a +# translation could be marked "The original work was translated from +# English to Spanish," or a modification could indicate "The original +# work has been modified."; +# 3. to Distribute and Publicly Perform the Work including as +# incorporated in Collections; and, +# 4. to Distribute and Publicly Perform Adaptations. +# 5. +# +# For the avoidance of doubt: +# +# 1. *Non-waivable Compulsory License Schemes*. In those +# jurisdictions in which the right to collect royalties through +# any statutory or compulsory licensing scheme cannot be waived, +# the Licensor reserves the exclusive right to collect such +# royalties for any exercise by You of the rights granted under +# this License; +# 2. *Waivable Compulsory License Schemes*. In those jurisdictions in +# which the right to collect royalties through any statutory or +# compulsory licensing scheme can be waived, the Licensor waives +# the exclusive right to collect such royalties for any exercise +# by You of the rights granted under this License; and, +# 3. *Voluntary License Schemes*. The Licensor waives the right to +# collect royalties, whether individually or, in the event that +# the Licensor is a member of a collecting society that +# administers voluntary licensing schemes, via that society, from +# any exercise by You of the rights granted under this License. +# +# The above rights may be exercised in all media and formats whether now +# known or hereafter devised. The above rights include the right to make +# such modifications as are technically necessary to exercise the rights +# in other media and formats. Subject to Section 8(f), all rights not +# expressly granted by Licensor are hereby reserved. +# +# *4. Restrictions.* The license granted in Section 3 above is expressly +# made subject to and limited by the following restrictions: +# +# 1. You may Distribute or Publicly Perform the Work only under the terms +# of this License. You must include a copy of, or the Uniform Resource +# Identifier (URI) for, this License with every copy of the Work You +# Distribute or Publicly Perform. You may not offer or impose any +# terms on the Work that restrict the terms of this License or the +# ability of the recipient of the Work to exercise the rights granted +# to that recipient under the terms of the License. You may not +# sublicense the Work. You must keep intact all notices that refer to +# this License and to the disclaimer of warranties with every copy of +# the Work You Distribute or Publicly Perform. When You Distribute or +# Publicly Perform the Work, You may not impose any effective +# technological measures on the Work that restrict the ability of a +# recipient of the Work from You to exercise the rights granted to +# that recipient under the terms of the License. This Section 4(a) +# applies to the Work as incorporated in a Collection, but this does +# not require the Collection apart from the Work itself to be made +# subject to the terms of this License. If You create a Collection, +# upon notice from any Licensor You must, to the extent practicable, +# remove from the Collection any credit as required by Section 4(c), +# as requested. If You create an Adaptation, upon notice from any +# Licensor You must, to the extent practicable, remove from the +# Adaptation any credit as required by Section 4(c), as requested. +# 2. You may Distribute or Publicly Perform an Adaptation only under the +# terms of: (i) this License; (ii) a later version of this License +# with the same License Elements as this License; (iii) a Creative +# Commons jurisdiction license (either this or a later license +# version) that contains the same License Elements as this License +# (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons +# Compatible License. If you license the Adaptation under one of the +# licenses mentioned in (iv), you must comply with the terms of that +# license. If you license the Adaptation under the terms of any of the +# licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), +# you must comply with the terms of the Applicable License generally +# and the following provisions: (I) You must include a copy of, or the +# URI for, the Applicable License with every copy of each Adaptation +# You Distribute or Publicly Perform; (II) You may not offer or impose +# any terms on the Adaptation that restrict the terms of the +# Applicable License or the ability of the recipient of the Adaptation +# to exercise the rights granted to that recipient under the terms of +# the Applicable License; (III) You must keep intact all notices that +# refer to the Applicable License and to the disclaimer of warranties +# with every copy of the Work as included in the Adaptation You +# Distribute or Publicly Perform; (IV) when You Distribute or Publicly +# Perform the Adaptation, You may not impose any effective +# technological measures on the Adaptation that restrict the ability +# of a recipient of the Adaptation from You to exercise the rights +# granted to that recipient under the terms of the Applicable License. +# This Section 4(b) applies to the Adaptation as incorporated in a +# Collection, but this does not require the Collection apart from the +# Adaptation itself to be made subject to the terms of the Applicable +# License. +# 3. If You Distribute, or Publicly Perform the Work or any Adaptations +# or Collections, You must, unless a request has been made pursuant to +# Section 4(a), keep intact all copyright notices for the Work and +# provide, reasonable to the medium or means You are utilizing: (i) +# the name of the Original Author (or pseudonym, if applicable) if +# supplied, and/or if the Original Author and/or Licensor designate +# another party or parties (e.g., a sponsor institute, publishing +# entity, journal) for attribution ("Attribution Parties") in +# Licensor's copyright notice, terms of service or by other reasonable +# means, the name of such party or parties; (ii) the title of the Work +# if supplied; (iii) to the extent reasonably practicable, the URI, if +# any, that Licensor specifies to be associated with the Work, unless +# such URI does not refer to the copyright notice or licensing +# information for the Work; and (iv) , consistent with Ssection 3(b), +# in the case of an Adaptation, a credit identifying the use of the +# Work in the Adaptation (e.g., "French translation of the Work by +# Original Author," or "Screenplay based on original Work by Original +# Author"). The credit required by this Section 4(c) may be +# implemented in any reasonable manner; provided, however, that in the +# case of a Adaptation or Collection, at a minimum such credit will +# appear, if a credit for all contributing authors of the Adaptation +# or Collection appears, then as part of these credits and in a manner +# at least as prominent as the credits for the other contributing +# authors. For the avoidance of doubt, You may only use the credit +# required by this Section for the purpose of attribution in the +# manner set out above and, by exercising Your rights under this +# License, You may not implicitly or explicitly assert or imply any +# connection with, sponsorship or endorsement by the Original Author, +# Licensor and/or Attribution Parties, as appropriate, of You or Your +# use of the Work, without the separate, express prior written +# permission of the Original Author, Licensor and/or Attribution Parties. +# 4. Except as otherwise agreed in writing by the Licensor or as may be +# otherwise permitted by applicable law, if You Reproduce, Distribute +# or Publicly Perform the Work either by itself or as part of any +# Adaptations or Collections, You must not distort, mutilate, modify +# or take other derogatory action in relation to the Work which would +# be prejudicial to the Original Author's honor or reputation. +# Licensor agrees that in those jurisdictions (e.g. Japan), in which +# any exercise of the right granted in Section 3(b) of this License +# (the right to make Adaptations) would be deemed to be a distortion, +# mutilation, modification or other derogatory action prejudicial to +# the Original Author's honor and reputation, the Licensor will waive +# or not assert, as appropriate, this Section, to the fullest extent +# permitted by the applicable national law, to enable You to +# reasonably exercise Your right under Section 3(b) of this License +# (right to make Adaptations) but not otherwise. +# +# *5. Representations, Warranties and Disclaimer* +# +# UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +# OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +# KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +# INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +# FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +# LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +# WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE +# EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. +# +# *6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY +# APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL +# THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY +# DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF +# LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +# +# *7. Termination* +# +# 1. This License and the rights granted hereunder will terminate +# automatically upon any breach by You of the terms of this License. +# Individuals or entities who have received Adaptations or Collections +# from You under this License, however, will not have their licenses +# terminated provided such individuals or entities remain in full +# compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will +# survive any termination of this License. +# 2. Subject to the above terms and conditions, the license granted here +# is perpetual (for the duration of the applicable copyright in the +# Work). Notwithstanding the above, Licensor reserves the right to +# release the Work under different license terms or to stop +# distributing the Work at any time; provided, however that any such +# election will not serve to withdraw this License (or any other +# license that has been, or is required to be, granted under the terms +# of this License), and this License will continue in full force and +# effect unless terminated as stated above. +# +# *8. Miscellaneous* +# +# 1. Each time You Distribute or Publicly Perform the Work or a +# Collection, the Licensor offers to the recipient a license to the +# Work on the same terms and conditions as the license granted to You +# under this License. +# 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor +# offers to the recipient a license to the original Work on the same +# terms and conditions as the license granted to You under this License. +# 3. If any provision of this License is invalid or unenforceable under +# applicable law, it shall not affect the validity or enforceability +# of the remainder of the terms of this License, and without further +# action by the parties to this agreement, such provision shall be +# reformed to the minimum extent necessary to make such provision +# valid and enforceable. +# 4. No term or provision of this License shall be deemed waived and no +# breach consented to unless such waiver or consent shall be in +# writing and signed by the party to be charged with such waiver or +# consent. +# 5. This License constitutes the entire agreement between the parties +# with respect to the Work licensed here. There are no understandings, +# agreements or representations with respect to the Work not specified +# here. Licensor shall not be bound by any additional provisions that +# may appear in any communication from You. This License may not be +# modified without the mutual written agreement of the Licensor and You. +# 6. The rights granted under, and the subject matter referenced, in this +# License were drafted utilizing the terminology of the Berne +# Convention for the Protection of Literary and Artistic Works (as +# amended on September 28, 1979), the Rome Convention of 1961, the +# WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms +# Treaty of 1996 and the Universal Copyright Convention (as revised on +# July 24, 1971). These rights and subject matter take effect in the +# relevant jurisdiction in which the License terms are sought to be +# enforced according to the corresponding provisions of the +# implementation of those treaty provisions in the applicable national +# law. If the standard suite of rights granted under applicable +# copyright law includes additional rights not granted under this +# License, such additional rights are deemed to be included in the +# License; this License is not intended to restrict the license of any +# rights under applicable law. +absorver->absorber +absorviendo->absorbiendo +aca->acá +academica->académica +academicamente->académicamente +academico->académico +accion->acción +aceptacion->aceptación +acetado->aceptado +ademas->además +administracion->administración +aerea->aérea +aereo->aéreo +aficion->afición +aficcion->afición +aficción->afición +ahi->ahà +al Cairo->a El Cairo +album->álbum +alevin->alevÃn +algun->algún +alli->allà +alla->allá +al rededor->alrededor +aprobechar->aprovechar +aqui->aquà +arabe->árabe +arbol->árbol +area->área +articulacion->articulación +asi->asà +atencion->atención +atlantico->atlántico +automovil->automóvil +avion->avión +azucar->azúcar +bibliografia->bibliografÃa +bién->bien +Bogota->Bogotá +Brasilero->brasileño +Brasilera->brasileña +buho->búho +cadaver->cadáver +cafe->café +cafeteria->cafeterÃa +camaleon->camaleón +camara->cámara +cancion->canción +candadear->candear +caracter->carácter +caracteristica->caracterÃstica +carroceria->carrocerÃa +catastrofe->catástrofe +catastrofica->catastrófica +catastrofico->catastrófico +categoria->categorÃa +cién->cien +CD's->CD +CDs->CD +cogeran->cogerán +cogia->cogÃa +cogian->cogÃan +cojer->coger +cojen->cogen +cojerán->cogerán +cojÃa->cogÃa +cojia->cogÃa +cojÃan->cogÃan +cojió->cogió +companÃa->compañÃa +compañia->compañÃa +compasion->compasión +comun->común +comunmente->comúnmente +conección->conexión +cono urbano->conurbano +consideracion->consideración +constituÃda->constituida +constituÃdo->constituido +construÃdo->construido +construÃr->construir +continuan->continúan +contÃnuo->continuo +convirtio->convirtió +cortesmente->cortésmente +cronologica->cronológica +cronologicamente->cronológicamente +cronologico->cronológico +da a lugar a->da lugar a +dar a lugar a->dar lugar a +darÃa a lugar a->darÃa lugar a +dá->da +definio->definió +del Cairo->de El Cairo +del interfaz->de la interfaz +delfin->delfÃn +desconto->descontó +desovediente->desobediente +deshechar->desechar +deshechando->desechando +despues->después +dia->dÃa +dias->dÃas +dieciseis->dieciséis +diéz->diez +dificil->difÃcil +dificilmente->difÃcilmente +dio a lugar a->dio lugar a +dió->dio +discusion->discusión +disolucion->disolución +distorción->distorsión +distorcionado->distorsionado +distribuÃdo->distribuido +duodecimo->duodécimo +e hielo->y hielo +e hierro->y hierro +e iones->y iones +ebano->ébano +eclesiastico->eclesiástico +eclesiasticos->eclesiásticos +el fue->él fue +el interfaz->la interfaz +el Osasuna->Osasuna +embarcacion->embarcación +enbarcacion->embarcación +enbarcación->embarcación +empezo->empezó +enlaze->enlace +eolico->eólico +equalización->ecualización +equalizador->ecualizador +equalizar->ecualizar +espiritu->espÃritu +estan->están +estandard->estándar +estándard->estándar +etc...->etc. +etimologia->etimologÃa +exámen->examen +examenes->exámenes +exitar->excitar +exito->éxito +exemplo->ejemplo +explendor->esplendor +extrangero->extranjero +estranjero->extranjero +estrangero->extranjero +extricta->estricta +extricto->estricto +extrictamente->estrictamente +espia->espÃa +esprecion->expresión +espreción->expresión +espresion->expresión +espresión->expresión +expresion->expresión +facil->fácil +facilmente->fácilmente +fanatica->fanática +fanaticamente->fanáticamente +fanatico->fanático +fé->fe +ficcion->ficción +fisica->fÃsica +fluÃdo->fluido +fricion->fricción +frición->fricción +friccion->fricción +fucion->fusión +fución->fusión +fué->fue +fuÃ->fui +funcion->función +fusion->fusión +futbol->fútbol +futil->fútil +garage->garaje +guión->guion +Guipuzcoa->Guipúzcoa +gustaria->gustarÃa +Gutierrez->Gutiérrez +habia->habÃa +haiga->haya +habian->habÃan +hechar->echar +hechado->echado +herbivoro->herbÃvoro +herviboro->herbÃvoro +hervÃboro->herbÃvoro +hervivoro->herbÃvoro +hervÃvoro->herbÃvoro +hermita->ermita +heroe->héroe +heróica->heroica +heróico->heroico +hibridización->hibridación +hinduÃsmo->hinduismo +hinduÃsta->hinduista +homogenea->homogénea +homogeneo->homogéneo +hormigon->hormigón +ideologia->ideologÃa +ideologica->ideológica +ideologicamente->ideológicamente +ideologico->ideológico +imágen->imagen +imagenes->imágenes +IMDB->IMDb +incluÃdo->incluido +incluÃr->incluir +indice->Ãndice +interface->interfaz +interperie->intemperie +inutil->inútil +invasion->invasión +israeli->israelà +israelies->israelÃes +jardin->jardÃn +jente->gente +jóven->joven +judia->judÃa +judias->judÃas +judio->judÃo +judios->judÃos +Km->km +km2->km² +lampara->lámpara +le hecha->le echa +leido->leÃdo +leon->león +lider->lÃder +linea->lÃnea +lineas->lÃneas +linia->lÃnea +llendo->yendo +llevada acabo->llevada a cabo +llevado acabo->llevado a cabo +llevaron acabo->llevaron a cabo +llevó acabo->llevó a cabo +logica->lógica +logicamente->lógicamente +logico->lógico +lo hecha->lo echa +lonjeva->longeva +lonjevo->longevo +mecanica->mecánica +mecanicamente->mecánicamente +mecanico->mecánico +magica->mágica +magico->mágico +martir->mártir +maxima->máxima +maximo->máximo +mayoria->mayorÃa +mayuscula->mayúscula +mayusculo->mayúsculo +metodologia->metodologÃa +Mexico->México +mÃl->mil +minima->mÃnima +minimo->mÃnimo +minoria->minorÃa +minuscula->minúscula +minusculo->minúsculo +mitologia->mitologÃa +mitologica->mitológica +mitologico->mitológico +mitomana->mitómana +mitomania->mitomanÃa +mitomano->mitómano +monton->montón +movil->móvil +murciegalo->murciélago +murciégalo->murciélago +murio->murió +musica->música +nacio->nació +nadien->nadie +ningun->ningún +oceano->océano +olimpica->olÃmpica +olimpicamente->olÃmpicamente +olimpico->olÃmpico +operacion->operación +oraculo->oráculo +órden->orden +organica->orgánica +organico->orgánico +organo->órgano +orÃgen->origen +origenes->orÃgenes +osea->o sea +oceano pacifico->océano pacÃfico +ONG's->ONG +ONGs-> ONG +OVNI's->OVNI +OVNIs->OVNI +pagina->página +pais->paÃs +paparazzis->paparazzi +participacion->participación +pasion->pasión +pelicula->pelÃcula +peloton->pelotón +perfÃl->perfil +persuación->persuasión +politica->polÃtica +politicamente->polÃticamente +politico->polÃtico +por contra-> por el contrario +practicamente->prácticamente +prerequisito->prerrequisito +pre-requisito->prerrequisito +preveer->prever +prevencion->prevención +programacion->programación +promocion->promoción +protejer->proteger +publicamente->públicamente +quiza->quizá +quizas->quizás +rapido->rápido +rapida->rápida +regilla->rejilla +remplazar->reemplazar +republica->república +resolucion->resolución +restaurant->restaurante +revizado->revisado +revizar->revisar +revolucion->revolución +rocin->rocÃn +ruÃdo->ruido +sacerdotiza->sacerdotisa +sazon->sazón +se a->se ha +séis->seis +segun->según +sera->será +serpentin->serpentÃn +sinembargo->sin embargo +sinfin->sinfÃn +slogan->eslogan +sóla->sola +sólamente->solamente +solucion->solución +stándard->estándar +subrraya->subraya +subrrayado->subrayado +subrrayar->subrayar +superfÃcie->superficie +supérflua->superflua +tagea->tajea +talvez->tal vez +tambien->también +tanbien->también +tanbién->también +tecnica->técnica +tecnicamente->técnicamente +tecnico->técnico +tÃ->ti +tia->tÃa +tio->tÃo +tipica->tÃpica +tipicamente->tÃpicamente +tipico->tÃpico +tradució->tradujo,traducción +traducion->traducción +tradución->traducción +traduccion->traducción +traf->tráf +tunel->túnel +ubicacion->ubicación +ultimamente->últimamente +ultimo->último +ultimos->últimos +un interfaz->una interfaz +undecimo->undécimo +unica->única +unicamente->únicamente +unico->único +util->útil +vease->véase +veintidos->veintidós +veintiseis->veintiséis +veintitres->veintitrés +vision->visión +via->vÃa +vió->vio +watios->vatios diff --git a/files/typos/typos-hu.txt b/files/typos/typos-hu.txt new file mode 100644 index 0000000..e0586bf --- /dev/null +++ b/files/typos/typos-hu.txt @@ -0,0 +1,431 @@ +# This file contains a number of common Hungarian typos: +andriod->android + +# The remainder of this file contains misspellings from +# http://hu.wikipedia.org/wiki/Szerkeszt%C5%91:AntiVandal/Hiba +# plus some post-processing to fix invalid entries, remove duplicates, etc. +# +# The content is available under the +# "Creative Commons Attribution-ShareAlike License" +# http://creativecommons.org/licenses/by-sa/3.0/ +# +# THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +# COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +# COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +# AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. +# +# BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +# TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +# BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +# CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +# CONDITIONS. +# +# *1. Definitions* +# +# 1. *"Adaptation"* means a work based upon the Work, or upon the Work +# and other pre-existing works, such as a translation, adaptation, +# derivative work, arrangement of music or other alterations of a +# literary or artistic work, or phonogram or performance and includes +# cinematographic adaptations or any other form in which the Work may +# be recast, transformed, or adapted including in any form +# recognizably derived from the original, except that a work that +# constitutes a Collection will not be considered an Adaptation for +# the purpose of this License. For the avoidance of doubt, where the +# Work is a musical work, performance or phonogram, the +# synchronization of the Work in timed-relation with a moving image +# ("synching") will be considered an Adaptation for the purpose of +# this License. +# 2. *"Collection"* means a collection of literary or artistic works, +# such as encyclopedias and anthologies, or performances, phonograms +# or broadcasts, or other works or subject matter other than works +# listed in Section 1(f) below, which, by reason of the selection and +# arrangement of their contents, constitute intellectual creations, in +# which the Work is included in its entirety in unmodified form along +# with one or more other contributions, each constituting separate and +# independent works in themselves, which together are assembled into a +# collective whole. A work that constitutes a Collection will not be +# considered an Adaptation (as defined below) for the purposes of this +# License. +# 3. *"Creative Commons Compatible License"* means a license that is +# listed at http://creativecommons.org/compatiblelicenses that has +# been approved by Creative Commons as being essentially equivalent to +# this License, including, at a minimum, because that license: (i) +# contains terms that have the same purpose, meaning and effect as the +# License Elements of this License; and, (ii) explicitly permits the +# relicensing of adaptations of works made available under that +# license under this License or a Creative Commons jurisdiction +# license with the same License Elements as this License. +# 4. *"Distribute"* means to make available to the public the original +# and copies of the Work or Adaptation, as appropriate, through sale +# or other transfer of ownership. +# 5. *"License Elements"* means the following high-level license +# attributes as selected by Licensor and indicated in the title of +# this License: Attribution, ShareAlike. +# 6. *"Licensor"* means the individual, individuals, entity or entities +# that offer(s) the Work under the terms of this License. +# 7. *"Original Author"* means, in the case of a literary or artistic +# work, the individual, individuals, entity or entities who created +# the Work or if no individual or entity can be identified, the +# publisher; and in addition (i) in the case of a performance the +# actors, singers, musicians, dancers, and other persons who act, +# sing, deliver, declaim, play in, interpret or otherwise perform +# literary or artistic works or expressions of folklore; (ii) in the +# case of a phonogram the producer being the person or legal entity +# who first fixes the sounds of a performance or other sounds; and, +# (iii) in the case of broadcasts, the organization that transmits the +# broadcast. +# 8. *"Work"* means the literary and/or artistic work offered under the +# terms of this License including without limitation any production in +# the literary, scientific and artistic domain, whatever may be the +# mode or form of its expression including digital form, such as a +# book, pamphlet and other writing; a lecture, address, sermon or +# other work of the same nature; a dramatic or dramatico-musical work; +# a choreographic work or entertainment in dumb show; a musical +# composition with or without words; a cinematographic work to which +# are assimilated works expressed by a process analogous to +# cinematography; a work of drawing, painting, architecture, +# sculpture, engraving or lithography; a photographic work to which +# are assimilated works expressed by a process analogous to +# photography; a work of applied art; an illustration, map, plan, +# sketch or three-dimensional work relative to geography, topography, +# architecture or science; a performance; a broadcast; a phonogram; a +# compilation of data to the extent it is protected as a copyrightable +# work; or a work performed by a variety or circus performer to the +# extent it is not otherwise considered a literary or artistic work. +# 9. *"You"* means an individual or entity exercising rights under this +# License who has not previously violated the terms of this License +# with respect to the Work, or who has received express permission +# from the Licensor to exercise rights under this License despite a +# previous violation. +# 10. *"Publicly Perform"* means to perform public recitations of the Work +# and to communicate to the public those public recitations, by any +# means or process, including by wire or wireless means or public +# digital performances; to make available to the public Works in such +# a way that members of the public may access these Works from a place +# and at a place individually chosen by them; to perform the Work to +# the public by any means or process and the communication to the +# public of the performances of the Work, including by public digital +# performance; to broadcast and rebroadcast the Work by any means +# including signs, sounds or images. +# 11. *"Reproduce"* means to make copies of the Work by any means +# including without limitation by sound or visual recordings and the +# right of fixation and reproducing fixations of the Work, including +# storage of a protected performance or phonogram in digital form or +# other electronic medium. +# +# *2. Fair Dealing Rights.* Nothing in this License is intended to reduce, +# limit, or restrict any uses free from copyright or rights arising from +# limitations or exceptions that are provided for in connection with the +# copyright protection under copyright law or other applicable laws. +# +# *3. License Grant.* Subject to the terms and conditions of this License, +# Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +# perpetual (for the duration of the applicable copyright) license to +# exercise the rights in the Work as stated below: +# +# 1. to Reproduce the Work, to incorporate the Work into one or more +# Collections, and to Reproduce the Work as incorporated in the +# Collections; +# 2. to create and Reproduce Adaptations provided that any such +# Adaptation, including any translation in any medium, takes +# reasonable steps to clearly label, demarcate or otherwise identify +# that changes were made to the original Work. For example, a +# translation could be marked "The original work was translated from +# English to Spanish," or a modification could indicate "The original +# work has been modified."; +# 3. to Distribute and Publicly Perform the Work including as +# incorporated in Collections; and, +# 4. to Distribute and Publicly Perform Adaptations. +# 5. +# +# For the avoidance of doubt: +# +# 1. *Non-waivable Compulsory License Schemes*. In those +# jurisdictions in which the right to collect royalties through +# any statutory or compulsory licensing scheme cannot be waived, +# the Licensor reserves the exclusive right to collect such +# royalties for any exercise by You of the rights granted under +# this License; +# 2. *Waivable Compulsory License Schemes*. In those jurisdictions in +# which the right to collect royalties through any statutory or +# compulsory licensing scheme can be waived, the Licensor waives +# the exclusive right to collect such royalties for any exercise +# by You of the rights granted under this License; and, +# 3. *Voluntary License Schemes*. The Licensor waives the right to +# collect royalties, whether individually or, in the event that +# the Licensor is a member of a collecting society that +# administers voluntary licensing schemes, via that society, from +# any exercise by You of the rights granted under this License. +# +# The above rights may be exercised in all media and formats whether now +# known or hereafter devised. The above rights include the right to make +# such modifications as are technically necessary to exercise the rights +# in other media and formats. Subject to Section 8(f), all rights not +# expressly granted by Licensor are hereby reserved. +# +# *4. Restrictions.* The license granted in Section 3 above is expressly +# made subject to and limited by the following restrictions: +# +# 1. You may Distribute or Publicly Perform the Work only under the terms +# of this License. You must include a copy of, or the Uniform Resource +# Identifier (URI) for, this License with every copy of the Work You +# Distribute or Publicly Perform. You may not offer or impose any +# terms on the Work that restrict the terms of this License or the +# ability of the recipient of the Work to exercise the rights granted +# to that recipient under the terms of the License. You may not +# sublicense the Work. You must keep intact all notices that refer to +# this License and to the disclaimer of warranties with every copy of +# the Work You Distribute or Publicly Perform. When You Distribute or +# Publicly Perform the Work, You may not impose any effective +# technological measures on the Work that restrict the ability of a +# recipient of the Work from You to exercise the rights granted to +# that recipient under the terms of the License. This Section 4(a) +# applies to the Work as incorporated in a Collection, but this does +# not require the Collection apart from the Work itself to be made +# subject to the terms of this License. If You create a Collection, +# upon notice from any Licensor You must, to the extent practicable, +# remove from the Collection any credit as required by Section 4(c), +# as requested. If You create an Adaptation, upon notice from any +# Licensor You must, to the extent practicable, remove from the +# Adaptation any credit as required by Section 4(c), as requested. +# 2. You may Distribute or Publicly Perform an Adaptation only under the +# terms of: (i) this License; (ii) a later version of this License +# with the same License Elements as this License; (iii) a Creative +# Commons jurisdiction license (either this or a later license +# version) that contains the same License Elements as this License +# (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons +# Compatible License. If you license the Adaptation under one of the +# licenses mentioned in (iv), you must comply with the terms of that +# license. If you license the Adaptation under the terms of any of the +# licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), +# you must comply with the terms of the Applicable License generally +# and the following provisions: (I) You must include a copy of, or the +# URI for, the Applicable License with every copy of each Adaptation +# You Distribute or Publicly Perform; (II) You may not offer or impose +# any terms on the Adaptation that restrict the terms of the +# Applicable License or the ability of the recipient of the Adaptation +# to exercise the rights granted to that recipient under the terms of +# the Applicable License; (III) You must keep intact all notices that +# refer to the Applicable License and to the disclaimer of warranties +# with every copy of the Work as included in the Adaptation You +# Distribute or Publicly Perform; (IV) when You Distribute or Publicly +# Perform the Adaptation, You may not impose any effective +# technological measures on the Adaptation that restrict the ability +# of a recipient of the Adaptation from You to exercise the rights +# granted to that recipient under the terms of the Applicable License. +# This Section 4(b) applies to the Adaptation as incorporated in a +# Collection, but this does not require the Collection apart from the +# Adaptation itself to be made subject to the terms of the Applicable +# License. +# 3. If You Distribute, or Publicly Perform the Work or any Adaptations +# or Collections, You must, unless a request has been made pursuant to +# Section 4(a), keep intact all copyright notices for the Work and +# provide, reasonable to the medium or means You are utilizing: (i) +# the name of the Original Author (or pseudonym, if applicable) if +# supplied, and/or if the Original Author and/or Licensor designate +# another party or parties (e.g., a sponsor institute, publishing +# entity, journal) for attribution ("Attribution Parties") in +# Licensor's copyright notice, terms of service or by other reasonable +# means, the name of such party or parties; (ii) the title of the Work +# if supplied; (iii) to the extent reasonably practicable, the URI, if +# any, that Licensor specifies to be associated with the Work, unless +# such URI does not refer to the copyright notice or licensing +# information for the Work; and (iv) , consistent with Ssection 3(b), +# in the case of an Adaptation, a credit identifying the use of the +# Work in the Adaptation (e.g., "French translation of the Work by +# Original Author," or "Screenplay based on original Work by Original +# Author"). The credit required by this Section 4(c) may be +# implemented in any reasonable manner; provided, however, that in the +# case of a Adaptation or Collection, at a minimum such credit will +# appear, if a credit for all contributing authors of the Adaptation +# or Collection appears, then as part of these credits and in a manner +# at least as prominent as the credits for the other contributing +# authors. For the avoidance of doubt, You may only use the credit +# required by this Section for the purpose of attribution in the +# manner set out above and, by exercising Your rights under this +# License, You may not implicitly or explicitly assert or imply any +# connection with, sponsorship or endorsement by the Original Author, +# Licensor and/or Attribution Parties, as appropriate, of You or Your +# use of the Work, without the separate, express prior written +# permission of the Original Author, Licensor and/or Attribution Parties. +# 4. Except as otherwise agreed in writing by the Licensor or as may be +# otherwise permitted by applicable law, if You Reproduce, Distribute +# or Publicly Perform the Work either by itself or as part of any +# Adaptations or Collections, You must not distort, mutilate, modify +# or take other derogatory action in relation to the Work which would +# be prejudicial to the Original Author's honor or reputation. +# Licensor agrees that in those jurisdictions (e.g. Japan), in which +# any exercise of the right granted in Section 3(b) of this License +# (the right to make Adaptations) would be deemed to be a distortion, +# mutilation, modification or other derogatory action prejudicial to +# the Original Author's honor and reputation, the Licensor will waive +# or not assert, as appropriate, this Section, to the fullest extent +# permitted by the applicable national law, to enable You to +# reasonably exercise Your right under Section 3(b) of this License +# (right to make Adaptations) but not otherwise. +# +# *5. Representations, Warranties and Disclaimer* +# +# UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +# OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +# KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +# INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +# FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +# LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +# WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE +# EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. +# +# *6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY +# APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL +# THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY +# DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF +# LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +# +# *7. Termination* +# +# 1. This License and the rights granted hereunder will terminate +# automatically upon any breach by You of the terms of this License. +# Individuals or entities who have received Adaptations or Collections +# from You under this License, however, will not have their licenses +# terminated provided such individuals or entities remain in full +# compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will +# survive any termination of this License. +# 2. Subject to the above terms and conditions, the license granted here +# is perpetual (for the duration of the applicable copyright in the +# Work). Notwithstanding the above, Licensor reserves the right to +# release the Work under different license terms or to stop +# distributing the Work at any time; provided, however that any such +# election will not serve to withdraw this License (or any other +# license that has been, or is required to be, granted under the terms +# of this License), and this License will continue in full force and +# effect unless terminated as stated above. +# +# *8. Miscellaneous* +# +# 1. Each time You Distribute or Publicly Perform the Work or a +# Collection, the Licensor offers to the recipient a license to the +# Work on the same terms and conditions as the license granted to You +# under this License. +# 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor +# offers to the recipient a license to the original Work on the same +# terms and conditions as the license granted to You under this License. +# 3. If any provision of this License is invalid or unenforceable under +# applicable law, it shall not affect the validity or enforceability +# of the remainder of the terms of this License, and without further +# action by the parties to this agreement, such provision shall be +# reformed to the minimum extent necessary to make such provision +# valid and enforceable. +# 4. No term or provision of this License shall be deemed waived and no +# breach consented to unless such waiver or consent shall be in +# writing and signed by the party to be charged with such waiver or +# consent. +# 5. This License constitutes the entire agreement between the parties +# with respect to the Work licensed here. There are no understandings, +# agreements or representations with respect to the Work not specified +# here. Licensor shall not be bound by any additional provisions that +# may appear in any communication from You. This License may not be +# modified without the mutual written agreement of the Licensor and You. +# 6. The rights granted under, and the subject matter referenced, in this +# License were drafted utilizing the terminology of the Berne +# Convention for the Protection of Literary and Artistic Works (as +# amended on September 28, 1979), the Rome Convention of 1961, the +# WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms +# Treaty of 1996 and the Universal Copyright Convention (as revised on +# July 24, 1971). These rights and subject matter take effect in the +# relevant jurisdiction in which the License terms are sought to be +# enforced according to the corresponding provisions of the +# implementation of those treaty provisions in the applicable national +# law. If the standard suite of rights granted under applicable +# copyright law includes additional rights not granted under this +# License, such additional rights are deemed to be included in the +# License; this License is not intended to restrict the license of any +# rights under applicable law. +0-át->0-t +1.-én->1-jén +10.-én->10-én +11.-én->11-én +12.-én->12-én +13.-án->13-án +14.-én->14-én +15.-én->15-én +16.-án->16-án +17.-én->17-én +18.-án->18-án +19.-én->19-én +1-e->1-je +1-el->1-gyel +1-én->1-jén +2.-án->2-án +20.-án->20-án +21.-én->21-én +22.-én->22-én +23.-án->23-án +24.-én->24-én +25.-én->25-én +26.-án->26-án +27.-én->27-én +28.-án->28-án +29.-én->29-én +2-Å‘t->2-t +3.-án->3-án +30.-án->30-án +31.-én->31-én +4.-én->4-én +5.-én->5-én +6.-án->6-án +7.-én->7-én +8.-án->8-án +9.-én->9-én +abszolut->abszolút +ambÃciózus->ambiciózus +asszimetrikus->aszimmetrikus +árú->áru +azomban->azonban +bejjebb->beljebb +bisztos->biztos +brilliáns->briliáns +cimke->cÃmke +dÃcséret->dicséret +egyenlÅ‘re->egyelÅ‘re +egyértelmüsÃtÅ‘->egyértelműsÃtÅ‘ +eggyütt->együtt +elipszis->ellipszis +follyon->folyjon +hektóliter->hektoliter +hellénista->hellenista +hellénisztikus->hellenisztikus +hellénizmus->hellenizmus +Horatiussal->Horatiusszal +igéret->Ãgéret +irÃgy->irigy +kálcium->kalcium +kellet->kellett +keveseb->kevesebb +kilóméter->kilométer +kisseb->kisebb +kissebb->kisebb +konkurrencia->konkurencia +konkurrens->konkurens +könnyeb->könnyebb +könyebb->könnyebb +kultura->kultúra +kultúrális->kulturális +külömbség->különbség +külömbözÅ‘->különbözÅ‘ +legjob->legjobb +legkeveseb->legkevesebb +legnagyob->legnagyobb +lessz->lesz +mellet->mellett +mindÃg->mindig +muszály->muszáj +new yorki->New York-i +orzság->ország +önnálló->önálló +raffinált->rafinált +szinvonal->szÃnvonal +Szovjetúnió->Szovjetunió +Torino-i->torinói +únió->unió +vákum->vákuum +Vietnám->Vietnam diff --git a/files/typos/typos-it.txt b/files/typos/typos-it.txt new file mode 100644 index 0000000..5c2d496 --- /dev/null +++ b/files/typos/typos-it.txt @@ -0,0 +1,665 @@ +# This file contains a number of common Italian typos: +andriod->android + +# The remainder of this file contains misspellings from +# http://it.m.wikipedia.org/wiki/Utente:Senpai/Lista_degli_errori_comuni/Formato_macchina +# plus some post-processing to fix invalid entries, remove duplicates, etc. +# +# The content is available under the +# "Creative Commons Attribution-ShareAlike License" +# http://creativecommons.org/licenses/by-sa/3.0/ +# +# THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +# COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +# COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +# AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. +# +# BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +# TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +# BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +# CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +# CONDITIONS. +# +# *1. Definitions* +# +# 1. *"Adaptation"* means a work based upon the Work, or upon the Work +# and other pre-existing works, such as a translation, adaptation, +# derivative work, arrangement of music or other alterations of a +# literary or artistic work, or phonogram or performance and includes +# cinematographic adaptations or any other form in which the Work may +# be recast, transformed, or adapted including in any form +# recognizably derived from the original, except that a work that +# constitutes a Collection will not be considered an Adaptation for +# the purpose of this License. For the avoidance of doubt, where the +# Work is a musical work, performance or phonogram, the +# synchronization of the Work in timed-relation with a moving image +# ("synching") will be considered an Adaptation for the purpose of +# this License. +# 2. *"Collection"* means a collection of literary or artistic works, +# such as encyclopedias and anthologies, or performances, phonograms +# or broadcasts, or other works or subject matter other than works +# listed in Section 1(f) below, which, by reason of the selection and +# arrangement of their contents, constitute intellectual creations, in +# which the Work is included in its entirety in unmodified form along +# with one or more other contributions, each constituting separate and +# independent works in themselves, which together are assembled into a +# collective whole. A work that constitutes a Collection will not be +# considered an Adaptation (as defined below) for the purposes of this +# License. +# 3. *"Creative Commons Compatible License"* means a license that is +# listed at http://creativecommons.org/compatiblelicenses that has +# been approved by Creative Commons as being essentially equivalent to +# this License, including, at a minimum, because that license: (i) +# contains terms that have the same purpose, meaning and effect as the +# License Elements of this License; and, (ii) explicitly permits the +# relicensing of adaptations of works made available under that +# license under this License or a Creative Commons jurisdiction +# license with the same License Elements as this License. +# 4. *"Distribute"* means to make available to the public the original +# and copies of the Work or Adaptation, as appropriate, through sale +# or other transfer of ownership. +# 5. *"License Elements"* means the following high-level license +# attributes as selected by Licensor and indicated in the title of +# this License: Attribution, ShareAlike. +# 6. *"Licensor"* means the individual, individuals, entity or entities +# that offer(s) the Work under the terms of this License. +# 7. *"Original Author"* means, in the case of a literary or artistic +# work, the individual, individuals, entity or entities who created +# the Work or if no individual or entity can be identified, the +# publisher; and in addition (i) in the case of a performance the +# actors, singers, musicians, dancers, and other persons who act, +# sing, deliver, declaim, play in, interpret or otherwise perform +# literary or artistic works or expressions of folklore; (ii) in the +# case of a phonogram the producer being the person or legal entity +# who first fixes the sounds of a performance or other sounds; and, +# (iii) in the case of broadcasts, the organization that transmits the +# broadcast. +# 8. *"Work"* means the literary and/or artistic work offered under the +# terms of this License including without limitation any production in +# the literary, scientific and artistic domain, whatever may be the +# mode or form of its expression including digital form, such as a +# book, pamphlet and other writing; a lecture, address, sermon or +# other work of the same nature; a dramatic or dramatico-musical work; +# a choreographic work or entertainment in dumb show; a musical +# composition with or without words; a cinematographic work to which +# are assimilated works expressed by a process analogous to +# cinematography; a work of drawing, painting, architecture, +# sculpture, engraving or lithography; a photographic work to which +# are assimilated works expressed by a process analogous to +# photography; a work of applied art; an illustration, map, plan, +# sketch or three-dimensional work relative to geography, topography, +# architecture or science; a performance; a broadcast; a phonogram; a +# compilation of data to the extent it is protected as a copyrightable +# work; or a work performed by a variety or circus performer to the +# extent it is not otherwise considered a literary or artistic work. +# 9. *"You"* means an individual or entity exercising rights under this +# License who has not previously violated the terms of this License +# with respect to the Work, or who has received express permission +# from the Licensor to exercise rights under this License despite a +# previous violation. +# 10. *"Publicly Perform"* means to perform public recitations of the Work +# and to communicate to the public those public recitations, by any +# means or process, including by wire or wireless means or public +# digital performances; to make available to the public Works in such +# a way that members of the public may access these Works from a place +# and at a place individually chosen by them; to perform the Work to +# the public by any means or process and the communication to the +# public of the performances of the Work, including by public digital +# performance; to broadcast and rebroadcast the Work by any means +# including signs, sounds or images. +# 11. *"Reproduce"* means to make copies of the Work by any means +# including without limitation by sound or visual recordings and the +# right of fixation and reproducing fixations of the Work, including +# storage of a protected performance or phonogram in digital form or +# other electronic medium. +# +# *2. Fair Dealing Rights.* Nothing in this License is intended to reduce, +# limit, or restrict any uses free from copyright or rights arising from +# limitations or exceptions that are provided for in connection with the +# copyright protection under copyright law or other applicable laws. +# +# *3. License Grant.* Subject to the terms and conditions of this License, +# Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +# perpetual (for the duration of the applicable copyright) license to +# exercise the rights in the Work as stated below: +# +# 1. to Reproduce the Work, to incorporate the Work into one or more +# Collections, and to Reproduce the Work as incorporated in the +# Collections; +# 2. to create and Reproduce Adaptations provided that any such +# Adaptation, including any translation in any medium, takes +# reasonable steps to clearly label, demarcate or otherwise identify +# that changes were made to the original Work. For example, a +# translation could be marked "The original work was translated from +# English to Spanish," or a modification could indicate "The original +# work has been modified."; +# 3. to Distribute and Publicly Perform the Work including as +# incorporated in Collections; and, +# 4. to Distribute and Publicly Perform Adaptations. +# 5. +# +# For the avoidance of doubt: +# +# 1. *Non-waivable Compulsory License Schemes*. In those +# jurisdictions in which the right to collect royalties through +# any statutory or compulsory licensing scheme cannot be waived, +# the Licensor reserves the exclusive right to collect such +# royalties for any exercise by You of the rights granted under +# this License; +# 2. *Waivable Compulsory License Schemes*. In those jurisdictions in +# which the right to collect royalties through any statutory or +# compulsory licensing scheme can be waived, the Licensor waives +# the exclusive right to collect such royalties for any exercise +# by You of the rights granted under this License; and, +# 3. *Voluntary License Schemes*. The Licensor waives the right to +# collect royalties, whether individually or, in the event that +# the Licensor is a member of a collecting society that +# administers voluntary licensing schemes, via that society, from +# any exercise by You of the rights granted under this License. +# +# The above rights may be exercised in all media and formats whether now +# known or hereafter devised. The above rights include the right to make +# such modifications as are technically necessary to exercise the rights +# in other media and formats. Subject to Section 8(f), all rights not +# expressly granted by Licensor are hereby reserved. +# +# *4. Restrictions.* The license granted in Section 3 above is expressly +# made subject to and limited by the following restrictions: +# +# 1. You may Distribute or Publicly Perform the Work only under the terms +# of this License. You must include a copy of, or the Uniform Resource +# Identifier (URI) for, this License with every copy of the Work You +# Distribute or Publicly Perform. You may not offer or impose any +# terms on the Work that restrict the terms of this License or the +# ability of the recipient of the Work to exercise the rights granted +# to that recipient under the terms of the License. You may not +# sublicense the Work. You must keep intact all notices that refer to +# this License and to the disclaimer of warranties with every copy of +# the Work You Distribute or Publicly Perform. When You Distribute or +# Publicly Perform the Work, You may not impose any effective +# technological measures on the Work that restrict the ability of a +# recipient of the Work from You to exercise the rights granted to +# that recipient under the terms of the License. This Section 4(a) +# applies to the Work as incorporated in a Collection, but this does +# not require the Collection apart from the Work itself to be made +# subject to the terms of this License. If You create a Collection, +# upon notice from any Licensor You must, to the extent practicable, +# remove from the Collection any credit as required by Section 4(c), +# as requested. If You create an Adaptation, upon notice from any +# Licensor You must, to the extent practicable, remove from the +# Adaptation any credit as required by Section 4(c), as requested. +# 2. You may Distribute or Publicly Perform an Adaptation only under the +# terms of: (i) this License; (ii) a later version of this License +# with the same License Elements as this License; (iii) a Creative +# Commons jurisdiction license (either this or a later license +# version) that contains the same License Elements as this License +# (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons +# Compatible License. If you license the Adaptation under one of the +# licenses mentioned in (iv), you must comply with the terms of that +# license. If you license the Adaptation under the terms of any of the +# licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), +# you must comply with the terms of the Applicable License generally +# and the following provisions: (I) You must include a copy of, or the +# URI for, the Applicable License with every copy of each Adaptation +# You Distribute or Publicly Perform; (II) You may not offer or impose +# any terms on the Adaptation that restrict the terms of the +# Applicable License or the ability of the recipient of the Adaptation +# to exercise the rights granted to that recipient under the terms of +# the Applicable License; (III) You must keep intact all notices that +# refer to the Applicable License and to the disclaimer of warranties +# with every copy of the Work as included in the Adaptation You +# Distribute or Publicly Perform; (IV) when You Distribute or Publicly +# Perform the Adaptation, You may not impose any effective +# technological measures on the Adaptation that restrict the ability +# of a recipient of the Adaptation from You to exercise the rights +# granted to that recipient under the terms of the Applicable License. +# This Section 4(b) applies to the Adaptation as incorporated in a +# Collection, but this does not require the Collection apart from the +# Adaptation itself to be made subject to the terms of the Applicable +# License. +# 3. If You Distribute, or Publicly Perform the Work or any Adaptations +# or Collections, You must, unless a request has been made pursuant to +# Section 4(a), keep intact all copyright notices for the Work and +# provide, reasonable to the medium or means You are utilizing: (i) +# the name of the Original Author (or pseudonym, if applicable) if +# supplied, and/or if the Original Author and/or Licensor designate +# another party or parties (e.g., a sponsor institute, publishing +# entity, journal) for attribution ("Attribution Parties") in +# Licensor's copyright notice, terms of service or by other reasonable +# means, the name of such party or parties; (ii) the title of the Work +# if supplied; (iii) to the extent reasonably practicable, the URI, if +# any, that Licensor specifies to be associated with the Work, unless +# such URI does not refer to the copyright notice or licensing +# information for the Work; and (iv) , consistent with Ssection 3(b), +# in the case of an Adaptation, a credit identifying the use of the +# Work in the Adaptation (e.g., "French translation of the Work by +# Original Author," or "Screenplay based on original Work by Original +# Author"). The credit required by this Section 4(c) may be +# implemented in any reasonable manner; provided, however, that in the +# case of a Adaptation or Collection, at a minimum such credit will +# appear, if a credit for all contributing authors of the Adaptation +# or Collection appears, then as part of these credits and in a manner +# at least as prominent as the credits for the other contributing +# authors. For the avoidance of doubt, You may only use the credit +# required by this Section for the purpose of attribution in the +# manner set out above and, by exercising Your rights under this +# License, You may not implicitly or explicitly assert or imply any +# connection with, sponsorship or endorsement by the Original Author, +# Licensor and/or Attribution Parties, as appropriate, of You or Your +# use of the Work, without the separate, express prior written +# permission of the Original Author, Licensor and/or Attribution Parties. +# 4. Except as otherwise agreed in writing by the Licensor or as may be +# otherwise permitted by applicable law, if You Reproduce, Distribute +# or Publicly Perform the Work either by itself or as part of any +# Adaptations or Collections, You must not distort, mutilate, modify +# or take other derogatory action in relation to the Work which would +# be prejudicial to the Original Author's honor or reputation. +# Licensor agrees that in those jurisdictions (e.g. Japan), in which +# any exercise of the right granted in Section 3(b) of this License +# (the right to make Adaptations) would be deemed to be a distortion, +# mutilation, modification or other derogatory action prejudicial to +# the Original Author's honor and reputation, the Licensor will waive +# or not assert, as appropriate, this Section, to the fullest extent +# permitted by the applicable national law, to enable You to +# reasonably exercise Your right under Section 3(b) of this License +# (right to make Adaptations) but not otherwise. +# +# *5. Representations, Warranties and Disclaimer* +# +# UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +# OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +# KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +# INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +# FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +# LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +# WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE +# EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. +# +# *6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY +# APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL +# THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY +# DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF +# LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +# +# *7. Termination* +# +# 1. This License and the rights granted hereunder will terminate +# automatically upon any breach by You of the terms of this License. +# Individuals or entities who have received Adaptations or Collections +# from You under this License, however, will not have their licenses +# terminated provided such individuals or entities remain in full +# compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will +# survive any termination of this License. +# 2. Subject to the above terms and conditions, the license granted here +# is perpetual (for the duration of the applicable copyright in the +# Work). Notwithstanding the above, Licensor reserves the right to +# release the Work under different license terms or to stop +# distributing the Work at any time; provided, however that any such +# election will not serve to withdraw this License (or any other +# license that has been, or is required to be, granted under the terms +# of this License), and this License will continue in full force and +# effect unless terminated as stated above. +# +# *8. Miscellaneous* +# +# 1. Each time You Distribute or Publicly Perform the Work or a +# Collection, the Licensor offers to the recipient a license to the +# Work on the same terms and conditions as the license granted to You +# under this License. +# 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor +# offers to the recipient a license to the original Work on the same +# terms and conditions as the license granted to You under this License. +# 3. If any provision of this License is invalid or unenforceable under +# applicable law, it shall not affect the validity or enforceability +# of the remainder of the terms of this License, and without further +# action by the parties to this agreement, such provision shall be +# reformed to the minimum extent necessary to make such provision +# valid and enforceable. +# 4. No term or provision of this License shall be deemed waived and no +# breach consented to unless such waiver or consent shall be in +# writing and signed by the party to be charged with such waiver or +# consent. +# 5. This License constitutes the entire agreement between the parties +# with respect to the Work licensed here. There are no understandings, +# agreements or representations with respect to the Work not specified +# here. Licensor shall not be bound by any additional provisions that +# may appear in any communication from You. This License may not be +# modified without the mutual written agreement of the Licensor and You. +# 6. The rights granted under, and the subject matter referenced, in this +# License were drafted utilizing the terminology of the Berne +# Convention for the Protection of Literary and Artistic Works (as +# amended on September 28, 1979), the Rome Convention of 1961, the +# WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms +# Treaty of 1996 and the Universal Copyright Convention (as revised on +# July 24, 1971). These rights and subject matter take effect in the +# relevant jurisdiction in which the License terms are sought to be +# enforced according to the corresponding provisions of the +# implementation of those treaty provisions in the applicable national +# law. If the standard suite of rights granted under applicable +# copyright law includes additional rights not granted under this +# License, such additional rights are deemed to be included in the +# License; this License is not intended to restrict the license of any +# rights under applicable law. +accellerare->accelerare +acellerare->accelerare +accellerata->accelerata +accellerato->accelerato +accellerazione->accelerazione +aereonautica->aeronautica +aereoporti->aeroporti +aereoporto->aeroporto +aereosilurante->aerosilurante +aereosiluranti->aerosiluranti +affianco->a fianco +affilliate->affiliate +aggiottaggio->aggiotaggio +aggresive->aggressive +agravate->aggravate +alse->else +appropiata->appropriata +appropiate->appropriate +appropiati->appropriati +appropiato->appropriato +approposito->a proposito +appropraite->appropriate +appropropiate->appropriate +approvigionamento->approvvigionamento +apropriate->appropriate +areazione->aerazione +areoporti->aeroporti +areoporto->aeroporto +assisnate->assassinate +assit->assist +asume->assume +audeince->audience +austrailia->Australia +automibile->automobile +avvallo->avallo +backgorund->background +backrounds->backgrounds +benchè->benché +Bernouilli->Bernoulli +biricchino->birichino +bizzare->bizzarre +Buddah->Buddha +buisness->business +busness->business +bussiness->business +caffé->caffè +Caltanisetta->Caltanissetta +Cambrige->Cambridge +candadate->candidate +candiate->candidate +candidiate->candidate +casette->cassette +Celcius->Celsius +Champange->Champagne +cioé->cioè +ciriculum->curriculum +cmoputer->computer +coctail->cocktail +coefficente->coefficiente +coefficenti->coefficienti +collaberative->collaborative +collutazione->colluttazione +commemerative->commemorative +commemmorate->commemorate +comparitive->comparative +competative->competitive +competive->competitive +comprimise->compromise +compropietari->comproprietari +compropietaria->comproprietaria +compropietarie->comproprietarie +compropietario->comproprietario +Conneticut->Connecticut +conosciente->conoscente +conoscienti->conoscenti +conoscienza->conoscenza +consectutive->consecutive +consentrate->concentrate +conservitive->conservative +consolodate->consolidate +contaiminate->contaminate +contendor->contender +coputer->computer +copywrite->copyright +corelate->correlate +correzzione->correzione +coscente->cosciente +coscenti->coscienti +coscenza->coscienza +cosi->così +cosidetto->cosiddetto +cumulatative->cumulative +curch->church +curriculem->curriculum +dasse->desse +decomposit->decompose +deficente->deficiente +deficenti->deficienti +deficenza->deficienza +definate->definite +derivitive->derivative +deside->decide +desktiop->desktop +deteriate->deteriorate +devide->divide +diminuitive->diminutive +dispence->dispense +doesnt->doesn't +dosen't->doesn't +drnik->drink +dupicate->duplicate +E'->È +É->È +etc.->ecc. +eccezzionale->eccezionale +eccezzionali->eccezionali +eccezzione->eccezione +ect->etc +eminate->emanate +enduce->induce +esle->else +esterefatto->esterrefatto +faciliate->facilitate +facillitate->facilitate +Farenheit->Fahrenheit +fianite->finite +foootball->football +foucs->focus +Gameboy->Game Boy +ganerate->generate +Ghandi->Gandhi +gia->già +gia'->già +giacchè->giacché +giaccue->giacque +grafitti->graffiti +Guilia->Giulia +Guilio->Giulio +Guiness->Guinness +Guiseppe->Giuseppe +halp->help +hapening->happening +hertzs->hertz +imcomplete->incomplete +imense->immense +immitate->imitate +inappropiate->inappropriate +includ->include +incoscente->incosciente +incoscenti->incoscienti +incoscenza->incoscienza +inctroduce->introduce +indulgue->indulge +infilitrate->infiltrate +infinit->infinite +ingegniere->ingegnere +innoquo->innocuo +inpolite->impolite +inquanto->in quanto +insufficente->insufficiente +insufficenti->insufficienti +insufficenza->insufficienza +interm->interim +interrim->interim +intutive->intuitive +investingate->investigate +iunior->junior +knwo->know +konw->know +kwno->know +levetate->levitate +loev->love +lveo->love +lvoe->love +Macchiavelli->Machiavelli +maggiorparte->maggior parte +magolia->magnolia +managment->management +marketting->marketing +Massachussets->Massachusetts +Massachussetts->Massachusetts +medacine->medicine +mercentile->mercantile +messanger->messenger +metereologia->meteorologia +metereologico->meteorologico +Michagan->Michigan +minature->miniature +misile->missile +Misouri->Missouri +Missisipi->Mississippi +Missisippi->Mississippi +missle->missile +moderm->modem +modle->model +Monserrat->Montserrat +mroe->more +muscial->musical +mussulmano->musulmano +naturual->natural +Nazereth->Nazareth +necessiate->necessitate +nkow->know +nkwo->know +noveau->nouveau +ocuntry->country +omlette->omelette +omre->more +onniscente->onnisciente +onniscenti->onniscienti +onoreficenze->onorificenze +onyl->only +ovverossia->ovverosia +pallete->palette +pantomine->pantomime +pary->party +penatly->penalty +perchè->perché +perche'->perché +percui->per cui +performence->performance +pero'->però +perogative->prerogative +peronospera->peronospora +piu->più +piu'->più +plateu->plateau +pò->po' +poiche'->poiché +poichè->poiché +preceed->precede +pressocche'->pressoché +pressocché->pressoché +preverse->perverse +primative->primitive +privte->private +proceedure->procedure +processer->processor +profesor->professor +professer->professor +proffesed->professed +proffesor->professor +profiquo->proficuo +proove->prove +propietà ->proprietà +propietari->proprietari +propietaria->proprietaria +propietarie->proprietarie +propietario->proprietario +propio->proprio +propoganda->propaganda +propogate->propagate +prospicente->prospiciente +prospicenti->prospicienti +provacative->provocative +psuedo->pseudo +Pucini->Puccini +pursuade->persuade +pwoer->power +recrod->record +redarre->redigere +refedendum->referendum +rela->real +riconosciente->riconoscente +riconoscienti->riconoscenti +riconoscienza->riconoscenza +rocord->record +rubgy->rugby +sandwhich->sandwich +satelite->satellite +sattelite->satellite +scandanavia->Scandinavia +scenza->scienza +scenze->scienze +scirpt->script +se'->sé +sè->sé +sensa->senza +senstive->sensitive +sensure->censure +senzo->senso +smoe->some +soem->some +sofware->software +sohw->show +sopratutto->soprattutto +soudn->sound +speci->specie +spoace->space +sponser->sponsor +staion->station +stasse->stesse +stong->strong +stpo->stop +strazzio->strazio +su'->sù +succesiva->successiva +succesive->successive +succesivi->successivi +succesivo->successivo +sucessiva->successiva +sucessive->successive +sucessivi->successivi +sucessivo->successivo +sufficente->sufficiente +sufficenti->sufficienti +sufficenza->sufficienza +sytem->system +tast->taste +té->tè +tghe->the +timne->time +tje->the +tjhe->the +transare->transigere +tremelo->tremolo +troup->troupe +tust->trust +vadino->vadano +valetta->valletta +ventitrè->ventitré +vicere->viceré +zeebra->zebra diff --git a/files/typos-nb.txt b/files/typos/typos-nb.txt index a662d9a..1043627 100644 --- a/files/typos-nb.txt +++ b/files/typos/typos-nb.txt @@ -3,6 +3,7 @@ andriod->android # The remainder of this file contains misspellings from # http://no.wikipedia.org/wiki/Wikipedia:Liste_over_alminnelige_stavefeil/Maskinform +# plus some post-processing to fix invalid entries, remove duplicates, etc. # # The content is available under the # "Creative Commons Attribution-ShareAlike License" @@ -445,4 +446,4 @@ underholdene->underholdende vakum->vakuum viderekommende->viderekomne værre->verre -værste->verste
\ No newline at end of file +værste->verste diff --git a/files/typos/typos-pt.txt b/files/typos/typos-pt.txt new file mode 100644 index 0000000..6285d37 --- /dev/null +++ b/files/typos/typos-pt.txt @@ -0,0 +1,1647 @@ +# This file contains a number of common Portuguese typos: +andriod->android + +# The remainder of this file contains misspellings from +# http://pt.wikipedia.org/wiki/Wikip%C3%A9dia:Software/Anti-vandal_tool/Ortografia +# plus some post-processing to fix invalid entries, remove duplicates, etc. +# +# The content is available under the +# "Creative Commons Attribution-ShareAlike License" +# http://creativecommons.org/licenses/by-sa/3.0/ +# +# THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +# COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +# COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +# AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. +# +# BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +# TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +# BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +# CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +# CONDITIONS. +# +# *1. Definitions* +# +# 1. *"Adaptation"* means a work based upon the Work, or upon the Work +# and other pre-existing works, such as a translation, adaptation, +# derivative work, arrangement of music or other alterations of a +# literary or artistic work, or phonogram or performance and includes +# cinematographic adaptations or any other form in which the Work may +# be recast, transformed, or adapted including in any form +# recognizably derived from the original, except that a work that +# constitutes a Collection will not be considered an Adaptation for +# the purpose of this License. For the avoidance of doubt, where the +# Work is a musical work, performance or phonogram, the +# synchronization of the Work in timed-relation with a moving image +# ("synching") will be considered an Adaptation for the purpose of +# this License. +# 2. *"Collection"* means a collection of literary or artistic works, +# such as encyclopedias and anthologies, or performances, phonograms +# or broadcasts, or other works or subject matter other than works +# listed in Section 1(f) below, which, by reason of the selection and +# arrangement of their contents, constitute intellectual creations, in +# which the Work is included in its entirety in unmodified form along +# with one or more other contributions, each constituting separate and +# independent works in themselves, which together are assembled into a +# collective whole. A work that constitutes a Collection will not be +# considered an Adaptation (as defined below) for the purposes of this +# License. +# 3. *"Creative Commons Compatible License"* means a license that is +# listed at http://creativecommons.org/compatiblelicenses that has +# been approved by Creative Commons as being essentially equivalent to +# this License, including, at a minimum, because that license: (i) +# contains terms that have the same purpose, meaning and effect as the +# License Elements of this License; and, (ii) explicitly permits the +# relicensing of adaptations of works made available under that +# license under this License or a Creative Commons jurisdiction +# license with the same License Elements as this License. +# 4. *"Distribute"* means to make available to the public the original +# and copies of the Work or Adaptation, as appropriate, through sale +# or other transfer of ownership. +# 5. *"License Elements"* means the following high-level license +# attributes as selected by Licensor and indicated in the title of +# this License: Attribution, ShareAlike. +# 6. *"Licensor"* means the individual, individuals, entity or entities +# that offer(s) the Work under the terms of this License. +# 7. *"Original Author"* means, in the case of a literary or artistic +# work, the individual, individuals, entity or entities who created +# the Work or if no individual or entity can be identified, the +# publisher; and in addition (i) in the case of a performance the +# actors, singers, musicians, dancers, and other persons who act, +# sing, deliver, declaim, play in, interpret or otherwise perform +# literary or artistic works or expressions of folklore; (ii) in the +# case of a phonogram the producer being the person or legal entity +# who first fixes the sounds of a performance or other sounds; and, +# (iii) in the case of broadcasts, the organization that transmits the +# broadcast. +# 8. *"Work"* means the literary and/or artistic work offered under the +# terms of this License including without limitation any production in +# the literary, scientific and artistic domain, whatever may be the +# mode or form of its expression including digital form, such as a +# book, pamphlet and other writing; a lecture, address, sermon or +# other work of the same nature; a dramatic or dramatico-musical work; +# a choreographic work or entertainment in dumb show; a musical +# composition with or without words; a cinematographic work to which +# are assimilated works expressed by a process analogous to +# cinematography; a work of drawing, painting, architecture, +# sculpture, engraving or lithography; a photographic work to which +# are assimilated works expressed by a process analogous to +# photography; a work of applied art; an illustration, map, plan, +# sketch or three-dimensional work relative to geography, topography, +# architecture or science; a performance; a broadcast; a phonogram; a +# compilation of data to the extent it is protected as a copyrightable +# work; or a work performed by a variety or circus performer to the +# extent it is not otherwise considered a literary or artistic work. +# 9. *"You"* means an individual or entity exercising rights under this +# License who has not previously violated the terms of this License +# with respect to the Work, or who has received express permission +# from the Licensor to exercise rights under this License despite a +# previous violation. +# 10. *"Publicly Perform"* means to perform public recitations of the Work +# and to communicate to the public those public recitations, by any +# means or process, including by wire or wireless means or public +# digital performances; to make available to the public Works in such +# a way that members of the public may access these Works from a place +# and at a place individually chosen by them; to perform the Work to +# the public by any means or process and the communication to the +# public of the performances of the Work, including by public digital +# performance; to broadcast and rebroadcast the Work by any means +# including signs, sounds or images. +# 11. *"Reproduce"* means to make copies of the Work by any means +# including without limitation by sound or visual recordings and the +# right of fixation and reproducing fixations of the Work, including +# storage of a protected performance or phonogram in digital form or +# other electronic medium. +# +# *2. Fair Dealing Rights.* Nothing in this License is intended to reduce, +# limit, or restrict any uses free from copyright or rights arising from +# limitations or exceptions that are provided for in connection with the +# copyright protection under copyright law or other applicable laws. +# +# *3. License Grant.* Subject to the terms and conditions of this License, +# Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +# perpetual (for the duration of the applicable copyright) license to +# exercise the rights in the Work as stated below: +# +# 1. to Reproduce the Work, to incorporate the Work into one or more +# Collections, and to Reproduce the Work as incorporated in the +# Collections; +# 2. to create and Reproduce Adaptations provided that any such +# Adaptation, including any translation in any medium, takes +# reasonable steps to clearly label, demarcate or otherwise identify +# that changes were made to the original Work. For example, a +# translation could be marked "The original work was translated from +# English to Spanish," or a modification could indicate "The original +# work has been modified."; +# 3. to Distribute and Publicly Perform the Work including as +# incorporated in Collections; and, +# 4. to Distribute and Publicly Perform Adaptations. +# 5. +# +# For the avoidance of doubt: +# +# 1. *Non-waivable Compulsory License Schemes*. In those +# jurisdictions in which the right to collect royalties through +# any statutory or compulsory licensing scheme cannot be waived, +# the Licensor reserves the exclusive right to collect such +# royalties for any exercise by You of the rights granted under +# this License; +# 2. *Waivable Compulsory License Schemes*. In those jurisdictions in +# which the right to collect royalties through any statutory or +# compulsory licensing scheme can be waived, the Licensor waives +# the exclusive right to collect such royalties for any exercise +# by You of the rights granted under this License; and, +# 3. *Voluntary License Schemes*. The Licensor waives the right to +# collect royalties, whether individually or, in the event that +# the Licensor is a member of a collecting society that +# administers voluntary licensing schemes, via that society, from +# any exercise by You of the rights granted under this License. +# +# The above rights may be exercised in all media and formats whether now +# known or hereafter devised. The above rights include the right to make +# such modifications as are technically necessary to exercise the rights +# in other media and formats. Subject to Section 8(f), all rights not +# expressly granted by Licensor are hereby reserved. +# +# *4. Restrictions.* The license granted in Section 3 above is expressly +# made subject to and limited by the following restrictions: +# +# 1. You may Distribute or Publicly Perform the Work only under the terms +# of this License. You must include a copy of, or the Uniform Resource +# Identifier (URI) for, this License with every copy of the Work You +# Distribute or Publicly Perform. You may not offer or impose any +# terms on the Work that restrict the terms of this License or the +# ability of the recipient of the Work to exercise the rights granted +# to that recipient under the terms of the License. You may not +# sublicense the Work. You must keep intact all notices that refer to +# this License and to the disclaimer of warranties with every copy of +# the Work You Distribute or Publicly Perform. When You Distribute or +# Publicly Perform the Work, You may not impose any effective +# technological measures on the Work that restrict the ability of a +# recipient of the Work from You to exercise the rights granted to +# that recipient under the terms of the License. This Section 4(a) +# applies to the Work as incorporated in a Collection, but this does +# not require the Collection apart from the Work itself to be made +# subject to the terms of this License. If You create a Collection, +# upon notice from any Licensor You must, to the extent practicable, +# remove from the Collection any credit as required by Section 4(c), +# as requested. If You create an Adaptation, upon notice from any +# Licensor You must, to the extent practicable, remove from the +# Adaptation any credit as required by Section 4(c), as requested. +# 2. You may Distribute or Publicly Perform an Adaptation only under the +# terms of: (i) this License; (ii) a later version of this License +# with the same License Elements as this License; (iii) a Creative +# Commons jurisdiction license (either this or a later license +# version) that contains the same License Elements as this License +# (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons +# Compatible License. If you license the Adaptation under one of the +# licenses mentioned in (iv), you must comply with the terms of that +# license. If you license the Adaptation under the terms of any of the +# licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), +# you must comply with the terms of the Applicable License generally +# and the following provisions: (I) You must include a copy of, or the +# URI for, the Applicable License with every copy of each Adaptation +# You Distribute or Publicly Perform; (II) You may not offer or impose +# any terms on the Adaptation that restrict the terms of the +# Applicable License or the ability of the recipient of the Adaptation +# to exercise the rights granted to that recipient under the terms of +# the Applicable License; (III) You must keep intact all notices that +# refer to the Applicable License and to the disclaimer of warranties +# with every copy of the Work as included in the Adaptation You +# Distribute or Publicly Perform; (IV) when You Distribute or Publicly +# Perform the Adaptation, You may not impose any effective +# technological measures on the Adaptation that restrict the ability +# of a recipient of the Adaptation from You to exercise the rights +# granted to that recipient under the terms of the Applicable License. +# This Section 4(b) applies to the Adaptation as incorporated in a +# Collection, but this does not require the Collection apart from the +# Adaptation itself to be made subject to the terms of the Applicable +# License. +# 3. If You Distribute, or Publicly Perform the Work or any Adaptations +# or Collections, You must, unless a request has been made pursuant to +# Section 4(a), keep intact all copyright notices for the Work and +# provide, reasonable to the medium or means You are utilizing: (i) +# the name of the Original Author (or pseudonym, if applicable) if +# supplied, and/or if the Original Author and/or Licensor designate +# another party or parties (e.g., a sponsor institute, publishing +# entity, journal) for attribution ("Attribution Parties") in +# Licensor's copyright notice, terms of service or by other reasonable +# means, the name of such party or parties; (ii) the title of the Work +# if supplied; (iii) to the extent reasonably practicable, the URI, if +# any, that Licensor specifies to be associated with the Work, unless +# such URI does not refer to the copyright notice or licensing +# information for the Work; and (iv) , consistent with Ssection 3(b), +# in the case of an Adaptation, a credit identifying the use of the +# Work in the Adaptation (e.g., "French translation of the Work by +# Original Author," or "Screenplay based on original Work by Original +# Author"). The credit required by this Section 4(c) may be +# implemented in any reasonable manner; provided, however, that in the +# case of a Adaptation or Collection, at a minimum such credit will +# appear, if a credit for all contributing authors of the Adaptation +# or Collection appears, then as part of these credits and in a manner +# at least as prominent as the credits for the other contributing +# authors. For the avoidance of doubt, You may only use the credit +# required by this Section for the purpose of attribution in the +# manner set out above and, by exercising Your rights under this +# License, You may not implicitly or explicitly assert or imply any +# connection with, sponsorship or endorsement by the Original Author, +# Licensor and/or Attribution Parties, as appropriate, of You or Your +# use of the Work, without the separate, express prior written +# permission of the Original Author, Licensor and/or Attribution Parties. +# 4. Except as otherwise agreed in writing by the Licensor or as may be +# otherwise permitted by applicable law, if You Reproduce, Distribute +# or Publicly Perform the Work either by itself or as part of any +# Adaptations or Collections, You must not distort, mutilate, modify +# or take other derogatory action in relation to the Work which would +# be prejudicial to the Original Author's honor or reputation. +# Licensor agrees that in those jurisdictions (e.g. Japan), in which +# any exercise of the right granted in Section 3(b) of this License +# (the right to make Adaptations) would be deemed to be a distortion, +# mutilation, modification or other derogatory action prejudicial to +# the Original Author's honor and reputation, the Licensor will waive +# or not assert, as appropriate, this Section, to the fullest extent +# permitted by the applicable national law, to enable You to +# reasonably exercise Your right under Section 3(b) of this License +# (right to make Adaptations) but not otherwise. +# +# *5. Representations, Warranties and Disclaimer* +# +# UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +# OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +# KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +# INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +# FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +# LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +# WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE +# EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. +# +# *6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY +# APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL +# THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY +# DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF +# LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +# +# *7. Termination* +# +# 1. This License and the rights granted hereunder will terminate +# automatically upon any breach by You of the terms of this License. +# Individuals or entities who have received Adaptations or Collections +# from You under this License, however, will not have their licenses +# terminated provided such individuals or entities remain in full +# compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will +# survive any termination of this License. +# 2. Subject to the above terms and conditions, the license granted here +# is perpetual (for the duration of the applicable copyright in the +# Work). Notwithstanding the above, Licensor reserves the right to +# release the Work under different license terms or to stop +# distributing the Work at any time; provided, however that any such +# election will not serve to withdraw this License (or any other +# license that has been, or is required to be, granted under the terms +# of this License), and this License will continue in full force and +# effect unless terminated as stated above. +# +# *8. Miscellaneous* +# +# 1. Each time You Distribute or Publicly Perform the Work or a +# Collection, the Licensor offers to the recipient a license to the +# Work on the same terms and conditions as the license granted to You +# under this License. +# 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor +# offers to the recipient a license to the original Work on the same +# terms and conditions as the license granted to You under this License. +# 3. If any provision of this License is invalid or unenforceable under +# applicable law, it shall not affect the validity or enforceability +# of the remainder of the terms of this License, and without further +# action by the parties to this agreement, such provision shall be +# reformed to the minimum extent necessary to make such provision +# valid and enforceable. +# 4. No term or provision of this License shall be deemed waived and no +# breach consented to unless such waiver or consent shall be in +# writing and signed by the party to be charged with such waiver or +# consent. +# 5. This License constitutes the entire agreement between the parties +# with respect to the Work licensed here. There are no understandings, +# agreements or representations with respect to the Work not specified +# here. Licensor shall not be bound by any additional provisions that +# may appear in any communication from You. This License may not be +# modified without the mutual written agreement of the Licensor and You. +# 6. The rights granted under, and the subject matter referenced, in this +# License were drafted utilizing the terminology of the Berne +# Convention for the Protection of Literary and Artistic Works (as +# amended on September 28, 1979), the Rome Convention of 1961, the +# WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms +# Treaty of 1996 and the Universal Copyright Convention (as revised on +# July 24, 1971). These rights and subject matter take effect in the +# relevant jurisdiction in which the License terms are sought to be +# enforced according to the corresponding provisions of the +# implementation of those treaty provisions in the applicable national +# law. If the standard suite of rights granted under applicable +# copyright law includes additional rights not granted under this +# License, such additional rights are deemed to be included in the +# License; this License is not intended to restrict the license of any +# rights under applicable law. +a a->a +à cavalo->a cavalo +a muito tempo->há muito tempo +à muito tempo->há muito tempo +a nÃvel de->em nÃvel de, ao nÃvel de +à pé->a pé +aandeija->bandeja +abitual->habitual +acêrca->acerca +à cerca->acerca +acessiveis->acessÃveis +acessivel->acessÃvel +acessor->assessor +acessora->assessora +acessoras->assessoras +acessores->assessores +acessoria->assessoria +acessorio->acessório +acessorios->acessórios +acesssada->acessada +acesssadas->acessadas +acesssado->acessado +acesssados->acessados +açoes->acções +aconselhaveis->aconselháveis +aconselhavel->aconselhável +açoreana->açoriana +açoreanas->açorianas +açoreano->açoriano +açoreanos->açorianos +actris->atriz +açucar ->açúcar +acustica->acústica +acusticas->acústicas +acustico->acústico +acusticos->acústicos +adimite->admite +adimitir->admitir +adimitiram->admitiram +adimitiu->admitiu +admnistração->administração +admnistrar->administrar +adolescencia->adolescência +afim->a fim +Africa->Ãfrica +agencia->agência +agradaveis->agradáveis +agradavel->agradável +agricola->agrÃcola +agricolas->agrÃcolas +agua->água +aguas->águas +aki->aqui +album->álbum +albúm->álbum +albùm->álbum +albums->álbuns +albun->álbum +albuns->álbuns +albúns->álbuns +albùns->álbuns +alcolémia->alcoolemia +alcolico->alcoólico +alcólico->alcoólico +alcolicos->alcoólicos +alcólicos->alcoólicos +alcoolémia->alcoolemia +alcóolica->alcoólica +alcoolico->alcoólico +alcóolico->alcoólico +alcoolicos->alcoólicos +aleatorios->aleatórios +algeriano->argelino +algorÃtmo->algoritmo +algorÃtmos->algoritmos +alguem->alguém +altoridade->autoridade +altoridades->autoridades +amanha->amanhã +amargúra->amargura +amargúria->amargura +ambulancia->ambulância +ambulancias->ambulâncias +anciosa->ansiosa +ancioso->ansioso +anciosas->ansiosas +anciosos->ansiosos +anciosamente->ansiosamente +anemona->anémona,anêmona +anglofona->anglófona +anglófonas->anglófonas +anglofono->anglófono +anglofonos->anglófonos +angulo->ângulo +angulos->ângulos +anonimo->anónimo, anônimo +antepôr->antepor +anti aéreo->antiaéreo +anti depressivo->antidepressivo +anti-vÃrus->antivÃrus +anuncio->anúncio +ao meu ver->a meu ver +aparencia->aparência, aparecia +aparencias->aparências +aplicaçao->aplicação +Aracajú->Aracaju +arco-iris->arco-Ãris +arcoiris->arco-Ãris +arcoÃris->arco-Ãris +areas->áreas +argerino->argelino +aristocratica->aristocrática +aristocraticas->aristocráticas +aristocratico->aristocrático +aristocraticos->aristocráticos +armonia->harmonia +arquipelago->arquipélago +arquipelagos->arquipélagos +arquipelogo->arquipélago +artistica->artÃstica +artisticas->artÃsticas +artistico->artÃstico +artisticos->artÃsticos +ascençao->ascensão +ascenção->ascensão +ascensao->ascensão +Asia->Ãsia +asiatica->asiática +asim->assim +assasinato->assassinato +assistencia->assistência +associção->associação +aste->haste +ateismo->ateÃsmo +aterisagem->aterrissagem +aterissagem->aterrissagem +aterrisagem->aterrissagem +aterrizagem->aterrissagem +atras->atrás +atraves->através +atravez->através +atravéz->através +atraz->atrás +atráz->atrás +atribuida->atribuÃda +atribuidas->atribuÃdas +atribuido->atribuÃdo +atribuidos->atribuÃdos +atris->atriz, actriz, atris +audiencia->audiência +audiencias->audiências +ausencia->ausência +ausencias->ausências +autentica->autêntica +autenticas->autênticas +autentico->autêntico +autenticos->autênticos +automoveis->automóveis +automovel->automóvel +autonoma->autónoma, autônoma +autonomas->autónomas, autônomas +autonomo->autónomo, autônomo +autonomos->autónomos, autônomos +autopsia->autópsia +aver->haver +aviacao->aviação +aviacão->aviação +aviasão->aviação +avogrado->Avogadro +avulsso->avulso +azaléia->azaléa +azas->asas +bahiana->baiana +bahiano->baiano +baÃnha->bainha +baÃnhas->bainhas +banca-rota->bancarrota +banca-rrota->bancarrota +bancarota->bancarrota +barbarie->barbárie +barbaries->barbáries +bébe->bebé +bébé->bebé +bébes->bebés +bébés->bebés +beige->bege +beiges->beges +beije->bege +beijes->beges +bem vindo->bem-vindo +benção->bênção +bençãos->bênçãos +beneficencia->beneficência +beneficio->benefÃcio +beneficios->benefÃcios +benvindo->bem-vindo +Bertold Brecht->Bertolt Brecht +bevocar->invocar +bi-campeão->bicampeão +bibliografica->bibliográfica +bibliograficas->bibliográficas +bibliografico->bibliográfico +bibliograficos->bibliográficos +biografico->biográfico +biograficos->biográficos +biograifa->biografia +biograifas->biografias +biópsia->biopsia +biópsias->biopsias +boas vindas->Boas-vindas +boeiro->bueiro +borburinho->burburinho +brasao->brasão +brazão->brasão +Brazil->Brasil +britanico->britânico +burborinho->burburinho +bussula->bússola +cadaço->cadarço +caiem->caem +calsado->calçado +calvice->calvÃcie +calvÃce->calvÃcie +camara->câmara +camera->câmera +caminhoes->caminhões, camiões +camioes->camiões, caminhões +campeao->campeão +campeoes->campeões +campiao->campeão +campião->campeão +campioes->campeões +campiões->campeões +campionato->campeonato +campionatos->campeonatos +cançao->canção +cansão->canção +capitão mor->capitão-mor +capitulo->capÃtulo +capitulos->capÃtulos +caracteristica->caracterÃstica +caracteristicas->caracterÃsticas +caracteristico->caracterÃstico +caracteristicos->caracterÃsticos +carissimo->carÃssimo +cassar->caçar, casar, cassar +catalizador->catalisador +catalogo->catálogo +catalogos->catálogos +catequisador->catequizador +catequisar->catequizar +cazamento->casamento +cazar->casar +cazara->casara +cazaram->casaram +cazou->casou +Ceara->Ceará +celebro->cérebro +cemiterio->cemitério +cemiterios->cemitérios +cenario->cenário +cenarios->cenários +cerebro->cérebro +cerebros->cérebros +chopp->chope +ciclano->sicrano +cidadães->cidadãos +cidadões->cidadãos +ciencia->ciência +ciencias->ciências +cientifica->cientÃfica +cientificas->cientÃficas +cientifico->cientÃfico +cientificos->cientÃficos +circulo->cÃrculo +circulos->cÃrculos +classica->clássica +classicas->clássicas +classico->clássico +classicos->clássicos +clinica->clÃnica +cms->cm +co-habitação->coabitação +coalisão->coalizão +côco->coco +coerencia->coerência +coerencias->coerências +cohabitação->coabitação +comcerteza->com certeza +comecou->começou +comedia->comédia +comercio->comércio +comercios->comércios +comisão->comissão +comisoes->comissões +comisões->comissões +comissao->comissão +comnosco->connosco +compôr->compor +compreenção->compreensão +compreenções->compreensões +compreenssão->compreensão +compreenssões->compreensões +concerteza->com certeza +conciderada->considerada +concideradas->consideradas +conciderado->considerado +conciderados->considerados +concluÃndo->concluindo +concretisar->concretizar +condiçao->condição +condissao->condição +condissão->condição +conseguÃrem->conseguirem +constituia->constituÃa +constituiam->constituÃam +constituiram->constituÃram +constroi->constrói +construia->construÃa +construida->construÃda +construidas->construÃdas +construido->construÃdo +construidos->construÃdo +contemporaneo->contemporâneo +contemporaneos->contemporâneos +contribue->contribui +contrução->construção +contruÃdo->construÃdo +contruir->construir +converçao->conversão +converção->conversão +conversao->conversão +converssão->conversão +côr->cor +corçario->corsário +côres->cores +cornea->córnea +corneas->córneas +corografico->corográfico +corograficos->corográficos +correiro eletronico->correio electrónico, correio eletrônico +corrijiam->corrigiam +corrijir->corrigir +corrijiram->corrigiram +crâneo->crânio +crâneos->crânios +criaça->criança +criacao->criação +criaçao->criação +criaças->crianças +crianca->criança +criancas->crianças +cristianizacao->cristianização +cristianizacão->cristianização +cristianizacoes->cristianizações +cristianizacões->cristianizações +criticas->crÃticas +critÃcas->crÃticas +criticos->crÃticos +critÃcos->crÃticos +crueis->cruéis +culinaria->culinária +custuma->costuma +custumava->costumava +custumavam->costumavam +custume->costume +custumes->costumes +decada->década +decadas->décadas +decadencia->decadência +decadencias->decadências +decer->descer +deceram->desceram +declinio->declÃnio +declinios->declÃnios +defeniçao->definição +defenição->definição +defenições->definições +defenido->definido +defenir->definir +definitamente->definitivamente +deiche->deixe +deisponiveis->disponÃveis +deisponivel->disponÃvel +democratica->democrática +demonio->demónio, demônio +demonios->demónios, demônios +depedente->dependente +depedentes->dependentes +deposito->depósito +depositos->depósitos +desagradaveis->desagradáveis +desagradavel->desagradável +descubrimento->descobrimento +descubrimentos->descobrimentos +descubrir->descobrir +descubriram->descobriram +descubrire->descobrire +deseçeis->dezesseis +desembro->Dezembro +desesseis->dezesseis +desnecessario->desnecessário +despensaveis->dispensáveis +despensáveis->dispensáveis +despensavel->dispensável +despensável->dispensável +desprotejida->desprotegida +desprotejidas->desprotegidas +desprotejido->desprotegido +desprotejidos->desprotegidos +destruida->destruÃda +devocao->devoção +devocão->devoção +devoçao->devoção +diagnostico->diagnóstico +diagnosticos->diagnósticos +diaria->diária +diáriamente->diariamente +diario->diário +dibre->drible +diferencas->diferenças +dÃficeis->difÃceis +dificil->difÃcil +dÃficil->difÃcil +dificulidade->dificuldade +difusao->difusão +dignatária->dignitária +dignatárias->dignitárias +dignatário->dignitário +dignatários->dignitários +dijita->digita +dijitar->digitar +dijitara->digitara +dijitaram->digitaram +dijitou->digitou +diminue->diminui +dinamico->dinâmico +discuções->discussões +discursso->discurso +dispender->despender +dispenderam->despenderam +dispendio->dispêndio +dispendios->dispêndios +dispensaveis->dispensáveis +dispensavel->dispensável +disponiveis->disponÃveis +disponivel->disponÃvel +distribuida->distribuÃda +distribuidas->distribuÃdas +distribuido->distribuÃdo +distribuidos->distribuÃdos +disturbio->distúrbio +disturbios->distúrbios +diverssas->diversas +diverssos->diversos +documentario->documentário +documentarios->documentários +dragao->dragão +druÃda->druida +druÃdas->druidas +dsenho->desenho +duvidas->dúvidas +ecessão->exceção +ecessões->exceções +eciclopedia->enciclopédia +eciclopédia->enciclopédia +economica->económica, econômica +ect->etc +egipcios->egÃpcios +egipsio->egÃpcio +elacção->elação +electrônica->electrónica, eletrônica +electrônicas->electrónicas, eletrônicas +electrônico->electrónico, eletrônico +electrônicos->electrónicos, eletrônicos +eletroima->eletroÃmã +eletroimã->eletroÃmã +eletronica->electrónica, eletrônica +eletrónica->electrónica, eletrônica +eletronicas->electrónicas, eletrônicas +eletrónicas->electrónicas, eletrônicas +eletronico->electrónico, eletrônico +eletrónico->electrónico, eletrônico +eletronicos->electrónicos, eletrônicos +eletrónicos->electrónicos, eletrônicos +elice->hélice +emaili->e-mail, email, correio electrónico, correio eletrônico +eminencia->eminência +eminencias->eminências +empresario->empresário +empresarios->empresários +enciclopedia->enciclopédia +enciclopedias->enciclopédias +enfase->ênfase +enfases->ênfases +entao->então +entertido->entretido +entitular->intitular +entretando->entretanto +entreteram->entretiveram +entreterimento->entretenimento +entreteu->entreteve +epecial->especial +epica->épica +epicas->épicas +epico->épico +epicos->épicos +eplepsia->epilepsia +epoca->época +epocas->épocas +equilibrio->equilÃbrio +ernegia->energia +erói->herói +errupção->erupção +escerda->esquerda +escerdas->esquerdas +esitaram->hesitaram +esitou->hesitou +especialisada->especializada +especialisadas->especializadas +especialisado->especializado +especialisados->especializados +espectativa->expectativa +espectativas->expectativas +esperanca->esperança +esperancas->esperanças +espetativa->expectativa +espetativas->expectativas +espirita->espÃrita +espiritas->espÃritas +espirito->espÃrito +espiritos->espÃritos +espulsou->expulsou +esquesita->esquisita +esquesitas->esquisitas +esquesito->esquisito +esquesitos->esquisitos +estabelecimente->estabelecimento +estabelecimentes->estabelecimentos +estaçãoos->estações +estadio->estádio +estadios->estádios +estao->estão +esteje->esteja +estinto->extinto +estintos->extintos +estorquir->extorquir +estorquiram->extorquiram +estorquiu->extorquiu +estudio->estúdio +estudios->estúdios +esturquir->extorquir +esturquiram->extorquiram +esturquiu->extorquiu +ethanol->etanol +etica->ética +eticas->éticas +excavação->escavação +excavar->escavar +excessão->exceção +exdrúxula->esdrúxula +exdrúxulas->esdrúxulas +exdrúxulo->esdrúxulo +exdrúxulos->esdrúxulos +exepto->excepto, exceto +exercicio->exercÃcio +exercicios->exercÃcios +exeto->exceto, excepto +exijência->exigência +exijências->exigências +exitar->hesitar +exitaram->hesitaram +exitou->hesitou +expectador->espectador +expontânea->espontânea +expontâneas->espontâneas +expontâneo->espontâneo +expontâneos->espontâneos +extende-se->estende-se +extender->estender +extenderam->estenderam +facil->fácil +familia->famÃlia +familias->famÃlias +farmaceutica->farmacêutica +farmaceuticas->farmacêuticas +farmaceutico->farmacêutico +farmaceuticos->farmacêuticos +faser->fazer +fecula->fécula +fémea->fêmea +femeninismo->femininismo +femeninismos->femininismos +femenino->feminino +femeninos->femininos +ferverosos->fervorosos +fimeninismo->femininismo +fimeninismos->femininismos +fimenino->feminino +fimeninos->femininos +Finlandia->finlândia +fisica->fÃsica +fizestes->fizeste +flôr->flor +flôres->flores +flôrs->flores +fluÃdo->fluido +fluÃdos->fluidos +forão->foram +fortuÃto->fortuito +fortuÃtos->fortuitos +fotografica->fotográfica +frageis->frágeis +fragil->frágil +Frankstein->Frankenstein +funeraria->funerária +funerarias->funerárias +funerario->funerário +funerarios->funerários +furá->furar +furacao->furacão +furacoes->furacões +galaxia->galáxia +gas->gás +gaz->gás +gáz->gás +geito->jeito +geneceu->gineceu +generico->genérico +genericos->genéricos +genero->género +generos->géneros +genio->génio, gênio +geometrica->geométrico +geometricas->geométricos +geometrico->geométrico +geometricos->geométricos +gipe->jipe +gipes->jipes +giria->gÃria +girias->gÃrias +giroscopico->giroscópio +giroscopio->giroscópio +gorgeta->gorjeta +gorgetas->gorjetas +Grã Bretanha->Grã-Bretanha +graca->graça +gracas->graças +grafico->gráfico +graficos->gráficos +grangear->granjear +gratuÃto->gratuito +gratuÃtos->gratuitos +grau centigrado->grau Celsius +grau centÃgrado->grau Celsius +grau centÃgrados->grau Celsius +grau kelvin->kelvin +guizar->guisar +hà ->há +hambiente->ambiente +hambientes->ambientes +haviam muitos->havia muitos +haviam poucos->havia poucos +hectar->hectare +heraldica->heráldica +heraldico->heráldico +heranca->herança +Herodoto->Heródoto +heróico->heroico +hexa-campeão->hexacampeão +hilariedade->hilaridade +historia->história +historica->histórica +historicas->históricas +historico->histórico +historicos->históricos +homosexual->homossexual +homosexualidade->homossexualidade +horario->horário +horarios->horários +hoxigenio->oxigênio +hoxigênio->oxigênio +humoristica->humorÃstica +humoristico->humorÃstico +ideologÃa->ideologia +idolo->Ãdolo +idolos->Ãdolos +igiene->higiene +igienico->higiênico +iguasu->Iguaçu +ilacção->ilação +imenência->iminência +imenente->iminente +imoveis->imóveis +imovel->imóvel +imperio->império +imperios->impérios +importancia->importância +importancias->importâncias +impresa->empresa +imuno-deficiência->imunodeficiência +imuno-deficiências->imunodeficiências +incluiam->incluÃam +inclusivé->inclusive +indefenição->indefinição +indefenições->indefinições +indefenir->indefinir +indentidade->identidade +indentidades->identidades +India->Ãndia +indice->Ãndice +indigena->indÃgena +indiguinação->indignação +indiguinado->indignado +indiguinar->indignar +indioma->idioma +indiomas->idiomas +individada->endividada +individadas->endividadas +individado->endividado +individados->endividados +individuo->indivÃduo +individuos->indivÃduos +inedita->inédita +ineditas->inéditas +inedito->inédito +ineditos->inéditos +infancia->infância +infelismente->infelizmente +inflacção->inflação +infra vermelho->infravermelho +infra vermelhos->infravermelhos +infra-vermelho->infravermelho +infra-vermelhos->infravermelhos +ingenuo->ingénuo +ingles->inglês +inglêsa->inglesa +inglêsas->inglesas +inglêses->ingleses +ingreja->igreja +inÃcia->inicia +inicio->inÃcio +inicios->inÃcios +inteligencia->inteligência +inteligencias->inteligências +intensão->intenção +intertido->entretido +intervemos->intervimos +intervi->intervim +intervido->intervindo +interviram->intervieram +interviste->intervieste +interviu->interveio +intigração->integração +intrumental->instrumental +intrumento->instrumento +inumeras->inúmeras +inumeros->inúmeros +invensivel->invencÃvel +invensÃvel->invencÃvel +invenssÃvel->invencÃvel +inves->invés +invez->invés +invéz->invés +iorgute->iogurte +iper->hiper +ipopótamo->hipopótamo +ipslon->Ãpslon +irisar->irizar +irmao->irmão +irmaos->irmãos +irupção->irrupção +ispirar->inspirar +ispirou->inspirou +issu->isso +jamelão->jamelada,rabada +japones->japonês +jeropiga->geropiga +Joana d´Arc->Joana d'Arc +judiciaria->judiciária +judiciarias->judiciárias +juÃz->juiz +juiza->juÃza +juizas->juÃzas +juizes->juÃzes +junior->júnior +júniores->juniores +juridica->jurÃdica +juridição->jurisdição +juridicas->jurÃdicas +juridico->jurÃdico +juridicos->jurÃdicos +juz->jus +kilo->quilograma +kilômetro->quilômetro +kilometro->quilómetro, quilômetro +kilómetro->quilómetro, quilômetro +kilometros->quilómetros, quilômetros +kilómetros->quilómetros, quilômetros +km2->km² +largartixa->lagartixa +largarto->lagarto +leem->lêem +leêm->lêem +lêm->lêem +lendaria->lendária +lendarias->lendárias +lendario->lendário +lendarios->lendários +leucémia->leucemia +licenca->licença +licencas->licenças +licensa->licença +lider->lÃder +lideres->lÃderes +lingua->lÃngua +linguas->lÃnguas +linguÃsta->linguista +lÃnguÃsta->linguista +linguÃstas->linguistas +lÃnguÃstas->linguistas +lisongea->lisonjeia +lisongear->lisonjear +lisongeara->lisonjeara +lisongearam->lisonjearam +lisongearou->lisonjearou +lisonjea->lisonjeia +logica->lógica +lógicamente->logicamente +logista->lojista +logistas->lojistas +lojica->lógica +lójica->lógica +lusofona->lusófona +lusofonas->lusófonas +lusofono->lusófono +lusofonos->lusófonos +magestade->majestade +magestades->majestades +magica->mágica +magico->mágico +mangerico->manjerico +mangericos->manjericos +manteram->mantiveram +manteu->manteve +maritima->marÃtima +maritimas->marÃtimas +maritimo->marÃtimo +maritimos->marÃtimos +massiça->maciça +massiças->maciças +massiço->maciço +massiços->maciços +meche->mexe +mecher->mexer +mecheram->mexeram +mecheu->mexeu +médico cirurgião->médico-cirurgião +memoria->memória +memorias->memórias +menas->menos +mercenaria->mercenária +mercenarias->mercenárias +mercenario->mercenário +mercenarios->mercenários +mêses->meses +metereologia->meteorologia +metodo->método +metodos->métodos +miceis->mÃsseis +mÃceis->mÃsseis +micil->mÃssil +mÃcil->mÃssil +minerio->minério +minimo->mÃnimo +missao->missão +mistica->mÃstica +misticas->mÃsticas +mistico->mÃstico +misticos->mÃsticos +miticas->mÃticas +molar->mol/L +molaridade->concentração em quantidade de matéria +muinto->muito +muintos->muitos +multi-uso-> multiúso +multimedia->multimedia, multimÃdia +multimedias->multimédias, multimÃdias +multimidia->multimÃdia, multimédia +multimidias-> multimÃdias, multimédias +multiuso-> multiúso +municipio->municÃpio +munÃcipio->municÃpio +munÃcÃpio->municÃpio +municipios->municÃpios +munÃcipios->municÃpios +munÃcÃpios->municÃpios +munto->muito +muntos->muitos +musica->música +musicas->músicas +musico->músico +musicos->músicos +ñ->não +nanômetro->nanometro +nao->não +naum->não +negocios->negócios +nenum->nenhum +neo darwinismo->neodarwinismo +neo liberais->neoliberais +neo liberal->neoliberal +neo liberalismo->neoliberalismo +neo zelandês->neozelandês +neo zelandesa->neozelandesa +neo-darwinismo->neodarwinismo +neo-liberais->neoliberais +neo-liberal->neoliberal +neo-liberalismo->neoliberalismo +neo-zelandês->neozelandês +neo-zelandesa->neozelandesa +nescessário->necessário +ninguem->ninguém +nivel->nÃvel +nonagesima->nonagésima +nonagesimo->nonagésimo +nonagessima->nonagésima +nonagéssima->nonagésima +nonagessimo->nonagésimo +nonagéssimo->nonagésimo +nostalgico->nostálgico +nostalgicos->nostálgicos +notávelmente->notavelmente +númerais->numerais +númeral->numeral +número de Avogadro->constante de Avogadro +número de moles->quantidade de matéria +número de mols->quantidade de matéria +numero->número +numeros->números +numismatica->numismática +numismatico->numismático +núvem->nuvem +núvens->nuvens +obrigatoria->obrigatória +obrigatorias->obrigatórias +obrigatorio->obrigatório +obrigatorios->obrigatórios +obtem->obtém, obtêm +obteram->obtiveram +obteu->obteve +ºC->°C +odio->ódio +ºF->°F +oje->hoje +olimpico->olÃmpico +olimpicos->olÃmpicos +omem->homem +optima->óptima, ótima +optimo->óptimo, ótimo +orta->horta +otima->ótima, óptima +otimisadas->otimizadas, optimizadas +otimo->ótimo, óptimo +oxido-redução->oxirredução +pagaos->pagãos +pagina->página +paises->paÃses +paleolitica->paleolÃtica +paleolitico->paleolÃtico +papeis->papéis +para mim fazer->para eu fazer +paraiso->paraÃso +paraisos->paraÃsos +paraizo->paraÃso +paraÃzo->paraÃso +paraizos->paraÃsos +paraÃzos->paraÃsos +paralização->paralisação +paralizado->paralisado +paralizar->paralisar +paroco->pároco +parocos->párocos +pascais->pascals +patria->pátria +Paulinia->PaulÃnia +pedigri->pedigree +penta-campeão->pentacampeão +percursora->precursora +percursoras->precursoras +periodo->perÃodo +periodos->perÃodos +periudo->perÃodo +perÃudo->perÃodo +periudos->perÃodos +perÃudos->perÃodos +permenor->pormenor +permenores->pormenores +perola->pérola +perolas->pérolas +personalisação->personalização +personalisar->personalizar +personalisou->personalizou +pertubar->perturbar +peso atômico->massa atômica +peso molecular->massa molecular +pesquiza->pesquisa +picômetro->picometro +plásticamente->plasticamente +plasticas->plásticas +plastico->plástico +plasticos->plásticos +poblema->problema +pobrema->problema +politica->polÃtica +politicas->polÃticas +politico->polÃtico +politicos->polÃticos +poluicao->poluição +Portugual->Portugal +posivel->possÃvel +possiveis->possÃveis +possivel->possÃvel +possue->possui +pq->porque,porquê,por que,por quê +praca->praça +prefêrencias->preferências +prescisa->precisa +prestaçãões->prestações +pretenção->pretensão +pretenssão->pretensão +previlegio->privilégio +previlégio->privilégio +previlegios->privilégios +previlégios->privilégios +primaria->primária +primarias->primárias +primario->primário +primarios->primários +primeiro ministro->primeiro-ministro +princÃpalmente->principalmente +prÃncipalmente->principalmente +principios->princÃpios +prisao->prisão +prisoes->prisões +privatizaçao->privatização +privilegio->privilégio +privilegios->privilégios +proceço->processo +proceços->processos +proceso->processo +procesos->processos +producao->produção +progama->programa +progamas->programas +proibe->proÃbe +proÃbido->proibido +propia->própria +própia->própria +propias->próprias +propiedade->propriedade +propio->próprio +própio->próprio +propios->próprios +proposito->propósito +prosceço->processo +prosceços->processos +prosceso->processo +proscesos->processos +proseço->processo +proseços->processos +prosseço->processo +prosseços->processos +protejida->protegida +protejidas->protegidas +protejido->protegido +protejidos->protegidos +prototipo->protótipo +prototipos->protótipos +provincia->provÃncia +provincias->provÃncias +proxima->próxima +proximas->próximas +proximo->próximo +proximos->próximos +pseudo-ciência->pseudociência +publico->público +publicos->públicos +qeu->que +questao->questão +quilómetro->quilômetro +quilometro->quilómetro, quilômetro +quilometros->quilómetros, quilômetros +quimica->quÃmica +quimicas->quÃmicas +quimico->quÃmico +quimicos->quÃmicos +quizer->quiser +quizesse->quisesse +quizessem->quisessem +radiaçao->radiação +radio->rádio +raÃz->raiz +raizes->raÃzes +rarissimo->rarÃssimo +rarissimos->rarÃssimos +razao->razão +razoes->razões +récorde->recorde +referencia->referência +referencias->referências +reibi->râguebi +reinterar->reiterar +reinvidicação->reivindicação +reinvidicar->reivindicar +renovaveis->renováveis +repertorio->repertório +repertorios->repertórios +reportorio->reportório +reportorios->reportórios +requesito->requisito +responsaveis->responsáveis +responsavel->responsável +retem->retém, retêm +reteram->retiveram +reteu->reteve +reune->reúne +reunem->reúnem +reuniao->reunião +reunioes->reuniões +reuso-> reúso +riquissimo->riquÃssimo +riquissimos->riquÃssimos +ritualistico->ritualÃstico +rúbrica->rubrica +rúbricas->rubricas +sacerdocio->sacerdócio +sacrificio->sacrifÃcio +saira->saÃra, sairá +santuario->santuário +sao->são +saude->saúde +secudaria->secudária +secudarias->secudárias +secudario->secudário +secudarios->secudários +seculo->século +seculos->séculos +seissentos->seiscentos +seje->seja +semaforo->semáforo +semaforos->semáforos +semi cÃrculo->semicÃrculo +semi cÃrculos->semicÃrculos +semi finais->semifinais +semi final->semifinal +semi precioso->semiprecioso +semi preciosos->semipreciosos +semi presidencialismos->semipresidencialismos +semi presidencialistas->semipresidencialistas +semi-cÃrculo->semicÃrculo +semi-cÃrculos->semicÃrculos +semi-finais->semifinais +semi-final->semifinal +semi-precioso->semiprecioso +semi-preciosos->semipreciosos +semi-presidencialismos->semipresidencialismos +semi-presidencialistas->semipresidencialistas +sensiveis->sensÃveis +sensivel->sensÃvel +separaçoes->separações +serie->série +serio->sério, série, seriado +setessentos->setecentos +siclano->sicrano +simbolo->sÃmbolo +simbolos->sÃmbolos +simplemente->simplesmente +sindrome->sÃndrome +sinonimo->sinónimo, sinônimo +sÃntaze->sÃntaxe +sistemico->sistémico +sobrevivencia->sobrevivência +sombrancelha->sobrancelha +subdivisáo->subdivisão +substituida->substituÃda +substituidas->substituÃdas +substituido->substituÃdo +substituidos->substituÃdos +suçeso->sucesso +suçesos->sucessos +suçesso->sucesso +suçessos->sucessos +Suiça->SuÃça +suiço->suÃço +suino->suÃno +suseço->sucesso +suseços->sucessos +susseço->sucesso +susseços->sucessos +sussesso->sucesso +sussessos->sucessos +tambem->também +támbem->também +támbém->também +tao->tão +tb->também +tbm->também +tecnica->técnica +tecnico->técnico +têmporo-mandibular->temporomandibular +tendencia->tendência +tendencias->tendências +tetra-hidrofurano->tetraidrofurano +tipica->tÃpica +tipicas->tÃpicas +tipico->tÃpico +tipicos->tÃpicos +titulos->tÃtulos +tracao->tracção, tração +tranformar->transformar +transmissiveis->transmissÃveis +transmissivel->transmissÃvel +traser->trazer +trasnporta->transporta +trasnporte->transporte +trasnportes->transportes +tratrahidrofurano->tetraidrofurano +tres->três +treslagoense->três-lagoense +tri-campeão->tricampeão +trovao->trovão +TupÃ-guarani->Tupi-guarani +turistico->turÃstico +turisticos->turÃsticos +u.m.a->u +ultima->última +ultimo->último +ultimos->últimos +um um->um +úmidade->umidade, humidade +unica->única +unicas->únicas +unico->único +unicos->únicos +univercidade->universidade +univercidades->universidades +universitaria->universitária +universitarias->universitárias +universitario->universitário +universitarios->universitários +uqe->que +usuario->usuário, utilizador +util->útil +utilisador->utilizador, usuário +uzada->usada +uzadas->usadas +uzado->usado +uzados->usados +uzar->usar +uzo->uso +uzou->usou +váriados->variados +varias->várias +varios->vários +vc->você +veiculo->veÃculo +veiculos->veÃculos +verçao->versão +verção->versão +verçoes->versões +verções->versões +ves->vez, vês +veses->vezes +vestigio->vestÃgio +vestigios->vestÃgios +vezis->vezes +viajem->viagem +vice governador->vice-governador +vice governadores->vice-governadores +vice prefeito->vice-prefeito +vice prefeitos->vice-prefeitos +vice presidente->vice-presidente +vice presidentes->vice-presidentes +video game->videogame +video->vÃdeo +videoclip->videoclipe +vigilancia->vigilância +violencia->violência +viros->vÃrus +vÃros->vÃrus +virus->vÃrus +virús->vÃrus +vÃrús->vÃrus +vitoria->vitória +vitorias->vitórias +viuva->viúva +voçe->você +voçê->você +Wikimapa->WikiMapia +Wikimapia->WikiMapia +xafariz->chafariz +xuxu->chuchu +yoga->ioga +yôga->ioga diff --git a/files/typos/typos-tr.txt b/files/typos/typos-tr.txt new file mode 100644 index 0000000..4db11e7 --- /dev/null +++ b/files/typos/typos-tr.txt @@ -0,0 +1,604 @@ +# This file contains a number of common Turkish typos: +andriod->android + +# The remainder of this file contains misspellings from +# http://tr.wikipedia.org/wiki/Vikipedi:Yaygin_kelime_hatalari/makinalar_icin +# plus some post-processing to fix invalid entries, remove duplicates, etc. +# +# The content is available under the +# "Creative Commons Attribution-ShareAlike License" +# http://creativecommons.org/licenses/by-sa/3.0/ +# +# THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +# COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +# COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +# AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. +# +# BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +# TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +# BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +# CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +# CONDITIONS. +# +# *1. Definitions* +# +# 1. *"Adaptation"* means a work based upon the Work, or upon the Work +# and other pre-existing works, such as a translation, adaptation, +# derivative work, arrangement of music or other alterations of a +# literary or artistic work, or phonogram or performance and includes +# cinematographic adaptations or any other form in which the Work may +# be recast, transformed, or adapted including in any form +# recognizably derived from the original, except that a work that +# constitutes a Collection will not be considered an Adaptation for +# the purpose of this License. For the avoidance of doubt, where the +# Work is a musical work, performance or phonogram, the +# synchronization of the Work in timed-relation with a moving image +# ("synching") will be considered an Adaptation for the purpose of +# this License. +# 2. *"Collection"* means a collection of literary or artistic works, +# such as encyclopedias and anthologies, or performances, phonograms +# or broadcasts, or other works or subject matter other than works +# listed in Section 1(f) below, which, by reason of the selection and +# arrangement of their contents, constitute intellectual creations, in +# which the Work is included in its entirety in unmodified form along +# with one or more other contributions, each constituting separate and +# independent works in themselves, which together are assembled into a +# collective whole. A work that constitutes a Collection will not be +# considered an Adaptation (as defined below) for the purposes of this +# License. +# 3. *"Creative Commons Compatible License"* means a license that is +# listed at http://creativecommons.org/compatiblelicenses that has +# been approved by Creative Commons as being essentially equivalent to +# this License, including, at a minimum, because that license: (i) +# contains terms that have the same purpose, meaning and effect as the +# License Elements of this License; and, (ii) explicitly permits the +# relicensing of adaptations of works made available under that +# license under this License or a Creative Commons jurisdiction +# license with the same License Elements as this License. +# 4. *"Distribute"* means to make available to the public the original +# and copies of the Work or Adaptation, as appropriate, through sale +# or other transfer of ownership. +# 5. *"License Elements"* means the following high-level license +# attributes as selected by Licensor and indicated in the title of +# this License: Attribution, ShareAlike. +# 6. *"Licensor"* means the individual, individuals, entity or entities +# that offer(s) the Work under the terms of this License. +# 7. *"Original Author"* means, in the case of a literary or artistic +# work, the individual, individuals, entity or entities who created +# the Work or if no individual or entity can be identified, the +# publisher; and in addition (i) in the case of a performance the +# actors, singers, musicians, dancers, and other persons who act, +# sing, deliver, declaim, play in, interpret or otherwise perform +# literary or artistic works or expressions of folklore; (ii) in the +# case of a phonogram the producer being the person or legal entity +# who first fixes the sounds of a performance or other sounds; and, +# (iii) in the case of broadcasts, the organization that transmits the +# broadcast. +# 8. *"Work"* means the literary and/or artistic work offered under the +# terms of this License including without limitation any production in +# the literary, scientific and artistic domain, whatever may be the +# mode or form of its expression including digital form, such as a +# book, pamphlet and other writing; a lecture, address, sermon or +# other work of the same nature; a dramatic or dramatico-musical work; +# a choreographic work or entertainment in dumb show; a musical +# composition with or without words; a cinematographic work to which +# are assimilated works expressed by a process analogous to +# cinematography; a work of drawing, painting, architecture, +# sculpture, engraving or lithography; a photographic work to which +# are assimilated works expressed by a process analogous to +# photography; a work of applied art; an illustration, map, plan, +# sketch or three-dimensional work relative to geography, topography, +# architecture or science; a performance; a broadcast; a phonogram; a +# compilation of data to the extent it is protected as a copyrightable +# work; or a work performed by a variety or circus performer to the +# extent it is not otherwise considered a literary or artistic work. +# 9. *"You"* means an individual or entity exercising rights under this +# License who has not previously violated the terms of this License +# with respect to the Work, or who has received express permission +# from the Licensor to exercise rights under this License despite a +# previous violation. +# 10. *"Publicly Perform"* means to perform public recitations of the Work +# and to communicate to the public those public recitations, by any +# means or process, including by wire or wireless means or public +# digital performances; to make available to the public Works in such +# a way that members of the public may access these Works from a place +# and at a place individually chosen by them; to perform the Work to +# the public by any means or process and the communication to the +# public of the performances of the Work, including by public digital +# performance; to broadcast and rebroadcast the Work by any means +# including signs, sounds or images. +# 11. *"Reproduce"* means to make copies of the Work by any means +# including without limitation by sound or visual recordings and the +# right of fixation and reproducing fixations of the Work, including +# storage of a protected performance or phonogram in digital form or +# other electronic medium. +# +# *2. Fair Dealing Rights.* Nothing in this License is intended to reduce, +# limit, or restrict any uses free from copyright or rights arising from +# limitations or exceptions that are provided for in connection with the +# copyright protection under copyright law or other applicable laws. +# +# *3. License Grant.* Subject to the terms and conditions of this License, +# Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +# perpetual (for the duration of the applicable copyright) license to +# exercise the rights in the Work as stated below: +# +# 1. to Reproduce the Work, to incorporate the Work into one or more +# Collections, and to Reproduce the Work as incorporated in the +# Collections; +# 2. to create and Reproduce Adaptations provided that any such +# Adaptation, including any translation in any medium, takes +# reasonable steps to clearly label, demarcate or otherwise identify +# that changes were made to the original Work. For example, a +# translation could be marked "The original work was translated from +# English to Spanish," or a modification could indicate "The original +# work has been modified."; +# 3. to Distribute and Publicly Perform the Work including as +# incorporated in Collections; and, +# 4. to Distribute and Publicly Perform Adaptations. +# 5. +# +# For the avoidance of doubt: +# +# 1. *Non-waivable Compulsory License Schemes*. In those +# jurisdictions in which the right to collect royalties through +# any statutory or compulsory licensing scheme cannot be waived, +# the Licensor reserves the exclusive right to collect such +# royalties for any exercise by You of the rights granted under +# this License; +# 2. *Waivable Compulsory License Schemes*. In those jurisdictions in +# which the right to collect royalties through any statutory or +# compulsory licensing scheme can be waived, the Licensor waives +# the exclusive right to collect such royalties for any exercise +# by You of the rights granted under this License; and, +# 3. *Voluntary License Schemes*. The Licensor waives the right to +# collect royalties, whether individually or, in the event that +# the Licensor is a member of a collecting society that +# administers voluntary licensing schemes, via that society, from +# any exercise by You of the rights granted under this License. +# +# The above rights may be exercised in all media and formats whether now +# known or hereafter devised. The above rights include the right to make +# such modifications as are technically necessary to exercise the rights +# in other media and formats. Subject to Section 8(f), all rights not +# expressly granted by Licensor are hereby reserved. +# +# *4. Restrictions.* The license granted in Section 3 above is expressly +# made subject to and limited by the following restrictions: +# +# 1. You may Distribute or Publicly Perform the Work only under the terms +# of this License. You must include a copy of, or the Uniform Resource +# Identifier (URI) for, this License with every copy of the Work You +# Distribute or Publicly Perform. You may not offer or impose any +# terms on the Work that restrict the terms of this License or the +# ability of the recipient of the Work to exercise the rights granted +# to that recipient under the terms of the License. You may not +# sublicense the Work. You must keep intact all notices that refer to +# this License and to the disclaimer of warranties with every copy of +# the Work You Distribute or Publicly Perform. When You Distribute or +# Publicly Perform the Work, You may not impose any effective +# technological measures on the Work that restrict the ability of a +# recipient of the Work from You to exercise the rights granted to +# that recipient under the terms of the License. This Section 4(a) +# applies to the Work as incorporated in a Collection, but this does +# not require the Collection apart from the Work itself to be made +# subject to the terms of this License. If You create a Collection, +# upon notice from any Licensor You must, to the extent practicable, +# remove from the Collection any credit as required by Section 4(c), +# as requested. If You create an Adaptation, upon notice from any +# Licensor You must, to the extent practicable, remove from the +# Adaptation any credit as required by Section 4(c), as requested. +# 2. You may Distribute or Publicly Perform an Adaptation only under the +# terms of: (i) this License; (ii) a later version of this License +# with the same License Elements as this License; (iii) a Creative +# Commons jurisdiction license (either this or a later license +# version) that contains the same License Elements as this License +# (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons +# Compatible License. If you license the Adaptation under one of the +# licenses mentioned in (iv), you must comply with the terms of that +# license. If you license the Adaptation under the terms of any of the +# licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), +# you must comply with the terms of the Applicable License generally +# and the following provisions: (I) You must include a copy of, or the +# URI for, the Applicable License with every copy of each Adaptation +# You Distribute or Publicly Perform; (II) You may not offer or impose +# any terms on the Adaptation that restrict the terms of the +# Applicable License or the ability of the recipient of the Adaptation +# to exercise the rights granted to that recipient under the terms of +# the Applicable License; (III) You must keep intact all notices that +# refer to the Applicable License and to the disclaimer of warranties +# with every copy of the Work as included in the Adaptation You +# Distribute or Publicly Perform; (IV) when You Distribute or Publicly +# Perform the Adaptation, You may not impose any effective +# technological measures on the Adaptation that restrict the ability +# of a recipient of the Adaptation from You to exercise the rights +# granted to that recipient under the terms of the Applicable License. +# This Section 4(b) applies to the Adaptation as incorporated in a +# Collection, but this does not require the Collection apart from the +# Adaptation itself to be made subject to the terms of the Applicable +# License. +# 3. If You Distribute, or Publicly Perform the Work or any Adaptations +# or Collections, You must, unless a request has been made pursuant to +# Section 4(a), keep intact all copyright notices for the Work and +# provide, reasonable to the medium or means You are utilizing: (i) +# the name of the Original Author (or pseudonym, if applicable) if +# supplied, and/or if the Original Author and/or Licensor designate +# another party or parties (e.g., a sponsor institute, publishing +# entity, journal) for attribution ("Attribution Parties") in +# Licensor's copyright notice, terms of service or by other reasonable +# means, the name of such party or parties; (ii) the title of the Work +# if supplied; (iii) to the extent reasonably practicable, the URI, if +# any, that Licensor specifies to be associated with the Work, unless +# such URI does not refer to the copyright notice or licensing +# information for the Work; and (iv) , consistent with Ssection 3(b), +# in the case of an Adaptation, a credit identifying the use of the +# Work in the Adaptation (e.g., "French translation of the Work by +# Original Author," or "Screenplay based on original Work by Original +# Author"). The credit required by this Section 4(c) may be +# implemented in any reasonable manner; provided, however, that in the +# case of a Adaptation or Collection, at a minimum such credit will +# appear, if a credit for all contributing authors of the Adaptation +# or Collection appears, then as part of these credits and in a manner +# at least as prominent as the credits for the other contributing +# authors. For the avoidance of doubt, You may only use the credit +# required by this Section for the purpose of attribution in the +# manner set out above and, by exercising Your rights under this +# License, You may not implicitly or explicitly assert or imply any +# connection with, sponsorship or endorsement by the Original Author, +# Licensor and/or Attribution Parties, as appropriate, of You or Your +# use of the Work, without the separate, express prior written +# permission of the Original Author, Licensor and/or Attribution Parties. +# 4. Except as otherwise agreed in writing by the Licensor or as may be +# otherwise permitted by applicable law, if You Reproduce, Distribute +# or Publicly Perform the Work either by itself or as part of any +# Adaptations or Collections, You must not distort, mutilate, modify +# or take other derogatory action in relation to the Work which would +# be prejudicial to the Original Author's honor or reputation. +# Licensor agrees that in those jurisdictions (e.g. Japan), in which +# any exercise of the right granted in Section 3(b) of this License +# (the right to make Adaptations) would be deemed to be a distortion, +# mutilation, modification or other derogatory action prejudicial to +# the Original Author's honor and reputation, the Licensor will waive +# or not assert, as appropriate, this Section, to the fullest extent +# permitted by the applicable national law, to enable You to +# reasonably exercise Your right under Section 3(b) of this License +# (right to make Adaptations) but not otherwise. +# +# *5. Representations, Warranties and Disclaimer* +# +# UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +# OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +# KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +# INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +# FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +# LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +# WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE +# EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. +# +# *6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY +# APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL +# THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY +# DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF +# LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +# +# *7. Termination* +# +# 1. This License and the rights granted hereunder will terminate +# automatically upon any breach by You of the terms of this License. +# Individuals or entities who have received Adaptations or Collections +# from You under this License, however, will not have their licenses +# terminated provided such individuals or entities remain in full +# compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will +# survive any termination of this License. +# 2. Subject to the above terms and conditions, the license granted here +# is perpetual (for the duration of the applicable copyright in the +# Work). Notwithstanding the above, Licensor reserves the right to +# release the Work under different license terms or to stop +# distributing the Work at any time; provided, however that any such +# election will not serve to withdraw this License (or any other +# license that has been, or is required to be, granted under the terms +# of this License), and this License will continue in full force and +# effect unless terminated as stated above. +# +# *8. Miscellaneous* +# +# 1. Each time You Distribute or Publicly Perform the Work or a +# Collection, the Licensor offers to the recipient a license to the +# Work on the same terms and conditions as the license granted to You +# under this License. +# 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor +# offers to the recipient a license to the original Work on the same +# terms and conditions as the license granted to You under this License. +# 3. If any provision of this License is invalid or unenforceable under +# applicable law, it shall not affect the validity or enforceability +# of the remainder of the terms of this License, and without further +# action by the parties to this agreement, such provision shall be +# reformed to the minimum extent necessary to make such provision +# valid and enforceable. +# 4. No term or provision of this License shall be deemed waived and no +# breach consented to unless such waiver or consent shall be in +# writing and signed by the party to be charged with such waiver or +# consent. +# 5. This License constitutes the entire agreement between the parties +# with respect to the Work licensed here. There are no understandings, +# agreements or representations with respect to the Work not specified +# here. Licensor shall not be bound by any additional provisions that +# may appear in any communication from You. This License may not be +# modified without the mutual written agreement of the Licensor and You. +# 6. The rights granted under, and the subject matter referenced, in this +# License were drafted utilizing the terminology of the Berne +# Convention for the Protection of Literary and Artistic Works (as +# amended on September 28, 1979), the Rome Convention of 1961, the +# WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms +# Treaty of 1996 and the Universal Copyright Convention (as revised on +# July 24, 1971). These rights and subject matter take effect in the +# relevant jurisdiction in which the License terms are sought to be +# enforced according to the corresponding provisions of the +# implementation of those treaty provisions in the applicable national +# law. If the standard suite of rights granted under applicable +# copyright law includes additional rights not granted under this +# License, such additional rights are deemed to be included in the +# License; this License is not intended to restrict the license of any +# rights under applicable law. +acizane->âcizane +alamanya->almanya +aferim->aferin +agrasif->agresif +aÄŸostos->aÄŸustos +ahret->ahiret +ayle->aile +alarım->alarm +atmış->altmış +alemiyon->alüminyum +amarika->amerika +anfi->amfi +aparetif->aperitif +arabeks->arabesk +artiz->artist +aÅŸÅŸağı->aÅŸağı +ahçı->aşçı +avut->aut +ayakıbı->ayakkabı +azarbeycan->azerbaycan +azerbeycan->azerbaycan +avusturalya->avustralya +bangledeÅŸ->bangladeÅŸ +pıçak->bıçak +bilmukavele->bilmukabele +birÅŸey->bir ÅŸey +bir kaç->birkaç +bir çok->birçok +pisiklet->bisiklet +püsküüt->bisküvi +canbaz->cambaz +çoçuk->çocuk +çoÅŸku->coÅŸku +cıplak->çıplak +çiflik->çiftlik +çünki->çünkü +dekarasyon->dekorasyon +debrem->deprem +dohtor->doktor +doktur->doktor +doktör->doktor +tiken->diken +dinazor->dinozor +diplamat->diplomat +distibütör->distribütör +dinayet->diyanet +domat->domates +domtiz->domates +domatis->domates +domatiz->domates +döküman->doküman +döndermek->döndürmek +dükkan->dükkân +tukkan->dükkân +egsos->egzoz +egsoz->egzoz +egsozt->egzoz +egzos->egzoz +egzost->egzoz +eksos->egzoz +eksoz->egzoz +eksozt->egzoz +ekzos->egzoz +ekzost->egzoz +eÅŸki->ekÅŸi +eylence->eÄŸlence +elenktirik->elektrik +elenktrik->elektrik +elektirik->elektrik +entellektüel->entelektüel +aÅŸortman->eÅŸofman +eÅŸortman->eÅŸofman +felan->falan +filim->film +formil->formül +gardırop->gardrop +gardolap->gardrop +gaste->gazete +goometri->geometri +giriÅŸgen->giriÅŸken +greyfirut->greyfurt +greyfrut->greyfurt +gürcüstan->gürcistan +güzelgah->güzergâh +güzergah->güzergâh +harfiyat->hafriyat +hastene->hastane +havunç->havuç +herhangibir->herhangi bir +herÅŸey->her ÅŸey,her ÅŸey +haparlör->hoparlör +hopollo->hoparlör +hoporlör->hoparlör +operlo->hoparlör +operlor->hoparlör +hakkari->hakkâri +heralda->herhalde +herkez->herkes +#hiç bir->hiçbir +hiç birÅŸey->hiçbir ÅŸey +hükümet->hükûmet +holanda->hollanda +istakoz->ıstakoz +imkan->imkân +imlâ->imla +inkilap->inkılap +insiyatif->inisiyatif +iskan->iskân +ıstanbul->istanbul +istambul->istanbul +istinâden->istinaden +itibariyle->itibarıyla +celatin->jelatin +capon->Japon +ceton->jeton +jöton->jeton +kağıt->kâğıt +kaÄŸat->kâğıt +kayfaltı->kahvaltı +gahfe->kahve +gayfe->kahve +kaave->kahve +kayfe->kahve +kave->kahve +gangren->kangren +kankıran->kangren +karekter->karakter +kaysı->kayısı +kebelek->kelebek +keÅŸki->keÅŸke +kırahatane->kıraathane +kirbit->kibrit +kipri->kirpi +kiprik->kirpik,kirpik +kokreç->kokoreç +komonis->komünist +komonist->komünist +komonizm->komünizm +kontür->kontör +kopye->kopya +kareografi->koreografi +gipür->kupür +küpür->kupür +lahap->lakap +leplepi->leblebi +nalet->lanet +leyen->leÄŸen +liÄŸen->leÄŸen +liyen->leÄŸen +lüx->lüks +makadonya->makedonya +makina->makine +maaÅŸallah->maÅŸallah +matamatik->matematik +menejer->menajer +menapoz->menopoz +mentalite->mantalite +meraba->merhaba +meyva->meyve +mihendis->mühendis +moÄŸalistan->moÄŸolistan +müdehale->müdahale +münübüs->minibüs +müracat->müracaat +mütahit->müteahhit +mütevazi->mütevazı +nacizane->naçizane +laylon->naylon +nufüs->nüfus +nülüfer->nilüfer +netekim->nitekim +oce->oje +okÅŸizen->oksijen +orjinal->orijinal +otibis->otobüs +#öğe->öge +ötenazi->ötanazi +palyanço->palyaço +panaroma->panorama +pantalon->pantolon +pattes->patates +pattis->patates +peçeta->peçete +penbe->pembe +pelisilin->penilisin +poaça->poÄŸaça +pohaça->poÄŸaça +poğçe->poÄŸaça +pırofösör->profesör +prefesör->profesör +profösör->profesör +profütür->profiterol +proÄŸram->program +promasyon->promosyon +radyosyon->radyasyon +romenya->romanya +ruc->ruj +sandaviç->sandviç +sandeviç->sandviç +sandoviç->sandviç +sandöviç->sandviç +sarmısak->sarımsak +sarumsak->sarımsak +satlık->satılık +santranç->satranç +santraç->satranç +satraç->satranç +skayner->scanner +zebze->sebze +seramoni->seremoni +seromoni->seremoni +sikorta->sigorta +sinama->sinema +siyasî->siyasi +sıkandal->skandal +sovan->soÄŸan +sosyel->sosyal +sitretoskop->stetoskop +siteteskop->stetoskop +süpriz->sürpriz +südyen->sütyen +ÅŸartel->ÅŸalter +ÅŸaltel->ÅŸalter +ÅŸarz->ÅŸarj +ÅŸindi->ÅŸimdi +şöfer->ÅŸoför +şöför->ÅŸoför +tetbir->tedbir +temis->temiz +telafuz->telaffuz +tenefüs->teneffüs +tellik->terlik +tranvay->tramvay +törörist->terörist +teÅŸebüs->teÅŸebbüs +teÅŸeppüs->teÅŸebbüs +tiskinmek->tiksinmek +tos->tost +tükrük->tükürük +tüprük->tükürük +traÅŸ->tıraÅŸ +türkiya->türkiye +ukele->ukala +ükela->ukala +ukranya->ukrayna +ukrayin->ukrayna +ünvan->unvan +üçken->üçgen +vucüt->vücut +vucud->vücut +vürüs->virüs +fites->vites +valeybol->voleybol +veleybol->voleybol +yada->ya da +yanlız->yalnız +yannış->yanlış +yalnış->yanlış +yimek->yemek +yeni zellanda->yeni zelanda +gine->yine +zerafet->zarafet diff --git a/lint/cli/src/com/android/tools/lint/HtmlReporter.java b/lint/cli/src/com/android/tools/lint/HtmlReporter.java index e962fec..c3ed9d2 100644 --- a/lint/cli/src/com/android/tools/lint/HtmlReporter.java +++ b/lint/cli/src/com/android/tools/lint/HtmlReporter.java @@ -33,10 +33,10 @@ import com.google.common.base.Charsets; import com.google.common.collect.Maps; import com.google.common.io.ByteStreams; import com.google.common.io.Closeables; +import com.google.common.io.Files; import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Writer; @@ -86,7 +86,7 @@ public class HtmlReporter extends Reporter { */ public HtmlReporter(Main client, File output) throws IOException { super(client, output); - mWriter = new BufferedWriter(new FileWriter(output)); + mWriter = new BufferedWriter(Files.newWriter(output, Charsets.UTF_8)); } @Override @@ -96,6 +96,7 @@ public class HtmlReporter extends Reporter { mWriter.write( "<html>\n" + //$NON-NLS-1$ "<head>\n" + //$NON-NLS-1$ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>" + //$NON-NLS-1$ "<title>" + mTitle + "</title>\n"); //$NON-NLS-1$//$NON-NLS-2$ writeStyleSheet(); diff --git a/lint/cli/src/com/android/tools/lint/Main.java b/lint/cli/src/com/android/tools/lint/Main.java index fbb0b16..6cdb689 100644 --- a/lint/cli/src/com/android/tools/lint/Main.java +++ b/lint/cli/src/com/android/tools/lint/Main.java @@ -41,6 +41,7 @@ import com.android.tools.lint.detector.api.Position; import com.android.tools.lint.detector.api.Project; import com.android.tools.lint.detector.api.Severity; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.io.Closeables; import java.io.BufferedWriter; @@ -85,6 +86,8 @@ public class Main extends LintClient { private static final String ARG_URL = "--url"; //$NON-NLS-1$ private static final String ARG_VERSION = "--version"; //$NON-NLS-1$ private static final String ARG_EXITCODE = "--exitcode"; //$NON-NLS-1$ + private static final String ARG_CLASSES = "--classpath"; //$NON-NLS-1$ + private static final String ARG_SOURCES = "--sources"; //$NON-NLS-1$ private static final String ARG_NOWARN2 = "--nowarn"; //$NON-NLS-1$ // GCC style flag names for options @@ -118,6 +121,8 @@ public class Main extends LintClient { private boolean mWarnAll; private boolean mNoWarnings; private boolean mAllErrors; + private List<File> mSources; + private List<File> mClasses; private Configuration mDefaultConfiguration; private IssueRegistry mRegistry; @@ -456,6 +461,40 @@ public class Main extends LintClient { mWarnAll = true; } else if (arg.equals(ARG_ALLERROR)) { mAllErrors = true; + } else if (arg.equals(ARG_CLASSES)) { + if (index == args.length - 1) { + System.err.println("Missing class folder name"); + System.exit(ERRNO_INVALIDARGS); + } + String paths = args[++index]; + for (String path : LintUtils.splitPath(paths)) { + File input = getInArgumentPath(path); + if (!input.exists()) { + System.err.println("Class path entry " + input + " does not exist."); + System.exit(ERRNO_INVALIDARGS); + } + if (mClasses == null) { + mClasses = new ArrayList<File>(); + } + mClasses.add(input); + } + } else if (arg.equals(ARG_SOURCES)) { + if (index == args.length - 1) { + System.err.println("Missing source folder name"); + System.exit(ERRNO_INVALIDARGS); + } + String paths = args[++index]; + for (String path : LintUtils.splitPath(paths)) { + File input = getInArgumentPath(path); + if (!input.exists()) { + System.err.println("Source folder " + input + " does not exist."); + System.exit(ERRNO_INVALIDARGS); + } + if (mSources == null) { + mSources = new ArrayList<File>(); + } + mSources.add(input); + } } else if (arg.startsWith("--")) { System.err.println("Invalid argument " + arg + "\n"); printUsage(System.err); @@ -475,6 +514,10 @@ public class Main extends LintClient { if (files.size() == 0) { System.err.println("No files to analyze."); System.exit(ERRNO_INVALIDARGS); + } else if (files.size() > 1 && (mClasses != null || mSources != null)) { + System.err.println("The " + ARG_SOURCES + " and " + ARG_CLASSES + + " can only be used with a single project"); + System.exit(ERRNO_INVALIDARGS); } if (mReporters.isEmpty()) { @@ -683,8 +726,18 @@ public class Main extends LintClient { "\"lint --ignore UnusedResources,UselessLeaf /my/project/path\"\n"; } - @SuppressWarnings("resource") // Eclipse doesn't know about Closeables.closeQuietly private void printVersion() { + String revision = getRevision(); + if (revision != null) { + System.out.println(String.format("lint: version %1$s", revision)); + } else { + System.out.println("lint: unknown version"); + } + } + + @SuppressWarnings("resource") // Eclipse doesn't know about Closeables.closeQuietly + @Nullable + String getRevision() { File file = findResource("tools" + File.separator + //$NON-NLS-1$ "source.properties"); //$NON-NLS-1$ if (file != null && file.exists()) { @@ -696,8 +749,7 @@ public class Main extends LintClient { String revision = properties.getProperty("Pkg.Revision"); //$NON-NLS-1$ if (revision != null && revision.length() > 0) { - System.out.println(String.format("lint: version %1$s", revision)); - return; + return revision; } } catch (IOException e) { // Couldn't find or read the version info: just print out unknown below @@ -706,7 +758,7 @@ public class Main extends LintClient { } } - System.out.println("lint: unknown version"); + return null; } private void displayValidIds(IssueRegistry registry, PrintStream out) { @@ -896,6 +948,12 @@ public class Main extends LintClient { ARG_SIMPLEHTML + " <filename>", "Create a simple HTML report", ARG_XML + " <filename>", "Create an XML report instead.", + "", "\nProject Options:", + ARG_SOURCES + " <dir>", "Add the given folder (or path) as a source directory for " + + "the project. Only valid when running lint on a single project.", + ARG_CLASSES + " <dir>", "Add the given folder (or jar file, or path) as a class " + + "directory for the project. Only valid when running lint on a single project.", + "", "\nExit Status:", "0", "Success.", Integer.toString(ERRNO_ERRORS), "Lint errors detected.", @@ -1122,6 +1180,45 @@ public class Main extends LintClient { return mCheck != null; } + private Map<Project, ClassPathInfo> mProjectInfo; + + @Override + @NonNull + protected ClassPathInfo getClassPath(@NonNull Project project) { + ClassPathInfo classPath = super.getClassPath(project); + + if (mClasses == null && mSources == null) { + return classPath; + } + + ClassPathInfo info; + if (mProjectInfo == null) { + mProjectInfo = Maps.newHashMap(); + info = null; + } else { + info = mProjectInfo.get(project); + } + + if (info == null) { + List<File> sources; + if (mSources != null) { + sources = mSources; + } else { + sources = classPath.getSourceFolders(); + } + List<File> classes; + if (mClasses != null) { + classes = mClasses; + } else { + classes = classPath.getClassFolders(); + } + info = new ClassPathInfo(sources, classes, classPath.getLibraries()); + mProjectInfo.put(project, info); + } + + return info; + } + /** * Consult the lint.xml file, but override with the --enable and --disable * flags supplied on the command line diff --git a/lint/cli/src/com/android/tools/lint/XmlReporter.java b/lint/cli/src/com/android/tools/lint/XmlReporter.java index f924def..04ac1d9 100644 --- a/lint/cli/src/com/android/tools/lint/XmlReporter.java +++ b/lint/cli/src/com/android/tools/lint/XmlReporter.java @@ -16,6 +16,8 @@ package com.android.tools.lint; +import com.android.tools.lint.checks.BuiltinIssueRegistry; +import com.android.tools.lint.detector.api.Issue; import com.android.tools.lint.detector.api.Location; import com.android.tools.lint.detector.api.Position; import com.google.common.annotations.Beta; @@ -52,18 +54,53 @@ public class XmlReporter extends Reporter { @Override public void write(int errorCount, int warningCount, List<Warning> issues) throws IOException { - mWriter.write( - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + //$NON-NLS-1$ - "<issues>\n"); //$NON-NLS-1$ + mWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); //$NON-NLS-1$ + mWriter.write("<issues format=\"3\""); //$NON-NLS-1$ + String revision = mClient.getRevision(); + if (revision != null) { + mWriter.write(String.format(" by=\"lint %1$s\"", revision)); //$NON-NLS-1$ + } + mWriter.write(">\n"); //$NON-NLS-1$ if (issues.size() > 0) { for (Warning warning : issues) { mWriter.write('\n'); indent(mWriter, 1); mWriter.write("<issue"); //$NON-NLS-1$ - writeAttribute(mWriter, 2, "id", warning.issue.getId()); //$NON-NLS-1$ - writeAttribute(mWriter, 2, "severity", warning.severity.getDescription()); //$NON-NLS-1$ - writeAttribute(mWriter, 2, "message", warning.message); //$NON-NLS-1$ + Issue issue = warning.issue; + writeAttribute(mWriter, 2, "id", issue.getId()); //$NON-NLS-1$ + writeAttribute(mWriter, 2, "severity", + warning.severity.getDescription()); + writeAttribute(mWriter, 2, "message", warning.message); //$NON-NLS-1$ + + writeAttribute(mWriter, 2, "category", //$NON-NLS-1$ + issue.getCategory().getFullName()); + writeAttribute(mWriter, 2, "priority", //$NON-NLS-1$ + Integer.toString(issue.getPriority())); + writeAttribute(mWriter, 2, "summary", issue.getDescription()); //$NON-NLS-1$ + writeAttribute(mWriter, 2, "explanation", issue.getExplanation()); //$NON-NLS-1$ + if (issue.getMoreInfo() != null) { + writeAttribute(mWriter, 2, "url", issue.getMoreInfo()); //$NON-NLS-1$ + } + if (warning.errorLine != null && !warning.errorLine.isEmpty()) { + String line = warning.errorLine; + int index1 = line.indexOf('\n'); + if (index1 != -1) { + int index2 = line.indexOf('\n', index1 + 1); + if (index2 != -1) { + String line1 = line.substring(0, index1); + String line2 = line.substring(index1 + 1, index2); + writeAttribute(mWriter, 2, "errorLine1", line1); //$NON-NLS-1$ + writeAttribute(mWriter, 2, "errorLine2", line2); //$NON-NLS-1$ + } + } + } + if (mClient.getRegistry() instanceof BuiltinIssueRegistry && + ((BuiltinIssueRegistry) mClient.getRegistry()).hasAutoFix( + "adt", issue)) { //$NON-NLS-1$ + writeAttribute(mWriter, 2, "quickfix", "adt"); //$NON-NLS-1$ //$NON-NLS-2$ + } + assert (warning.file != null) == (warning.location != null); if (warning.file != null) { diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java index 4cca31c..f168d7a 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java @@ -423,6 +423,45 @@ public abstract class LintClient { } } + if (classes.size() == 0) { + File folder = new File(projectDir, CLASS_FOLDER); + if (folder.exists()) { + classes.add(folder); + } else { + // Maven checks + folder = new File(projectDir, + "target" + File.separator + "classes"); //$NON-NLS-1$ //$NON-NLS-2$ + if (folder.exists()) { + classes.add(folder); + + // If it's maven, also correct the source path, "src" works but + // it's in a more specific subfolder + if (sources.size() == 0) { + File src = new File(projectDir, + "src" + File.separator //$NON-NLS-1$ + + "main" + File.separator //$NON-NLS-1$ + + "java"); //$NON-NLS-1$ + if (src.exists()) { + sources.add(src); + } else { + src = new File(projectDir, SRC_FOLDER); + if (src.exists()) { + sources.add(src); + } + } + + File gen = new File(projectDir, + "target" + File.separator //$NON-NLS-1$ + + "generated-sources" + File.separator //$NON-NLS-1$ + + "r"); //$NON-NLS-1$ + if (gen.exists()) { + sources.add(gen); + } + } + } + } + } + // Fallback, in case there is no Eclipse project metadata here if (sources.size() == 0) { File src = new File(projectDir, SRC_FOLDER); @@ -434,12 +473,6 @@ public abstract class LintClient { sources.add(gen); } } - if (classes.size() == 0) { - File folder = new File(projectDir, CLASS_FOLDER); - if (folder.exists()) { - classes.add(folder); - } - } info = new ClassPathInfo(sources, classes, libraries); mProjectInfo.put(project, info); diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java index 47a52c0..a0ff760 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java @@ -175,6 +175,7 @@ public class LintConstants { public static final String ATTR_IME_ACTION_LABEL = "imeActionLabel"; //$NON-NLS-1$ public static final String ATTR_PRIVATE_IME_OPTIONS = "privateImeOptions"; //$NON-NLS-1$ public static final String VALUE_NONE = "none"; //$NON-NLS-1$ + public static final String VALUE_NO = "no"; //$NON-NLS-1$ public static final String ATTR_NUMERIC = "numeric"; //$NON-NLS-1$ public static final String ATTR_IME_ACTION_ID = "imeActionId"; //$NON-NLS-1$ public static final String ATTR_IME_OPTIONS = "imeOptions"; //$NON-NLS-1$ @@ -190,7 +191,9 @@ public class LintConstants { public static final String ATTR_AUTO_TEXT = "autoText"; //$NON-NLS-1$ public static final String ATTR_ENABLED = "enabled"; //$NON-NLS-1$ public static final String ATTR_SINGLE_LINE = "singleLine"; //$NON-NLS-1$ - public static final String ATTR_SCALE_TYPE = "scaleType"; //$NON-NLS-1$ + public static final String ATTR_SCALE_TYPE = "scaleType"; //$NON-NLS-1$ + public static final String ATTR_IMPORTANT_FOR_ACCESSIBILITY = + "importantForAccessibility"; //$NON-NLS-1$ // AbsoluteLayout layout params public static final String ATTR_LAYOUT_Y = "layout_y"; //$NON-NLS-1$ diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java index ce64fe3..1d9ba2e 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java @@ -30,6 +30,8 @@ import com.android.resources.ResourceType; import com.android.tools.lint.client.api.LintClient; import com.android.util.PositionXmlParser; import com.google.common.annotations.Beta; +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; @@ -324,6 +326,41 @@ public class LintUtils { } /** + * Splits the given path into its individual parts, attempting to be + * tolerant about path separators (: or ;). It can handle possibly ambiguous + * paths, such as {@code c:\foo\bar:\other}, though of course these are to + * be avoided if possible. + * + * @param path the path variable to split, which can use both : and ; as + * path separators. + * @return the individual path components as an iterable of strings + */ + public static Iterable<String> splitPath(String path) { + if (path.indexOf(';') != -1) { + return Splitter.on(';').omitEmptyStrings().trimResults().split(path); + } + + List<String> combined = new ArrayList<String>(); + Iterables.addAll(combined, Splitter.on(':').omitEmptyStrings().trimResults().split(path)); + for (int i = 0, n = combined.size(); i < n; i++) { + String p = combined.get(i); + if (p.length() == 1 && i < n - 1 && Character.isLetter(p.charAt(0)) + // Technically, Windows paths do not have to have a \ after the :, + // which means it would be using the current directory on that drive, + // but that's unlikely to be the case in a path since it would have + // unpredictable results + && !combined.get(i+1).isEmpty() && combined.get(i+1).charAt(0) == '\\') { + combined.set(i, p + ':' + combined.get(i+1)); + combined.remove(i+1); + n--; + continue; + } + } + + return combined; + } + + /** * Computes the shared parent among a set of files (which may be null). * * @param files the set of files to be checked @@ -633,4 +670,41 @@ public class LintUtils { return hasManifest; } + + /** + * Look up the locale and region from the given parent folder name and + * return it as a combined string, such as "en", "en-rUS", etc, or null if + * no language is specified. + * + * @param folderName the folder name + * @return the locale+region string or null + */ + @Nullable + public static String getLocaleAndRegion(@NonNull String folderName) { + if (folderName.equals("values")) { //$NON-NLS-1$ + return null; + } + + String locale = null; + + for (String qualifier : Splitter.on('-').split(folderName)) { + int qualifierLength = qualifier.length(); + if (qualifierLength == 2) { + char first = qualifier.charAt(0); + char second = qualifier.charAt(1); + if (first >= 'a' && first <= 'z' && second >= 'a' && second <= 'z') { + locale = qualifier; + } + } else if (qualifierLength == 3 && qualifier.charAt(0) == 'r' && locale != null) { + char first = qualifier.charAt(1); + char second = qualifier.charAt(2); + if (first >= 'A' && first <= 'Z' && second >= 'A' && second <= 'Z') { + return locale + '-' + qualifier; + } + break; + } + } + + return locale; + } } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java index 323f88a..e1be383 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java @@ -18,8 +18,10 @@ package com.android.tools.lint.checks; import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; import static com.android.tools.lint.detector.api.LintConstants.ATTR_CONTENT_DESCRIPTION; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_IMPORTANT_FOR_ACCESSIBILITY; import static com.android.tools.lint.detector.api.LintConstants.IMAGE_BUTTON; import static com.android.tools.lint.detector.api.LintConstants.IMAGE_VIEW; +import static com.android.tools.lint.detector.api.LintConstants.VALUE_NO; import com.android.annotations.NonNull; import com.android.tools.lint.detector.api.Category; @@ -78,6 +80,11 @@ public class AccessibilityDetector extends LayoutDetector { @Override public void visitElement(@NonNull XmlContext context, @NonNull Element element) { if (!element.hasAttributeNS(ANDROID_URI, ATTR_CONTENT_DESCRIPTION)) { + // Ignore views that are explicitly not important for accessibility + if (VALUE_NO.equals(element.getAttributeNS(ANDROID_URI, + ATTR_IMPORTANT_FOR_ACCESSIBILITY))) { + return; + } context.report(ISSUE, element, context.getLocation(element), "[Accessibility] Missing contentDescription attribute on image", null); } else { diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java index f89fb81..391033e 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java @@ -30,6 +30,7 @@ import com.android.resources.ResourceFolderType; import com.android.tools.lint.detector.api.Category; import com.android.tools.lint.detector.api.Context; import com.android.tools.lint.detector.api.Issue; +import com.android.tools.lint.detector.api.LintUtils; import com.android.tools.lint.detector.api.Location; import com.android.tools.lint.detector.api.ResourceXmlDetector; import com.android.tools.lint.detector.api.Scope; @@ -73,6 +74,12 @@ public class TranslationDetector extends ResourceXmlDetector { "If an application has more than one locale, then all the strings declared in " + "one language should also be translated in all other languages.\n" + "\n" + + "If the string should *not* be translated, you can add the attribute\n" + + "translatable=\"false\" on the <string> element, or you can define all " + + "your non-translatable strings in a resource file called \"donottranslate.xml\". " + + "Or, you can ignore the issue with a tools:ignore=\"MissingTranslation\" " + + "attribute.\n" + + "\n" + "By default this detector allows regions of a language to just provide a " + "subset of the strings and fall back to the standard language strings. " + "You can require all regions to provide a full translation by setting the " + @@ -90,15 +97,19 @@ public class TranslationDetector extends ResourceXmlDetector { "If a string appears in a specific language translation file, but there is " + "no corresponding string in the default locale, then this string is probably " + "unused. (It's technically possible that your application is only intended to " + - "run in a specific locale, but it's still a good idea to provide a fallback.)", + "run in a specific locale, but it's still a good idea to provide a fallback.).\n" + + "\n" + + "Note that these strings can lead to crashes if the string is looked up on any " + + "locale not providing a translation, so it's important to clean them up.", Category.MESSAGES, 6, - Severity.WARNING, + Severity.FATAL, TranslationDetector.class, Scope.ALL_RESOURCES_SCOPE); private Set<String> mNames; private Set<String> mTranslatedArrays; + private Set<String> mNonTranslatable; private boolean mIgnoreFile; private Map<File, Set<String>> mFileToNames; @@ -457,6 +468,17 @@ public class TranslationDetector extends ResourceXmlDetector { Attr translatable = element.getAttributeNode(ATTR_TRANSLATABLE); if (translatable != null && !Boolean.valueOf(translatable.getValue())) { + String l = LintUtils.getLocaleAndRegion(context.file.getParentFile().getName()); + if (l != null) { + context.report(EXTRA, context.getLocation(translatable), + "Non-translatable resources should only be defined in the base " + + "values/ folder", null); + } else { + if (mNonTranslatable == null) { + mNonTranslatable = new HashSet<String>(); + } + mNonTranslatable.add(name); + } return; } @@ -489,6 +511,12 @@ public class TranslationDetector extends ResourceXmlDetector { mNames.add(name); + if (mNonTranslatable != null && mNonTranslatable.contains(name)) { + String message = String.format("The resource string \"%1$s\" has been marked as " + + "translatable=\"false\"", name); + context.report(EXTRA, context.getLocation(attribute), message, null); + } + // TBD: Also make sure that the strings are not empty or placeholders? } } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java index 5b50308..ad3b7a3 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java @@ -16,6 +16,7 @@ package com.android.tools.lint.checks; +import static com.android.tools.lint.checks.TypoLookup.isLetter; import static com.android.tools.lint.detector.api.LintConstants.TAG_STRING; import static com.google.common.base.Objects.equal; @@ -40,7 +41,6 @@ import org.w3c.dom.NodeList; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.List; /** @@ -76,8 +76,11 @@ import java.util.List; * </ul> */ public class TypoDetector extends ResourceXmlDetector { - private TypoLookup mLookup; - private String mLastLanguage; + private @Nullable TypoLookup mLookup; + private @Nullable String mLastLanguage; + private @Nullable String mLastRegion; + private @Nullable String mLanguage; + private @Nullable String mRegion; /** The main issue discovered by this detector */ public static final Issue ISSUE = Issue.create( @@ -101,36 +104,46 @@ public class TypoDetector extends ResourceXmlDetector { return folderType == ResourceFolderType.VALUES; } - /** Look up the locale from the given parent folder name, or null if there isn't one */ - @Nullable - private String getLocale(@NonNull String parent) { + /** Look up the locale and region from the given parent folder name and store it + * in {@link #mLanguage} and {@link #mRegion} */ + private void initLocale(@NonNull String parent) { + mLanguage = null; + mRegion = null; + if (parent.equals("values")) { //$NON-NLS-1$ - return null; + return; } for (String qualifier : Splitter.on('-').split(parent)) { - if (qualifier.length() == 2) { + int qualifierLength = qualifier.length(); + if (qualifierLength == 2) { char first = qualifier.charAt(0); - char second = qualifier.charAt(0); + char second = qualifier.charAt(1); if (first >= 'a' && first <= 'z' && second >= 'a' && second <= 'z') { - return qualifier; + mLanguage = qualifier; + } + } else if (qualifierLength == 3 && qualifier.charAt(0) == 'r') { + char first = qualifier.charAt(1); + char second = qualifier.charAt(2); + if (first >= 'A' && first <= 'Z' && second >= 'A' && second <= 'Z') { + mRegion = new String(new char[] { first, second }); // Don't include the "r" } + break; } } - - return null; } @Override public void beforeCheckFile(@NonNull Context context) { - String language = getLocale(context.file.getParentFile().getName()); - if (language == null) { - language = "en"; //$NON-NLS-1$ + initLocale(context.file.getParentFile().getName()); + if (mLanguage == null) { + mLanguage = "en"; //$NON-NLS-1$ } - if (!equal(mLastLanguage, language)) { - mLastLanguage = language; - mLookup = TypoLookup.get(context.getClient(), language); + if (!equal(mLastLanguage, mLanguage) || !equal(mLastRegion, mRegion)) { + mLookup = TypoLookup.get(context.getClient(), mLanguage, mRegion); + mLastLanguage = mLanguage; + mLastRegion = mRegion; } } @@ -177,7 +190,6 @@ public class TypoDetector extends ResourceXmlDetector { return; } int begin = index; - index++; while (index < max && Character.isLetter(text.charAt(index))) { if (text.charAt(index) >= 0x80) { // Switch to UTF-8 handling for this string @@ -200,10 +212,9 @@ public class TypoDetector extends ResourceXmlDetector { int end = index; checkedTypos = true; - Iterable<String> replacements = mLookup.getTypos(text, begin, end); + List<String> replacements = mLookup.getTypos(text, begin, end); if (replacements != null) { - String word = text.substring(begin, end); - reportTypo(context, node, word, begin, end, replacements); + reportTypo(context, node, text, begin, replacements); } index = end + 1; @@ -214,10 +225,10 @@ public class TypoDetector extends ResourceXmlDetector { int byteStart, int byteEnd, String text, int charStart) { int index = byteStart; while (index < byteEnd) { - byte b = utf8Text[index]; // Find beginning of word while (index < byteEnd) { - if (b != ' ' && b != '\t' && b != '\n' && b != '\r') { + byte b = utf8Text[index]; + if (isLetter(b)) { break; } index++; @@ -232,12 +243,12 @@ public class TypoDetector extends ResourceXmlDetector { } int charEnd = charStart; int begin = index; - index++; // Find end of word. Unicode has the nice property that even 2nd, 3rd and 4th // bytes won't match these ASCII characters (because the high bit must be set there) while (index < byteEnd) { - if (b == ' ' || b == '\t' || b == '\n' || b == '\r') { + byte b = utf8Text[index]; + if (!isLetter(b)) { break; } index++; @@ -248,56 +259,62 @@ public class TypoDetector extends ResourceXmlDetector { } int end = index; - Iterable<String> replacements = mLookup.getTypos(utf8Text, begin, end); + List<String> replacements = mLookup.getTypos(utf8Text, begin, end); if (replacements != null) { - String word = text.substring(charStart, charEnd); - reportTypo(context, node, word, charStart, end, replacements); + reportTypo(context, node, text, charStart, replacements); } - index = end + 1; + charStart = charEnd; } } - /** Report the typo found at the given offset and suggest the given replacements */ - private void reportTypo(XmlContext context, Node node, - String word, int begin, int end, Iterable<String> replacements) { + private void reportTypo(XmlContext context, Node node, String text, int begin, + List<String> replacements) { + if (replacements.size() < 2) { + return; + } + + String typo = replacements.get(0); + String word = text.substring(begin, begin + typo.length()); + String first = null; String message; - Iterator<String> iterator = replacements.iterator(); - if (iterator.hasNext()) { - boolean isCapitalized = Character.isUpperCase(word.charAt(0)); - StringBuilder sb = new StringBuilder(); - for (String replacement : replacements) { - if (first == null) { - first = replacement; - } - if (sb.length() > 0) { - sb.append(" or "); - } - sb.append('"'); - if (isCapitalized) { - sb.append(Character.toUpperCase(replacement.charAt(0)) - + replacement.substring(1)); - } else { - sb.append(replacement); - } - sb.append('"'); - } - if (first != null && first.equalsIgnoreCase(word)) { - message = String.format( - "\"%1$s\" is usually capitalized as \"%2$s\"", - word, first); + boolean isCapitalized = Character.isUpperCase(word.charAt(0)); + StringBuilder sb = new StringBuilder(); + for (int i = 1, n = replacements.size(); i < n; i++) { + String replacement = replacements.get(i); + if (first == null) { + first = replacement; + } + if (sb.length() > 0) { + sb.append(" or "); + } + sb.append('"'); + if (isCapitalized) { + sb.append(Character.toUpperCase(replacement.charAt(0)) + + replacement.substring(1)); } else { - message = String.format( - "\"%1$s\" is a common misspelling; did you mean %2$s ?", - word, sb.toString()); + sb.append(replacement); + } + sb.append('"'); + } + + if (first != null && first.equalsIgnoreCase(word)) { + if (first.equals(word)) { + return; } + message = String.format( + "\"%1$s\" is usually capitalized as \"%2$s\"", + word, first); } else { - message = String.format("\"%1$s\" is a common misspelling", word); + message = String.format( + "\"%1$s\" is a common misspelling; did you mean %2$s ?", + word, sb.toString()); } + int end = begin + word.length(); context.report(ISSUE, node, context.getLocation(node, begin, end), message, null); } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoLookup.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoLookup.java index 767a6ec..4a4591d 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoLookup.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoLookup.java @@ -21,12 +21,12 @@ import static com.android.tools.lint.detector.api.LintUtils.assertionsEnabled; import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import com.android.annotations.VisibleForTesting; import com.android.tools.lint.client.api.LintClient; import com.android.tools.lint.detector.api.LintUtils; import com.google.common.base.Charsets; import com.google.common.base.Splitter; import com.google.common.io.Files; -import com.google.common.primitives.UnsignedBytes; import java.io.File; import java.io.FileOutputStream; @@ -79,16 +79,32 @@ public class TypoLookup { * originally passed in. In other words, this parameter may be * ignored if the client created is not new. * @param locale the locale to look up a typo database for (should be a - * language code (ISO 639-1, two lowercase character names) + * language code (ISO 639-1, two lowercase character names) + * @param region the region to look up a typo database for (should be a two + * letter ISO 3166-1 alpha-2 country code in upper case) language + * code * @return a (possibly shared) instance of the typo database, or null if its * data can't be found */ @Nullable - public static TypoLookup get(@NonNull LintClient client, @NonNull String locale) { + public static TypoLookup get(@NonNull LintClient client, @NonNull String locale, + @Nullable String region) { synchronized (TypoLookup.class) { - TypoLookup db = sInstanceMap.get(locale); + String key = locale; + + if (region != null) { + // Allow for region-specific dictionaries. See for example + // http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences + assert region.length() == 2 + && Character.isUpperCase(region.charAt(0)) + && Character.isUpperCase(region.charAt(1)) : region; + // Look for typos-en-rUS.txt etc + key = locale + 'r' + region; + } + + TypoLookup db = sInstanceMap.get(key); if (db == null) { - String path = String.format(XML_FILE_PATH, locale); + String path = String.format(XML_FILE_PATH, key); File file = client.findResource(path); if (file == null) { // AOSP build environment? @@ -101,11 +117,16 @@ public class TypoLookup { } if (file == null || !file.exists()) { + if (region != null) { + // Fall back to the generic locale (non-region-specific) database + return get(client, locale, null); + } db = NONE; } else { db = get(client, file); + assert db != null : file; } - sInstanceMap.put(locale, db); + sInstanceMap.put(key, db); } if (db == NONE) { @@ -126,7 +147,8 @@ public class TypoLookup { * @return a (possibly shared) instance of the typo database, or null * if its data can't be found */ - public static TypoLookup get(LintClient client, File xmlFile) { + @Nullable + private static TypoLookup get(LintClient client, File xmlFile) { if (!xmlFile.exists()) { client.log(null, "The typo database file %1$s does not exist", xmlFile); return null; @@ -303,8 +325,12 @@ public class TypoLookup { if (end == -1) { end = line.trim().length(); } - String typo = line.substring(0, end); + String typo = line.substring(0, end).trim(); String replacements = line.substring(end + WORD_SEPARATOR.length()).trim(); + if (replacements.isEmpty()) { + // We don't support empty replacements + continue; + } String combined = typo + (char) 0 + replacements; words.add(combined); @@ -398,36 +424,65 @@ public class TypoLookup { // For debugging only private String dumpEntry(int offset) { if (DEBUG_SEARCH) { - StringBuilder sb = new StringBuilder(); - for (int i = offset; i < mData.length; i++) { - if (mData[i] == 0) { - break; - } - char c = (char) UnsignedBytes.toInt(mData[i]); - sb.append(c); + int end = offset; + while (mData[end] != 0) { + end++; } - - return sb.toString(); + return new String(mData, offset, end - offset, Charsets.UTF_8); } else { return "<disabled>"; //$NON-NLS-1$ } } /** Comparison function: *only* used for ASCII strings */ - private static int compare(byte[] data, int offset, byte terminator, CharSequence s, + @VisibleForTesting + static int compare(byte[] data, int offset, byte terminator, CharSequence s, int begin, int end) { int i = offset; int j = begin; - for (; j < end; i++, j++) { + for (; ; i++, j++) { byte b = data[i]; + if (b == ' ') { + // We've matched up to the space in a split-word typo, such as + // in German all zu=>allzu; here we've matched just past "all". + // Rather than terminating, attempt to continue in the buffer. + if (j == end) { + int max = s.length(); + if (end < max && s.charAt(end) == ' ') { + // Find next word + for (; end < max; end++) { + char c = s.charAt(end); + if (!Character.isLetter(c)) { + if (c == ' ' && end == j) { + continue; + } + break; + } + } + } + } + } + + if (j == end) { + break; + } + + if (b == '*') { + // Glob match (only supported at the end) + return 0; + } char c = s.charAt(j); byte cb = (byte) c; int delta = b - cb; if (delta != 0) { cb = (byte) Character.toLowerCase(c); - delta = b - cb; - if (delta != 0) { - return delta; + if (b != cb) { + // Ensure that it has the right sign + b = (byte) Character.toLowerCase(b); + delta = b - cb; + if (delta != 0) { + return delta; + } } } } @@ -436,22 +491,51 @@ public class TypoLookup { } /** Comparison function used for general UTF-8 encoded strings */ - private static int compare(byte[] data, int offset, byte terminator, byte[] s, + @VisibleForTesting + static int compare(byte[] data, int offset, byte terminator, byte[] s, int begin, int end) { int i = offset; int j = begin; - for (; j < end; i++, j++) { + for (; ; i++, j++) { byte b = data[i]; + if (b == ' ') { + // We've matched up to the space in a split-word typo, such as + // in German all zu=>allzu; here we've matched just past "all". + // Rather than terminating, attempt to continue in the buffer. + // We've matched up to the space in a split-word typo, such as + // in German all zu=>allzu; here we've matched just past "all". + // Rather than terminating, attempt to continue in the buffer. + if (j == end) { + int max = s.length; + if (end < max && s[end] == ' ') { + // Find next word + for (; end < max; end++) { + byte cb = s[end]; + if (!isLetter(cb)) { + if (cb == ' ' && end == j) { + continue; + } + break; + } + } + } + } + } + + if (j == end) { + break; + } + if (b == '*') { + // Glob match (only supported at the end) + return 0; + } byte cb = s[j]; int delta = b - cb; if (delta != 0) { - if (cb >= 'A' && cb <= 'Z') { // TODO: Generalize lower-casing here - cb -= 'A' - 'a'; - delta = b - cb; - if (delta != 0) { - return delta; - } - } else { + cb = toLowerCase(cb); + b = toLowerCase(b); + delta = b - cb; + if (delta != 0) { return delta; } } @@ -465,17 +549,19 @@ public class TypoLookup { } /** - * Look up whether this word is a typo, and if so, return one or more likely - * meanings + * Look up whether this word is a typo, and if so, return the typo itself + * and one or more likely meanings * * @param text the string containing the word * @param begin the index of the first character in the word - * @param end the index of the first character after the word - * @return an iterable of replacement strings if the word represents a typo, - * and null otherwise + * @param end the index of the first character after the word. Note that the + * search may extend <b>beyond</b> this index, if for example the + * word matches a multi-word typo in the dictionary + * @return a list of the typo itself followed by the replacement strings if + * the word represents a typo, and null otherwise */ @Nullable - public Iterable<String> getTypos(@NonNull CharSequence text, int begin, int end) { + public List<String> getTypos(@NonNull CharSequence text, int begin, int end) { assert end <= text.length(); if (assertionsEnabled()) { @@ -501,15 +587,36 @@ public class TypoLookup { // Compare the word at the given index. int compare = compare(mData, offset, (byte) 0, text, begin, end); + if (compare == 0) { offset = mIndices[middle]; + // Don't allow matching uncapitalized words, such as "enlish", when + // the dictionary word is capitalized, "Enlish". + if (mData[offset] != text.charAt(begin) + && Character.isLowerCase(text.charAt(begin))) { + return null; + } + // Make sure there is a case match; we only want to allow // matching capitalized words to capitalized typos or uncapitalized typos // (e.g. "Teh" and "teh" to "the"), but not uncapitalized words to capitalized // typos (e.g. "enlish" to "Enlish"). - for (int i = begin; i < end; i++) { + String glob = null; + for (int i = begin; ; i++) { byte b = mData[offset++]; + if (b == 0) { + offset--; + break; + } else if (b == '*') { + int globEnd = i; + while (globEnd < text.length() + && Character.isLetter(text.charAt(globEnd))) { + globEnd++; + } + glob = text.subSequence(i, globEnd).toString(); + break; + } char c = text.charAt(i); byte cb = (byte) c; if (b != cb && i > begin) { @@ -517,15 +624,7 @@ public class TypoLookup { } } - assert mData[offset] == 0; - offset++; - int replacementEnd = offset; - while (mData[replacementEnd] != 0) { - replacementEnd++; - } - String replacements = new String(mData, offset, replacementEnd - offset, - Charsets.UTF_8); - return Splitter.on(',').omitEmptyStrings().trimResults().split(replacements); + return computeSuggestions(mIndices[middle], offset, glob); } if (compare < 0) { @@ -542,17 +641,19 @@ public class TypoLookup { } /** - * Look up whether this word is a typo, and if so, return one or more likely - * meanings + * Look up whether this word is a typo, and if so, return the typo itself + * and one or more likely meanings * * @param utf8Text the string containing the word, encoded as UTF-8 * @param begin the index of the first character in the word - * @param end the index of the first character after the word - * @return an iterable of replacement strings if the word represents a typo, - * and null otherwise + * @param end the index of the first character after the word. Note that the + * search may extend <b>beyond</b> this index, if for example the + * word matches a multi-word typo in the dictionary + * @return a list of the typo itself followed by the replacement strings if + * the word represents a typo, and null otherwise */ @Nullable - public Iterable<String> getTypos(@NonNull byte[] utf8Text, int begin, int end) { + public List<String> getTypos(@NonNull byte[] utf8Text, int begin, int end) { assert end <= utf8Text.length; int low = 0; @@ -562,36 +663,53 @@ public class TypoLookup { int offset = mIndices[middle]; if (DEBUG_SEARCH) { - System.out.println("Comparing string " + utf8Text +" with entry at " + offset + String s = new String(Arrays.copyOfRange(utf8Text, begin, end), Charsets.UTF_8); + System.out.println("Comparing string " + s +" with entry at " + offset + ": " + dumpEntry(offset)); + System.out.println(" middle=" + middle + ", low=" + low + ", high=" + high); } // Compare the word at the given index. int compare = compare(mData, offset, (byte) 0, utf8Text, begin, end); + + if (DEBUG_SEARCH) { + System.out.println(" signum=" + (int)Math.signum(compare) + ", delta=" + compare); + } + if (compare == 0) { offset = mIndices[middle]; + // Don't allow matching uncapitalized words, such as "enlish", when + // the dictionary word is capitalized, "Enlish". + if (mData[offset] != utf8Text[begin] && isUpperCase(mData[offset])) { + return null; + } + // Make sure there is a case match; we only want to allow // matching capitalized words to capitalized typos or uncapitalized typos // (e.g. "Teh" and "teh" to "the"), but not uncapitalized words to capitalized // typos (e.g. "enlish" to "Enlish"). - for (int i = begin; i < end; i++) { + String glob = null; + for (int i = begin; ; i++) { byte b = mData[offset++]; + if (b == 0) { + offset--; + break; + } else if (b == '*') { + int globEnd = i; + while (globEnd < utf8Text.length && isLetter(utf8Text[globEnd])) { + globEnd++; + } + glob = new String(utf8Text, i, globEnd - i, Charsets.UTF_8); + break; + } byte cb = utf8Text[i]; if (b != cb && i > begin) { return null; } } - assert mData[offset] == 0; - offset++; - int replacementEnd = offset; - while (mData[replacementEnd] != 0) { - replacementEnd++; - } - String replacements = new String(mData, offset, replacementEnd - offset, - Charsets.UTF_8); - return Splitter.on(',').omitEmptyStrings().trimResults().split(replacements); + return computeSuggestions(mIndices[middle], offset, glob); } if (compare < 0) { @@ -606,4 +724,62 @@ public class TypoLookup { return null; } + + private List<String> computeSuggestions(int begin, int offset, String glob) { + String typo = new String(mData, begin, offset - begin, Charsets.UTF_8); + + if (glob != null) { + typo = typo.replaceAll("\\*", glob); //$NON-NLS-1$ + } + + assert mData[offset] == 0; + offset++; + int replacementEnd = offset; + while (mData[replacementEnd] != 0) { + replacementEnd++; + } + String replacements = new String(mData, offset, replacementEnd - offset, Charsets.UTF_8); + List<String> words = new ArrayList<String>(); + words.add(typo); + + // The first entry should be the typo itself. We need to pass this back since due + // to multi-match words and globbing it could extend beyond the initial word range + + for (String s : Splitter.on(',').omitEmptyStrings().trimResults().split(replacements)) { + if (glob != null) { + // Need to append the glob string to each result + words.add(s.replaceAll("\\*", glob)); //$NON-NLS-1$ + } else { + words.add(s); + } + } + + return words; + } + + // "Character" handling for bytes. This assumes that the bytes correspond to Unicode + // characters in the ISO 8859-1 range, which is are encoded the same way in UTF-8. + // This obviously won't work to for example uppercase to lowercase conversions for + // multi byte characters, which means we simply won't catch typos if the dictionaries + // contain these. None of the currently included dictionaries do. However, it does + // help us properly deal with punctuation and spacing characters. + + static final boolean isUpperCase(byte b) { + return Character.isUpperCase((char) b); + } + + static final byte toLowerCase(byte b) { + return (byte) Character.toLowerCase((char) b); + } + + static final boolean isSpace(byte b) { + return Character.isWhitespace((char) b); + } + + static final boolean isLetter(byte b) { + // Assume that multi byte characters represent letters in other languages. + // Obviously, it could be unusual punctuation etc but letters are more likely + // in this context. + return Character.isLetter((char) b) || (b & 0x80) != 0; + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java new file mode 100644 index 0000000..4206161 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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. + */ +package com.android.tools.lint; + +import com.android.tools.lint.checks.AbstractCheckTest; +import com.android.tools.lint.checks.HardcodedValuesDetector; +import com.android.tools.lint.checks.ManifestOrderDetector; +import com.android.tools.lint.detector.api.DefaultPosition; +import com.android.tools.lint.detector.api.Detector; +import com.android.tools.lint.detector.api.Location; +import com.android.tools.lint.detector.api.Project; +import com.android.tools.lint.detector.api.Severity; +import com.android.util.PositionXmlParser; +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +import org.w3c.dom.Document; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +@SuppressWarnings("javadoc") +public class XmlReporterTest extends AbstractCheckTest { + public void test() throws Exception { + File file = new File(getTargetDir(), "report"); + try { + Main client = new Main() { + @Override + String getRevision() { + return "unittest"; // Hardcode version to keep unit test output stable + } + }; + file.getParentFile().mkdirs(); + XmlReporter reporter = new XmlReporter(client, file); + Project project = Project.create(client, new File("/foo/bar/Foo"), + new File("/foo/bar/Foo")); + + Warning warning1 = new Warning(ManifestOrderDetector.USES_SDK, + "<uses-sdk> tag should specify a target API level (the highest verified " + + "version; when running on later versions, compatibility behaviors may " + + "be enabled) with android:targetSdkVersion=\"?\"", + Severity.WARNING, project, null); + warning1.line = 6; + warning1.file = new File("/foo/bar/Foo/AndroidManifest.xml"); + warning1.errorLine = " <uses-sdk android:minSdkVersion=\"8\" />\n ^\n"; + warning1.path = "AndroidManifest.xml"; + warning1.location = Location.create(warning1.file, + new DefaultPosition(6, 4, 198), new DefaultPosition(6, 42, 236)); + + Warning warning2 = new Warning(HardcodedValuesDetector.ISSUE, + "[I18N] Hardcoded string \"Fooo\", should use @string resource", + Severity.WARNING, project, null); + warning2.line = 11; + warning2.file = new File("/foo/bar/Foo/res/layout/main.xml"); + warning2.errorLine = " (java.lang.String) android:text=\"Fooo\" />\n" + + " ~~~~~~~~~~~~~~~~~~~\n"; + warning2.path = "res/layout/main.xml"; + warning2.location = Location.create(warning2.file, + new DefaultPosition(11, 8, 377), new DefaultPosition(11, 27, 396)); + + List<Warning> warnings = new ArrayList<Warning>(); + warnings.add(warning1); + warnings.add(warning2); + + reporter.write(0, 2, warnings); + + String report = Files.toString(file, Charsets.UTF_8); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<issues format=\"3\" by=\"lint unittest\">\n" + + "\n" + + " <issue\n" + + " id=\"UsesMinSdkAttributes\"\n" + + " severity=\"Warning\"\n" + + " message=\"<uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion="?"\"\n" + + " category=\"Correctness\"\n" + + " priority=\"2\"\n" + + " summary=\"Checks that the minimum SDK and target SDK attributes are defined\"\n" + + " explanation=\"The manifest should contain a <uses-sdk> element which defines the minimum minimum API Level required for the application to run, as well as the target version (the highest API level you have tested the version for.)\"\n" + + " url=\"http://developer.android.com/guide/topics/manifest/uses-sdk-element.html\"\n" + + " errorLine1=\" <uses-sdk android:minSdkVersion="8" />\"\n" + + " errorLine2=\" ^\">\n" + + " <location\n" + + " file=\"AndroidManifest.xml\"\n" + + " line=\"7\"\n" + + " column=\"5\"/>\n" + + " </issue>\n" + + "\n" + + " <issue\n" + + " id=\"HardcodedText\"\n" + + " severity=\"Warning\"\n" + + " message=\"[I18N] Hardcoded string "Fooo", should use @string resource\"\n" + + " category=\"Internationalization\"\n" + + " priority=\"5\"\n" + + " summary=\"Looks for hardcoded text attributes which should be converted to resource lookup\"\n" + + " explanation=\"Hardcoding text attributes directly in layout files is bad for several reasons:\n" + + "\n" + + "* When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes)\n" + + "\n" + + "* The application cannot be translated to other languages by just adding new translations for existing string resources.\"\n" + + " errorLine1=\" (java.lang.String) android:text="Fooo" />\"\n" + + " errorLine2=\" ~~~~~~~~~~~~~~~~~~~\">\n" + + " <location\n" + + " file=\"res/layout/main.xml\"\n" + + " line=\"12\"\n" + + " column=\"9\"/>\n" + + " </issue>\n" + + "\n" + + "</issues>\n", + report); + + // Make sure the XML is valid + Document document = new PositionXmlParser().parse(report); + assertNotNull(document); + assertEquals(2, document.getElementsByTagName("issue").getLength()); + } finally { + file.delete(); + } + } + + @Override + protected Detector getDetector() { + fail("Not used in this test"); + return null; + } +} diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java index 90bb29b..da84ae1 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java @@ -408,6 +408,7 @@ public abstract class AbstractCheckTest extends TestCase { File sdkDir = dir.getParentFile().getParentFile().getParentFile() .getParentFile().getParentFile().getParentFile(); File file = new File(sdkDir, "sdk" + File.separator + "files" + + File.separator + "typos" + File.separator + base); return file; } catch (URISyntaxException e) { diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java index 6f1c2e6..39231dd 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java @@ -34,9 +34,9 @@ public class TranslationDetectorTest extends AbstractCheckTest { TranslationDetector.COMPLETE_REGIONS = false; assertEquals( // Sample files from the Home app - "values-cs/arrays.xml:3: Warning: \"security_questions\" is translated here but not found in default locale\n" + + "values-cs/arrays.xml:3: Error: \"security_questions\" is translated here but not found in default locale\n" + "=> values-es/strings.xml:12: Also translated here\n" + - "values-de-rDE/strings.xml:11: Warning: \"continue_skip_label\" is translated here but not found in default locale\n" + + "values-de-rDE/strings.xml:11: Error: \"continue_skip_label\" is translated here but not found in default locale\n" + "values/strings.xml:20: Error: \"show_all_apps\" is not translated in nl-rNL\n" + "values/strings.xml:23: Error: \"menu_wallpaper\" is not translated in nl-rNL\n" + "values/strings.xml:25: Error: \"menu_settings\" is not translated in cs, de-rDE, es, es-rUS, nl-rNL", @@ -57,7 +57,7 @@ public class TranslationDetectorTest extends AbstractCheckTest { TranslationDetector.COMPLETE_REGIONS = true; assertEquals( // Sample files from the Home app - "values-de-rDE/strings.xml:11: Warning: \"continue_skip_label\" is translated here but not found in default locale\n" + + "values-de-rDE/strings.xml:11: Error: \"continue_skip_label\" is translated here but not found in default locale\n" + "values/strings.xml:19: Error: \"home_title\" is not translated in es-rUS\n" + "values/strings.xml:20: Error: \"show_all_apps\" is not translated in es-rUS, nl-rNL\n" + "values/strings.xml:23: Error: \"menu_wallpaper\" is not translated in es-rUS, nl-rNL\n" + @@ -137,4 +137,25 @@ public class TranslationDetectorTest extends AbstractCheckTest { "res/values-cs/strings.xml=>../LibraryProject/res/values-nl/strings.xml" )); } + + public void testNonTranslatable1() throws Exception { + TranslationDetector.COMPLETE_REGIONS = true; + assertEquals( + // Sample files from the Home app + "values-nb/nontranslatable.xml:3: Error: The resource string \"dummy\" has been " + + "marked as translatable=\"false\"", + + lintProject("res/values/nontranslatable.xml", + "res/values/nontranslatable2.xml=>res/values-nb/nontranslatable.xml")); + } + + public void testNonTranslatable2() throws Exception { + TranslationDetector.COMPLETE_REGIONS = true; + assertEquals( + // Sample files from the Home app + "values-nb/nontranslatable.xml:3: Error: Non-translatable resources should only " + + "be defined in the base values/ folder", + + lintProject("res/values/nontranslatable.xml=>res/values-nb/nontranslatable.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java index 646f032..864c065 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java @@ -63,10 +63,19 @@ public class TypoDetectorTest extends AbstractCheckTest { lintProject("res/values-nb/typos.xml")); } + public void testGerman() throws Exception { + // Test globbing and multiple word matching + assertEquals( + "typos.xml:10: Warning: \"zurŸck gefoobaren\" is a common misspelling; did you mean \"zurŸckgefoobaren\" ?\n" + + "typos.xml:6: Warning: \"befindet eine\" is a common misspelling; did you mean \"befindet sich eine\" ?\n" + + "typos.xml:9: Warning: \"Authorisierungscode\" is a common misspelling; did you mean \"Autorisierungscode\" ?", + lintProject("res/values-de/typos.xml")); + } + public void testOk() throws Exception { assertEquals( "No warnings.", - lintProject("res/values/typos.xml=>res/values-de/strings.xml")); + lintProject("res/values/typos.xml=>res/values-xy/strings.xml")); } public void testGetReplacements() { @@ -75,6 +84,5 @@ public class TypoDetectorTest extends AbstractCheckTest { assertEquals("throught", TypoDetector.getTypo(s)); assertEquals(Arrays.asList("thought", "through", "throughout"), TypoDetector.getSuggestions(s)); - } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoLookupTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoLookupTest.java index 0f4e15a..e57b8ce 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoLookupTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoLookupTest.java @@ -16,47 +16,110 @@ package com.android.tools.lint.checks; +import com.android.tools.lint.client.api.LintClient; import com.android.tools.lint.detector.api.Detector; import com.google.common.base.Charsets; +import com.google.common.base.Splitter; +import com.google.common.io.Files; -import java.util.Iterator; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; @SuppressWarnings("javadoc") public class TypoLookupTest extends AbstractCheckTest { + private static final String SEPARATOR = "->"; + + public void testCapitalization() throws Exception { + LintClient client = new TestLintClient(); + // Make sure it can be read in + TypoLookup db = TypoLookup.get(client, "de", null); + assertNotNull(db); + assertNotNull(db.getTypos("Andriod".getBytes(Charsets.UTF_8), 0, "Andriod".length())); + } + + public void testDictionary_English() throws Exception { + validateDictionary("en"); + } + + public void testDictionary_German() throws Exception { + validateDictionary("de"); + } + + public void testDictionary_Spanish() throws Exception { + validateDictionary("es"); + } + + public void testDictionary_Hungarian() throws Exception { + validateDictionary("hu"); + } + + public void testDictionary_Italian() throws Exception { + validateDictionary("it"); + } + + public void testDictionary_Norwegian() throws Exception { + validateDictionary("nb"); + } + + public void testDictionary_Portuguese() throws Exception { + validateDictionary("pt"); + } + + public void testDictionary_Turkish() throws Exception { + validateDictionary("tr"); + } public void test1() { - TypoLookup db = TypoLookup.get(new TestLintClient(), "en"); + TypoLookup db = TypoLookup.get(new TestLintClient(), "en", null); assertNull(db.getTypos("hello", 0, "hello".length())); assertNull(db.getTypos("this", 0, "this".length())); assertNotNull(db.getTypos("wiht", 0, "wiht".length())); assertNotNull(db.getTypos("woudl", 0, "woudl".length())); - assertEquals("would", db.getTypos("woudl", 0, "woudl".length()).iterator().next()); - assertEquals("would", db.getTypos(" woudl ", 2, 7).iterator().next()); + assertEquals("would", db.getTypos("woudl", 0, "woudl".length()).get(1)); + assertEquals("would", db.getTypos(" woudl ", 2, 7).get(1)); assertNotNull(db.getTypos("foo wiht bar", 4, 8)); - Iterator<String> typos = db.getTypos("throught", 0, "throught".length()).iterator(); - assertEquals("thought", typos.next()); - assertEquals("through", typos.next()); - assertEquals("throughout", typos.next()); + List<String> typos = db.getTypos("throught", 0, "throught".length()); + assertEquals("throught", typos.get(0)); // the typo + assertEquals("thought", typos.get(1)); + assertEquals("through", typos.get(2)); + assertEquals("throughout", typos.get(3)); // Capitalization handling assertNotNull(db.getTypos("Woudl", 0, "Woudl".length())); assertNotNull(db.getTypos("Enlish", 0, "Enlish".length())); assertNull(db.getTypos("enlish", 0, "enlish".length())); + assertNull(db.getTypos("enlish".getBytes(Charsets.UTF_8), 0, "enlish".length())); assertNotNull(db.getTypos("ok", 0, "ok".length())); assertNotNull(db.getTypos("Ok", 0, "Ok".length())); assertNull(db.getTypos("OK", 0, "OK".length())); } + public void testRegion() { + TypoLookup db = TypoLookup.get(new TestLintClient(), "en", "US"); + assertNotNull(db.getTypos("wiht", 0, "wiht".length())); + db = TypoLookup.get(new TestLintClient(), "en", "GB"); + assertNotNull(db.getTypos("wiht", 0, "wiht".length())); + } + public void test2() { - TypoLookup db = TypoLookup.get(new TestLintClient(), "nb"); //$NON-NLS-1$ + TypoLookup db = TypoLookup.get(new TestLintClient(), "nb", null); //$NON-NLS-1$ assertNull(db.getTypos("hello", 0, "hello".length())); assertNull(db.getTypos("this", 0, "this".length())); assertNotNull(db.getTypos("altid", 0, "altid".length())); - assertEquals("alltid", db.getTypos("altid", 0, "altid".length()).iterator().next()); - assertEquals("alltid", db.getTypos(" altid ", 2, 7).iterator().next()); + assertEquals("alltid", db.getTypos("altid", 0, "altid".length()).get(1)); + assertEquals("alltid", db.getTypos(" altid ", 2, 7).get(1)); assertNotNull(db.getTypos("foo altid bar", 4, 9)); // Test utf-8 string which isn't ASCII @@ -64,7 +127,392 @@ public class TypoLookupTest extends AbstractCheckTest { byte[] sb = s.getBytes(Charsets.UTF_8); assertNotNull(db.getTypos(sb, 0, sb.length)); - assertEquals("karrière", db.getTypos(sb, 0, sb.length).iterator().next()); + assertEquals("karrière", db.getTypos(sb, 0, sb.length).get(1)); + } + + public void testMultiWords() { + // Some language dictionaries contain multi-word sequences (e.g. where there's a + // space on the left hand side). This needs some particular care in the lookup + // which is usually word oriented. + TypoLookup db = TypoLookup.get(new TestLintClient(), "de", "DE"); //$NON-NLS-1$ + + // all zu->allzu + + // Text handling + String t = "all zu"; + assertNotNull(db.getTypos(t, 0, t.length())); + assertEquals("allzu", db.getTypos(t, 0, t.length()).get(1)); + + // Byte handling + byte[] text = "all zu".getBytes(Charsets.UTF_8); + assertNotNull(db.getTypos(text, 0, text.length)); + assertEquals("allzu", db.getTypos(text, 0, text.length).get(1)); + + // Test automatically extending search beyond current word + text = "all zu".getBytes(Charsets.UTF_8); + assertNotNull(db.getTypos(text, 0, 3)); + assertEquals("allzu", db.getTypos(text, 0, text.length).get(1)); + + + text = ") all zu (".getBytes(Charsets.UTF_8); + assertNotNull(db.getTypos(text, 2, 8)); + assertEquals("allzu", db.getTypos(text, 2, 8).get(1)); + + text = "am einem".getBytes(Charsets.UTF_8); + assertNotNull(db.getTypos(text, 0, text.length)); + assertEquals("an einem", db.getTypos(text, 0, text.length).get(1)); + } + + public void testGlobbing() { + TypoLookup db = TypoLookup.get(new TestLintClient(), "de", null); + + // Authorisierung*->Autorisierung* + String text = "Authorisierungscode"; + byte[] bytes = text.getBytes(Charsets.UTF_8); + + assertNotNull(db.getTypos(text, 0, text.length())); + assertEquals("Autorisierungscode", db.getTypos(text, 0, text.length()).get(1)); + assertEquals(text, db.getTypos(text, 0, text.length()).get(0)); + + assertNotNull(db.getTypos(bytes, 0, bytes.length)); + assertEquals("Autorisierungscode", db.getTypos(bytes, 0, bytes.length).get(1)); + + // befindet ein*->befindet sich ein* + text = "wo befindet eine ip"; + assertEquals("befindet sich eine", db.getTypos(text, 3, 16).get(1)); + + // zurück ge*->zurückge* + text = "zurück gefoobaren"; + bytes = text.getBytes(Charsets.UTF_8); + assertNotNull(db.getTypos(bytes, 0, bytes.length)); + assertEquals("zurückgefoobaren", db.getTypos(bytes, 0, bytes.length).get(1)); + } + + public void testComparisons() throws Exception { + // Ensure that the two comparison methods agree + + LintClient client = new TestLintClient(); + for (String locale : new String[] { "de", "nb", "es", "en", "pt", "hu", "it", "tr" }) { + File f = client.findResource(String.format("tools/support/typos-%1$s.txt", locale)); + assertTrue(locale, f != null && f.exists()); + + Set<String> typos = new HashSet<String>(2000); + List<String> lines = Files.readLines(f, Charsets.UTF_8); + for (int i = 0, n = lines.size(); i < n; i++) { + String line = lines.get(i); + if (line.isEmpty() || line.trim().startsWith("#")) { //$NON-NLS-1$ + continue; + } + + int index = line.indexOf(SEPARATOR); + if (index == -1) { + continue; + } + String typo = line.substring(0, index).trim(); + typos.add(typo); + } + + List<String> words = new ArrayList<String>(typos); + + // Make sure that the two comparison methods agree on all the strings + // (which should be in a semi-random order now that they're in a set ordered + // by their hash codes) + + String prevText = words.get(0) + '\000'; + byte[] prevBytes = prevText.getBytes(Charsets.UTF_8); + + for (int i = 1; i < words.size(); i++) { + String text = words.get(i) + '\000';; + byte[] bytes = text.getBytes(Charsets.UTF_8); + + int textCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, text, 0, + text.length()); + int byteCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, bytes, 0, + bytes.length); + assertEquals("Word " + text + " versus prev " + prevText + " at " + i, + Math.signum(textCompare), Math.signum(byteCompare)); + } + } + } + + public void testComparison1() throws Exception { + String prevText = "heraus gebracht\u0000"; + byte[] prevBytes = prevText.getBytes(Charsets.UTF_8); + + String text = "Päsident\u0000"; + byte[] bytes = text.getBytes(Charsets.UTF_8); + + + int textCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, text, 0, + text.length()); + int byteCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, bytes, 0, + bytes.length); + assertTrue(byteCompare < 0); + assertTrue(textCompare < 0); + assertEquals("Word " + text + " versus prev " + prevText, + Math.signum(textCompare), Math.signum(byteCompare)); + } + + public void testComparison2() throws Exception { + String prevText = "intepretation\u0000"; + byte[] prevBytes = prevText.getBytes(Charsets.UTF_8); + + String text = "Woudl\u0000"; + byte[] bytes = text.getBytes(Charsets.UTF_8); + + int textCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, text, 0, text.length()); + int byteCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, bytes, 0, bytes.length); + assertTrue(byteCompare < 0); + assertTrue(textCompare < 0); + assertEquals("Word " + text + " versus prev " + prevText, + Math.signum(textCompare), Math.signum(byteCompare)); + + // Reverse capitalization and ensure that it's still the same + prevText = "Intepretation\u0000"; + prevBytes = prevText.getBytes(Charsets.UTF_8); + + text = "woudl\u0000"; + bytes = text.getBytes(Charsets.UTF_8); + + textCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, text, 0, text.length()); + byteCompare = TypoLookup.compare(prevBytes, 0, (byte) 0, bytes, 0, bytes.length); + assertTrue(byteCompare < 0); + assertTrue(textCompare < 0); + assertEquals("Word " + text + " versus prev " + prevText, + Math.signum(textCompare), Math.signum(byteCompare)); + } + + // Some dictionaries contain actual sentences regarding usage; these must be stripped out. + // They're just hardcoded here as we find them + private static final String[] sRemove = new String[] { + "- besser ganz darauf verzichten", + "oft fälschlich für \"angekündigt\"", + "hinausgehende* − insb. „darüber hinausgehende“", + " - besser ganz darauf verzichten", + "svw. bzw. so viel wie bzw. sprachverwandt" + }; + + private void validateDictionary(String locale) throws Exception { + // Check that all the typo files are well formed + LintClient client = new TestLintClient(); + File f = client.findResource(String.format("tools/support/typos-%1$s.txt", locale)); + assertTrue(locale, f != null && f.exists()); + + Set<String> typos = new HashSet<String>(2000); + List<Pattern> patterns = new ArrayList<Pattern>(100); + + List<String> lines = Files.readLines(f, Charsets.UTF_8); + for (int i = 0, n = lines.size(); i < n; i++) { + String line = lines.get(i); + if (line.isEmpty() || line.trim().startsWith("#")) { //$NON-NLS-1$ + continue; + } + + assertTrue(msg(f, i, "Line should contain '->': %1$s", line), + line.contains(SEPARATOR)); + int index = line.indexOf(SEPARATOR); + String typo = line.substring(0, index).trim(); + String replacements = line.substring(index + SEPARATOR.length()).trim(); + + if (typo.contains("*") && !typo.endsWith("*")) { + fixDictionary(f); + fail(msg(f, i, "Globbing (*) not supported anywhere but at the tail: %1$s", line)); + } else if (typo.contains("*") && !replacements.contains("*")) { + fail(msg(f, i, "No glob found in the replacements for %1$s", line)); + } + + if (replacements.indexOf(',') != -1) { + Set<String> seen = new HashSet<String>(); + for (String s : Splitter.on(',').omitEmptyStrings().split(replacements)) { + if (seen.contains(s)) { + fixDictionary(f); + fail(msg(f, i, "For typo " + typo + + " there are repeated replacements (" + s + "): " + line)); + } + } + } + + assertTrue(msg(f, i, "Typo entry was empty: %1$s", line), !typo.isEmpty()); + assertTrue(msg(f, i, "Typo replacements was empty: %1$s", line), + !replacements.isEmpty()); + + for (String blacklist : sRemove) { + if (replacements.contains(blacklist)) { + fail(msg(f, i, "Replacements for typo %1$s contain description: %2$s", + typo, replacements)); + } + } + if (typo.equals("sólo") && locale.equals("es")) { + // sólo->solo + // This seems to trigger a lot of false positives + fail(msg(f, i, "Typo %1$s triggers a lot of false positives, should be omitted", + typo)); + } + if (locale.equals("tr") && (typo.equals("hiç bir")|| typo.equals("öğe"))) { + // hiç bir->hiçbir + // öğe->öge + // According to a couple of native speakers these are not necessarily + // typos + fail(msg(f, i, "Typo %1$s triggers a lot of false positives, should be omitted", + typo)); + } + + if (typo.contains("*")) { + patterns.add(Pattern.compile(typo.replace("*", ".*"))); + } else if (!patterns.isEmpty()) { + for (Pattern pattern : patterns) { + if (pattern.matcher(typo).matches()) { + fixDictionary(f); + fail(msg(f, i, "The typo " + typo + " matches an earlier glob: ignoring")); + continue; + } + } + } + + + if (typos.contains(typo)) { + fixDictionary(f); + fail(msg(f, i, "Typo appeared more than once on lhs: %1$s", typo)); + } + typos.add(typo); + } + + // Make sure it can be read in + TypoLookup db = TypoLookup.get(client, locale, null); + assertNotNull(db); + assertNull(db.getTypos("abcdefghijklmnopqrstuvxyz", 0, 25)); + assertNull(db.getTypos("abcdefghijklmnopqrstuvxyz".getBytes(Charsets.UTF_8), 0, 25)); + assertNotNull(db.getTypos("Andriod", 0, "Andriod".length())); + assertNotNull(db.getTypos("Andriod".getBytes(Charsets.UTF_8), 0, "Andriod".length())); + } + + private void fixDictionary(File original) throws Exception { + File fixed = new File(original.getParentFile(), "fixed-" + original.getName()); + + Map<String, Integer> typos = new HashMap<String, Integer>(2000); + List<Pattern> patterns = new ArrayList<Pattern>(100); + List<String> lines = Files.readLines(original, Charsets.UTF_8); + List<String> output = new ArrayList<String>(lines.size()); + + wordLoop: + for (int i = 0, n = lines.size(); i < n; i++) { + String line = lines.get(i); + if (line.isEmpty() || line.trim().startsWith("#")) { //$NON-NLS-1$ + output.add(line); + continue; + } + + if (!line.contains(SEPARATOR)) { + System.err.println("Commented out line missing ->: " + line); + output.add("# " + line); + continue; + } + int index = line.indexOf(SEPARATOR); + String typo = line.substring(0, index).trim(); + String replacements = line.substring(index + SEPARATOR.length()).trim(); + + if (typo.isEmpty()) { + System.err.println("Commented out line missing a typo on the lhs: " + line); + output.add("# " + line); + continue; + } + if (replacements.isEmpty()) { + System.err.println("Commented out line missing replacements on the rhs: " + line); + output.add("# " + line); + continue; + } + + // Ensure that all the replacements are unique + if (replacements.indexOf(',') != -1) { + Set<String> seen = new HashSet<String>(); + List<String> out = new ArrayList<String>(); + boolean rewrite = false; + for (String s : Splitter.on(',').omitEmptyStrings().split(replacements)) { + if (seen.contains(s)) { + System.err.println("For typo " + typo + + " there are repeated replacements (" + s + "): " + line); + rewrite = true; + } + seen.add(s); + out.add(s); + } + if (rewrite) { + StringBuilder sb = new StringBuilder(); + for (String s : out) { + if (sb.length() > 0) { + sb.append(","); + } + sb.append(s); + } + replacements = sb.toString(); + line = typo + SEPARATOR + replacements; + } + } + + if (typo.contains("*")) { + if (!typo.endsWith("*")) { + // Globbing not supported anywhere but the end + // Drop the whole word + System.err.println("Skipping typo " + typo + + " because globbing is only supported at the end of the word"); + continue; + } + patterns.add(Pattern.compile(typo.replace("*", ".*"))); + } else if (replacements.contains("*")) { + System.err.println("Skipping typo " + typo + " because unexpected " + + "globbing character found in replacements: " + + replacements); + continue; + } else if (!patterns.isEmpty()) { + for (Pattern pattern : patterns) { + if (pattern.matcher(typo).matches()) { + System.err.println("The typo " + typo + + " matches an earlier glob: ignoring"); + continue wordLoop; + } + } + } + + // TODO: Strip whitespace around ->, prefix of # etc such that reading in + // the databases needs to do less work at runtime + + if (typos.containsKey(typo)) { + int l = typos.get(typo); + String prev = output.get(l); + assertTrue(prev.startsWith(typo)); + // Append new replacements and put back into the list + // (unless they're already listed as replacements) + Set<String> seen = new HashSet<String>(); + for (String s : Splitter.on(',').split(prev.substring(prev.indexOf(SEPARATOR) + + 2))) { + seen.add(s); + } + for (String s : Splitter.on(',').omitEmptyStrings().split(replacements)) { + if (!seen.contains(s)) { + prev = prev + "," + s; + } + seen.add(s); + } + output.set(l, prev); + } else { + typos.put(typo, output.size()); + output.add(line); + } + } + + Writer writer = new BufferedWriter(new FileWriter(fixed)); + for (String line : output) { + writer.write(line); + writer.write('\n'); + } + writer.close(); + + System.err.println("==> Wrote fixed typo file to " + fixed.getPath()); + } + + private static String msg(File file, int line, String message, Object... args) { + return file.getName() + ':' + Integer.toString(line + 1) + ':' + ' ' + + String.format(message, args); } @Override diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml index 7afb182..c00a880 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml @@ -2,7 +2,8 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/newlinear" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> <ImageView android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> - <ImageButton android:id="@+id/android_logo2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> + <ImageButton android:importantForAccessibility="yes" android:id="@+id/android_logo2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> <Button android:id="@+android:id/summary" android:contentDescription="@string/label" /> + <ImageButton android:importantForAccessibility="no" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> </LinearLayout> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-de/typos.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-de/typos.xml new file mode 100644 index 0000000..9583fc7 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-de/typos.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="s1"> + + wo befindet eine ip + + </string> + <string name="s2">(Authorisierungscode!)</string> + <string name="s3"> zurück gefoobaren!</string> + +</resources> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos.xml index d0f4a41..06cec0d 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos.xml +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos.xml @@ -16,5 +16,7 @@ <string name="s7">Midt-Østen midt-østen</string> <!-- Non-ASCII UTF-8 string --> <string name="s7">Koding er en spennende karriære</string> + <string name="internet">"Koble til Internett.</string> + </resources> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/nontranslatable.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/nontranslatable.xml new file mode 100644 index 0000000..f608bff --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/nontranslatable.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="dummy" translatable="false">Ignore Me</string> +</resources> + diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/nontranslatable2.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/nontranslatable2.xml new file mode 100644 index 0000000..4fcfdc6 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/nontranslatable2.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="dummy">Ignore Me</string> +</resources> + diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/typos.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/typos.xml index a167e44..a94be49 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/typos.xml +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/typos.xml @@ -3,9 +3,9 @@ <!-- No typos --> <string name="s1">Home Sample</string> <!-- Plain typos --> - <string name="s2">Andriod activites</string> + <string name="s2">Andriod activites!</string> <!-- Make capitalization match typo --> - <string name="s3"> Cmoputer </string> + <string name="s3"> (Cmoputer </string> <!-- Markup indirection --> <string name="s4"><b>throught</b></string> <!-- Typo, match capitalized --> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java index 4765f41..8379618 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java @@ -16,7 +16,11 @@ package com.android.tools.lint.detector.api; +import static com.android.tools.lint.detector.api.LintUtils.splitPath; +import static com.android.tools.lint.detector.api.LintUtils.getLocaleAndRegion; + import com.android.tools.lint.Main; +import com.google.common.collect.Iterables; import java.io.BufferedOutputStream; import java.io.File; @@ -92,6 +96,31 @@ public class LintUtilsTest extends TestCase { assertEquals(6, LintUtils.editDistance("radiobutton", "bitton")); } + public void testSplitPath() throws Exception { + assertTrue(Arrays.equals(new String[] { "/foo", "/bar", "/baz" }, + Iterables.toArray(splitPath("/foo:/bar:/baz"), String.class))); + + assertTrue(Arrays.equals(new String[] { "/foo", "/bar" }, + Iterables.toArray(splitPath("/foo;/bar"), String.class))); + + assertTrue(Arrays.equals(new String[] { "/foo", "/bar:baz" }, + Iterables.toArray(splitPath("/foo;/bar:baz"), String.class))); + + assertTrue(Arrays.equals(new String[] { "\\foo\\bar", "\\bar\\foo" }, + Iterables.toArray(splitPath("\\foo\\bar;\\bar\\foo"), String.class))); + + assertTrue(Arrays.equals(new String[] { "${sdk.dir}\\foo\\bar", "\\bar\\foo" }, + Iterables.toArray(splitPath("${sdk.dir}\\foo\\bar;\\bar\\foo"), + String.class))); + + assertTrue(Arrays.equals(new String[] { "${sdk.dir}/foo/bar", "/bar/foo" }, + Iterables.toArray(splitPath("${sdk.dir}/foo/bar:/bar/foo"), + String.class))); + + assertTrue(Arrays.equals(new String[] { "C:\\foo", "/bar" }, + Iterables.toArray(splitPath("C:\\foo:/bar"), String.class))); + } + public void testCommonParen1() { assertEquals(new File("/a"), (LintUtils.getCommonParent( new File("/a/b/c/d/e"), new File("/a/c")))); @@ -246,4 +275,14 @@ public class LintUtilsTest extends TestCase { checkEncoding("UTF_32", true /*bom*/, "\r\n"); checkEncoding("UTF_32LE", true /*bom*/, "\r\n"); } + + public void testGetLocaleAndRegion() throws Exception { + assertNull(getLocaleAndRegion("")); + assertNull(getLocaleAndRegion("values")); + assertNull(getLocaleAndRegion("values-xlarge-port")); + assertEquals("en", getLocaleAndRegion("values-en")); + assertEquals("pt-rPT", getLocaleAndRegion("values-pt-rPT-nokeys")); + assertEquals("zh-rCN", getLocaleAndRegion("values-zh-rCN-keyshidden")); + assertEquals("ms", getLocaleAndRegion("values-ms-keyshidden")); + } }
\ No newline at end of file diff --git a/manifmerger/src/com/android/manifmerger/ManifestMerger.java b/manifmerger/src/com/android/manifmerger/ManifestMerger.java index 229faa3..d63ecd8 100755 --- a/manifmerger/src/com/android/manifmerger/ManifestMerger.java +++ b/manifmerger/src/com/android/manifmerger/ManifestMerger.java @@ -36,7 +36,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; @@ -742,8 +742,8 @@ public class ManifestMerger { Element destUsesSdk = findFirstElement(mMainDoc, "/manifest/uses-sdk"); //$NON-NLS-1$ Element srcUsesSdk = findFirstElement(libDoc, "/manifest/uses-sdk"); //$NON-NLS-1$ - AtomicInteger destValue = new AtomicInteger(1); - AtomicInteger srcValue = new AtomicInteger(1); + AtomicReference<Object> destValue = new AtomicReference<Object>(1); // String or Integer + AtomicReference<Object> srcValue = new AtomicReference<Object>(1); AtomicBoolean destImplied = new AtomicBoolean(true); AtomicBoolean srcImplied = new AtomicBoolean(true); @@ -756,16 +756,17 @@ public class ManifestMerger { destValue, srcValue, destImplied, srcImplied); - if (result) { + if (result && destValue.get() instanceof Integer && srcValue.get() instanceof Integer) { // Make it an error for an application to use a library with a greater // minSdkVersion. This means the library code may crash unexpectedly. // TODO it would be nice to be able to work around this in case the // user think s/he knows what s/he's doing. // We could define a simple XML comment flag: <!-- @NoMinSdkVersionMergeError --> - destMinSdk = destValue.get(); + destMinSdk = (Integer) destValue.get(); - if (destMinSdk < srcValue.get()) { + int srcMinSdk = (Integer) srcValue.get(); + if (destMinSdk < srcMinSdk) { mLog.conflict(Severity.ERROR, xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk), xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk), @@ -794,13 +795,14 @@ public class ManifestMerger { destImplied, srcImplied); result &= result2; - if (result2) { + if (result2 && destValue.get() instanceof Integer && srcValue.get() instanceof Integer) { // Make it a warning for an application to use a library with a greater // targetSdkVersion. - int destTargetSdk = destImplied.get() ? destMinSdk : destValue.get(); + int destTargetSdk = destImplied.get() ? destMinSdk : (Integer) destValue.get(); - if (destTargetSdk < srcValue.get()) { + int srcMinSdk = (Integer) srcValue.get(); + if (destTargetSdk < srcMinSdk) { mLog.conflict(Severity.WARNING, xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk), xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk), @@ -831,8 +833,8 @@ public class ManifestMerger { Element destUsesSdk, Element srcUsesSdk, String attr, - AtomicInteger destValue, - AtomicInteger srcValue, + AtomicReference<Object> destValue, + AtomicReference<Object> srcValue, AtomicBoolean destImplied, AtomicBoolean srcImplied) { String s = destUsesSdk == null ? "" //$NON-NLS-1$ @@ -846,14 +848,9 @@ public class ManifestMerger { destImplied.set(false); } } catch (NumberFormatException e) { - // Note: NumberFormatException.toString() has no interesting information - // so we don't output it. - mLog.error(Severity.ERROR, - xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk), - "Failed to parse <uses-sdk %1$sSdkVersion='%2$s'>: must be an integer number.", - attr, - s); - return false; + // Versions can contain codenames such as "JellyBean" + destValue.set(s); + destImplied.set(false); } s = srcUsesSdk == null ? "" //$NON-NLS-1$ @@ -866,12 +863,9 @@ public class ManifestMerger { srcImplied.set(false); } } catch (NumberFormatException e) { - mLog.error(Severity.ERROR, - xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk), - "Failed to parse <uses-sdk %1$sSdkVersion='%2$s'>: must be an integer number.", - attr, - s); - return false; + // Versions can contain codenames such as "JellyBean" + destValue.set(s); + destImplied.set(false); } return true; diff --git a/monitor/Android.mk b/monitor/Android.mk index 9973d64..fbf5a6d 100644 --- a/monitor/Android.mk +++ b/monitor/Android.mk @@ -1,7 +1,7 @@ # Copyright 2012 The Android Open Source Project # Expose the Monitor RCP only for the SDK builds. -ifneq (,$(is_sdk_build)$(filter sdk sdk_x86,$(TARGET_PRODUCT))) +ifneq (,$(is_sdk_build)$(filter sdk sdk_x86 sdk_mips,$(TARGET_PRODUCT))) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java index 0f55eeb..21a2332 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java @@ -17,6 +17,7 @@ package com.android.sdklib; import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.annotations.VisibleForTesting; import com.android.annotations.VisibleForTesting.Visibility; import com.android.io.FileWrapper; @@ -30,6 +31,7 @@ import com.android.sdklib.internal.repository.NullTaskMonitor; import com.android.sdklib.internal.repository.archives.Archive; import com.android.sdklib.internal.repository.packages.ExtraPackage; import com.android.sdklib.internal.repository.packages.Package; +import com.android.sdklib.internal.repository.packages.PlatformToolPackage; import com.android.sdklib.repository.PkgProps; import com.android.util.Pair; @@ -364,6 +366,21 @@ public class SdkManager { return extraVersions; } + /** Returns the platform tools version if installed, null otherwise. */ + public @Nullable String getPlatformToolsVersion() { + LocalSdkParser parser = new LocalSdkParser(); + Package[] packages = parser.parseSdk(mOsSdkPath, this, LocalSdkParser.PARSE_PLATFORM_TOOLS, + new NullTaskMonitor(new NullSdkLog())); + + for (Package pkg : packages) { + if (pkg instanceof PlatformToolPackage && pkg.isLocal()) { + return pkg.getRevision().toShortString(); + } + } + + return null; + } + // -------- private methods ---------- diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceManager.java index 61d8307..d46ca5f 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceManager.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceManager.java @@ -68,6 +68,8 @@ public class DeviceManager { private static List<Device> mUserDevices; private static List<Device> mDefaultDevices; private static final Object lock = new Object(); + private static final List<DevicesChangeListener> listeners = + Collections.synchronizedList(new ArrayList<DevicesChangeListener>()); // TODO: Refactor this to look more like AvdManager so that we don't have // multiple instances @@ -79,6 +81,34 @@ public class DeviceManager { } /** + * Interface implemented by objects which want to know when changes occur to the {@link Device} + * lists. + */ + public static interface DevicesChangeListener { + /** + * Called after one of the {@link Device} lists has been updated. + */ + public void onDevicesChange(); + } + + /** + * Register a listener to be notified when the device lists are modified. + * @param listener The listener to add + */ + public void registerListener(DevicesChangeListener listener) { + listeners.add(listener); + } + + /** + * Removes a listener from the notification list such that it will no longer receive + * notifications when modifications to the {@link Device} list occur. + * @param listener The listener to remove. + */ + public void unregisterListener(DevicesChangeListener listener) { + listeners.remove(listener); + } + + /** * Returns both vendor provided and user created {@link Device}s. * * @param sdkLocation Location of the Android SDK @@ -111,6 +141,7 @@ public class DeviceManager { mLog.error(null, "Error reading default devices"); mDefaultDevices = new ArrayList<Device>(); } + notifyListeners(); } } return Collections.unmodifiableList(mDefaultDevices); @@ -125,6 +156,7 @@ public class DeviceManager { public List<Device> getVendorDevices(String sdkLocation) { synchronized (lock) { if (mVendorDevices == null || !mVendorDevicesLocation.equals(sdkLocation)) { + mVendorDevicesLocation = sdkLocation; List<Device> devices = new ArrayList<Device>(); File extrasFolder = new File(sdkLocation, SdkConstants.FD_EXTRAS); List<File> deviceDirs = getExtraDirs(extrasFolder); @@ -135,6 +167,7 @@ public class DeviceManager { } } mVendorDevices = devices; + notifyListeners(); } } return Collections.unmodifiableList(mVendorDevices); @@ -151,12 +184,29 @@ public class DeviceManager { // User devices should be saved out to // $HOME/.android/devices.xml mUserDevices = new ArrayList<Device>(); + File userDevicesFile = null; try { - File userDevicesFile = new File(AndroidLocation.getFolder(), + userDevicesFile = new File(AndroidLocation.getFolder(), SdkConstants.FN_DEVICES_XML); - mUserDevices.addAll(loadDevices(userDevicesFile)); + mUserDevices.addAll(DeviceParser.parse(userDevicesFile)); + notifyListeners(); } catch (AndroidLocationException e) { mLog.warning("Couldn't load user devices: %1$s", e.getMessage()); + } catch (SAXException e) { + // Probably an old config file which we don't want to overwrite. + String base = userDevicesFile.getAbsoluteFile()+".old"; + File renamedConfig = new File(base); + int i = 0; + while (renamedConfig.exists()) { + renamedConfig = new File(base + "." + (i++)); + } + mLog.error(null, "Error parsing %1$s, backing up to %2$s", + userDevicesFile.getAbsolutePath(), renamedConfig.getAbsolutePath()); + userDevicesFile.renameTo(renamedConfig); + } catch (ParserConfigurationException e) { + mLog.error(null, "Error parsing %1$s", userDevicesFile.getAbsolutePath()); + } catch (IOException e) { + mLog.error(null, "Error parsing %1$s", userDevicesFile.getAbsolutePath()); } } } @@ -170,6 +220,7 @@ public class DeviceManager { } mUserDevices.add(d); } + notifyListeners(); } public void removeUserDevice(Device d) { @@ -183,6 +234,7 @@ public class DeviceManager { if (userDevice.getName().equals(d.getName()) && userDevice.getManufacturer().equals(d.getManufacturer())) { it.remove(); + notifyListeners(); break; } @@ -253,17 +305,6 @@ public class DeviceManager { Integer.toString(hw.getScreen().getPixelDensity().getDpiValue())); props.put("hw.sensors.proximity", getBooleanVal(sensors.contains(Sensor.PROXIMITY_SENSOR))); - - for (Camera c : hw.getCameras()) { - String prop; - if (c.getLocation().equals(CameraLocation.FRONT)) { - prop = "hw.camera.front"; - } else { - prop = "hw.camera.back"; - } - props.put(prop, "emulated"); - } - return props; } @@ -281,7 +322,7 @@ public class DeviceManager { props.put("hw.keyboard.lid", getBooleanVal(true)); } } - return getHardwareProperties(d.getDefaultState()); + return props; } /** @@ -317,6 +358,14 @@ public class DeviceManager { return new ArrayList<Device>(); } + private void notifyListeners() { + synchronized (listeners) { + for (DevicesChangeListener listener : listeners) { + listener.onDevicesChange(); + } + } + } + /* Returns all of DeviceProfiles in the extras/ folder */ private List<File> getExtraDirs(File extrasFolder) { List<File> extraDirs = new ArrayList<File>(); diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceParser.java index 43b63cb..dd63af2 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceParser.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceParser.java @@ -304,6 +304,8 @@ public class DeviceParser { } else { mState.setNavState(NavigationState.getEnum(getString(mStringAccumulator))); } + } else if (DeviceSchema.NODE_STATUS_BAR.equals(localName)) { + mSoftware.setStatusBar(getBool(mStringAccumulator)); } } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Software.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Software.java index b89860f..a452b6e 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Software.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Software.java @@ -27,6 +27,7 @@ public class Software { private Set<BluetoothProfile> mBluetoothProfiles = new HashSet<BluetoothProfile>(); private String mGlVersion; private Set<String> mGlExtensions = new HashSet<String>(); + private boolean mStatusBar; public int getMinSdkLevel() { return mMinSdkLevel; @@ -84,6 +85,14 @@ public class Software { mGlExtensions.addAll(extensions); } + public void setStatusBar(boolean hasBar) { + mStatusBar = hasBar; + } + + public boolean hasStatusBar() { + return mStatusBar; + } + public Software deepCopy() { Software s = new Software(); s.setMinSdkLevel(getMinSdkLevel()); @@ -92,6 +101,7 @@ public class Software { s.addAllBluetoothProfiles(getBluetoothProfiles()); s.setGlVersion(getGlVersion()); s.addAllGlExtensions(getGlExtensions()); + s.setStatusBar(hasStatusBar()); return s; } @@ -110,7 +120,8 @@ public class Software { && mLiveWallpaperSupport == sw.hasLiveWallpaperSupport() && mBluetoothProfiles.equals(sw.getBluetoothProfiles()) && mGlVersion.equals(sw.getGlVersion()) - && mGlExtensions.equals(sw.getGlExtensions()); + && mGlExtensions.equals(sw.getGlExtensions()) + && mStatusBar == sw.hasStatusBar(); } @Override @@ -122,6 +133,7 @@ public class Software { hash = 31 * hash + mBluetoothProfiles.hashCode(); hash = 31 * hash + mGlVersion.hashCode(); hash = 31 * hash + mGlExtensions.hashCode(); + hash = 31 * hash + (mStatusBar ? 1 : 0); return hash; } } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/devices.xml b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/devices.xml index bc9ec91..e18280d 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/devices.xml +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/devices.xml @@ -75,6 +75,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -163,6 +164,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -257,6 +259,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -351,6 +354,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -439,6 +443,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -526,6 +531,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -614,6 +620,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -702,6 +709,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -796,6 +804,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -934,6 +943,7 @@ GL_OES_vertex_array_object GL_OES_vertex_half_float </d:gl-extensions> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> <d:description>The phone in portrait view</d:description> @@ -1021,6 +1031,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -1109,6 +1120,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -1197,6 +1209,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -1285,6 +1298,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> @@ -1379,6 +1393,7 @@ <d:bluetooth-profiles /> <d:gl-version>2.1</d:gl-version> <d:gl-extensions /> + <d:status-bar>true</d:status-bar> </d:software> <d:state name="Portrait" default="true"> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java index 46d3124..091dc0b 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java @@ -152,6 +152,21 @@ public class AvdManager { public final static String AVD_INI_SNAPSHOT_PRESENT = "snapshot.present"; //$NON-NLS-1$ /** + * AVD/config.ini key name representing whether hardware OpenGLES emulation is enabled + */ + public final static String AVD_INI_GPU_EMULATION = "hw.gpu.enabled"; //$NON-NLS-1$ + + /** + * AVD/config.ini key name representing how to emulate the front facing camera + */ + public final static String AVD_INI_CAMERA_FRONT = "hw.camera.front"; //$NON-NLS-1$ + + /** + * AVD/config.ini key name representing how to emulate the rear facing camera + */ + public final static String AVD_INI_CAMERA_BACK = "hw.camera.back"; //$NON-NLS-1$ + + /** * Pattern to match pixel-sized skin "names", e.g. "320x480". */ public final static Pattern NUMERIC_SKIN_SIZE = Pattern.compile("([0-9]{2,})x([0-9]{2,})"); //$NON-NLS-1$ diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSources.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSources.java index b1354c3..619d7b2 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSources.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSources.java @@ -287,7 +287,21 @@ public class SdkSources { for (int i = 0; i < count; i++) {
String url = props.getProperty(String.format("%s%02d", KEY_SRC, i)); //$NON-NLS-1$
if (url != null) {
- SdkSource s = new SdkAddonSource(url, null/*uiName*/);
+ // FIXME: this code originally only dealt with add-on XML sources.
+ // Now we'd like it to deal with system-image sources too, but we
+ // don't know which kind of object it is (at least not without
+ // trying to fetch it.) As a temporary workaround, just take a
+ // guess based on the leaf URI name. However ideally what we can
+ // simply do is add a checkbox "is system-image XML" in the user
+ // dialog and pass this info down here. Another alternative is to
+ // make a "dynamic" source object that tries to guess its type once
+ // the URI has been fetched.
+ SdkSource s;
+ if (url.endsWith("sys-img.xml")) {
+ s = new SdkSysImgSource(url, null/*uiName*/);
+ } else {
+ s = new SdkAddonSource(url, null/*uiName*/);
+ }
if (!hasSourceUrl(s)) {
add(SdkSourceCategory.USER_ADDONS, s);
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java index ba9bce7..8e66c63 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java @@ -130,6 +130,34 @@ public class AdtUpdateDialog extends SwtBaseDialog { }
/**
+ * Displays the update dialog and triggers installation of platform-tools package.
+ * <p/>
+ * Callers must not try to reuse this dialog after this call.
+ *
+ * @return A boolean indicating whether the installation was successful (meaning the package
+ * was either already present, or got installed or updated properly) and a {@link File}
+ * with the path to the root folder of the package. The file is null when the boolean
+ * is false, otherwise it should point to an existing valid folder.
+ * @wbp.parser.entryPoint
+ */
+ public Pair<Boolean, File> installPlatformTools() {
+ mPackageFilter = createPlatformToolsFilter();
+ open();
+
+ File installPath = null;
+ if (mResultPaths != null) {
+ for (Entry<Package, File> entry : mResultPaths.entrySet()) {
+ if (entry.getKey() instanceof ExtraPackage) {
+ installPath = entry.getValue();
+ break;
+ }
+ }
+ }
+
+ return Pair.of(mResultCode, installPath);
+ }
+
+ /**
* Displays the update dialog and triggers installation of the requested platform
* package with the specified API level.
* <p/>
@@ -337,6 +365,25 @@ public class AdtUpdateDialog extends SwtBaseDialog { };
}
+ private PackageFilter createPlatformToolsFilter() {
+ return new PackageFilter() {
+ @Override
+ boolean accept(Package pkg) {
+ return pkg instanceof PlatformToolPackage;
+ }
+
+ @Override
+ void visit(Package pkg) {
+ // nop
+ }
+
+ @Override
+ int installFlags() {
+ return UpdaterData.TOOLS_MSG_UPDATED_FROM_ADT;
+ }
+ };
+ }
+
public static PackageFilter createPlatformFilter(final int apiLevel) {
return new PackageFilter() {
int mApiLevel = apiLevel;
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AvdManagerWindowImpl1.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AvdManagerWindowImpl1.java index c84506b..06cdc74 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AvdManagerWindowImpl1.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AvdManagerWindowImpl1.java @@ -362,7 +362,9 @@ public class AvdManagerWindowImpl1 { public void widgetSelected(SelectionEvent e) { DeviceCreationDialog dlg = new DeviceCreationDialog( mShell, manager, mUpdaterData.getImageFactory(), null); - dlg.open(); + if (dlg.open() == Window.OK) { + setupDevices(menuBarDevices); + } } }); new MenuItem(menuDevices, SWT.SEPARATOR); diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java index 39a2710..1c0b167 100644 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,43 +16,26 @@ package com.android.sdkuilib.internal.widgets; -import com.android.io.FileWrapper; import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.ISdkLog; import com.android.sdklib.ISystemImage; import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; -import com.android.sdklib.devices.Abi; +import com.android.sdklib.devices.Camera; +import com.android.sdklib.devices.CameraLocation; import com.android.sdklib.devices.Device; import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.devices.Hardware; +import com.android.sdklib.devices.Screen; import com.android.sdklib.internal.avd.AvdInfo; import com.android.sdklib.internal.avd.AvdManager; import com.android.sdklib.internal.avd.AvdManager.AvdConflict; import com.android.sdklib.internal.avd.HardwareProperties; -import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty; -import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdkuilib.internal.repository.icons.ImageFactory; import com.android.sdkuilib.ui.GridDialog; import com.android.util.Pair; import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.CellLabelProvider; -import org.eclipse.jface.viewers.ComboBoxCellEditor; -import org.eclipse.jface.viewers.EditingSupport; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; @@ -60,7 +43,6 @@ import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -71,90 +53,64 @@ import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import java.io.File; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; import java.util.TreeMap; -import java.util.regex.Matcher; -/** - * AVD creation or edit dialog. - * - * TODO: - * - use SdkTargetSelector instead of Combo - * - tooltips on widgets. - * - */ -final class AvdCreationDialog extends GridDialog { +public class AvdCreationDialog extends GridDialog { - private final AvdManager mAvdManager; + private AvdManager mAvdManager; + private ImageFactory mImageFactory; + private ISdkLog mSdkLog; + private AvdInfo mAvdInfo; + + // A map from manufacturers to their list of devices. + private Map<String, List<Device>> mDeviceMap; private final TreeMap<String, IAndroidTarget> mCurrentTargets = - new TreeMap<String, IAndroidTarget>(); - - private final Map<String, HardwareProperty> mHardwareMap; - private final Map<String, String> mProperties = new HashMap<String, String>(); - // a list of user-edited properties. - private final ArrayList<String> mEditedProperties = new ArrayList<String>(); - private final ImageFactory mImageFactory; - private final ISdkLog mSdkLog; - private final DeviceManager mDeviceManager; - private final List<Device> mDeviceList = new ArrayList<Device>(); - /** - * The original AvdInfo if we're editing an existing AVD. - * Null when we're creating a new AVD. - */ - private final AvdInfo mEditAvdInfo; + new TreeMap<String, IAndroidTarget>(); + + private Button mOkButton; private Text mAvdName; - private Combo mTargetCombo; - private Combo mAbiTypeCombo; - private String mAbiType; + private Combo mDeviceManufacturer; + private Combo mDeviceName; + + private Combo mTarget; + private Combo mAbi; - private Combo mDeviceCombo; + private Combo mFrontCamera; + private Combo mBackCamera; + + private Button mSnapshot; + private Button mGpuEmulation; private Button mSdCardSizeRadio; private Text mSdCardSize; private Combo mSdCardSizeCombo; - + private Button mSdCardFileRadio; private Text mSdCardFile; private Button mBrowseSdCard; - private Button mSdCardFileRadio; - - private Button mSnapshotCheck; - - private Button mSkinListRadio; - private Combo mSkinCombo; - - private Button mSkinSizeRadio; - private Text mSkinSizeWidth; - private Text mSkinSizeHeight; - - private TableViewer mHardwareViewer; - private Button mDeleteHardwareProp; private Button mForceCreation; - private Button mOkButton; + private Composite mStatusComposite; + private Label mStatusIcon; private Label mStatusLabel; - private Composite mStatusComposite; /** - * {@link VerifyListener} for {@link Text} widgets that should only contains numbers. + * {@link VerifyListener} for {@link Text} widgets that should only contains + * numbers. */ private final VerifyListener mDigitVerifier = new VerifyListener() { @Override public void verifyText(VerifyEvent event) { int count = event.text.length(); - for (int i = 0 ; i < count ; i++) { + for (int i = 0; i < count; i++) { char c = event.text.charAt(i); if (c < '0' || c > '9') { event.doit = false; @@ -164,202 +120,158 @@ final class AvdCreationDialog extends GridDialog { } }; - /** - * Callback when the AVD name is changed. - * When creating a new AVD, enables the force checkbox if the name is a duplicate. - * When editing an existing AVD, it's OK for the name to match the existing AVD. - */ - private class CreateNameModifyListener implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - String name = mAvdName.getText().trim(); - if (mEditAvdInfo == null || !name.equals(mEditAvdInfo.getName())) { - // Case where we're creating a new AVD or editing an existing one - // and the AVD name has been changed... check for name uniqueness. - - Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(name); - if (conflict.getFirst() != AvdManager.AvdConflict.NO_CONFLICT) { - // If we're changing the state from disabled to enabled, make sure - // to uncheck the button, to force the user to voluntarily re-enforce it. - // This happens when editing an existing AVD and changing the name from - // the existing AVD to another different existing AVD. - if (!mForceCreation.isEnabled()) { - mForceCreation.setEnabled(true); - mForceCreation.setSelection(false); - } - } else { - mForceCreation.setEnabled(false); - mForceCreation.setSelection(false); - } - } else { - // Case where we're editing an existing AVD with the name unchanged. - - mForceCreation.setEnabled(false); - mForceCreation.setSelection(false); - } - validatePage(); - } - } - - /** - * {@link ModifyListener} used for live-validation of the fields content. - */ - private class ValidateListener extends SelectionAdapter implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - validatePage(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - validatePage(); - } - } - - /** - * Creates the dialog. Caller should then use {@link Window#open()} and - * refresh if the status is {@link Window#OK}. - * - * @param parentShell The parent shell. - * @param avdManager The existing {@link AvdManager} to use. Must not be null. - * @param imageFactory An existing {@link ImageFactory} to use. Must not be null. - * @param log An existing {@link ISdkLog} where output will go. Must not be null. - * @param editAvdInfo An optional {@link AvdInfo}. When null, the dialog is used - * to create a new AVD. When non-null, the dialog is used to <em>edit</em> this AVD. - */ - protected AvdCreationDialog(Shell parentShell, + public AvdCreationDialog(Shell shell, AvdManager avdManager, ImageFactory imageFactory, ISdkLog log, AvdInfo editAvdInfo) { - super(parentShell, 2, false); + + super(shell, 2, false); mAvdManager = avdManager; mImageFactory = imageFactory; mSdkLog = log; - mEditAvdInfo = editAvdInfo; + mAvdInfo = editAvdInfo; - File hardwareDefs = null; - mDeviceManager = new DeviceManager(log); - mDeviceList.addAll(mDeviceManager.getUserDevices()); - mDeviceList.addAll(mDeviceManager.getDefaultDevices()); + mDeviceMap = new TreeMap<String, List<Device>>(); SdkManager sdkMan = avdManager.getSdkManager(); - if (sdkMan != null) { - String sdkPath = sdkMan.getLocation(); - if (sdkPath != null) { - hardwareDefs = new File (sdkPath + File.separator + - SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI); - mDeviceList.addAll(mDeviceManager.getVendorDevices(sdkPath)); + if (sdkMan != null && sdkMan.getLocation() != null) { + List<Device> devices = (new DeviceManager(log)).getDevices(sdkMan.getLocation()); + for (Device d : devices) { + List<Device> list; + if (mDeviceMap.containsKey(d.getManufacturer())) { + list = mDeviceMap.get(d.getManufacturer()); + } else { + list = new ArrayList<Device>(); + mDeviceMap.put(d.getManufacturer(), list); + } + list.add(d); } } - - if (hardwareDefs == null) { - log.error(null, "Failed to load file %s from SDK", SdkConstants.FN_HARDWARE_INI); - mHardwareMap = new HashMap<String, HardwareProperty>(); - } else { - mHardwareMap = HardwareProperties.parseHardwareDefinitions( - hardwareDefs, null /*sdkLog*/); - } - } - - @Override - public void create() { - super.create(); - - Point p = getShell().getSize(); - if (p.x < 400) { - p.x = 400; - } - getShell().setSize(p); } @Override protected Control createContents(Composite parent) { Control control = super.createContents(parent); - getShell().setText(mEditAvdInfo == null ? "Create new Android Virtual Device (AVD)" - : "Edit Android Virtual Device (AVD)"); + getShell().setText(mAvdInfo == null ? "Create new Android Virtual Device (AVD)" + : "Edit Android Virtual Device (AVD)"); mOkButton = getButton(IDialogConstants.OK_ID); - fillExistingAvdInfo(); - validatePage(); + if (mAvdInfo != null) { + fillExistingAvdInfo(mAvdInfo); + } + validatePage(); return control; } @Override - public void createDialogContent(final Composite parent) { - GridData gd; - GridLayout gl; + public void createDialogContent(Composite parent) { - Label label = new Label(parent, SWT.NONE); - label.setText("Name:"); - String tooltip = "Name of the new Android Virtual Device"; - label.setToolTipText(tooltip); + Label label; + String tooltip; + ValidateListener validateListener = new ValidateListener(); + // --- avd name + label = new Label(parent, SWT.NONE); + label.setText("AVD Name:"); + tooltip = "The name of the Android Virtual Device"; + label.setToolTipText(tooltip); mAvdName = new Text(parent, SWT.BORDER); mAvdName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); mAvdName.addModifyListener(new CreateNameModifyListener()); - mAvdName.setToolTipText(tooltip); + // --- device selection label = new Label(parent, SWT.NONE); - label.setText("Target:"); - tooltip = "The version of Android to use in the virtual device"; - label.setToolTipText(tooltip); - - mTargetCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mTargetCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mTargetCombo.setToolTipText(tooltip); - mTargetCombo.addSelectionListener(new SelectionAdapter() { + label.setText("Device\nManufacturer:"); + tooltip = "The manufacturer of the device this AVD will be based on"; + mDeviceManufacturer = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + for (String manufacturer : mDeviceMap.keySet()) { + mDeviceManufacturer.add(manufacturer); + } + mDeviceManufacturer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mDeviceManufacturer.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - reloadSkinCombo(); - reloadAbiTypeCombo(); - reloadDeviceCombo(); + reloadDeviceNameCombo(); validatePage(); } }); - // Device Selection label = new Label(parent, SWT.NONE); - label.setText("Device:"); - tooltip = "The device to base the AVD on. This is an optional setting and will merely " + - "prefill the settings so they match the selected device as closely as possible."; + label.setText("Device Name:"); + tooltip = "The name of the device this AVD will be based on"; + mDeviceName = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + mDeviceName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mDeviceName.addSelectionListener(new DeviceSelectionListener()); + + // --- api target + label = new Label(parent, SWT.NONE); + label.setText("Target:"); + tooltip = "The target API of the AVD"; label.setToolTipText(tooltip); - mDeviceCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mDeviceCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDeviceCombo.setToolTipText(tooltip); - mDeviceCombo.setEnabled(false); - mDeviceCombo.addSelectionListener(new SelectionAdapter() { + mTarget = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + mTarget.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mTarget.setToolTipText(tooltip); + mTarget.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - prefillWithDeviceConfig(); + reloadAbiTypeCombo(); validatePage(); } - - }); - //ABI group + reloadTargetCombo(); + + // --- avd ABIs label = new Label(parent, SWT.NONE); label.setText("CPU/ABI:"); - tooltip = "The CPU/ABI to use in the virtual device"; + tooltip = "The CPU/ABI of the virtual device"; + label.setToolTipText(tooltip); + mAbi = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + mAbi.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mAbi.setToolTipText(tooltip); + mAbi.addSelectionListener(validateListener); + + label = new Label(parent, SWT.NONE); + label.setText("Front Camera:"); + tooltip = ""; label.setToolTipText(tooltip); + mFrontCamera = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + mFrontCamera.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mFrontCamera.add("None"); + mFrontCamera.add("Emulated"); + mFrontCamera.add("Webcam0"); + mFrontCamera.select(0); + + label = new Label(parent, SWT.NONE); + label.setText("Back Camera:"); + tooltip = ""; + label.setToolTipText(tooltip); + mBackCamera = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + mBackCamera.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mBackCamera.add("None"); + mBackCamera.add("Emulated"); + mBackCamera.add("Webcam0"); + mBackCamera.select(0); + + toggleCameras(); - mAbiTypeCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mAbiTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mAbiTypeCombo.setToolTipText(tooltip); - mAbiTypeCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - validatePage(); - } - }); - mAbiTypeCombo.setEnabled(false); + // --- avd options group + label = new Label(parent, SWT.NONE); + label.setText("Options:"); + label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, + false, false)); + Group optionsGroup = new Group(parent, SWT.NONE); + optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + optionsGroup.setLayout(new GridLayout(2, true)); + mSnapshot = new Button(optionsGroup, SWT.CHECK); + mSnapshot.setText("Snapshot"); + mSnapshot.setToolTipText("Emulator's state will be persisted between emulator executions"); + mGpuEmulation = new Button(optionsGroup, SWT.CHECK); + mGpuEmulation.setText("GPU Emulation"); + mGpuEmulation.setToolTipText("Enable hardware OpenGLES emulation"); // --- sd card group label = new Label(parent, SWT.NONE); @@ -383,8 +295,6 @@ final class AvdCreationDialog extends GridDialog { } }); - ValidateListener validateListener = new ValidateListener(); - mSdCardSize = new Text(sdCardGroup, SWT.BORDER); mSdCardSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); mSdCardSize.addVerifyListener(mDigitVerifier); @@ -411,144 +321,21 @@ final class AvdCreationDialog extends GridDialog { mBrowseSdCard.setText("Browse..."); mBrowseSdCard.setToolTipText("Select the file to use for the SD Card"); mBrowseSdCard.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onBrowseSdCard(); - validatePage(); - } - }); - - mSdCardSizeRadio.setSelection(true); - enableSdCardWidgets(true); - - // --- snapshot group - - label = new Label(parent, SWT.NONE); - label.setText("Snapshot:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group snapshotGroup = new Group(parent, SWT.NONE); - snapshotGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - snapshotGroup.setLayout(new GridLayout(3, false)); - - mSnapshotCheck = new Button(snapshotGroup, SWT.CHECK); - mSnapshotCheck.setText("Enabled"); - mSnapshotCheck.setToolTipText( - "Emulator's state will be persisted between emulator executions"); - - // --- skin group - label = new Label(parent, SWT.NONE); - label.setText("Skin:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group skinGroup = new Group(parent, SWT.NONE); - skinGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - skinGroup.setLayout(new GridLayout(4, false)); - - mSkinListRadio = new Button(skinGroup, SWT.RADIO); - mSkinListRadio.setText("Built-in:"); - mSkinListRadio.setToolTipText("Select an emulated screen size provided by the current Android target"); - mSkinListRadio.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent arg0) { - boolean listMode = mSkinListRadio.getSelection(); - enableSkinWidgets(listMode); + onBrowseSdCard(); validatePage(); } }); - mSkinCombo = new Combo(skinGroup, SWT.READ_ONLY | SWT.DROP_DOWN); - mSkinCombo.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 3; - mSkinCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - // get the skin info - loadSkin(); - } - }); - - mSkinSizeRadio = new Button(skinGroup, SWT.RADIO); - mSkinSizeRadio.setText("Resolution:"); - mSkinSizeRadio.setToolTipText("Select a custom emulated screen size"); - - mSkinSizeWidth = new Text(skinGroup, SWT.BORDER); - mSkinSizeWidth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSkinSizeWidth.addVerifyListener(mDigitVerifier); - mSkinSizeWidth.addModifyListener(validateListener); - mSkinSizeWidth.setToolTipText("Width in pixels of the emulated screen size"); - - new Label(skinGroup, SWT.NONE).setText("x"); - - mSkinSizeHeight = new Text(skinGroup, SWT.BORDER); - mSkinSizeHeight.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSkinSizeHeight.addVerifyListener(mDigitVerifier); - mSkinSizeHeight.addModifyListener(validateListener); - mSkinSizeHeight.setToolTipText("Height in pixels of the emulated screen size"); - - mSkinListRadio.setSelection(true); - enableSkinWidgets(true); - - // --- hardware group - label = new Label(parent, SWT.NONE); - label.setText("Hardware:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group hwGroup = new Group(parent, SWT.NONE); - hwGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - hwGroup.setLayout(new GridLayout(2, false)); - - createHardwareTable(hwGroup); - - // composite for the side buttons - Composite hwButtons = new Composite(hwGroup, SWT.NONE); - hwButtons.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - hwButtons.setLayout(gl = new GridLayout(1, false)); - gl.marginHeight = gl.marginWidth = 0; - - Button b = new Button(hwButtons, SWT.PUSH | SWT.FLAT); - b.setText("New..."); - b.setToolTipText("Add a new hardware property"); - b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - b.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - HardwarePropertyChooser dialog = new HardwarePropertyChooser(parent.getShell(), - mHardwareMap, mProperties.keySet()); - if (dialog.open() == Window.OK) { - HardwareProperty choice = dialog.getProperty(); - if (choice != null) { - mProperties.put(choice.getName(), choice.getDefault()); - mHardwareViewer.refresh(); - } - } - } - }); - mDeleteHardwareProp = new Button(hwButtons, SWT.PUSH | SWT.FLAT); - mDeleteHardwareProp.setText("Delete"); - mDeleteHardwareProp.setToolTipText("Delete the selected hardware property"); - mDeleteHardwareProp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDeleteHardwareProp.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - ISelection selection = mHardwareViewer.getSelection(); - if (selection instanceof IStructuredSelection) { - String hwName = (String)((IStructuredSelection)selection).getFirstElement(); - mProperties.remove(hwName); - mHardwareViewer.refresh(); - } - } - }); - mDeleteHardwareProp.setEnabled(false); - - // --- end hardware group + mSdCardSizeRadio.setSelection(true); + enableSdCardWidgets(true); + // --- force creation group mForceCreation = new Button(parent, SWT.CHECK); mForceCreation.setText("Override the existing AVD with the same name"); - mForceCreation.setToolTipText("There's already an AVD with the same name. Check this to delete it and replace it by the new AVD."); + mForceCreation + .setToolTipText("There's already an AVD with the same name. Check this to delete it and replace it by the new AVD."); mForceCreation.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false, 2, 1)); mForceCreation.setEnabled(false); @@ -562,6 +349,7 @@ final class AvdCreationDialog extends GridDialog { mStatusComposite = new Composite(parent, SWT.NONE); mStatusComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); + GridLayout gl; mStatusComposite.setLayout(gl = new GridLayout(2, false)); gl.marginHeight = gl.marginWidth = 0; @@ -570,434 +358,119 @@ final class AvdCreationDialog extends GridDialog { false, false)); mStatusLabel = new Label(mStatusComposite, SWT.NONE); mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mStatusLabel.setText(" \n "); //$NON-NLS-1$ + mStatusLabel.setText(""); //$NON-NLS-1$ - reloadTargetCombo(); - reloadDeviceCombo(); } /** - * Creates the UI for the hardware properties table. - * This creates the {@link Table}, and several viewers ({@link TableViewer}, - * {@link TableViewerColumn}) and adds edit support for the 2nd column + * {@link ModifyListener} used for live-validation of the fields content. */ - private void createHardwareTable(Composite parent) { - final Table hardwareTable = new Table(parent, SWT.SINGLE | SWT.FULL_SELECTION); - GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); - gd.widthHint = 200; - gd.heightHint = 100; - hardwareTable.setLayoutData(gd); - hardwareTable.setHeaderVisible(true); - hardwareTable.setLinesVisible(true); - - // -- Table viewer - mHardwareViewer = new TableViewer(hardwareTable); - mHardwareViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - // it's a single selection mode, we can just access the selection index - // from the table directly. - mDeleteHardwareProp.setEnabled(hardwareTable.getSelectionIndex() != -1); - } - }); - - // only a content provider. Use viewers per column below (for editing support) - mHardwareViewer.setContentProvider(new IStructuredContentProvider() { - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // we can just ignore this. we just use mProperties directly. - } - - @Override - public Object[] getElements(Object arg0) { - return mProperties.keySet().toArray(); - } - - @Override - public void dispose() { - // pass - } - }); - - // -- column 1: prop abstract name - TableColumn col1 = new TableColumn(hardwareTable, SWT.LEFT); - col1.setText("Property"); - col1.setWidth(150); - TableViewerColumn tvc1 = new TableViewerColumn(mHardwareViewer, col1); - tvc1.setLabelProvider(new CellLabelProvider() { - @Override - public void update(ViewerCell cell) { - String name = cell.getElement().toString(); - HardwareProperty prop = mHardwareMap.get(name); - if (prop != null) { - cell.setText(prop.getAbstract()); - } else { - cell.setText(String.format("%1$s (Unknown)", name)); - } - } - }); - - // -- column 2: prop value - TableColumn col2 = new TableColumn(hardwareTable, SWT.LEFT); - col2.setText("Value"); - col2.setWidth(50); - TableViewerColumn tvc2 = new TableViewerColumn(mHardwareViewer, col2); - tvc2.setLabelProvider(new CellLabelProvider() { - @Override - public void update(ViewerCell cell) { - String value = mProperties.get(cell.getElement()); - cell.setText(value != null ? value : ""); - } - }); - - // add editing support to the 2nd column - tvc2.setEditingSupport(new EditingSupport(mHardwareViewer) { - @Override - protected void setValue(Object element, Object value) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - int index; - switch (property.getType()) { - case INTEGER: - mProperties.put((String)element, (String)value); - break; - case DISKSIZE: - if (HardwareProperties.DISKSIZE_PATTERN.matcher((String)value).matches()) { - mProperties.put((String)element, (String)value); - } - break; - case BOOLEAN: - index = (Integer)value; - mProperties.put((String)element, HardwareProperties.BOOLEAN_VALUES[index]); - break; - case STRING_ENUM: - case INTEGER_ENUM: - // For a combo, value is the index of the enum to use. - index = (Integer)value; - String[] values = property.getEnum(); - if (values != null && values.length > index) { - mProperties.put((String)element, values[index]); - } - break; - } - mHardwareViewer.refresh(element); - } - - @Override - protected Object getValue(Object element) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - String value = mProperties.get(hardwareName); - switch (property.getType()) { - case INTEGER: - // intended fall-through. - case DISKSIZE: - return value; - case BOOLEAN: - return HardwareProperties.getBooleanValueIndex(value); - case STRING_ENUM: - case INTEGER_ENUM: - // For a combo, we need to return the index of the value in the enum - String[] values = property.getEnum(); - if (values != null) { - for (int i = 0; i < values.length; i++) { - if (values[i].equals(value)) { - return i; - } - } - } - } - - return null; - } - - @Override - protected CellEditor getCellEditor(Object element) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - switch (property.getType()) { - // TODO: custom TextCellEditor that restrict input. - case INTEGER: - // intended fall-through. - case DISKSIZE: - return new TextCellEditor(hardwareTable); - case BOOLEAN: - return new ComboBoxCellEditor(hardwareTable, - HardwareProperties.BOOLEAN_VALUES, - SWT.READ_ONLY | SWT.DROP_DOWN); - case STRING_ENUM: - case INTEGER_ENUM: - String[] values = property.getEnum(); - if (values != null && values.length > 0) { - return new ComboBoxCellEditor(hardwareTable, - values, - SWT.READ_ONLY | SWT.DROP_DOWN); - } - } - return null; - } - - @Override - protected boolean canEdit(Object element) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - return property != null; - } - }); - + private class ValidateListener extends SelectionAdapter implements ModifyListener { + @Override + public void modifyText(ModifyEvent e) { + validatePage(); + } - mHardwareViewer.setInput(mProperties); + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + validatePage(); + } } - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - /** - * When editing an existing AVD info, fill the UI that has just been created with - * the values from the AVD. + * Callback when the AVD name is changed. When creating a new AVD, enables + * the force checkbox if the name is a duplicate. When editing an existing + * AVD, it's OK for the name to match the existing AVD. */ - public void fillExistingAvdInfo() { - if (mEditAvdInfo == null) { - return; - } - - mAvdName.setText(mEditAvdInfo.getName()); - - Map<String, String> props = mEditAvdInfo.getProperties(); - - if (props != null) { - // Try to match it to a device - - // The device has to be set before everything else because - // selecting a device will modify other options - for (int i = 0; i < mDeviceList.size(); i++){ - Device d = mDeviceList.get(i); - if(d.getManufacturer().equals(props.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER)) - && d.getName().equals(props.get(AvdManager.AVD_INI_DEVICE_NAME))) { - mDeviceCombo.select(i); - break; - } - } - } - - IAndroidTarget target = mEditAvdInfo.getTarget(); - if (target != null && !mCurrentTargets.isEmpty()) { - // Try to select the target in the target combo. - // This will fail if the AVD needs to be repaired. - // - // This is a linear search but the list is always - // small enough and we only do this once. - int n = mTargetCombo.getItemCount(); - for (int i = 0;i < n; i++) { - if (target.equals(mCurrentTargets.get(mTargetCombo.getItem(i)))) { - mTargetCombo.select(i); - reloadAbiTypeCombo(); - reloadDeviceCombo(); - reloadSkinCombo(); - break; - } - } - } - - // select the abi type - ISystemImage[] systemImages = getSystemImages(target); - if (target != null && systemImages.length > 0) { - mAbiTypeCombo.setEnabled(systemImages.length > 1); - String abiType = AvdInfo.getPrettyAbiType(mEditAvdInfo.getAbiType()); - int n = mAbiTypeCombo.getItemCount(); - for (int i = 0; i < n; i++) { - if (abiType.equals(mAbiTypeCombo.getItem(i))) { - mAbiTypeCombo.select(i); - reloadSkinCombo(); - break; - } - } - } - - if (props != null) { - - // First try the skin name and if it doesn't work fallback on the skin path - nextSkin: for (int s = 0; s < 2; s++) { - String skin = props.get(s == 0 ? AvdManager.AVD_INI_SKIN_NAME - : AvdManager.AVD_INI_SKIN_PATH); - if (skin != null && skin.length() > 0) { - Matcher m = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin); - if (m.matches() && m.groupCount() == 2) { - enableSkinWidgets(false); - mSkinListRadio.setSelection(false); - mSkinSizeRadio.setSelection(true); - mSkinSizeWidth.setText(m.group(1)); - mSkinSizeHeight.setText(m.group(2)); - break nextSkin; - } else { - enableSkinWidgets(true); - mSkinSizeRadio.setSelection(false); - mSkinListRadio.setSelection(true); - - int n = mSkinCombo.getItemCount(); - for (int i = 0; i < n; i++) { - if (skin.equals(mSkinCombo.getItem(i))) { - mSkinCombo.select(i); - break nextSkin; - } - } - } - } - } - - String sdcard = props.get(AvdManager.AVD_INI_SDCARD_PATH); - if (sdcard != null && sdcard.length() > 0) { - enableSdCardWidgets(false); - mSdCardSizeRadio.setSelection(false); - mSdCardFileRadio.setSelection(true); - mSdCardFile.setText(sdcard); - } - - sdcard = props.get(AvdManager.AVD_INI_SDCARD_SIZE); - if (sdcard != null && sdcard.length() > 0) { - String[] values = new String[2]; - long sdcardSize = AvdManager.parseSdcardSize(sdcard, values); - - if (sdcardSize != AvdManager.SDCARD_NOT_SIZE_PATTERN) { - enableSdCardWidgets(true); - mSdCardFileRadio.setSelection(false); - mSdCardSizeRadio.setSelection(true); - - mSdCardSize.setText(values[0]); + private class CreateNameModifyListener implements ModifyListener { + @Override + public void modifyText(ModifyEvent e) { + String name = mAvdName.getText().trim(); + if (mAvdInfo == null || !name.equals(mAvdInfo.getName())) { + // Case where we're creating a new AVD or editing an existing + // one + // and the AVD name has been changed... check for name + // uniqueness. - String suffix = values[1]; - int n = mSdCardSizeCombo.getItemCount(); - for (int i = 0; i < n; i++) { - if (mSdCardSizeCombo.getItem(i).startsWith(suffix)) { - mSdCardSizeCombo.select(i); - } + Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(name); + if (conflict.getFirst() != AvdManager.AvdConflict.NO_CONFLICT) { + // If we're changing the state from disabled to enabled, + // make sure + // to uncheck the button, to force the user to voluntarily + // re-enforce it. + // This happens when editing an existing AVD and changing + // the name from + // the existing AVD to another different existing AVD. + if (!mForceCreation.isEnabled()) { + mForceCreation.setEnabled(true); + mForceCreation.setSelection(false); } + } else { + mForceCreation.setEnabled(false); + mForceCreation.setSelection(false); } - } + } else { + // Case where we're editing an existing AVD with the name + // unchanged. - String snapshots = props.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); - if (snapshots != null && snapshots.length() > 0) { - mSnapshotCheck.setSelection(snapshots.equals("true")); + mForceCreation.setEnabled(false); + mForceCreation.setSelection(false); } + validatePage(); } + } - mProperties.clear(); + private class DeviceSelectionListener extends SelectionAdapter { - if (props != null) { - for (Entry<String, String> entry : props.entrySet()) { - HardwareProperty prop = mHardwareMap.get(entry.getKey()); - if (prop != null && prop.isValidForUi()) { - mProperties.put(entry.getKey(), entry.getValue()); - } - } + @Override + public void widgetSelected(SelectionEvent arg0) { + toggleCameras(); + validatePage(); } - // Cleanup known non-hardware properties - mProperties.remove(AvdManager.AVD_INI_ABI_TYPE); - mProperties.remove(AvdManager.AVD_INI_CPU_ARCH); - mProperties.remove(AvdManager.AVD_INI_SKIN_PATH); - mProperties.remove(AvdManager.AVD_INI_SKIN_NAME); - mProperties.remove(AvdManager.AVD_INI_SDCARD_SIZE); - mProperties.remove(AvdManager.AVD_INI_SDCARD_PATH); - mProperties.remove(AvdManager.AVD_INI_SNAPSHOT_PRESENT); - mProperties.remove(AvdManager.AVD_INI_IMAGES_1); - mProperties.remove(AvdManager.AVD_INI_IMAGES_2); - mProperties.remove(AvdManager.AVD_INI_DEVICE_MANUFACTURER); - mProperties.remove(AvdManager.AVD_INI_DEVICE_NAME); - - mHardwareViewer.refresh(); } - // Sets all of the other options based on the device currently selected in mDeviceCombo - private void prefillWithDeviceConfig() { - Device d = getSelectedDevice(); - if (d != null) { - Hardware hw = d.getDefaultHardware(); - - // Try setting the CPU/ABI - if (mAbiTypeCombo.isEnabled()) { - Set<Abi> abis = hw.getSupportedAbis(); - // This is O(n*m), but the two lists should be sufficiently small. - for (Abi abi : abis) { - for (int i = 0; i < mAbiTypeCombo.getItemCount(); i++) { - if (mAbiTypeCombo.getItem(i) - .equals(AvdInfo.getPrettyAbiType(abi.toString()))){ - mAbiTypeCombo.select(i); + private void toggleCameras() { + mFrontCamera.setEnabled(false); + mBackCamera.setEnabled(false); + if (mDeviceName.getSelectionIndex() >= 0) { + List<Device> devices = mDeviceMap.get(mDeviceManufacturer.getText()); + for (Device d : devices) { + if (mDeviceName.getText().equals(d.getName())) { + for (Camera c : d.getDefaultHardware().getCameras()) { + if (CameraLocation.FRONT.equals(c.getLocation())) { + mFrontCamera.setEnabled(true); + } + if (CameraLocation.BACK.equals(c.getLocation())) { + mBackCamera.setEnabled(true); } } } } - // Set the screen resolution - mSkinListRadio.setSelection(false); - mSkinSizeRadio.setSelection(true); - mSkinCombo.setEnabled(false); - mSkinSizeWidth.setEnabled(true); - mSkinSizeWidth.setText(Integer.toString(hw.getScreen().getXDimension())); - mSkinSizeHeight.setEnabled(true); - mSkinSizeHeight.setText(Integer.toString(hw.getScreen().getYDimension())); - - mProperties.putAll(DeviceManager.getHardwareProperties(d)); - mHardwareViewer.refresh(); - } } - @Override - protected void okPressed() { - if (createAvd()) { - super.okPressed(); + private void reloadDeviceNameCombo() { + mDeviceName.removeAll(); + if (mDeviceMap.containsKey(mDeviceManufacturer.getText())) { + for (final Device d : mDeviceMap.get(mDeviceManufacturer.getText())) { + mDeviceName.add(d.getName()); + } } - } - - /** - * Enable or disable the sd card widgets. - * @param sizeMode if true the size-based widgets are to be enabled, and the file-based ones - * disabled. - */ - private void enableSdCardWidgets(boolean sizeMode) { - mSdCardSize.setEnabled(sizeMode); - mSdCardSizeCombo.setEnabled(sizeMode); - - mSdCardFile.setEnabled(!sizeMode); - mBrowseSdCard.setEnabled(!sizeMode); - } - - /** - * Enable or disable the skin widgets. - * @param listMode if true the list-based widgets are to be enabled, and the size-based ones - * disabled. - */ - private void enableSkinWidgets(boolean listMode) { - mSkinCombo.setEnabled(listMode); - mSkinSizeWidth.setEnabled(!listMode); - mSkinSizeHeight.setEnabled(!listMode); } - - private void onBrowseSdCard() { - FileDialog dlg = new FileDialog(getContents().getShell(), SWT.OPEN); - dlg.setText("Choose SD Card image file."); - - String fileName = dlg.open(); - if (fileName != null) { - mSdCardFile.setText(fileName); - } - } - - - private void reloadTargetCombo() { String selected = null; - int index = mTargetCombo.getSelectionIndex(); + int index = mTarget.getSelectionIndex(); if (index >= 0) { - selected = mTargetCombo.getItem(index); + selected = mTarget.getItem(index); } mCurrentTargets.clear(); - mTargetCombo.removeAll(); + mTarget.removeAll(); boolean found = false; index = -1; @@ -1017,7 +490,7 @@ final class AvdCreationDialog extends GridDialog { target.getVersion().getApiString()); } mCurrentTargets.put(name, target); - mTargetCombo.add(name); + mTarget.add(name); if (!found) { index++; found = name.equals(selected); @@ -1025,283 +498,153 @@ final class AvdCreationDialog extends GridDialog { } } - mTargetCombo.setEnabled(mCurrentTargets.size() > 0); + mTarget.setEnabled(mCurrentTargets.size() > 0); if (found) { - mTargetCombo.select(index); - } - - reloadSkinCombo(); - } - - - private void reloadDeviceCombo() { - Device selectedDevice = getSelectedDevice(); - - mDeviceCombo.removeAll(); - for (Device d : mDeviceList) { - mDeviceCombo.add(d.getManufacturer() + " " + d.getName()); - } - - // Try to select the previously selected device if it still exists - if (selectedDevice != null) { - int index = mDeviceList.indexOf(selectedDevice); - if (index >= 0) { - mDeviceCombo.select(index); - } + mTarget.select(index); } - - mDeviceCombo.setEnabled(mTargetCombo.getSelectionIndex() >= 0); } - private void reloadSkinCombo() { + /** + * Reload all the abi types in the selection list + */ + private void reloadAbiTypeCombo() { String selected = null; - int index = mSkinCombo.getSelectionIndex(); + boolean found = false; + + int index = mTarget.getSelectionIndex(); if (index >= 0) { - selected = mSkinCombo.getItem(index); - } + String targetName = mTarget.getItem(index); + IAndroidTarget target = mCurrentTargets.get(targetName); - mSkinCombo.removeAll(); - mSkinCombo.setEnabled(false); + ISystemImage[] systemImages = getSystemImages(target); - index = mTargetCombo.getSelectionIndex(); - if (index >= 0) { + mAbi.setEnabled(systemImages.length > 1); + + // If user explicitly selected an ABI before, preserve that option + // If user did not explicitly select before (only one option before) + // force them to select + index = mAbi.getSelectionIndex(); + if (index >= 0 && mAbi.getItemCount() > 1) { + selected = mAbi.getItem(index); + } - String targetName = mTargetCombo.getItem(index); + mAbi.removeAll(); - boolean found = false; - IAndroidTarget target = mCurrentTargets.get(targetName); - if (target != null) { - mSkinCombo.add(String.format("Default (%s)", target.getDefaultSkin())); - - index = -1; - for (String skin : target.getSkins()) { - mSkinCombo.add(skin); - if (!found) { - index++; - found = skin.equals(selected); + int i; + for (i = 0; i < systemImages.length; i++) { + String prettyAbiType = AvdInfo.getPrettyAbiType(systemImages[i].getAbiType()); + mAbi.add(prettyAbiType); + if (!found) { + found = prettyAbiType.equals(selected); + if (found) { + mAbi.select(i); } } + } - mSkinCombo.setEnabled(true); - - if (found) { - mSkinCombo.select(index); - } else { - mSkinCombo.select(0); // default - loadSkin(); - } + if (systemImages.length == 1) { + mAbi.select(0); } } } /** - * Reload all the abi types in the selection list - */ - private void reloadAbiTypeCombo() { - String selected = null; - boolean found = false; - - int index = mTargetCombo.getSelectionIndex(); - if (index >= 0) { - String targetName = mTargetCombo.getItem(index); - IAndroidTarget target = mCurrentTargets.get(targetName); - - ISystemImage[] systemImages = getSystemImages(target); - - mAbiTypeCombo.setEnabled(systemImages.length > 1); - - // If user explicitly selected an ABI before, preserve that option - // If user did not explicitly select before (only one option before) - // force them to select - index = mAbiTypeCombo.getSelectionIndex(); - if (index >= 0 && mAbiTypeCombo.getItemCount() > 1) { - selected = mAbiTypeCombo.getItem(index); - } - - mAbiTypeCombo.removeAll(); - - int i; - for ( i = 0; i < systemImages.length ; i++ ) { - String prettyAbiType = AvdInfo.getPrettyAbiType(systemImages[i].getAbiType()); - mAbiTypeCombo.add(prettyAbiType); - if (!found) { - found = prettyAbiType.equals(selected); - if (found) { - mAbiTypeCombo.select(i); - } - } - } - - if (systemImages.length == 1) { - mAbiTypeCombo.select(0); - } - } + * Enable or disable the sd card widgets. + * + * @param sizeMode if true the size-based widgets are to be enabled, and the + * file-based ones disabled. + */ + private void enableSdCardWidgets(boolean sizeMode) { + mSdCardSize.setEnabled(sizeMode); + mSdCardSizeCombo.setEnabled(sizeMode); + + mSdCardFile.setEnabled(!sizeMode); + mBrowseSdCard.setEnabled(!sizeMode); } - /** - * Validates the fields, displays errors and warnings. - * Enables the finish button if there are no errors. - */ - private void validatePage() { - String error = null; - String warning = null; + private void onBrowseSdCard() { + FileDialog dlg = new FileDialog(getContents().getShell(), SWT.OPEN); + dlg.setText("Choose SD Card image file."); - // Validate AVD name - String avdName = mAvdName.getText().trim(); - boolean hasAvdName = avdName.length() > 0; - boolean isCreate = mEditAvdInfo == null || !avdName.equals(mEditAvdInfo.getName()); + String fileName = dlg.open(); + if (fileName != null) { + mSdCardFile.setText(fileName); + } + } - if (hasAvdName && !AvdManager.RE_AVD_NAME.matcher(avdName).matches()) { - error = String.format( - "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s", - avdName, AvdManager.CHARS_AVD_NAME); + @Override + public void okPressed() { + if (createAvd()) { + super.okPressed(); } + } - // Validate target - if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() < 0) { - error = "A target must be selected in order to create an AVD."; + private void validatePage() { + String error = null; + String warning = null; + boolean valid = true; + if (mAvdName.getText().isEmpty()) { + valid = false; } - // validate abi type if the selected target supports multi archs. - if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() > 0) { - int index = mTargetCombo.getSelectionIndex(); - String targetName = mTargetCombo.getItem(index); - IAndroidTarget target = mCurrentTargets.get(targetName); - ISystemImage[] systemImages = getSystemImages(target); - if (systemImages.length > 1 && mAbiTypeCombo.getSelectionIndex() < 0) { - error = "An ABI type must be selected in order to create an AVD."; - } + if (mDeviceManufacturer.getSelectionIndex() < 0 || mDeviceName.getSelectionIndex() < 0) { + valid = false; } - // Validate SDCard path or value - if (error == null) { - // get the mode. We only need to check the file since the - // verifier on the size Text will prevent invalid input - boolean sdcardFileMode = mSdCardFileRadio.getSelection(); - if (sdcardFileMode) { - String sdName = mSdCardFile.getText().trim(); - if (sdName.length() > 0 && !new File(sdName).isFile()) { - error = "SD Card path isn't valid."; - } - } else { - String valueString = mSdCardSize.getText(); - if (valueString.length() > 0) { - long value = 0; - try { - value = Long.parseLong(valueString); - - int sizeIndex = mSdCardSizeCombo.getSelectionIndex(); - if (sizeIndex >= 0) { - // index 0 shifts by 10 (1024=K), index 1 by 20, etc. - value <<= 10*(1 + sizeIndex); - } + if (mTarget.getSelectionIndex() < 0 || mAbi.getSelectionIndex() < 0) { + valid = false; + } - if (value < AvdManager.SDCARD_MIN_BYTE_SIZE || - value > AvdManager.SDCARD_MAX_BYTE_SIZE) { - value = 0; - } - } catch (Exception e) { - // ignore, we'll test value below. + // validate sdcard size or file + if (mSdCardSizeRadio.getSelection()) { + if (!mSdCardSize.getText().isEmpty() && mSdCardSizeCombo.getSelectionIndex() >= 0) { + try { + long sdSize = Long.parseLong(mSdCardSize.getText()); + + int sizeIndex = mSdCardSizeCombo.getSelectionIndex(); + if (sizeIndex >= 0) { + // index 0 shifts by 10 (1024=K), index 1 by 20, etc. + sdSize <<= 10 * (1 + sizeIndex); } - if (value <= 0) { + + if (sdSize < AvdManager.SDCARD_MIN_BYTE_SIZE || + sdSize > AvdManager.SDCARD_MAX_BYTE_SIZE) { + valid = false; error = "SD Card size is invalid. Range is 9 MiB..1023 GiB."; - } else if (mEditAvdInfo != null) { - // When editing an existing AVD, compare with the existing - // sdcard size, if any. It only matters if there was an sdcard setting - // before. - Map<String, String> props = mEditAvdInfo.getProperties(); - if (props != null) { - String original = - mEditAvdInfo.getProperties().get(AvdManager.AVD_INI_SDCARD_SIZE); - if (original != null && original.length() > 0) { - long originalSize = - AvdManager.parseSdcardSize(original, null/*parsedStrings*/); - if (originalSize > 0 && value != originalSize) { - warning = "A new SD Card file will be created.\nThe current SD Card file will be lost."; - } - } - } } + } catch (NumberFormatException e) { + valid = false; + error = " SD Card size must be a valid integer between 9 MiB and 1023 GiB"; } } - } - - // validate the skin - if (error == null) { - // get the mode, we should only check if it's in size mode since - // the built-in list mode is always valid. - if (mSkinSizeRadio.getSelection()) { - // need both with and heigh to be non null - String width = mSkinSizeWidth.getText(); // no need for trim, since the verifier - String height = mSkinSizeHeight.getText(); // rejects non digit. - - if (width.length() == 0 || height.length() == 0) { - error = "Skin size is incorrect.\nBoth dimensions must be > 0."; - } + } else { + if (mSdCardFile.getText().isEmpty() || !new File(mSdCardFile.getText()).isFile()) { + valid = false; + error = "SD Card path isn't valid."; } } - // Check for duplicate AVD name - if (isCreate && hasAvdName && error == null && !mForceCreation.getSelection()) { - Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(avdName); - assert conflict != null; - switch(conflict.getFirst()) { - case NO_CONFLICT: - break; - case CONFLICT_EXISTING_AVD: - case CONFLICT_INVALID_AVD: - error = String.format( - "The AVD name '%s' is already used.\n" + - "Check \"Override the existing AVD\" to delete the existing one.", - avdName); - break; - case CONFLICT_EXISTING_PATH: - error = String.format( - "Conflict with %s\n" + - "Check \"Override the existing AVD\" to delete the existing one.", - conflict.getSecond()); - break; - default: - // Hmm not supposed to happen... probably someone expanded the - // enum without adding something here. In this case just do an - // assert and use a generic error message. - error = String.format( - "Conflict %s with %s.\n" + - "Check \"Override the existing AVD\" to delete the existing one.", - conflict.getFirst().toString(), - conflict.getSecond()); - assert false; - break; - } + if (mForceCreation.isEnabled() && !mForceCreation.getSelection()) { + valid = false; + error = String.format( + "The AVD name '%s' is already used.\n" + + "Check \"Override the existing AVD\" to delete the existing one.", + mAvdName.getText()); } - if (error == null && mEditAvdInfo != null && isCreate) { + if (mAvdInfo != null && !mAvdInfo.getName().equals(mAvdName.getText())) { warning = String.format("The AVD '%1$s' will be duplicated into '%2$s'.", - mEditAvdInfo.getName(), - avdName); - } - - // Validate the create button - boolean can_create = hasAvdName && error == null; - if (can_create) { - can_create &= mTargetCombo.getSelectionIndex() >= 0; - } - mOkButton.setEnabled(can_create); - - // Adjust the create button label as needed - if (isCreate) { - mOkButton.setText("Create AVD"); - } else { - mOkButton.setText("Edit AVD"); + mAvdInfo.getName(), + mAvdName.getText()); } - // -- update UI + mOkButton.setEnabled(valid); if (error != null) { - mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png")); //$NON-NLS-1$ + mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png")); //$NON-NLS-1$ mStatusLabel.setText(error); } else if (warning != null) { - mStatusIcon.setImage(mImageFactory.getImageByName("warning_icon16.png")); //$NON-NLS-1$ + mStatusIcon.setImage(mImageFactory.getImageByName("warning_icon16.png")); //$NON-NLS-1$ mStatusLabel.setText(warning); } else { mStatusIcon.setImage(null); @@ -1311,119 +654,30 @@ final class AvdCreationDialog extends GridDialog { mStatusComposite.pack(true); } - private void loadSkin() { - int targetIndex = mTargetCombo.getSelectionIndex(); - if (targetIndex < 0) { - return; - } - - // resolve the target. - String targetName = mTargetCombo.getItem(targetIndex); - IAndroidTarget target = mCurrentTargets.get(targetName); - if (target == null) { - return; - } - - // get the skin name - String skinName = null; - int skinIndex = mSkinCombo.getSelectionIndex(); - if (skinIndex < 0) { - return; - } else if (skinIndex == 0) { // default skin for the target - skinName = target.getDefaultSkin(); - } else { - skinName = mSkinCombo.getItem(skinIndex); - } - - // load the skin properties - String path = target.getPath(IAndroidTarget.SKINS); - File skin = new File(path, skinName); - if (skin.isDirectory() == false && target.isPlatform() == false) { - // it's possible the skin is in the parent target - path = target.getParent().getPath(IAndroidTarget.SKINS); - skin = new File(path, skinName); - } - - if (skin.isDirectory() == false) { - return; - } - - // now get the hardware.ini from the add-on (if applicable) and from the skin - // (if applicable) - HashMap<String, String> hardwareValues = new HashMap<String, String>(); - if (target.isPlatform() == false) { - FileWrapper targetHardwareFile = new FileWrapper(target.getLocation(), - AvdManager.HARDWARE_INI); - if (targetHardwareFile.isFile()) { - Map<String, String> targetHardwareConfig = ProjectProperties.parsePropertyFile( - targetHardwareFile, null /*log*/); - - if (targetHardwareConfig != null) { - hardwareValues.putAll(targetHardwareConfig); - } - } - } - - // from the skin - FileWrapper skinHardwareFile = new FileWrapper(skin, AvdManager.HARDWARE_INI); - if (skinHardwareFile.isFile()) { - Map<String, String> skinHardwareConfig = ProjectProperties.parsePropertyFile( - skinHardwareFile, null /*log*/); - - if (skinHardwareConfig != null) { - hardwareValues.putAll(skinHardwareConfig); - } - } - - // now set those values in the list of properties for the AVD. - // We just check that none of those properties have been edited by the user yet. - for (Entry<String, String> entry : hardwareValues.entrySet()) { - if (mEditedProperties.contains(entry.getKey()) == false) { - mProperties.put(entry.getKey(), entry.getValue()); - } - } - - mHardwareViewer.refresh(); - } - - /** - * Creates an AVD from the values in the UI. Called when the user presses the OK button. - */ private boolean createAvd() { - String avdName = mAvdName.getText().trim(); - int index = mTargetCombo.getSelectionIndex(); - // quick check on the name and the target selection - if (avdName.length() == 0 || index < 0) { + String avdName = mAvdName.getText(); + if (avdName == null || avdName.isEmpty()) { return false; } - // resolve the target. - String targetName = mTargetCombo.getItem(index); + String targetName = mTarget.getItem(mTarget.getSelectionIndex()); IAndroidTarget target = mCurrentTargets.get(targetName); if (target == null) { return false; } - index = mDeviceCombo.getSelectionIndex(); - if (index >= 0 && index < mDeviceList.size()) { - Device d = mDeviceList.get(index); - // Set the properties so it gets saved to the avd's ini - mProperties.put(AvdManager.AVD_INI_DEVICE_MANUFACTURER, d.getManufacturer()); - mProperties.put(AvdManager.AVD_INI_DEVICE_NAME, d.getName()); - } - // get the abi type - mAbiType = SdkConstants.ABI_ARMEABI; + String abiType = SdkConstants.ABI_ARMEABI; ISystemImage[] systemImages = getSystemImages(target); if (systemImages.length > 0) { - int abiIndex = mAbiTypeCombo.getSelectionIndex(); + int abiIndex = mAbi.getSelectionIndex(); if (abiIndex >= 0) { - String prettyname = mAbiTypeCombo.getItem(abiIndex); - //Extract the abi type + String prettyname = mAbi.getItem(abiIndex); + // Extract the abi type int firstIndex = prettyname.indexOf("("); int lastIndex = prettyname.indexOf(")"); - mAbiType = prettyname.substring(firstIndex+1, lastIndex); + abiType = prettyname.substring(firstIndex + 1, lastIndex); } } @@ -1437,13 +691,13 @@ final class AvdCreationDialog extends GridDialog { // add the unit switch (mSdCardSizeCombo.getSelectionIndex()) { case 0: - sdName += "K"; //$NON-NLS-1$ + sdName += "K"; //$NON-NLS-1$ break; case 1: - sdName += "M"; //$NON-NLS-1$ + sdName += "M"; //$NON-NLS-1$ break; case 2: - sdName += "G"; //$NON-NLS-1$ + sdName += "G"; //$NON-NLS-1$ break; default: // shouldn't be here @@ -1455,21 +709,27 @@ final class AvdCreationDialog extends GridDialog { sdName = mSdCardFile.getText().trim(); } - // get the Skin data from the UI - String skinName = null; - if (mSkinListRadio.getSelection()) { - // built-in list provides the skin - int skinIndex = mSkinCombo.getSelectionIndex(); - if (skinIndex > 0) { - // index 0 is the default, we don't use it - skinName = mSkinCombo.getItem(skinIndex); + // Get the device + List<Device> devices = mDeviceMap.get(mDeviceManufacturer.getText()); + if (devices == null) { + return false; + } + + Device device = null; + for (Device d : devices) { + if (mDeviceName.getText().equals(d.getName())) { + device = d; + break; } - } else { - // size mode. get both size and writes it as a skin name - // thanks to validatePage() we know the content of the fields is correct - skinName = mSkinSizeWidth.getText() + "x" + mSkinSizeHeight.getText(); //$NON-NLS-1$ } + if (device == null) { + return false; + } + + Screen s = device.getDefaultHardware().getScreen(); + String skinName = s.getXDimension() + "x" + s.getYDimension(); + ISdkLog log = mSdkLog; if (log == null || log instanceof MessageBoxLog) { // If the current logger is a message box, we use our own (to make sure @@ -1477,7 +737,12 @@ final class AvdCreationDialog extends GridDialog { log = new MessageBoxLog( String.format("Result of creating AVD '%s':", avdName), getContents().getDisplay(), - false /*logErrorsOnly*/); + false /* logErrorsOnly */); + } + + Map<String, String> hwProps = DeviceManager.getHardwareProperties(device); + if (mGpuEmulation.getSelection()) { + hwProps.put(AvdManager.AVD_INI_GPU_EMULATION, HardwareProperties.BOOLEAN_VALUES[0]); } File avdFolder = null; @@ -1487,28 +752,32 @@ final class AvdCreationDialog extends GridDialog { return false; } - boolean force = mForceCreation.getSelection(); - boolean snapshot = mSnapshotCheck.getSelection(); + hwProps.put(AvdManager.AVD_INI_DEVICE_MANUFACTURER, mDeviceManufacturer.getText()); + hwProps.put(AvdManager.AVD_INI_DEVICE_NAME, mDeviceName.getText()); + + if (mFrontCamera.isEnabled()) { + hwProps.put(AvdManager.AVD_INI_CAMERA_FRONT, + mFrontCamera.getText().toLowerCase()); + } - boolean success = false; - AvdInfo avdInfo = mAvdManager.createAvd( - avdFolder, + if (mBackCamera.isEnabled()) { + hwProps.put(AvdManager.AVD_INI_CAMERA_BACK, + mBackCamera.getText().toLowerCase()); + } + + AvdInfo avdInfo = mAvdManager.createAvd(avdFolder, avdName, target, - mAbiType, + abiType, skinName, sdName, - mProperties, - snapshot, - force, - mEditAvdInfo != null, //edit existing + hwProps, + mSnapshot.getSelection(), + mForceCreation.getSelection(), + mAvdInfo != null, // edit existing log); - success = avdInfo != null; - - // Remove the device name and manufacturer properties so they don't show up in the hardware list - mProperties.remove(AvdManager.AVD_INI_DEVICE_MANUFACTURER); - mProperties.remove(AvdManager.AVD_INI_DEVICE_NAME); + boolean success = avdInfo != null; if (log instanceof MessageBoxLog) { ((MessageBoxLog) log).displayResult(success); @@ -1516,11 +785,128 @@ final class AvdCreationDialog extends GridDialog { return success; } + private void fillExistingAvdInfo(AvdInfo avd) { + mAvdName.setText(avd.getName()); + String manufacturer = avd.getDeviceManufacturer(); + for (int i = 0; i < mDeviceManufacturer.getItemCount(); i++) { + if (mDeviceManufacturer.getItem(i).equals(manufacturer)) { + mDeviceManufacturer.select(i); + break; + } + } + reloadDeviceNameCombo(); + + String deviceName = avd.getDeviceName(); + for (int i = 0; i < mDeviceName.getItemCount(); i++) { + if (mDeviceName.getItem(i).equals(deviceName)) { + mDeviceName.select(i); + break; + } + } + toggleCameras(); + + IAndroidTarget target = avd.getTarget(); + + if (target != null && !mCurrentTargets.isEmpty()) { + // Try to select the target in the target combo. + // This will fail if the AVD needs to be repaired. + // + // This is a linear search but the list is always + // small enough and we only do this once. + int n = mTarget.getItemCount(); + for (int i = 0; i < n; i++) { + if (target.equals(mCurrentTargets.get(mTarget.getItem(i)))) { + mTarget.select(i); + reloadAbiTypeCombo(); + break; + } + } + } + + ISystemImage[] systemImages = getSystemImages(target); + if (target != null && systemImages.length > 0) { + mAbi.setEnabled(systemImages.length > 1); + String abiType = AvdInfo.getPrettyAbiType(avd.getAbiType()); + int n = mAbi.getItemCount(); + for (int i = 0; i < n; i++) { + if (abiType.equals(mAbi.getItem(i))) { + mAbi.select(i); + break; + } + } + } + + Map<String, String> props = avd.getProperties(); + + if (props != null) { + String snapshots = props.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); + if (snapshots != null && snapshots.length() > 0) { + mSnapshot.setSelection(snapshots.equals("true")); + } + + String gpuEmulation = props.get(AvdManager.AVD_INI_GPU_EMULATION); + mGpuEmulation.setSelection(gpuEmulation != null && + gpuEmulation.equals(HardwareProperties.BOOLEAN_VALUES[0])); + + String sdcard = props.get(AvdManager.AVD_INI_SDCARD_PATH); + if (sdcard != null && sdcard.length() > 0) { + enableSdCardWidgets(false); + mSdCardSizeRadio.setSelection(false); + mSdCardFileRadio.setSelection(true); + mSdCardFile.setText(sdcard); + } + + String cameraFront = props.get(AvdManager.AVD_INI_CAMERA_FRONT); + if (cameraFront != null) { + String[] items = mFrontCamera.getItems(); + for (int i = 0; i < items.length; i++) { + if (items[i].toLowerCase().equals(cameraFront)) { + mFrontCamera.select(i); + break; + } + } + } + + String cameraBack = props.get(AvdManager.AVD_INI_CAMERA_BACK); + if (cameraBack != null) { + String[] items = mBackCamera.getItems(); + for (int i = 0; i < items.length; i++) { + if (items[i].toLowerCase().equals(cameraBack)) { + mBackCamera.select(i); + break; + } + } + } + + sdcard = props.get(AvdManager.AVD_INI_SDCARD_SIZE); + if (sdcard != null && sdcard.length() > 0) { + String[] values = new String[2]; + long sdcardSize = AvdManager.parseSdcardSize(sdcard, values); + + if (sdcardSize != AvdManager.SDCARD_NOT_SIZE_PATTERN) { + enableSdCardWidgets(true); + mSdCardFileRadio.setSelection(false); + mSdCardSizeRadio.setSelection(true); + + mSdCardSize.setText(values[0]); + + String suffix = values[1]; + int n = mSdCardSizeCombo.getItemCount(); + for (int i = 0; i < n; i++) { + if (mSdCardSizeCombo.getItem(i).startsWith(suffix)) { + mSdCardSizeCombo.select(i); + } + } + } + } + } + } + /** * Returns the list of system images of a target. * <p/> - * If target is null, returns an empty list. - * If target is an add-on with no system images, return the list from its parent platform. + * If target is null, returns an empty list. If target is an add-on with no + * system images, return the list from its parent platform. * * @param target An IAndroidTarget. Can be null. * @return A non-null ISystemImage array. Can be empty. @@ -1530,7 +916,8 @@ final class AvdCreationDialog extends GridDialog { ISystemImage[] images = target.getSystemImages(); if ((images == null || images.length == 0) && !target.isPlatform()) { - // If an add-on does not provide any system images, use the ones from the parent. + // If an add-on does not provide any system images, use the ones + // from the parent. images = target.getParent().getSystemImages(); } @@ -1542,15 +929,4 @@ final class AvdCreationDialog extends GridDialog { return new ISystemImage[0]; } - private Device getSelectedDevice() { - int targetIndex = mDeviceCombo.getSelectionIndex(); - if (targetIndex >= 0 && mDeviceList.size() > targetIndex){ - return mDeviceList.get(targetIndex); - } else { - return null; - } - } - - // End of hiding from SWT Designer - //$hide<<$ } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java index 3a76b2a..58bacec 100644 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java @@ -35,6 +35,7 @@ import com.android.sdkuilib.internal.repository.icons.ImageFactory; import com.android.sdkuilib.internal.repository.sdkman2.AvdManagerWindowImpl1; import com.android.sdkuilib.internal.tasks.ProgressTask; import com.android.sdkuilib.repository.AvdManagerWindow.AvdInvocationContext; +import com.android.sdkuilib.ui.GridDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; @@ -885,12 +886,21 @@ public final class AvdSelector { private void onEdit() { AvdInfo avdInfo = getTableSelection(); + GridDialog dlg; + if(!avdInfo.getDeviceName().isEmpty()) { + dlg = new AvdCreationDialog(mTable.getShell(), + mAvdManager, + mImageFactory, + mSdkLog, + avdInfo); + } else { + dlg = new LegacyAvdEditDialog(mTable.getShell(), + mAvdManager, + mImageFactory, + mSdkLog, + avdInfo); + } - AvdCreationDialog dlg = new AvdCreationDialog(mTable.getShell(), - mAvdManager, - mImageFactory, - mSdkLog, - avdInfo); if (dlg.open() == Window.OK) { refresh(false /*reload*/); diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/LegacyAvdEditDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/LegacyAvdEditDialog.java new file mode 100644 index 0000000..dc6b459 --- /dev/null +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/LegacyAvdEditDialog.java @@ -0,0 +1,1425 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * 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. + */ + +package com.android.sdkuilib.internal.widgets; + +import com.android.io.FileWrapper; +import com.android.prefs.AndroidLocation.AndroidLocationException; +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.ISdkLog; +import com.android.sdklib.ISystemImage; +import com.android.sdklib.SdkConstants; +import com.android.sdklib.SdkManager; +import com.android.sdklib.internal.avd.AvdInfo; +import com.android.sdklib.internal.avd.AvdManager; +import com.android.sdklib.internal.avd.AvdManager.AvdConflict; +import com.android.sdklib.internal.avd.HardwareProperties; +import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty; +import com.android.sdklib.internal.project.ProjectProperties; +import com.android.sdkuilib.internal.repository.icons.ImageFactory; +import com.android.sdkuilib.ui.GridDialog; +import com.android.util.Pair; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ComboBoxCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.regex.Matcher; + +/** + * AVD creation or edit dialog. + * + * TODO: + * - use SdkTargetSelector instead of Combo + * - tooltips on widgets. + * + */ +final class LegacyAvdEditDialog extends GridDialog { + + private final AvdManager mAvdManager; + private final TreeMap<String, IAndroidTarget> mCurrentTargets = + new TreeMap<String, IAndroidTarget>(); + + private final Map<String, HardwareProperty> mHardwareMap; + private final Map<String, String> mProperties = new HashMap<String, String>(); + // a list of user-edited properties. + private final ArrayList<String> mEditedProperties = new ArrayList<String>(); + private final ImageFactory mImageFactory; + private final ISdkLog mSdkLog; + /** + * The original AvdInfo if we're editing an existing AVD. + * Null when we're creating a new AVD. + */ + private final AvdInfo mEditAvdInfo; + + private Text mAvdName; + private Combo mTargetCombo; + + private Combo mAbiTypeCombo; + private String mAbiType; + + private Button mSdCardSizeRadio; + private Text mSdCardSize; + private Combo mSdCardSizeCombo; + + private Text mSdCardFile; + private Button mBrowseSdCard; + private Button mSdCardFileRadio; + + private Button mSnapshotCheck; + + private Button mSkinListRadio; + private Combo mSkinCombo; + + private Button mSkinSizeRadio; + private Text mSkinSizeWidth; + private Text mSkinSizeHeight; + + private TableViewer mHardwareViewer; + private Button mDeleteHardwareProp; + + private Button mForceCreation; + private Button mOkButton; + private Label mStatusIcon; + private Label mStatusLabel; + private Composite mStatusComposite; + + /** + * {@link VerifyListener} for {@link Text} widgets that should only contains numbers. + */ + private final VerifyListener mDigitVerifier = new VerifyListener() { + @Override + public void verifyText(VerifyEvent event) { + int count = event.text.length(); + for (int i = 0 ; i < count ; i++) { + char c = event.text.charAt(i); + if (c < '0' || c > '9') { + event.doit = false; + return; + } + } + } + }; + + /** + * Callback when the AVD name is changed. + * When creating a new AVD, enables the force checkbox if the name is a duplicate. + * When editing an existing AVD, it's OK for the name to match the existing AVD. + */ + private class CreateNameModifyListener implements ModifyListener { + @Override + public void modifyText(ModifyEvent e) { + String name = mAvdName.getText().trim(); + if (mEditAvdInfo == null || !name.equals(mEditAvdInfo.getName())) { + // Case where we're creating a new AVD or editing an existing one + // and the AVD name has been changed... check for name uniqueness. + + Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(name); + if (conflict.getFirst() != AvdManager.AvdConflict.NO_CONFLICT) { + // If we're changing the state from disabled to enabled, make sure + // to uncheck the button, to force the user to voluntarily re-enforce it. + // This happens when editing an existing AVD and changing the name from + // the existing AVD to another different existing AVD. + if (!mForceCreation.isEnabled()) { + mForceCreation.setEnabled(true); + mForceCreation.setSelection(false); + } + } else { + mForceCreation.setEnabled(false); + mForceCreation.setSelection(false); + } + } else { + // Case where we're editing an existing AVD with the name unchanged. + + mForceCreation.setEnabled(false); + mForceCreation.setSelection(false); + } + validatePage(); + } + } + + /** + * {@link ModifyListener} used for live-validation of the fields content. + */ + private class ValidateListener extends SelectionAdapter implements ModifyListener { + @Override + public void modifyText(ModifyEvent e) { + validatePage(); + } + + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + validatePage(); + } + } + + /** + * Creates the dialog. Caller should then use {@link Window#open()} and + * refresh if the status is {@link Window#OK}. + * + * @param parentShell The parent shell. + * @param avdManager The existing {@link AvdManager} to use. Must not be null. + * @param imageFactory An existing {@link ImageFactory} to use. Must not be null. + * @param log An existing {@link ISdkLog} where output will go. Must not be null. + * @param editAvdInfo An optional {@link AvdInfo}. When null, the dialog is used + * to create a new AVD. When non-null, the dialog is used to <em>edit</em> this AVD. + */ + protected LegacyAvdEditDialog(Shell parentShell, + AvdManager avdManager, + ImageFactory imageFactory, + ISdkLog log, + AvdInfo editAvdInfo) { + super(parentShell, 2, false); + mAvdManager = avdManager; + mImageFactory = imageFactory; + mSdkLog = log; + mEditAvdInfo = editAvdInfo; + + File hardwareDefs = null; + + SdkManager sdkMan = avdManager.getSdkManager(); + if (sdkMan != null) { + String sdkPath = sdkMan.getLocation(); + if (sdkPath != null) { + hardwareDefs = new File (sdkPath + File.separator + + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI); + } + } + + if (hardwareDefs == null) { + log.error(null, "Failed to load file %s from SDK", SdkConstants.FN_HARDWARE_INI); + mHardwareMap = new HashMap<String, HardwareProperty>(); + } else { + mHardwareMap = HardwareProperties.parseHardwareDefinitions( + hardwareDefs, null /*sdkLog*/); + } + } + + @Override + public void create() { + super.create(); + + Point p = getShell().getSize(); + if (p.x < 400) { + p.x = 400; + } + getShell().setSize(p); + } + + @Override + protected Control createContents(Composite parent) { + Control control = super.createContents(parent); + getShell().setText(mEditAvdInfo == null ? "Create new Android Virtual Device (AVD)" + : "Edit Android Virtual Device (AVD)"); + + mOkButton = getButton(IDialogConstants.OK_ID); + + fillExistingAvdInfo(); + validatePage(); + + return control; + } + + @Override + public void createDialogContent(final Composite parent) { + GridData gd; + GridLayout gl; + + Label label = new Label(parent, SWT.NONE); + label.setText("Name:"); + String tooltip = "Name of the new Android Virtual Device"; + label.setToolTipText(tooltip); + + mAvdName = new Text(parent, SWT.BORDER); + mAvdName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mAvdName.addModifyListener(new CreateNameModifyListener()); + mAvdName.setToolTipText(tooltip); + + label = new Label(parent, SWT.NONE); + label.setText("Target:"); + tooltip = "The version of Android to use in the virtual device"; + label.setToolTipText(tooltip); + + mTargetCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + mTargetCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mTargetCombo.setToolTipText(tooltip); + mTargetCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + reloadSkinCombo(); + reloadAbiTypeCombo(); + validatePage(); + } + }); + + //ABI group + label = new Label(parent, SWT.NONE); + label.setText("CPU/ABI:"); + tooltip = "The CPU/ABI to use in the virtual device"; + label.setToolTipText(tooltip); + + mAbiTypeCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + mAbiTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mAbiTypeCombo.setToolTipText(tooltip); + mAbiTypeCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + validatePage(); + } + }); + mAbiTypeCombo.setEnabled(false); + + // --- sd card group + label = new Label(parent, SWT.NONE); + label.setText("SD Card:"); + label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, + false, false)); + + final Group sdCardGroup = new Group(parent, SWT.NONE); + sdCardGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + sdCardGroup.setLayout(new GridLayout(3, false)); + + mSdCardSizeRadio = new Button(sdCardGroup, SWT.RADIO); + mSdCardSizeRadio.setText("Size:"); + mSdCardSizeRadio.setToolTipText("Create a new SD Card file"); + mSdCardSizeRadio.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + boolean sizeMode = mSdCardSizeRadio.getSelection(); + enableSdCardWidgets(sizeMode); + validatePage(); + } + }); + + ValidateListener validateListener = new ValidateListener(); + + mSdCardSize = new Text(sdCardGroup, SWT.BORDER); + mSdCardSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mSdCardSize.addVerifyListener(mDigitVerifier); + mSdCardSize.addModifyListener(validateListener); + mSdCardSize.setToolTipText("Size of the new SD Card file (must be at least 9 MiB)"); + + mSdCardSizeCombo = new Combo(sdCardGroup, SWT.DROP_DOWN | SWT.READ_ONLY); + mSdCardSizeCombo.add("KiB"); + mSdCardSizeCombo.add("MiB"); + mSdCardSizeCombo.add("GiB"); + mSdCardSizeCombo.select(1); + mSdCardSizeCombo.addSelectionListener(validateListener); + + mSdCardFileRadio = new Button(sdCardGroup, SWT.RADIO); + mSdCardFileRadio.setText("File:"); + mSdCardFileRadio.setToolTipText("Use an existing file for the SD Card"); + + mSdCardFile = new Text(sdCardGroup, SWT.BORDER); + mSdCardFile.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mSdCardFile.addModifyListener(validateListener); + mSdCardFile.setToolTipText("File to use for the SD Card"); + + mBrowseSdCard = new Button(sdCardGroup, SWT.PUSH); + mBrowseSdCard.setText("Browse..."); + mBrowseSdCard.setToolTipText("Select the file to use for the SD Card"); + mBrowseSdCard.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + onBrowseSdCard(); + validatePage(); + } + }); + + mSdCardSizeRadio.setSelection(true); + enableSdCardWidgets(true); + + // --- snapshot group + + label = new Label(parent, SWT.NONE); + label.setText("Snapshot:"); + label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, + false, false)); + + final Group snapshotGroup = new Group(parent, SWT.NONE); + snapshotGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + snapshotGroup.setLayout(new GridLayout(3, false)); + + mSnapshotCheck = new Button(snapshotGroup, SWT.CHECK); + mSnapshotCheck.setText("Enabled"); + mSnapshotCheck.setToolTipText( + "Emulator's state will be persisted between emulator executions"); + + // --- skin group + label = new Label(parent, SWT.NONE); + label.setText("Skin:"); + label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, + false, false)); + + final Group skinGroup = new Group(parent, SWT.NONE); + skinGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + skinGroup.setLayout(new GridLayout(4, false)); + + mSkinListRadio = new Button(skinGroup, SWT.RADIO); + mSkinListRadio.setText("Built-in:"); + mSkinListRadio.setToolTipText("Select an emulated screen size provided by the current Android target"); + mSkinListRadio.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + boolean listMode = mSkinListRadio.getSelection(); + enableSkinWidgets(listMode); + validatePage(); + } + }); + + mSkinCombo = new Combo(skinGroup, SWT.READ_ONLY | SWT.DROP_DOWN); + mSkinCombo.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); + gd.horizontalSpan = 3; + mSkinCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + // get the skin info + loadSkin(); + } + }); + + mSkinSizeRadio = new Button(skinGroup, SWT.RADIO); + mSkinSizeRadio.setText("Resolution:"); + mSkinSizeRadio.setToolTipText("Select a custom emulated screen size"); + + mSkinSizeWidth = new Text(skinGroup, SWT.BORDER); + mSkinSizeWidth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mSkinSizeWidth.addVerifyListener(mDigitVerifier); + mSkinSizeWidth.addModifyListener(validateListener); + mSkinSizeWidth.setToolTipText("Width in pixels of the emulated screen size"); + + new Label(skinGroup, SWT.NONE).setText("x"); + + mSkinSizeHeight = new Text(skinGroup, SWT.BORDER); + mSkinSizeHeight.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mSkinSizeHeight.addVerifyListener(mDigitVerifier); + mSkinSizeHeight.addModifyListener(validateListener); + mSkinSizeHeight.setToolTipText("Height in pixels of the emulated screen size"); + + mSkinListRadio.setSelection(true); + enableSkinWidgets(true); + + // --- hardware group + label = new Label(parent, SWT.NONE); + label.setText("Hardware:"); + label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, + false, false)); + + final Group hwGroup = new Group(parent, SWT.NONE); + hwGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + hwGroup.setLayout(new GridLayout(2, false)); + + createHardwareTable(hwGroup); + + // composite for the side buttons + Composite hwButtons = new Composite(hwGroup, SWT.NONE); + hwButtons.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + hwButtons.setLayout(gl = new GridLayout(1, false)); + gl.marginHeight = gl.marginWidth = 0; + + Button b = new Button(hwButtons, SWT.PUSH | SWT.FLAT); + b.setText("New..."); + b.setToolTipText("Add a new hardware property"); + b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + b.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + HardwarePropertyChooser dialog = new HardwarePropertyChooser(parent.getShell(), + mHardwareMap, mProperties.keySet()); + if (dialog.open() == Window.OK) { + HardwareProperty choice = dialog.getProperty(); + if (choice != null) { + mProperties.put(choice.getName(), choice.getDefault()); + mHardwareViewer.refresh(); + } + } + } + }); + mDeleteHardwareProp = new Button(hwButtons, SWT.PUSH | SWT.FLAT); + mDeleteHardwareProp.setText("Delete"); + mDeleteHardwareProp.setToolTipText("Delete the selected hardware property"); + mDeleteHardwareProp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mDeleteHardwareProp.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + ISelection selection = mHardwareViewer.getSelection(); + if (selection instanceof IStructuredSelection) { + String hwName = (String)((IStructuredSelection)selection).getFirstElement(); + mProperties.remove(hwName); + mHardwareViewer.refresh(); + } + } + }); + mDeleteHardwareProp.setEnabled(false); + + // --- end hardware group + + mForceCreation = new Button(parent, SWT.CHECK); + mForceCreation.setText("Override the existing AVD with the same name"); + mForceCreation.setToolTipText("There's already an AVD with the same name. Check this to delete it and replace it by the new AVD."); + mForceCreation.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, + true, false, 2, 1)); + mForceCreation.setEnabled(false); + mForceCreation.addSelectionListener(validateListener); + + // add a separator to separate from the ok/cancel button + label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); + + // add stuff for the error display + mStatusComposite = new Composite(parent, SWT.NONE); + mStatusComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, + true, false, 3, 1)); + mStatusComposite.setLayout(gl = new GridLayout(2, false)); + gl.marginHeight = gl.marginWidth = 0; + + mStatusIcon = new Label(mStatusComposite, SWT.NONE); + mStatusIcon.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, + false, false)); + mStatusLabel = new Label(mStatusComposite, SWT.NONE); + mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mStatusLabel.setText(" \n "); //$NON-NLS-1$ + + reloadTargetCombo(); + } + + /** + * Creates the UI for the hardware properties table. + * This creates the {@link Table}, and several viewers ({@link TableViewer}, + * {@link TableViewerColumn}) and adds edit support for the 2nd column + */ + private void createHardwareTable(Composite parent) { + final Table hardwareTable = new Table(parent, SWT.SINGLE | SWT.FULL_SELECTION); + GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); + gd.widthHint = 200; + gd.heightHint = 100; + hardwareTable.setLayoutData(gd); + hardwareTable.setHeaderVisible(true); + hardwareTable.setLinesVisible(true); + + // -- Table viewer + mHardwareViewer = new TableViewer(hardwareTable); + mHardwareViewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + // it's a single selection mode, we can just access the selection index + // from the table directly. + mDeleteHardwareProp.setEnabled(hardwareTable.getSelectionIndex() != -1); + } + }); + + // only a content provider. Use viewers per column below (for editing support) + mHardwareViewer.setContentProvider(new IStructuredContentProvider() { + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // we can just ignore this. we just use mProperties directly. + } + + @Override + public Object[] getElements(Object arg0) { + return mProperties.keySet().toArray(); + } + + @Override + public void dispose() { + // pass + } + }); + + // -- column 1: prop abstract name + TableColumn col1 = new TableColumn(hardwareTable, SWT.LEFT); + col1.setText("Property"); + col1.setWidth(150); + TableViewerColumn tvc1 = new TableViewerColumn(mHardwareViewer, col1); + tvc1.setLabelProvider(new CellLabelProvider() { + @Override + public void update(ViewerCell cell) { + String name = cell.getElement().toString(); + HardwareProperty prop = mHardwareMap.get(name); + if (prop != null) { + cell.setText(prop.getAbstract()); + } else { + cell.setText(String.format("%1$s (Unknown)", name)); + } + } + }); + + // -- column 2: prop value + TableColumn col2 = new TableColumn(hardwareTable, SWT.LEFT); + col2.setText("Value"); + col2.setWidth(50); + TableViewerColumn tvc2 = new TableViewerColumn(mHardwareViewer, col2); + tvc2.setLabelProvider(new CellLabelProvider() { + @Override + public void update(ViewerCell cell) { + String value = mProperties.get(cell.getElement()); + cell.setText(value != null ? value : ""); + } + }); + + // add editing support to the 2nd column + tvc2.setEditingSupport(new EditingSupport(mHardwareViewer) { + @Override + protected void setValue(Object element, Object value) { + String hardwareName = (String)element; + HardwareProperty property = mHardwareMap.get(hardwareName); + int index; + switch (property.getType()) { + case INTEGER: + mProperties.put((String)element, (String)value); + break; + case DISKSIZE: + if (HardwareProperties.DISKSIZE_PATTERN.matcher((String)value).matches()) { + mProperties.put((String)element, (String)value); + } + break; + case BOOLEAN: + index = (Integer)value; + mProperties.put((String)element, HardwareProperties.BOOLEAN_VALUES[index]); + break; + case STRING_ENUM: + case INTEGER_ENUM: + // For a combo, value is the index of the enum to use. + index = (Integer)value; + String[] values = property.getEnum(); + if (values != null && values.length > index) { + mProperties.put((String)element, values[index]); + } + break; + } + mHardwareViewer.refresh(element); + } + + @Override + protected Object getValue(Object element) { + String hardwareName = (String)element; + HardwareProperty property = mHardwareMap.get(hardwareName); + String value = mProperties.get(hardwareName); + switch (property.getType()) { + case INTEGER: + // intended fall-through. + case DISKSIZE: + return value; + case BOOLEAN: + return HardwareProperties.getBooleanValueIndex(value); + case STRING_ENUM: + case INTEGER_ENUM: + // For a combo, we need to return the index of the value in the enum + String[] values = property.getEnum(); + if (values != null) { + for (int i = 0; i < values.length; i++) { + if (values[i].equals(value)) { + return i; + } + } + } + } + + return null; + } + + @Override + protected CellEditor getCellEditor(Object element) { + String hardwareName = (String)element; + HardwareProperty property = mHardwareMap.get(hardwareName); + switch (property.getType()) { + // TODO: custom TextCellEditor that restrict input. + case INTEGER: + // intended fall-through. + case DISKSIZE: + return new TextCellEditor(hardwareTable); + case BOOLEAN: + return new ComboBoxCellEditor(hardwareTable, + HardwareProperties.BOOLEAN_VALUES, + SWT.READ_ONLY | SWT.DROP_DOWN); + case STRING_ENUM: + case INTEGER_ENUM: + String[] values = property.getEnum(); + if (values != null && values.length > 0) { + return new ComboBoxCellEditor(hardwareTable, + values, + SWT.READ_ONLY | SWT.DROP_DOWN); + } + } + return null; + } + + @Override + protected boolean canEdit(Object element) { + String hardwareName = (String)element; + HardwareProperty property = mHardwareMap.get(hardwareName); + return property != null; + } + }); + + + mHardwareViewer.setInput(mProperties); + } + + // -- Start of internal part ---------- + // Hide everything down-below from SWT designer + //$hide>>$ + + /** + * When editing an existing AVD info, fill the UI that has just been created with + * the values from the AVD. + */ + public void fillExistingAvdInfo() { + if (mEditAvdInfo == null) { + return; + } + + mAvdName.setText(mEditAvdInfo.getName()); + + Map<String, String> props = mEditAvdInfo.getProperties(); + + IAndroidTarget target = mEditAvdInfo.getTarget(); + if (target != null && !mCurrentTargets.isEmpty()) { + // Try to select the target in the target combo. + // This will fail if the AVD needs to be repaired. + // + // This is a linear search but the list is always + // small enough and we only do this once. + int n = mTargetCombo.getItemCount(); + for (int i = 0;i < n; i++) { + if (target.equals(mCurrentTargets.get(mTargetCombo.getItem(i)))) { + mTargetCombo.select(i); + reloadAbiTypeCombo(); + reloadSkinCombo(); + break; + } + } + } + + // select the abi type + ISystemImage[] systemImages = getSystemImages(target); + if (target != null && systemImages.length > 0) { + mAbiTypeCombo.setEnabled(systemImages.length > 1); + String abiType = AvdInfo.getPrettyAbiType(mEditAvdInfo.getAbiType()); + int n = mAbiTypeCombo.getItemCount(); + for (int i = 0; i < n; i++) { + if (abiType.equals(mAbiTypeCombo.getItem(i))) { + mAbiTypeCombo.select(i); + reloadSkinCombo(); + break; + } + } + } + + if (props != null) { + + // First try the skin name and if it doesn't work fallback on the skin path + nextSkin: for (int s = 0; s < 2; s++) { + String skin = props.get(s == 0 ? AvdManager.AVD_INI_SKIN_NAME + : AvdManager.AVD_INI_SKIN_PATH); + if (skin != null && skin.length() > 0) { + Matcher m = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin); + if (m.matches() && m.groupCount() == 2) { + enableSkinWidgets(false); + mSkinListRadio.setSelection(false); + mSkinSizeRadio.setSelection(true); + mSkinSizeWidth.setText(m.group(1)); + mSkinSizeHeight.setText(m.group(2)); + break nextSkin; + } else { + enableSkinWidgets(true); + mSkinSizeRadio.setSelection(false); + mSkinListRadio.setSelection(true); + + int n = mSkinCombo.getItemCount(); + for (int i = 0; i < n; i++) { + if (skin.equals(mSkinCombo.getItem(i))) { + mSkinCombo.select(i); + break nextSkin; + } + } + } + } + } + + String sdcard = props.get(AvdManager.AVD_INI_SDCARD_PATH); + if (sdcard != null && sdcard.length() > 0) { + enableSdCardWidgets(false); + mSdCardSizeRadio.setSelection(false); + mSdCardFileRadio.setSelection(true); + mSdCardFile.setText(sdcard); + } + + sdcard = props.get(AvdManager.AVD_INI_SDCARD_SIZE); + if (sdcard != null && sdcard.length() > 0) { + String[] values = new String[2]; + long sdcardSize = AvdManager.parseSdcardSize(sdcard, values); + + if (sdcardSize != AvdManager.SDCARD_NOT_SIZE_PATTERN) { + enableSdCardWidgets(true); + mSdCardFileRadio.setSelection(false); + mSdCardSizeRadio.setSelection(true); + + mSdCardSize.setText(values[0]); + + String suffix = values[1]; + int n = mSdCardSizeCombo.getItemCount(); + for (int i = 0; i < n; i++) { + if (mSdCardSizeCombo.getItem(i).startsWith(suffix)) { + mSdCardSizeCombo.select(i); + } + } + } + } + + String snapshots = props.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); + if (snapshots != null && snapshots.length() > 0) { + mSnapshotCheck.setSelection(snapshots.equals("true")); + } + } + + mProperties.clear(); + + if (props != null) { + for (Entry<String, String> entry : props.entrySet()) { + HardwareProperty prop = mHardwareMap.get(entry.getKey()); + if (prop != null && prop.isValidForUi()) { + mProperties.put(entry.getKey(), entry.getValue()); + } + } + } + + // Cleanup known non-hardware properties + mProperties.remove(AvdManager.AVD_INI_ABI_TYPE); + mProperties.remove(AvdManager.AVD_INI_CPU_ARCH); + mProperties.remove(AvdManager.AVD_INI_SKIN_PATH); + mProperties.remove(AvdManager.AVD_INI_SKIN_NAME); + mProperties.remove(AvdManager.AVD_INI_SDCARD_SIZE); + mProperties.remove(AvdManager.AVD_INI_SDCARD_PATH); + mProperties.remove(AvdManager.AVD_INI_SNAPSHOT_PRESENT); + mProperties.remove(AvdManager.AVD_INI_IMAGES_1); + mProperties.remove(AvdManager.AVD_INI_IMAGES_2); + + mHardwareViewer.refresh(); + } + + @Override + protected void okPressed() { + if (createAvd()) { + super.okPressed(); + } + } + + /** + * Enable or disable the sd card widgets. + * @param sizeMode if true the size-based widgets are to be enabled, and the file-based ones + * disabled. + */ + private void enableSdCardWidgets(boolean sizeMode) { + mSdCardSize.setEnabled(sizeMode); + mSdCardSizeCombo.setEnabled(sizeMode); + + mSdCardFile.setEnabled(!sizeMode); + mBrowseSdCard.setEnabled(!sizeMode); + } + + /** + * Enable or disable the skin widgets. + * @param listMode if true the list-based widgets are to be enabled, and the size-based ones + * disabled. + */ + private void enableSkinWidgets(boolean listMode) { + mSkinCombo.setEnabled(listMode); + + mSkinSizeWidth.setEnabled(!listMode); + mSkinSizeHeight.setEnabled(!listMode); + } + + + private void onBrowseSdCard() { + FileDialog dlg = new FileDialog(getContents().getShell(), SWT.OPEN); + dlg.setText("Choose SD Card image file."); + + String fileName = dlg.open(); + if (fileName != null) { + mSdCardFile.setText(fileName); + } + } + + + + private void reloadTargetCombo() { + String selected = null; + int index = mTargetCombo.getSelectionIndex(); + if (index >= 0) { + selected = mTargetCombo.getItem(index); + } + + mCurrentTargets.clear(); + mTargetCombo.removeAll(); + + boolean found = false; + index = -1; + + SdkManager sdkManager = mAvdManager.getSdkManager(); + if (sdkManager != null) { + for (IAndroidTarget target : sdkManager.getTargets()) { + String name; + if (target.isPlatform()) { + name = String.format("%s - API Level %s", + target.getName(), + target.getVersion().getApiString()); + } else { + name = String.format("%s (%s) - API Level %s", + target.getName(), + target.getVendor(), + target.getVersion().getApiString()); + } + mCurrentTargets.put(name, target); + mTargetCombo.add(name); + if (!found) { + index++; + found = name.equals(selected); + } + } + } + + mTargetCombo.setEnabled(mCurrentTargets.size() > 0); + + if (found) { + mTargetCombo.select(index); + } + + reloadSkinCombo(); + } + + private void reloadSkinCombo() { + String selected = null; + int index = mSkinCombo.getSelectionIndex(); + if (index >= 0) { + selected = mSkinCombo.getItem(index); + } + + mSkinCombo.removeAll(); + mSkinCombo.setEnabled(false); + + index = mTargetCombo.getSelectionIndex(); + if (index >= 0) { + + String targetName = mTargetCombo.getItem(index); + + boolean found = false; + IAndroidTarget target = mCurrentTargets.get(targetName); + if (target != null) { + mSkinCombo.add(String.format("Default (%s)", target.getDefaultSkin())); + + index = -1; + for (String skin : target.getSkins()) { + mSkinCombo.add(skin); + if (!found) { + index++; + found = skin.equals(selected); + } + } + + mSkinCombo.setEnabled(true); + + if (found) { + mSkinCombo.select(index); + } else { + mSkinCombo.select(0); // default + loadSkin(); + } + } + } + } + + /** + * Reload all the abi types in the selection list + */ + private void reloadAbiTypeCombo() { + String selected = null; + boolean found = false; + + int index = mTargetCombo.getSelectionIndex(); + if (index >= 0) { + String targetName = mTargetCombo.getItem(index); + IAndroidTarget target = mCurrentTargets.get(targetName); + + ISystemImage[] systemImages = getSystemImages(target); + + mAbiTypeCombo.setEnabled(systemImages.length > 1); + + // If user explicitly selected an ABI before, preserve that option + // If user did not explicitly select before (only one option before) + // force them to select + index = mAbiTypeCombo.getSelectionIndex(); + if (index >= 0 && mAbiTypeCombo.getItemCount() > 1) { + selected = mAbiTypeCombo.getItem(index); + } + + mAbiTypeCombo.removeAll(); + + int i; + for ( i = 0; i < systemImages.length ; i++ ) { + String prettyAbiType = AvdInfo.getPrettyAbiType(systemImages[i].getAbiType()); + mAbiTypeCombo.add(prettyAbiType); + if (!found) { + found = prettyAbiType.equals(selected); + if (found) { + mAbiTypeCombo.select(i); + } + } + } + + if (systemImages.length == 1) { + mAbiTypeCombo.select(0); + } + } + } + + /** + * Validates the fields, displays errors and warnings. + * Enables the finish button if there are no errors. + */ + private void validatePage() { + String error = null; + String warning = null; + + // Validate AVD name + String avdName = mAvdName.getText().trim(); + boolean hasAvdName = avdName.length() > 0; + boolean isCreate = mEditAvdInfo == null || !avdName.equals(mEditAvdInfo.getName()); + + if (hasAvdName && !AvdManager.RE_AVD_NAME.matcher(avdName).matches()) { + error = String.format( + "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s", + avdName, AvdManager.CHARS_AVD_NAME); + } + + // Validate target + if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() < 0) { + error = "A target must be selected in order to create an AVD."; + } + + // validate abi type if the selected target supports multi archs. + if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() > 0) { + int index = mTargetCombo.getSelectionIndex(); + String targetName = mTargetCombo.getItem(index); + IAndroidTarget target = mCurrentTargets.get(targetName); + ISystemImage[] systemImages = getSystemImages(target); + if (systemImages.length > 1 && mAbiTypeCombo.getSelectionIndex() < 0) { + error = "An ABI type must be selected in order to create an AVD."; + } + } + + // Validate SDCard path or value + if (error == null) { + // get the mode. We only need to check the file since the + // verifier on the size Text will prevent invalid input + boolean sdcardFileMode = mSdCardFileRadio.getSelection(); + if (sdcardFileMode) { + String sdName = mSdCardFile.getText().trim(); + if (sdName.length() > 0 && !new File(sdName).isFile()) { + error = "SD Card path isn't valid."; + } + } else { + String valueString = mSdCardSize.getText(); + if (valueString.length() > 0) { + long value = 0; + try { + value = Long.parseLong(valueString); + + int sizeIndex = mSdCardSizeCombo.getSelectionIndex(); + if (sizeIndex >= 0) { + // index 0 shifts by 10 (1024=K), index 1 by 20, etc. + value <<= 10*(1 + sizeIndex); + } + + if (value < AvdManager.SDCARD_MIN_BYTE_SIZE || + value > AvdManager.SDCARD_MAX_BYTE_SIZE) { + value = 0; + } + } catch (Exception e) { + // ignore, we'll test value below. + } + if (value <= 0) { + error = "SD Card size is invalid. Range is 9 MiB..1023 GiB."; + } else if (mEditAvdInfo != null) { + // When editing an existing AVD, compare with the existing + // sdcard size, if any. It only matters if there was an sdcard setting + // before. + Map<String, String> props = mEditAvdInfo.getProperties(); + if (props != null) { + String original = + mEditAvdInfo.getProperties().get(AvdManager.AVD_INI_SDCARD_SIZE); + if (original != null && original.length() > 0) { + long originalSize = + AvdManager.parseSdcardSize(original, null/*parsedStrings*/); + if (originalSize > 0 && value != originalSize) { + warning = "A new SD Card file will be created.\nThe current SD Card file will be lost."; + } + } + } + } + } + } + } + + // validate the skin + if (error == null) { + // get the mode, we should only check if it's in size mode since + // the built-in list mode is always valid. + if (mSkinSizeRadio.getSelection()) { + // need both with and heigh to be non null + String width = mSkinSizeWidth.getText(); // no need for trim, since the verifier + String height = mSkinSizeHeight.getText(); // rejects non digit. + + if (width.length() == 0 || height.length() == 0) { + error = "Skin size is incorrect.\nBoth dimensions must be > 0."; + } + } + } + + // Check for duplicate AVD name + if (isCreate && hasAvdName && error == null && !mForceCreation.getSelection()) { + Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(avdName); + assert conflict != null; + switch(conflict.getFirst()) { + case NO_CONFLICT: + break; + case CONFLICT_EXISTING_AVD: + case CONFLICT_INVALID_AVD: + error = String.format( + "The AVD name '%s' is already used.\n" + + "Check \"Override the existing AVD\" to delete the existing one.", + avdName); + break; + case CONFLICT_EXISTING_PATH: + error = String.format( + "Conflict with %s\n" + + "Check \"Override the existing AVD\" to delete the existing one.", + conflict.getSecond()); + break; + default: + // Hmm not supposed to happen... probably someone expanded the + // enum without adding something here. In this case just do an + // assert and use a generic error message. + error = String.format( + "Conflict %s with %s.\n" + + "Check \"Override the existing AVD\" to delete the existing one.", + conflict.getFirst().toString(), + conflict.getSecond()); + assert false; + break; + } + } + + if (error == null && mEditAvdInfo != null && isCreate) { + warning = String.format("The AVD '%1$s' will be duplicated into '%2$s'.", + mEditAvdInfo.getName(), + avdName); + } + + // Validate the create button + boolean can_create = hasAvdName && error == null; + if (can_create) { + can_create &= mTargetCombo.getSelectionIndex() >= 0; + } + mOkButton.setEnabled(can_create); + + // Adjust the create button label as needed + if (isCreate) { + mOkButton.setText("Create AVD"); + } else { + mOkButton.setText("Edit AVD"); + } + + // -- update UI + if (error != null) { + mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png")); //$NON-NLS-1$ + mStatusLabel.setText(error); + } else if (warning != null) { + mStatusIcon.setImage(mImageFactory.getImageByName("warning_icon16.png")); //$NON-NLS-1$ + mStatusLabel.setText(warning); + } else { + mStatusIcon.setImage(null); + mStatusLabel.setText(" \n "); //$NON-NLS-1$ + } + + mStatusComposite.pack(true); + } + + private void loadSkin() { + int targetIndex = mTargetCombo.getSelectionIndex(); + if (targetIndex < 0) { + return; + } + + // resolve the target. + String targetName = mTargetCombo.getItem(targetIndex); + IAndroidTarget target = mCurrentTargets.get(targetName); + if (target == null) { + return; + } + + // get the skin name + String skinName = null; + int skinIndex = mSkinCombo.getSelectionIndex(); + if (skinIndex < 0) { + return; + } else if (skinIndex == 0) { // default skin for the target + skinName = target.getDefaultSkin(); + } else { + skinName = mSkinCombo.getItem(skinIndex); + } + + // load the skin properties + String path = target.getPath(IAndroidTarget.SKINS); + File skin = new File(path, skinName); + if (skin.isDirectory() == false && target.isPlatform() == false) { + // it's possible the skin is in the parent target + path = target.getParent().getPath(IAndroidTarget.SKINS); + skin = new File(path, skinName); + } + + if (skin.isDirectory() == false) { + return; + } + + // now get the hardware.ini from the add-on (if applicable) and from the skin + // (if applicable) + HashMap<String, String> hardwareValues = new HashMap<String, String>(); + if (target.isPlatform() == false) { + FileWrapper targetHardwareFile = new FileWrapper(target.getLocation(), + AvdManager.HARDWARE_INI); + if (targetHardwareFile.isFile()) { + Map<String, String> targetHardwareConfig = ProjectProperties.parsePropertyFile( + targetHardwareFile, null /*log*/); + + if (targetHardwareConfig != null) { + hardwareValues.putAll(targetHardwareConfig); + } + } + } + + // from the skin + FileWrapper skinHardwareFile = new FileWrapper(skin, AvdManager.HARDWARE_INI); + if (skinHardwareFile.isFile()) { + Map<String, String> skinHardwareConfig = ProjectProperties.parsePropertyFile( + skinHardwareFile, null /*log*/); + + if (skinHardwareConfig != null) { + hardwareValues.putAll(skinHardwareConfig); + } + } + + // now set those values in the list of properties for the AVD. + // We just check that none of those properties have been edited by the user yet. + for (Entry<String, String> entry : hardwareValues.entrySet()) { + if (mEditedProperties.contains(entry.getKey()) == false) { + mProperties.put(entry.getKey(), entry.getValue()); + } + } + + mHardwareViewer.refresh(); + } + + /** + * Creates an AVD from the values in the UI. Called when the user presses the OK button. + */ + private boolean createAvd() { + String avdName = mAvdName.getText().trim(); + int index = mTargetCombo.getSelectionIndex(); + + // quick check on the name and the target selection + if (avdName.length() == 0 || index < 0) { + return false; + } + + // resolve the target. + String targetName = mTargetCombo.getItem(index); + IAndroidTarget target = mCurrentTargets.get(targetName); + if (target == null) { + return false; + } + + // get the abi type + mAbiType = SdkConstants.ABI_ARMEABI; + ISystemImage[] systemImages = getSystemImages(target); + if (systemImages.length > 0) { + int abiIndex = mAbiTypeCombo.getSelectionIndex(); + if (abiIndex >= 0) { + String prettyname = mAbiTypeCombo.getItem(abiIndex); + //Extract the abi type + int firstIndex = prettyname.indexOf("("); + int lastIndex = prettyname.indexOf(")"); + mAbiType = prettyname.substring(firstIndex+1, lastIndex); + } + } + + // get the SD card data from the UI. + String sdName = null; + if (mSdCardSizeRadio.getSelection()) { + // size mode + String value = mSdCardSize.getText().trim(); + if (value.length() > 0) { + sdName = value; + // add the unit + switch (mSdCardSizeCombo.getSelectionIndex()) { + case 0: + sdName += "K"; //$NON-NLS-1$ + break; + case 1: + sdName += "M"; //$NON-NLS-1$ + break; + case 2: + sdName += "G"; //$NON-NLS-1$ + break; + default: + // shouldn't be here + assert false; + } + } + } else { + // file mode. + sdName = mSdCardFile.getText().trim(); + } + + // get the Skin data from the UI + String skinName = null; + if (mSkinListRadio.getSelection()) { + // built-in list provides the skin + int skinIndex = mSkinCombo.getSelectionIndex(); + if (skinIndex > 0) { + // index 0 is the default, we don't use it + skinName = mSkinCombo.getItem(skinIndex); + } + } else { + // size mode. get both size and writes it as a skin name + // thanks to validatePage() we know the content of the fields is correct + skinName = mSkinSizeWidth.getText() + "x" + mSkinSizeHeight.getText(); //$NON-NLS-1$ + } + + ISdkLog log = mSdkLog; + if (log == null || log instanceof MessageBoxLog) { + // If the current logger is a message box, we use our own (to make sure + // to display errors right away and customize the title). + log = new MessageBoxLog( + String.format("Result of creating AVD '%s':", avdName), + getContents().getDisplay(), + false /*logErrorsOnly*/); + } + + File avdFolder = null; + try { + avdFolder = AvdInfo.getDefaultAvdFolder(mAvdManager, avdName); + } catch (AndroidLocationException e) { + return false; + } + + boolean force = mForceCreation.getSelection(); + boolean snapshot = mSnapshotCheck.getSelection(); + + boolean success = false; + AvdInfo avdInfo = mAvdManager.createAvd( + avdFolder, + avdName, + target, + mAbiType, + skinName, + sdName, + mProperties, + snapshot, + force, + mEditAvdInfo != null, //edit existing + log); + + success = avdInfo != null; + + if (log instanceof MessageBoxLog) { + ((MessageBoxLog) log).displayResult(success); + } + return success; + } + + /** + * Returns the list of system images of a target. + * <p/> + * If target is null, returns an empty list. + * If target is an add-on with no system images, return the list from its parent platform. + * + * @param target An IAndroidTarget. Can be null. + * @return A non-null ISystemImage array. Can be empty. + */ + private ISystemImage[] getSystemImages(IAndroidTarget target) { + if (target != null) { + ISystemImage[] images = target.getSystemImages(); + + if ((images == null || images.length == 0) && !target.isPlatform()) { + // If an add-on does not provide any system images, use the ones from the parent. + images = target.getParent().getSystemImages(); + } + + if (images != null) { + return images; + } + } + + return new ISystemImage[0]; + } + + // End of hiding from SWT Designer + //$hide<<$ +} diff --git a/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl b/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl index 3aa1627..1c6fbd1 100644 --- a/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl +++ b/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl @@ -8,7 +8,7 @@ <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="${parentActivityClass}" /> </#if> - <#if isLauncher> + <#if isLauncher?string == "true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/templates/activities/BlankActivity/root/res/layout/activity_simple.xml.ftl b/templates/activities/BlankActivity/root/res/layout/activity_simple.xml.ftl index a472bfe..5f97369 100644 --- a/templates/activities/BlankActivity/root/res/layout/activity_simple.xml.ftl +++ b/templates/activities/BlankActivity/root/res/layout/activity_simple.xml.ftl @@ -1,5 +1,6 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" + tools:context=".${activityClass}" android:layout_width=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if> android:layout_height=<#if buildApi lt 8 >"fill_parent"<#else>"match_parent"</#if> > @@ -8,7 +9,6 @@ android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" - android:text="@string/hello_world" - tools:context=".${activityClass}" /> + android:text="@string/hello_world" /> </RelativeLayout> diff --git a/templates/activities/FullscreenActivity/globals.xml.ftl b/templates/activities/FullscreenActivity/globals.xml.ftl new file mode 100644 index 0000000..a416d3a --- /dev/null +++ b/templates/activities/FullscreenActivity/globals.xml.ftl @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<globals> + <global id="srcOut" value="src/${slashedPackageName(packageName)}" /> + <global id="simpleName" value="${activityToLayout(activityClass)}" /> +</globals> diff --git a/templates/activities/FullscreenActivity/recipe.xml.ftl b/templates/activities/FullscreenActivity/recipe.xml.ftl new file mode 100644 index 0000000..ce1aa18 --- /dev/null +++ b/templates/activities/FullscreenActivity/recipe.xml.ftl @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<recipe> + <merge from="AndroidManifest.xml.ftl" /> + + <merge from="res/values/colors.xml" /> + <merge from="res/values/styles.xml" /> + <merge from="res/values-v11/styles.xml" /> + <instantiate from="res/layout/activity_fullscreen.xml.ftl" + to="res/layout/${layoutName}.xml" /> + + <merge from="res/values/strings.xml.ftl" + to="res/values/strings.xml" /> + + <instantiate from="src/app_package/FullscreenActivity.java.ftl" + to="${srcOut}/${activityClass}.java" /> + <instantiate from="src/app_package/util/SystemUiHider.java.ftl" + to="${srcOut}/util/SystemUiHider.java" /> + <instantiate from="src/app_package/util/SystemUiHiderBase.java.ftl" + to="${srcOut}/util/SystemUiHiderBase.java" /> + <instantiate from="src/app_package/util/SystemUiHiderHoneycomb.java.ftl" + to="${srcOut}/util/SystemUiHiderHoneycomb.java" /> + + <open file="res/layout/${layoutName}.xml" /> +</recipe> diff --git a/templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl b/templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl new file mode 100644 index 0000000..3142546 --- /dev/null +++ b/templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl @@ -0,0 +1,22 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" > + + <application> + <activity android:name=".${activityClass}" + android:label="@string/title_${simpleName}" + android:configChanges="orientation|keyboardHidden|screenSize" + android:theme="@style/FullscreenTheme" + <#if buildApi gte 16 && parentActivityClass != "">android:parentActivityName="${parentActivityClass}"</#if>> + <#if parentActivityClass != ""> + <meta-data android:name="android.support.PARENT_ACTIVITY" + android:value="${parentActivityClass}" /> + </#if> + <#if isLauncher?string == "true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </#if> + </activity> + </application> + +</manifest> diff --git a/templates/activities/FullscreenActivity/root/res/layout/activity_fullscreen.xml.ftl b/templates/activities/FullscreenActivity/root/res/layout/activity_fullscreen.xml.ftl new file mode 100755 index 0000000..bed4e68 --- /dev/null +++ b/templates/activities/FullscreenActivity/root/res/layout/activity_fullscreen.xml.ftl @@ -0,0 +1,49 @@ +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#0099cc" + tools:context=".${activityClass}"> + + <!-- The primary full-screen view. This can be replaced with whatever view + is needed to present your content, e.g. VideoView, SurfaceView, + TextureView, etc. --> + <TextView android:id="@+id/fullscreen_content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:keepScreenOn="true" + android:textColor="#33b5e5" + android:textStyle="bold" + android:textSize="50sp" + android:gravity="center" + android:text="@string/dummy_content" /> + + <!-- This FrameLayout insets its children based on system windows using + android:fitsSystemWindows. --> + <FrameLayout android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + + <LinearLayout android:id="@+id/fullscreen_content_controls" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom|center_horizontal" + android:background="@color/black_overlay" + android:orientation="horizontal" + tools:ignore="UselessParent"> + + <Button android:id="@+id/button1" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/dummy_button1" /> + <Button android:id="@+id/button2" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/dummy_button2" /> + + </LinearLayout> + </FrameLayout> + +</FrameLayout> diff --git a/templates/activities/FullscreenActivity/root/res/values-v11/styles.xml b/templates/activities/FullscreenActivity/root/res/values-v11/styles.xml new file mode 100644 index 0000000..11159aa --- /dev/null +++ b/templates/activities/FullscreenActivity/root/res/values-v11/styles.xml @@ -0,0 +1,13 @@ +<resources> + + <style name="FullscreenTheme" parent="android:Theme.Holo"> + <item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item> + <item name="android:windowActionBarOverlay">true</item> + <item name="android:windowBackground">@null</item> + </style> + + <style name="FullscreenActionBarStyle" parent="android:Widget.Holo.ActionBar"> + <item name="android:background">@color/black_overlay</item> + </style> + +</resources> diff --git a/templates/activities/FullscreenActivity/root/res/values/colors.xml b/templates/activities/FullscreenActivity/root/res/values/colors.xml new file mode 100644 index 0000000..327c060 --- /dev/null +++ b/templates/activities/FullscreenActivity/root/res/values/colors.xml @@ -0,0 +1,5 @@ +<resources> + + <color name="black_overlay">#66000000</color> + +</resources> diff --git a/templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl b/templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl new file mode 100644 index 0000000..78275fa --- /dev/null +++ b/templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl @@ -0,0 +1,8 @@ +<resources> + + <string name="title_${simpleName}">${activityTitle}</string> + <string name="dummy_button1">Button 1</string> + <string name="dummy_button2">Button 2</string> + <string name="dummy_content">DUMMY\nCONTENT</string> + +</resources> diff --git a/templates/activities/FullscreenActivity/root/res/values/styles.xml b/templates/activities/FullscreenActivity/root/res/values/styles.xml new file mode 100644 index 0000000..976b8e1 --- /dev/null +++ b/templates/activities/FullscreenActivity/root/res/values/styles.xml @@ -0,0 +1,8 @@ +<resources> + + <style name="FullscreenTheme" parent="android:Theme.NoTitleBar"> + <item name="android:windowContentOverlay">@null</item> + <item name="android:windowBackground">@null</item> + </style> + +</resources> diff --git a/templates/activities/FullscreenActivity/root/src/app_package/FullscreenActivity.java.ftl b/templates/activities/FullscreenActivity/root/src/app_package/FullscreenActivity.java.ftl new file mode 100755 index 0000000..88e6f44 --- /dev/null +++ b/templates/activities/FullscreenActivity/root/src/app_package/FullscreenActivity.java.ftl @@ -0,0 +1,197 @@ +package ${packageName}; + +import ${packageName}.util.SystemUiHider; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.view.MotionEvent; +import android.view.View; +<#if parentActivityClass != ""> +import android.view.MenuItem; +import android.support.v4.app.NavUtils; +</#if> + +/** + * An example full-screen activity that shows and hides the system UI (i.e. + * status bar and navigation/system bar) with user interaction. + * + * @see SystemUiHider + */ +public class ${activityClass} extends Activity { + /** + * Whether or not the system UI should be auto-hidden after + * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds. + */ + private static final boolean AUTO_HIDE = true; + + /** + * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after + * user interaction before hiding the system UI. + */ + private static final int AUTO_HIDE_DELAY_MILLIS = 3000; + + /** + * If set, will toggle the system UI visibility upon interaction. Otherwise, + * will show the system UI visibility upon interaction. + */ + private static final boolean TOGGLE_ON_CLICK = true; + + /** + * The flags to pass to {@link SystemUiHider#getInstance}. + */ + private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION; + + /** + * The instance of the {@link SystemUiHider} for this activity. + */ + private SystemUiHider mSystemUiHider; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.${layoutName}); + <#if parentActivityClass != ""> + setupActionBar(); + </#if> + + final View controlsView = findViewById(R.id.fullscreen_content_controls); + final View contentView = findViewById(R.id.fullscreen_content); + + // Set up an instance of SystemUiHider to control the system UI for + // this activity. + mSystemUiHider = SystemUiHider.getInstance(this, contentView, HIDER_FLAGS); + mSystemUiHider.setup(); + mSystemUiHider + .setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() { + // Cached values. + int mControlsHeight; + int mShortAnimTime; + + @Override + @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) + public void onVisibilityChange(boolean visible) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { + // If the ViewPropertyAnimator API is available + // (Honeycomb MR2 and later), use it to animate the + // in-layout UI controls at the bottom of the + // screen. + if (mControlsHeight == 0) { + mControlsHeight = controlsView.getHeight(); + } + if (mShortAnimTime == 0) { + mShortAnimTime = getResources().getInteger( + android.R.integer.config_shortAnimTime); + } + controlsView.animate() + .translationY(visible ? 0 : mControlsHeight) + .setDuration(mShortAnimTime); + } else { + // If the ViewPropertyAnimator APIs aren't + // available, simply show or hide the in-layout UI + // controls. + controlsView.setVisibility(visible ? View.VISIBLE : View.GONE); + } + + if (visible && AUTO_HIDE) { + // Schedule a hide(). + delayedHide(AUTO_HIDE_DELAY_MILLIS); + } + } + }); + + // Set up the user interaction to manually show or hide the system UI. + contentView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (TOGGLE_ON_CLICK) { + mSystemUiHider.toggle(); + } else { + mSystemUiHider.show(); + } + } + }); + + // Upon interacting with UI controls, delay any scheduled hide() + // operations to prevent the jarring behavior of controls going away + // while interacting with the UI. + findViewById(R.id.button1).setOnTouchListener(mDelayHideTouchListener); + findViewById(R.id.button2).setOnTouchListener(mDelayHideTouchListener); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + + // Trigger the initial hide() shortly after the activity has been + // created, to briefly hint to the user that UI controls + // are available. + delayedHide(100); + } + + <#if parentActivityClass != ""> + /** + * Set up the {@link android.app.ActionBar}, if the API is available. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private void setupActionBar() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // Show the Up button in the action bar. + getActionBar().setDisplayHomeAsUpEnabled(true); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // This ID represents the Home or Up button. In the case of this + // activity, the Up button is shown. Use NavUtils to allow users + // to navigate up one level in the application structure. For + // more details, see the Navigation pattern on Android Design: + // + // http://developer.android.com/design/patterns/navigation.html#up-vs-back + // + // TODO: If Settings has multiple levels, Up should navigate up + // that hierarchy. + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } + </#if> + + /** + * Touch listener to use for in-layout UI controls to delay hiding the + * system UI. This is to prevent the jarring behavior of controls going away + * while interacting with activity UI. + */ + View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() { + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + if (AUTO_HIDE) { + delayedHide(AUTO_HIDE_DELAY_MILLIS); + } + return false; + } + }; + + Handler mHideHandler = new Handler(); + Runnable mHideRunnable = new Runnable() { + @Override + public void run() { + mSystemUiHider.hide(); + } + }; + + /** + * Schedules a call to hide() in [delay] milliseconds, canceling any + * previously scheduled calls. + */ + private void delayedHide(int delayMillis) { + mHideHandler.removeCallbacks(mHideRunnable); + mHideHandler.postDelayed(mHideRunnable, delayMillis); + } +} diff --git a/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHider.java.ftl b/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHider.java.ftl new file mode 100644 index 0000000..28efb77 --- /dev/null +++ b/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHider.java.ftl @@ -0,0 +1,172 @@ +package ${packageName}.util; + +import android.app.Activity; +import android.os.Build; +import android.view.View; + +/** + * A utility class that helps with showing and hiding system UI such as the + * status bar and navigation/system bar. This class uses backward-compatibility + * techniques described in <a href= + * "http://developer.android.com/training/backward-compatible-ui/index.html"> + * Creating Backward-Compatible UIs</a> to ensure that devices running any + * version of ndroid OS are supported. More specifically, there are separate + * implementations of this abstract class: for newer devices, + * {@link #getInstance} will return a {@link SystemUiHiderHoneycomb} instance, + * while on older devices {@link #getInstance} will return a + * {@link SystemUiHiderBase} instance. + * <p> + * For more on system bars, see <a href= + * "http://developer.android.com/design/get-started/ui-overview.html#system-bars" + * > System Bars</a>. + * + * @see android.view.View#setSystemUiVisibility(int) + * @see android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN + */ +public abstract class SystemUiHider { + /** + * When this flag is set, the + * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN} + * flag will be set on older devices, making the status bar "float" on top + * of the activity layout. This is most useful when there are no controls at + * the top of the activity layout. + * <p> + * This flag isn't used on newer devices because the <a + * href="http://developer.android.com/design/patterns/actionbar.html">action + * bar</a>, the most important structural element of an Android app, should + * be visible and not obscured by the system UI. + */ + public static final int FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES = 0x1; + + /** + * When this flag is set, {@link #show()} and {@link #hide()} will toggle + * the visibility of the status bar. If there is a navigation bar, show and + * hide will toggle low profile mode. + */ + public static final int FLAG_FULLSCREEN = 0x2; + + /** + * When this flag is set, {@link #show()} and {@link #hide()} will toggle + * the visibility of the navigation bar, if it's present on the device and + * the device allows hiding it. In cases where the navigation bar is present + * but cannot be hidden, show and hide will toggle low profile mode. + */ + public static final int FLAG_HIDE_NAVIGATION = FLAG_FULLSCREEN | 0x4; + + /** + * The activity associated with this UI hider object. + */ + protected Activity mActivity; + + /** + * The view on which {@link View#setSystemUiVisibility(int)} will be called. + */ + protected View mAnchorView; + + /** + * The current UI hider flags. + * + * @see #FLAG_FULLSCREEN + * @see #FLAG_HIDE_NAVIGATION + * @see #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES + */ + protected int mFlags; + + /** + * The current visibility callback. + */ + protected OnVisibilityChangeListener mOnVisibilityChangeListener = sDummyListener; + + /** + * Creates and returns an instance of {@link SystemUiHider} that is + * appropriate for this device. The object will be either a + * {@link SystemUiHiderBase} or {@link SystemUiHiderHoneycomb} depending on + * the device. + * + * @param activity The activity whose window's system UI should be + * controlled by this class. + * @param anchorView The view on which + * {@link View#setSystemUiVisibility(int)} will be called. + * @param flags Either 0 or any combination of {@link #FLAG_FULLSCREEN}, + * {@link #FLAG_HIDE_NAVIGATION}, and + * {@link #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES}. + */ + public static SystemUiHider getInstance(Activity activity, View anchorView, int flags) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + return new SystemUiHiderHoneycomb(activity, anchorView, flags); + } else { + return new SystemUiHiderBase(activity, anchorView, flags); + } + } + + protected SystemUiHider(Activity activity, View anchorView, int flags) { + mActivity = activity; + mAnchorView = anchorView; + mFlags = flags; + } + + /** + * Sets up the system UI hider. Should be called from + * {@link Activity#onCreate}. + */ + public abstract void setup(); + + /** + * Returns whether or not the system UI is visible. + */ + public abstract boolean isVisible(); + + /** + * Hide the system UI. + */ + public abstract void hide(); + + /** + * Show the system UI. + */ + public abstract void show(); + + /** + * Toggle the visibility of the system UI. + */ + public void toggle() { + if (isVisible()) { + hide(); + } else { + show(); + } + } + + /** + * Registers a callback, to be triggered when the system UI visibility + * changes. + */ + public void setOnVisibilityChangeListener(OnVisibilityChangeListener listener) { + if (listener == null) { + listener = sDummyListener; + } + + mOnVisibilityChangeListener = listener; + } + + /** + * A dummy no-op callback for use when there is no other listener set. + */ + private static OnVisibilityChangeListener sDummyListener = new OnVisibilityChangeListener() { + @Override + public void onVisibilityChange(boolean visible) { + } + }; + + /** + * A callback interface used to listen for system UI visibility changes. + */ + public interface OnVisibilityChangeListener { + /** + * Called when the system UI visibility has changed. + * + * @param visible True if the system UI is visible. + */ + public void onVisibilityChange(boolean visible); + } +} diff --git a/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHiderBase.java.ftl b/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHiderBase.java.ftl new file mode 100644 index 0000000..da08842 --- /dev/null +++ b/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHiderBase.java.ftl @@ -0,0 +1,63 @@ +package ${packageName}.util; + +import android.app.Activity; +import android.view.View; +import android.view.WindowManager; + +/** + * A base implementation of {@link SystemUiHider}. Uses APIs available in all + * API levels to show and hide the status bar. + */ +public class SystemUiHiderBase extends SystemUiHider { + /** + * Whether or not the system UI is currently visible. This is a cached value + * from calls to {@link #hide()} and {@link #show()}. + */ + private boolean mVisible = true; + + /** + * Constructor not intended to be called by clients. Use + * {@link SystemUiHider#getInstance} to obtain an instance. + */ + protected SystemUiHiderBase(Activity activity, View anchorView, int flags) { + super(activity, anchorView, flags); + } + + @Override + public void setup() { + if ((mFlags & FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES) == 0) { + mActivity.getWindow().setFlags( + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + } + + @Override + public boolean isVisible() { + return mVisible; + } + + @Override + public void hide() { + if ((mFlags & FLAG_FULLSCREEN) != 0) { + mActivity.getWindow().setFlags( + WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + mOnVisibilityChangeListener.onVisibilityChange(false); + mVisible = false; + } + + @Override + public void show() { + if ((mFlags & FLAG_FULLSCREEN) != 0) { + mActivity.getWindow().setFlags( + 0, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + mOnVisibilityChangeListener.onVisibilityChange(true); + mVisible = true; + } +} diff --git a/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHiderHoneycomb.java.ftl b/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHiderHoneycomb.java.ftl new file mode 100644 index 0000000..f2460eb --- /dev/null +++ b/templates/activities/FullscreenActivity/root/src/app_package/util/SystemUiHiderHoneycomb.java.ftl @@ -0,0 +1,133 @@ +package ${packageName}.util; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.os.Build; +import android.view.View; +import android.view.WindowManager; + +/** + * An API 11+ implementation of {@link SystemUiHider}. Uses APIs available in + * Honeycomb and later (specifically {@link View#setSystemUiVisibility(int)}) to + * show and hide the system UI. + */ +@TargetApi(Build.VERSION_CODES.HONEYCOMB) +public class SystemUiHiderHoneycomb extends SystemUiHiderBase { + /** + * Flags for {@link View#setSystemUiVisibility(int)} to use when showing the + * system UI. + */ + private int mShowFlags; + + /** + * Flags for {@link View#setSystemUiVisibility(int)} to use when hiding the + * system UI. + */ + private int mHideFlags; + + /** + * Flags to test against the first parameter in + * {@link android.view.View.OnSystemUiVisibilityChangeListener#onSystemUiVisibilityChange(int)} + * to determine the system UI visibility state. + */ + private int mTestFlags; + + /** + * Whether or not the system UI is currently visible. This is cached from + * {@link android.view.View.OnSystemUiVisibilityChangeListener}. + */ + private boolean mVisible = true; + + /** + * Constructor not intended to be called by clients. Use + * {@link SystemUiHider#getInstance} to obtain an instance. + */ + protected SystemUiHiderHoneycomb(Activity activity, View anchorView, int flags) { + super(activity, anchorView, flags); + + mShowFlags = View.SYSTEM_UI_FLAG_VISIBLE; + mHideFlags = View.SYSTEM_UI_FLAG_LOW_PROFILE; + mTestFlags = View.SYSTEM_UI_FLAG_LOW_PROFILE; + + if ((mFlags & FLAG_FULLSCREEN) != 0) { + // If the client requested fullscreen, add flags relevant to hiding + // the status bar. Note that some of these constants are new as of + // API 16 (Jelly Bean). It is safe to use them, as they are inlined + // at compile-time and do nothing on pre-Jelly Bean devices. + mShowFlags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + mHideFlags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_FULLSCREEN; + } + + if ((mFlags & FLAG_HIDE_NAVIGATION) != 0) { + // If the client requested hiding navigation, add relevant flags. + mShowFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + mHideFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + mTestFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + } + } + + /** {@inheritDoc} */ + @Override + public void setup() { + mAnchorView.setOnSystemUiVisibilityChangeListener(mSystemUiVisibilityChangeListener); + } + + /** {@inheritDoc} */ + @Override + public void hide() { + mAnchorView.setSystemUiVisibility(mHideFlags); + } + + /** {@inheritDoc} */ + @Override + public void show() { + mAnchorView.setSystemUiVisibility(mShowFlags); + } + + /** {@inheritDoc} */ + @Override + public boolean isVisible() { + return mVisible; + } + + private View.OnSystemUiVisibilityChangeListener mSystemUiVisibilityChangeListener + = new View.OnSystemUiVisibilityChangeListener() { + @Override + public void onSystemUiVisibilityChange(int vis) { + // Test against mTestFlags to see if the system UI is visible. + if ((vis & mTestFlags) != 0) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + // Pre-Jelly Bean, we must manually hide the action bar + // and use the old window flags API. + mActivity.getActionBar().hide(); + mActivity.getWindow().setFlags( + WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + + // Trigger the registered listener and cache the visibility + // state. + mOnVisibilityChangeListener.onVisibilityChange(false); + mVisible = false; + + } else { + mAnchorView.setSystemUiVisibility(mShowFlags); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + // Pre-Jelly Bean, we must manually show the action bar + // and use the old window flags API. + mActivity.getActionBar().show(); + mActivity.getWindow().setFlags( + 0, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + + // Trigger the registered listener and cache the visibility + // state. + mOnVisibilityChangeListener.onVisibilityChange(true); + mVisible = true; + } + } + }; +} diff --git a/templates/activities/FullscreenActivity/template.xml b/templates/activities/FullscreenActivity/template.xml new file mode 100644 index 0000000..90367dd --- /dev/null +++ b/templates/activities/FullscreenActivity/template.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<template + format="1" + revision="1" + name="New Fullscreen Activity" + description="Creates a new activity that shows and hides the system UI (status bar, navigation/system bar), and action bar, upon user interaction." + minApi="3" + minBuildApi="16"> + <dependency name="android-support-v4" revision="8" /> + + <category value="Activities" /> + + <parameter + id="activityClass" + name="Activity Name" + type="string" + constraints="class|nonempty" + default="FullscreenActivity" + help="The name of the activity class to create" /> + + <parameter + id="layoutName" + name="Layout Name" + type="string" + constraints="layout|unique|nonempty" + suggest="${activityToLayout(activityClass)}" + default="activity_fullscreen" + help="The name of the layout to create for the activity" /> + + <parameter + id="activityTitle" + name="Title" + type="string" + constraints="nonempty" + default="FullscreenActivity" + suggest="${activityClass}" + help="The name of the activity." /> + + <parameter + id="isLauncher" + name="Launcher Activity" + type="boolean" + default="false" + help="If true, this activity will have a CATEGORY_LAUNCHER intent filter, making it visible in the launcher" /> + + <parameter + id="parentActivityClass" + name="Hierarchical Parent" + type="string" + constraints="activity|exists|empty" + default="" + help="The hierarchical parent activity, used to provide a default implementation for the 'Up' button" /> + + <parameter + id="packageName" + name="Package name" + type="string" + constraints="package" + default="com.mycompany.myapp" /> + + <thumbs> + <thumb>template_fullscreen_activity.png</thumb> + </thumbs> + + <globals file="globals.xml.ftl" /> + <execute file="recipe.xml.ftl" /> + +</template> diff --git a/templates/activities/FullscreenActivity/template_fullscreen_activity.png b/templates/activities/FullscreenActivity/template_fullscreen_activity.png Binary files differnew file mode 100644 index 0000000..a8597b2 --- /dev/null +++ b/templates/activities/FullscreenActivity/template_fullscreen_activity.png diff --git a/templates/activities/LoginActivity/globals.xml.ftl b/templates/activities/LoginActivity/globals.xml.ftl new file mode 100644 index 0000000..cb45205 --- /dev/null +++ b/templates/activities/LoginActivity/globals.xml.ftl @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<globals> + <global id="srcOut" value="src/${slashedPackageName(packageName)}" /> + <global id="menuName" value="${layoutName}" /> + <global id="simpleName" value="${activityToLayout(activityClass)}" /> +</globals> diff --git a/templates/activities/LoginActivity/recipe.xml.ftl b/templates/activities/LoginActivity/recipe.xml.ftl new file mode 100644 index 0000000..ece4285 --- /dev/null +++ b/templates/activities/LoginActivity/recipe.xml.ftl @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<recipe> + <merge from="AndroidManifest.xml.ftl" /> + + <merge from="res/values/styles.xml" /> + <merge from="res/values-large/styles.xml" /> + <copy from="res/menu/activity_login.xml" + to="res/menu/${menuName}.xml" /> + <instantiate from="res/layout/activity_login.xml.ftl" + to="res/layout/${layoutName}.xml" /> + + <instantiate from="res/values/strings.xml.ftl" + to="res/values/strings_${simpleName}.xml" /> + + <instantiate from="src/app_package/LoginActivity.java.ftl" + to="${srcOut}/${activityClass}.java" /> + + <open file="res/layout/${layoutName}.xml" /> +</recipe> diff --git a/templates/activities/LoginActivity/root/AndroidManifest.xml.ftl b/templates/activities/LoginActivity/root/AndroidManifest.xml.ftl new file mode 100644 index 0000000..3825bb4 --- /dev/null +++ b/templates/activities/LoginActivity/root/AndroidManifest.xml.ftl @@ -0,0 +1,15 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" > + + <application> + <activity android:name=".${activityClass}" + android:label="@string/title_${simpleName}" + android:windowSoftInputMode="adjustResize|stateVisible" + <#if buildApi gte 16 && parentActivityClass != "">android:parentActivityName="${parentActivityClass}"</#if>> + <#if parentActivityClass != ""> + <meta-data android:name="android.support.PARENT_ACTIVITY" + android:value="${parentActivityClass}" /> + </#if> + </activity> + </application> + +</manifest> diff --git a/templates/activities/LoginActivity/root/res/layout/activity_login.xml.ftl b/templates/activities/LoginActivity/root/res/layout/activity_login.xml.ftl new file mode 100644 index 0000000..ceaadc8 --- /dev/null +++ b/templates/activities/LoginActivity/root/res/layout/activity_login.xml.ftl @@ -0,0 +1,69 @@ +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + tools:context=".${activityClass}"> + + <!-- Login progress --> + <LinearLayout android:id="@+id/login_status" + android:visibility="gone" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:gravity="center_horizontal" + android:orientation="vertical"> + <ProgressBar style="?android:attr/progressBarStyleLarge" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8dp"/> + <TextView + android:id="@+id/login_status_message" + android:textAppearance="?android:attr/textAppearanceMedium" + android:fontFamily="sans-serif-light" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="16dp" + android:text="@string/login_progress_signing_in" /> + </LinearLayout> + + <!-- Login form --> + <ScrollView + android:id="@+id/login_form" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout style="@style/LoginFormContainer" + android:orientation="vertical"> + + <EditText + android:id="@+id/email" + android:singleLine="true" + android:maxLines="2" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inputType="textEmailAddress" + android:hint="@string/prompt_email" /> + + <EditText + android:id="@+id/password" + android:singleLine="true" + android:maxLines="2" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/prompt_password" + android:inputType="textPassword" + android:imeActionLabel="@string/action_sign_in_short" + android:imeActionId="@+id/login" + android:imeOptions="actionUnspecified" /> + + <Button android:id="@+id/sign_in_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:text="@string/action_sign_in_register" + android:paddingLeft="32dp" + android:paddingRight="32dp" + android:layout_gravity="right" /> + + </LinearLayout> + + </ScrollView> +</merge> diff --git a/templates/activities/LoginActivity/root/res/menu/activity_login.xml b/templates/activities/LoginActivity/root/res/menu/activity_login.xml new file mode 100644 index 0000000..1254dce --- /dev/null +++ b/templates/activities/LoginActivity/root/res/menu/activity_login.xml @@ -0,0 +1,5 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/menu_forgot_password" + android:title="@string/menu_forgot_password" + android:showAsAction="never" /> +</menu> diff --git a/templates/activities/LoginActivity/root/res/values-large/styles.xml b/templates/activities/LoginActivity/root/res/values-large/styles.xml new file mode 100644 index 0000000..7b56acd --- /dev/null +++ b/templates/activities/LoginActivity/root/res/values-large/styles.xml @@ -0,0 +1,10 @@ +<resources> + + <style name="LoginFormContainer"> + <item name="android:layout_width">400dp</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_gravity">center</item> + <item name="android:padding">16dp</item> + </style> + +</resources> diff --git a/templates/activities/LoginActivity/root/res/values/strings.xml.ftl b/templates/activities/LoginActivity/root/res/values/strings.xml.ftl new file mode 100644 index 0000000..1410671 --- /dev/null +++ b/templates/activities/LoginActivity/root/res/values/strings.xml.ftl @@ -0,0 +1,19 @@ +<resources> + <string name="title_${simpleName}">${activityTitle}</string> + + <!-- Strings related to login --> + <string name="prompt_email">Email</string> + <string name="prompt_password">Password</string> + + <string name="action_sign_in_register"><b>Sign in</b> or register</string> + <string name="action_sign_in_short">Sign in</string> + + <string name="menu_forgot_password">Recover lost password</string> + + <string name="login_progress_signing_in">Signing in…</string> + + <string name="error_invalid_email">This email address is invalid</string> + <string name="error_invalid_password">This password is too short</string> + <string name="error_incorrect_password">This password is incorrect</string> + <string name="error_field_required">This field is required</string> +</resources> diff --git a/templates/activities/LoginActivity/root/res/values/styles.xml b/templates/activities/LoginActivity/root/res/values/styles.xml new file mode 100644 index 0000000..eaec28d --- /dev/null +++ b/templates/activities/LoginActivity/root/res/values/styles.xml @@ -0,0 +1,9 @@ +<resources> + + <style name="LoginFormContainer"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:padding">16dp</item> + </style> + +</resources> diff --git a/templates/activities/LoginActivity/root/src/app_package/LoginActivity.java.ftl b/templates/activities/LoginActivity/root/src/app_package/LoginActivity.java.ftl new file mode 100644 index 0000000..d766051 --- /dev/null +++ b/templates/activities/LoginActivity/root/src/app_package/LoginActivity.java.ftl @@ -0,0 +1,278 @@ +package ${packageName}; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.annotation.TargetApi; +import android.app.Activity; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.TextView; +<#if parentActivityClass != ""> +import android.view.MenuItem; +import android.support.v4.app.NavUtils; +</#if> + +/** + * Activity which displays a login screen to the user, offering registration as + * well. + */ +public class ${activityClass} extends Activity { + /** + * A dummy authentication store containing known user names and passwords. + * TODO: remove after connecting to a real authentication system. + */ + private static final String[] DUMMY_CREDENTIALS = new String[]{ + "foo@example.com:hello", + "bar@example.com:world" + }; + + /** + * The default email to populate the email field with. + */ + public static final String EXTRA_EMAIL = "com.example.android.authenticatordemo.extra.EMAIL"; + + /** + * Keep track of the login task to ensure we can cancel it if requested. + */ + private UserLoginTask mAuthTask = null; + + // Values for email and password at the time of the login attempt. + private String mEmail; + private String mPassword; + + // UI references. + private EditText mEmailView; + private EditText mPasswordView; + private View mLoginFormView; + private View mLoginStatusView; + private TextView mLoginStatusMessageView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + setContentView(R.layout.${layoutName}); + <#if parentActivityClass != ""> + setupActionBar(); + </#if> + + // Set up the login form. + mEmail = getIntent().getStringExtra(EXTRA_EMAIL); + mEmailView = (EditText) findViewById(R.id.email); + mEmailView.setText(mEmail); + + mPasswordView = (EditText) findViewById(R.id.password); + mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { + if (id == R.id.login || id == EditorInfo.IME_NULL) { + attemptLogin(); + return true; + } + return false; + } + }); + + mLoginFormView = findViewById(R.id.login_form); + mLoginStatusView = findViewById(R.id.login_status); + mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message); + + findViewById(R.id.sign_in_button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + attemptLogin(); + } + }); + } + + <#if parentActivityClass != ""> + /** + * Set up the {@link android.app.ActionBar}, if the API is available. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private void setupActionBar() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // Show the Up button in the action bar. + getActionBar().setDisplayHomeAsUpEnabled(true); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // This ID represents the Home or Up button. In the case of this + // activity, the Up button is shown. Use NavUtils to allow users + // to navigate up one level in the application structure. For + // more details, see the Navigation pattern on Android Design: + // + // http://developer.android.com/design/patterns/navigation.html#up-vs-back + // + // TODO: If Settings has multiple levels, Up should navigate up + // that hierarchy. + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } + </#if> + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + getMenuInflater().inflate(R.menu.${menuName}, menu); + return true; + } + + /** + * Attempts to sign in or register the account specified by the login form. + * If there are form errors (invalid email, missing fields, etc.), the + * errors are presented and no actual login attempt is made. + */ + public void attemptLogin() { + if (mAuthTask != null) { + return; + } + + // Reset errors. + mEmailView.setError(null); + mPasswordView.setError(null); + + // Store values at the time of the login attempt. + mEmail = mEmailView.getText().toString(); + mPassword = mPasswordView.getText().toString(); + + boolean cancel = false; + View focusView = null; + + // Check for a valid password. + if (TextUtils.isEmpty(mPassword)) { + mPasswordView.setError(getString(R.string.error_field_required)); + focusView = mPasswordView; + cancel = true; + } else if (mPassword.length() < 4) { + mPasswordView.setError(getString(R.string.error_invalid_password)); + focusView = mPasswordView; + cancel = true; + } + + // Check for a valid email address. + if (TextUtils.isEmpty(mEmail)) { + mEmailView.setError(getString(R.string.error_field_required)); + focusView = mEmailView; + cancel = true; + } else if (!mEmail.contains("@")) { + mEmailView.setError(getString(R.string.error_invalid_email)); + focusView = mEmailView; + cancel = true; + } + + if (cancel) { + // There was an error; don't attempt login and focus the first + // form field with an error. + focusView.requestFocus(); + } else { + // Show a progress spinner, and kick off a background task to + // perform the user login attempt. + mLoginStatusMessageView.setText(R.string.login_progress_signing_in); + showProgress(true); + mAuthTask = new UserLoginTask(); + mAuthTask.execute((Void) null); + } + } + + /** + * Shows the progress UI and hides the login form. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) + private void showProgress(final boolean show) { + // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow + // for very easy animations. If available, use these APIs to fade-in + // the progress spinner. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { + int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); + + mLoginStatusView.setVisibility(View.VISIBLE); + mLoginStatusView.animate() + .setDuration(shortAnimTime) + .alpha(show ? 1 : 0) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE); + } + }); + + mLoginFormView.setVisibility(View.VISIBLE); + mLoginFormView.animate() + .setDuration(shortAnimTime) + .alpha(show ? 0 : 1) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); + } + }); + } else { + // The ViewPropertyAnimator APIs are not available, so simply show + // and hide the relevant UI components. + mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE); + mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); + } + } + + /** + * Represents an asynchronous login/registration task used to authenticate + * the user. + */ + public class UserLoginTask extends AsyncTask<Void, Void, Boolean> { + @Override + protected Boolean doInBackground(Void... params) { + // TODO: attempt authentication against a network service. + + try { + // Simulate network access. + Thread.sleep(2000); + } catch (InterruptedException e) { + return false; + } + + for (String credential : DUMMY_CREDENTIALS) { + String[] pieces = credential.split(":"); + if (pieces[0].equals(mEmail)) { + // Account exists, return true if the password matches. + return pieces[1].equals(mPassword); + } + } + + // TODO: register the new account here. + return true; + } + + @Override + protected void onPostExecute(final Boolean success) { + mAuthTask = null; + showProgress(false); + + if (success) { + finish(); + } else { + mPasswordView.setError(getString(R.string.error_incorrect_password)); + mPasswordView.requestFocus(); + } + } + + @Override + protected void onCancelled() { + mAuthTask = null; + showProgress(false); + } + } +} diff --git a/templates/activities/LoginActivity/template.xml b/templates/activities/LoginActivity/template.xml new file mode 100644 index 0000000..7df8895 --- /dev/null +++ b/templates/activities/LoginActivity/template.xml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<template + format="1" + revision="1" + name="New Login Activity" + description="Creates a new login activity, allowing users to enter an email address and password to login or register for your service." + minApi="3" + minBuildApi="13"> + <dependency name="android-support-v4" revision="8" /> + + <category value="Activities" /> + + <parameter + id="activityClass" + name="Activity Name" + type="string" + constraints="class|nonempty" + default="LoginActivity" + help="The name of the activity class to create" /> + + <parameter + id="layoutName" + name="Layout Name" + type="string" + constraints="layout|unique|nonempty" + suggest="${activityToLayout(activityClass)}" + default="activity_login" + help="The name of the layout to create for the activity" /> + + <parameter + id="activityTitle" + name="Title" + type="string" + constraints="nonempty" + default="Sign in" + help="The name of the activity." /> + + <parameter + id="parentActivityClass" + name="Hierarchical Parent" + type="string" + constraints="activity|exists|empty" + default="" + help="The hierarchical parent activity, used to provide a default implementation for the 'Up' button" /> + + <parameter + id="packageName" + name="Package name" + type="string" + constraints="package" + default="com.mycompany.myapp" /> + + <thumbs> + <thumb>template_login_activity.png</thumb> + </thumbs> + + <globals file="globals.xml.ftl" /> + <execute file="recipe.xml.ftl" /> + +</template> diff --git a/templates/activities/LoginActivity/template_login_activity.png b/templates/activities/LoginActivity/template_login_activity.png Binary files differnew file mode 100644 index 0000000..0f9bfc0 --- /dev/null +++ b/templates/activities/LoginActivity/template_login_activity.png diff --git a/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl b/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl index 15ed087..395b227 100644 --- a/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl +++ b/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl @@ -8,7 +8,7 @@ <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="${parentActivityClass}" /> </#if> - <#if isLauncher> + <#if isLauncher?string == "true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/uiautomatorviewer/.classpath b/uiautomatorviewer/.classpath new file mode 100644 index 0000000..b9c01bb --- /dev/null +++ b/uiautomatorviewer/.classpath @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry excluding="images" kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/> + <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/> + <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/swt.jar"/> + <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.core.commands_3.6.0.I20100512-1500.jar"/> + <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.equinox.common_3.6.0.v20100503.jar"/> + <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.jface_3.6.2.M20110210-1200.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/uiautomatorviewer/.gitignore b/uiautomatorviewer/.gitignore new file mode 100644 index 0000000..ba077a4 --- /dev/null +++ b/uiautomatorviewer/.gitignore @@ -0,0 +1 @@ +bin diff --git a/uiautomatorviewer/.project b/uiautomatorviewer/.project new file mode 100644 index 0000000..d5a1115 --- /dev/null +++ b/uiautomatorviewer/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>uiautomatorviewer</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/uiautomatorviewer/Android.mk b/uiautomatorviewer/Android.mk index a5bc768..907718b 100644 --- a/uiautomatorviewer/Android.mk +++ b/uiautomatorviewer/Android.mk @@ -24,6 +24,8 @@ LOCAL_MODULE_TAGS := optional LOCAL_JAVA_LIBRARIES := \ swt \ + sdklib \ + ddmlib \ org.eclipse.jface_3.6.2.M20110210-1200 \ org.eclipse.core.commands_3.6.0.I20100512-1500 \ org.eclipse.equinox.common_3.6.0.v20100503 diff --git a/uiautomatorviewer/MODULE_LICENSE_APACHE2 b/uiautomatorviewer/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/uiautomatorviewer/MODULE_LICENSE_APACHE2 diff --git a/uiautomatorviewer/src/com/android/uiautomator/DebugBridge.java b/uiautomatorviewer/src/com/android/uiautomator/DebugBridge.java new file mode 100644 index 0000000..09272bc --- /dev/null +++ b/uiautomatorviewer/src/com/android/uiautomator/DebugBridge.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * 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. + */ + +package com.android.uiautomator; + +import com.android.ddmlib.AndroidDebugBridge; +import com.android.ddmlib.IDevice; +import com.android.sdklib.SdkConstants; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +public class DebugBridge { + private static AndroidDebugBridge sDebugBridge; + + private static String getAdbLocation() { + String toolsDir = System.getProperty("com.android.uiautomator.bindir"); //$NON-NLS-1$ + if (toolsDir == null) { + return null; + } + + File sdk = new File(toolsDir).getParentFile(); + + // check if adb is present in platform-tools + File platformTools = new File(sdk, "platform-tools"); + File adb = new File(platformTools, SdkConstants.FN_ADB); + if (adb.exists()) { + return adb.getAbsolutePath(); + } + + // check if adb is present in the tools directory + adb = new File(sdk, SdkConstants.FN_ADB); + if (adb.exists()) { + return adb.getAbsolutePath(); + } + + return null; + } + + public static void init() { + String adbLocation = getAdbLocation(); + if (adbLocation != null) { + AndroidDebugBridge.init(false /* debugger support */); + sDebugBridge = AndroidDebugBridge.createBridge(adbLocation, false); + } + } + + public static void terminate() { + if (sDebugBridge != null) { + sDebugBridge = null; + AndroidDebugBridge.terminate(); + } + } + + public static boolean isInitialized() { + return sDebugBridge != null; + } + + public static List<IDevice> getDevices() { + return Arrays.asList(sDebugBridge.getDevices()); + } +} diff --git a/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorViewer.java b/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorViewer.java index 9f758ae..48e01cf 100644 --- a/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorViewer.java +++ b/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorViewer.java @@ -66,7 +66,6 @@ import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Tree; public class UiAutomatorViewer extends ApplicationWindow { - private static final int IMG_BORDER = 2; private Canvas mScreenshotCanvas; @@ -280,6 +279,8 @@ public class UiAutomatorViewer extends ApplicationWindow { * @param args */ public static void main(String args[]) { + DebugBridge.init(); + try { UiAutomatorViewer window = new UiAutomatorViewer(); window.setBlockOnOpen(true); @@ -287,6 +288,8 @@ public class UiAutomatorViewer extends ApplicationWindow { UiAutomatorModel.getModel().cleanUp(); } catch (Exception e) { e.printStackTrace(); + } finally { + DebugBridge.terminate(); } } diff --git a/uiautomatorviewer/src/com/android/uiautomator/actions/ScreenshotAction.java b/uiautomatorviewer/src/com/android/uiautomator/actions/ScreenshotAction.java index 7d1eaa3..181f655 100644 --- a/uiautomatorviewer/src/com/android/uiautomator/actions/ScreenshotAction.java +++ b/uiautomatorviewer/src/com/android/uiautomator/actions/ScreenshotAction.java @@ -16,6 +16,11 @@ package com.android.uiautomator.actions; +import com.android.ddmlib.CollectingOutputReceiver; +import com.android.ddmlib.IDevice; +import com.android.ddmlib.RawImage; +import com.android.ddmlib.SyncService; +import com.android.uiautomator.DebugBridge; import com.android.uiautomator.UiAutomatorModel; import com.android.uiautomator.UiAutomatorViewer; @@ -23,20 +28,39 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; -import java.io.BufferedReader; import java.io.File; import java.io.IOException; -import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class ScreenshotAction extends Action { + private static final String UIAUTOMATOR = "/system/bin/uiautomator"; //$NON-NLS-1$ + private static final String UIAUTOMATOR_DUMP_COMMAND = "dump"; //$NON-NLS-1$ + private static final String UIDUMP_DEVICE_PATH = "/sdcard/uidump.xml"; //$NON-NLS-1$ + + private static final int MIN_API_LEVEL = 16; UiAutomatorViewer mViewer; @@ -52,6 +76,18 @@ public class ScreenshotAction extends Action { @Override public void run() { + if (!DebugBridge.isInitialized()) { + MessageDialog.openError(mViewer.getShell(), + "Error obtaining Device Screenshot", + "Unable to connect to adb. Check if adb is installed correctly."); + return; + } + + final IDevice device = pickDevice(); + if (device == null) { + return; + } + ProgressMonitorDialog dialog = new ProgressMonitorDialog(mViewer.getShell()); try { dialog.run(true, false, new IRunnableWithProgress() { @@ -63,7 +99,7 @@ public class ScreenshotAction extends Action { public void run() { Status s = new Status(IStatus.ERROR, "Screenshot", msg, t); ErrorDialog.openError( - mViewer.getShell(), "Error", "Cannot take screenshot", s); + mViewer.getShell(), "Error", "Error obtaining UI hierarchy", s); } }); } @@ -71,12 +107,9 @@ public class ScreenshotAction extends Action { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - ProcRunner procRunner = null; - String serial = System.getenv("ANDROID_SERIAL"); File tmpDir = null; File xmlDumpFile = null; File screenshotFile = null; - int retCode = -1; try { tmpDir = File.createTempFile("uiautomatorviewer_", ""); tmpDir.delete(); @@ -91,115 +124,72 @@ public class ScreenshotAction extends Action { } UiAutomatorModel.getModel().registerTempDirectory(tmpDir); - // boiler plates to do a bunch of adb stuff to take XML snapshot and screenshot - monitor.beginTask("Getting UI status dump from device...", - IProgressMonitor.UNKNOWN); - monitor.subTask("Detecting device..."); - procRunner = getAdbRunner(serial, "shell", "ls", "/system/bin/uiautomator"); + String apiLevelString = device.getProperty(IDevice.PROP_BUILD_API_LEVEL); + int apiLevel; try { - retCode = procRunner.run(30000); - } catch (IOException e) { - e.printStackTrace(); - showError("Failed to detect device", e, monitor); - return; + apiLevel = Integer.parseInt(apiLevelString); + } catch (NumberFormatException e) { + apiLevel = MIN_API_LEVEL; } - if (retCode != 0) { - showError("No device or multiple devices connected. " - + "Use ANDROID_SERIAL environment variable " - + "if you have multiple devices", null, monitor); - return; - } - if (procRunner.getOutputBlob().indexOf("No such file or directory") != -1) { - showError("/system/bin/uiautomator not found on device", null, monitor); + if (apiLevel < MIN_API_LEVEL) { + showError("uiautomator requires a device with API Level " + MIN_API_LEVEL, + null, monitor); return; } + monitor.subTask("Deleting old UI XML snapshot ..."); - procRunner = getAdbRunner(serial, - "shell", "rm", "/sdcard/uidump.xml"); + String command = "rm " + UIDUMP_DEVICE_PATH; try { - retCode = procRunner.run(30000); - if (retCode != 0) { - throw new IOException( - "Non-zero return code from \"rm\" xml dump command:\n" - + procRunner.getOutputBlob()); - } - } catch (IOException e) { - e.printStackTrace(); - showError("Failed to execute \"rm\" xml dump command.", e, monitor); - return; + CountDownLatch commandCompleteLatch = new CountDownLatch(1); + device.executeShellCommand(command, + new CollectingOutputReceiver(commandCompleteLatch)); + commandCompleteLatch.await(5, TimeUnit.SECONDS); + } catch (Exception e1) { + // ignore exceptions while deleting stale files } monitor.subTask("Taking UI XML snapshot..."); - procRunner = getAdbRunner(serial, - "shell", "/system/bin/uiautomator", "dump", "/sdcard/uidump.xml"); + command = String.format("%s %s %s", UIAUTOMATOR, + UIAUTOMATOR_DUMP_COMMAND, + UIDUMP_DEVICE_PATH); try { - retCode = procRunner.run(30000); - if (retCode != 0) { - throw new IOException("Non-zero return code from dump command:\n" - + procRunner.getOutputBlob()); - } - } catch (IOException e) { - e.printStackTrace(); - showError("Failed to execute dump command.", e, monitor); - return; - } - procRunner = getAdbRunner(serial, - "pull", "/sdcard/uidump.xml", xmlDumpFile.getAbsolutePath()); - try { - retCode = procRunner.run(30000); - if (retCode != 0) { - throw new IOException("Non-zero return code from pull command:\n" - + procRunner.getOutputBlob()); - } - } catch (IOException e) { - e.printStackTrace(); - showError("Failed to pull dump file.", e, monitor); + CountDownLatch commandCompleteLatch = new CountDownLatch(1); + device.executeShellCommand(command, + new CollectingOutputReceiver(commandCompleteLatch)); + commandCompleteLatch.await(5, TimeUnit.SECONDS); + } catch (Exception e1) { + showError("", e1, monitor); return; } - monitor.subTask("Deleting old device screenshot..."); - procRunner = getAdbRunner(serial, - "shell", "rm", "/sdcard/screenshot.png"); + monitor.subTask("Pull UI XML snapshot from device..."); try { - retCode = procRunner.run(30000); - if (retCode != 0) { - throw new IOException( - "Non-zero return code from \"rm\" screenshot command:\n" - + procRunner.getOutputBlob()); - } - } catch (IOException e) { - e.printStackTrace(); - showError("Failed to execute \"rm\" screenshot command.", e, monitor); + device.getSyncService().pullFile(UIDUMP_DEVICE_PATH, + xmlDumpFile.getAbsolutePath(), SyncService.getNullProgressMonitor()); + } catch (Exception e1) { + showError("Error copying UI XML file from device", e1, monitor); return; } - monitor.subTask("Taking device screenshot..."); - procRunner = getAdbRunner(serial, - "shell", "screencap", "-p", "/sdcard/screenshot.png"); - try { - retCode = procRunner.run(30000); - if (retCode != 0) { - throw new IOException("Non-zero return code from screenshot command:\n" - + procRunner.getOutputBlob()); - } - } catch (IOException e) { - e.printStackTrace(); - showError("Failed to execute screenshot command.", e, monitor); - return; - } - procRunner = getAdbRunner(serial, - "pull", "/sdcard/screenshot.png", screenshotFile.getAbsolutePath()); + monitor.subTask("Taking screenshot..."); + RawImage rawImage; try { - retCode = procRunner.run(30000); - if (retCode != 0) { - throw new IOException("Non-zero return code from pull command:\n" - + procRunner.getOutputBlob()); - } - } catch (IOException e) { - e.printStackTrace(); - showError("Failed to pull dump file.", e, monitor); + rawImage = device.getScreenshot(); + } catch (Exception e1) { + showError("Error taking device screenshot", e1, monitor); return; } + + PaletteData palette = new PaletteData( + rawImage.getRedMask(), + rawImage.getGreenMask(), + rawImage.getBlueMask()); + ImageData imageData = new ImageData(rawImage.width, rawImage.height, + rawImage.bpp, palette, 1, rawImage.data); + ImageLoader loader = new ImageLoader(); + loader.data = new ImageData[] { imageData }; + loader.save(screenshotFile.getAbsolutePath(), SWT.IMAGE_PNG); + final File png = screenshotFile, xml = xmlDumpFile; if(png.length() == 0) { showError("Screenshot file size is 0", null, monitor); @@ -222,81 +212,68 @@ public class ScreenshotAction extends Action { } } - /* - * Convenience function to construct an 'adb' command, e.g. use 'adb' or 'adb -s NNN' - */ - private ProcRunner getAdbRunner(String serial, String... command) { - List<String> cmd = new ArrayList<String>(); - cmd.add("adb"); - if (serial != null) { - cmd.add("-s"); - cmd.add(serial); - } - for (String s : command) { - cmd.add(s); + private IDevice pickDevice() { + List<IDevice> devices = DebugBridge.getDevices(); + if (devices.size() == 0) { + MessageDialog.openError(mViewer.getShell(), + "Error obtaining Device Screenshot", + "No Android devices were detected by adb."); + return null; + } else if (devices.size() == 1) { + return devices.get(0); + } else { + DevicePickerDialog dlg = new DevicePickerDialog(mViewer.getShell(), devices); + if (dlg.open() != Window.OK) { + return null; + } + return dlg.getSelectedDevice(); } - return new ProcRunner(cmd); } - /** - * Convenience class to run external process. - * - * Always redirects stderr into stdout, has timeout control - * - */ - private static class ProcRunner { - - ProcessBuilder mProcessBuilder; + private static class DevicePickerDialog extends Dialog { + private final List<IDevice> mDevices; + private final String[] mDeviceNames; + private static int sSelectedDeviceIndex; - List<String> mOutput = new ArrayList<String>(); + public DevicePickerDialog(Shell parentShell, List<IDevice> devices) { + super(parentShell); - public ProcRunner(List<String> command) { - mProcessBuilder = new ProcessBuilder(command).redirectErrorStream(true); + mDevices = devices; + mDeviceNames = new String[mDevices.size()]; + for (int i = 0; i < devices.size(); i++) { + mDeviceNames[i] = devices.get(i).getName(); + } } - public int run(long timeout) throws IOException { - final Process p = mProcessBuilder.start(); - Thread t = new Thread() { + @Override + protected Control createDialogArea(Composite parentShell) { + Composite parent = (Composite) super.createDialogArea(parentShell); + Composite c = new Composite(parent, SWT.NONE); + + c.setLayout(new GridLayout(2, false)); + + Label l = new Label(c, SWT.NONE); + l.setText("Select device: "); + + final Combo combo = new Combo(c, SWT.BORDER | SWT.READ_ONLY); + combo.setItems(mDeviceNames); + int defaultSelection = + sSelectedDeviceIndex < mDevices.size() ? sSelectedDeviceIndex : 0; + combo.select(defaultSelection); + sSelectedDeviceIndex = defaultSelection; + + combo.addSelectionListener(new SelectionAdapter() { @Override - public void run() { - String line; - mOutput.clear(); - try { - BufferedReader br = new BufferedReader(new InputStreamReader( - p.getInputStream())); - while ((line = br.readLine()) != null) { - mOutput.add(line); - } - br.close(); - } catch (IOException e) { - e.printStackTrace(); - } - }; - }; - t.start(); - try { - t.join(timeout); - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (t.isAlive()) { - throw new IOException("external process not terminating."); - } - try { - return p.waitFor(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new IOException(e); - } + public void widgetSelected(SelectionEvent arg0) { + sSelectedDeviceIndex = combo.getSelectionIndex(); + } + }); + + return parent; } - public String getOutputBlob() { - StringBuilder sb = new StringBuilder(); - for (String line : mOutput) { - sb.append(line); - sb.append(System.getProperty("line.separator")); - } - return sb.toString(); + public IDevice getSelectedDevice() { + return mDevices.get(sSelectedDeviceIndex); } } } |