diff --git a/.gitignore b/.gitignore index 6a2245c1b..c337f09ab 100644 --- a/.gitignore +++ b/.gitignore @@ -14,8 +14,4 @@ cache node_modules bower_components -app/profile.json -app/_cache -app/_build -app/resources/locale/**/*.json -demo/*.v +**/locale/**/*.json diff --git a/.travis.yml b/.travis.yml index a7abd9274..b3097cbbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ os: before_install: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo dpkg --add-architecture i386; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -q; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y wine; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y wine nsis; fi install: - npm install @@ -25,6 +25,7 @@ deploy: file: - dist/*.zip - dist/*.dmg + - dist/*.exe file_glob: true skip_cleanup: true on: diff --git a/README.md b/README.md index 38f932ff8..a2a0ca3e4 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,32 @@ Supported operating systems: * Windows * Mac OS X -## Version 0.3.0-beta2 (latest) +## Version 0.3.0-beta3 (latest) + +Documentation: http://icestudio.readthedocs.io/en/latest ### Installation -1. Install [Python 2.7](https://www.python.org) +* **GNU/Linux** -2. Download the [release](https://github.com/FPGAwars/icestudio/releases/tag/0.3.0-beta2), unzip and execute **icestudio** + 1. Install [Python 2.7](https://www.python.org) + 2. Download the [zipped release](https://github.com/FPGAwars/icestudio/releases/tag/0.3.0-beta3), unzip and execute **icestudio** -Documentation: http://icestudio.readthedocs.io/en/latest -NOTE: if you want to add blocks or examples, please contribute to [icestudio-blocks](https://github.com/FPGAwars/icestudio-blocks) or [icestudio-examples](https://github.com/FPGAwars/icestudio-examples). +NOTE: GNU/Linux users must have **xclip** installed to enable Copy/Paste. + + +* **Windows** + + 1. Download and execute the [Windows installer](https://github.com/FPGAwars/icestudio/releases/tag/0.3.0-beta3) + + +* **Mac OS X** - + 1. Install [Python 2.7](https://www.python.org) + 2. Download and execute the [DMG package](https://github.com/FPGAwars/icestudio/releases/tag/0.3.0-beta3) + + ## Development @@ -44,6 +57,9 @@ Install [Python 2.7](https://www.python.org/downloads/release/python-2711/) and Using [Atom](https://atom.io/) editor with [linter-jshint](https://atom.io/packages/linter-jshint). +NOTE: if you want to add blocks or examples, please contribute to [icestudio-blocks](https://github.com/FPGAwars/icestudio-blocks) or [icestudio-examples](https://github.com/FPGAwars/icestudio-examples). + + ##### Ubuntu ```bash @@ -76,7 +92,9 @@ npm start npm run dist ``` -NOTE: in Mac OS X this command also generates a **dmg** package. +Output +* *GNU/Linux*: linux32.zip, linux64.zip, win32.zip, win64.zip, win32.exe, win64.exe. +* *Mac OS X*: osx32.zip, osx64.zip, osx64.dmg. ## Languages @@ -84,9 +102,9 @@ NOTE: in Mac OS X this command also generates a **dmg** package. |:----------:|:------------------------------------------:| | English | ![Progress](http://progressed.io/bar/100) | | Spanish | ![Progress](http://progressed.io/bar/100) | -| Basque | ![Progress](http://progressed.io/bar/88) | -| French | ![Progress](http://progressed.io/bar/72) | -| Galician | ![Progress](http://progressed.io/bar/47) | +| Basque | ![Progress](http://progressed.io/bar/87) | +| French | ![Progress](http://progressed.io/bar/61) | +| Galician | ![Progress](http://progressed.io/bar/35) | **Contribute**: add or update the [translations](https://github.com/FPGAwars/icestudio/tree/develop/app/resources/locale) by following the [next instructions](https://angular-gettext.rocketeer.be/dev-guide/translate/#poedit). @@ -94,6 +112,16 @@ NOTE: in Mac OS X this command also generates a **dmg** package. npm run gettext ``` +## Troubleshooting + +If you get this error `npm ERR! peerinvalid The package grunt@1.0.1 does not satisfy its siblings' peerDependencies requirements!`, execute: + +```bash +npm update -g +``` + +[More information](https://github.com/angular-fullstack/generator-angular-fullstack/issues/431) + ## Roadmap There is a [Wishlist](https://github.com/FPGAwars/icestudio/wiki/Wishlist:-proposed-features) in the wiki with the features proposed by the Community. If you want to contribute with new features and ideas write in the [Google Group](https://groups.google.com/forum/#!forum/fpga-wars-explorando-el-lado-libre). diff --git a/app/index.html b/app/index.html index 1587487d7..708b75811 100644 --- a/app/index.html +++ b/app/index.html @@ -52,23 +52,26 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/app/package.json b/app/package.json index db4d53c43..a10cbf17a 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "icestudio", - "version": "0.3.0-beta2", + "version": "0.3.0-beta3", "description": "Experimental graphic editor for open FPGAs", "author": "Jesús Arroyo Torrens ", "repository": "https://github.com/FPGAwars/icestudio", @@ -18,13 +18,16 @@ "icon": "resources/images/icestudio-logo.png" }, "apio": { - "min": "0.2.0", - "max": "0.2.1" + "min": "0.2.1.2", + "max": "0.2.2" }, "engines": { "node": ">= 0.10.0" }, "dependencies": { + "adm-zip": "^0.4.7", + "angular-gettext-tools": "~2.3.3", + "copy-paste": "^1.3.0", "fs-extra": "^1.0.0", "glob": "^7.1.1", "is-online": "^5.2.0", @@ -38,8 +41,7 @@ "ssh-exec": "^2.0.0", "sudo-prompt": "^6.2.0", "svgo": "^0.7.1", - "tarball-extract": "0.0.3", - "unzip": "^0.1.11" + "tarball-extract": "0.0.3" }, "readme": "../README.md", "keywords": [ diff --git a/app/resources/boards/_iCEblink40-HX1K/pinout.json b/app/resources/boards/_iCEblink40-HX1K/pinout.json index 896353c97..41275fb4c 100644 --- a/app/resources/boards/_iCEblink40-HX1K/pinout.json +++ b/app/resources/boards/_iCEblink40-HX1K/pinout.json @@ -1 +1 @@ -[{"name": "CLK", "value": "13"}, {"name": "LED1", "value": "59"}, {"name": "LED2", "value": "56"}, {"name": "LED3", "value": "53"}, {"name": "LED4", "value": "51"}, {"name": "BTN1", "value": "60"}, {"name": "BTN2", "value": "57"}, {"name": "BTN3", "value": "54"}, {"name": "BTN4", "value": "52"}, {"name": "J2U1", "value": "66"}, {"name": "J2U2", "value": "69"}, {"name": "J2U3", "value": "72"}, {"name": "J2U4", "value": "74"}, {"name": "J2U5", "value": "79"}, {"name": "J2U6", "value": "81"}, {"name": "J2U7", "value": "83"}, {"name": "J2U8", "value": "86"}, {"name": "J2D1", "value": "68"}, {"name": "J2D2", "value": "71"}, {"name": "J2D3", "value": "73"}, {"name": "J2D4", "value": "78"}, {"name": "J2D5", "value": "80"}, {"name": "J2D6", "value": "82"}, {"name": "J2D7", "value": "85"}, {"name": "J2D8", "value": "87"}, {"name": "J4U1", "value": "89"}, {"name": "J4U2", "value": "91"}, {"name": "J4U3", "value": "94"}, {"name": "J4U4", "value": "96"}, {"name": "J4U5", "value": "99"}, {"name": "J4U6", "value": "12"}, {"name": "J4U8", "value": "18"}, {"name": "J4D1", "value": "90"}, {"name": "J4D2", "value": "93"}, {"name": "J4D3", "value": "95"}, {"name": "J4D4", "value": "97"}, {"name": "J4D5", "value": "100"}, {"name": "J4D6", "value": "15"}, {"name": "J4D7", "value": "16"}, {"name": "J4D8", "value": "19"}, {"name": "D11", "value": "64"}, {"name": "D10", "value": "62"}, {"name": "D9", "value": "42"}, {"name": "D8", "value": "40"}, {"name": "D7", "value": "36"}, {"name": "D6", "value": "30"}, {"name": "D5", "value": "65"}, {"name": "D4", "value": "63"}, {"name": "D3", "value": "41"}, {"name": "D2", "value": "37"}, {"name": "D1", "value": "34"}, {"name": "D0", "value": "29"}, {"name": "J6R1", "value": "25"}, {"name": "J6R2", "value": "24"}, {"name": "J6R3", "value": "21"}, {"name": "J6R4", "value": "20"}, {"name": "J6L1", "value": "26"}, {"name": "J6L2", "value": "27"}, {"name": "J6L3", "value": "28"}, {"name": "J6L4", "value": "33"}, {"name": "J1R1", "value": "10"}, {"name": "J1R2", "value": "9"}, {"name": "J1R3", "value": "8"}, {"name": "J1R4", "value": "7"}, {"name": "J1L1", "value": "4"}, {"name": "J1L2", "value": "3"}, {"name": "J1L3", "value": "2"}, {"name": "J1L4", "value": "1"}, {"name": "SS", "value": "49"}, {"name": "SO", "value": "45"}, {"name": "SI", "value": "46"}, {"name": "SCK", "value": "48"}] \ No newline at end of file +[{"type": "input", "name": "CLK", "value": "13"}, {"type": "output", "name": "LED1", "value": "59"}, {"type": "output", "name": "LED2", "value": "56"}, {"type": "output", "name": "LED3", "value": "53"}, {"type": "output", "name": "LED4", "value": "51"}, {"type": "input", "name": "BTN1", "value": "60"}, {"type": "input", "name": "BTN2", "value": "57"}, {"type": "input", "name": "BTN3", "value": "54"}, {"type": "input", "name": "BTN4", "value": "52"}, {"type": "inout", "name": "J2U1", "value": "66"}, {"type": "inout", "name": "J2U2", "value": "69"}, {"type": "inout", "name": "J2U3", "value": "72"}, {"type": "inout", "name": "J2U4", "value": "74"}, {"type": "inout", "name": "J2U5", "value": "79"}, {"type": "inout", "name": "J2U6", "value": "81"}, {"type": "inout", "name": "J2U7", "value": "83"}, {"type": "inout", "name": "J2U8", "value": "86"}, {"type": "inout", "name": "J2D1", "value": "68"}, {"type": "inout", "name": "J2D2", "value": "71"}, {"type": "inout", "name": "J2D3", "value": "73"}, {"type": "inout", "name": "J2D4", "value": "78"}, {"type": "inout", "name": "J2D5", "value": "80"}, {"type": "inout", "name": "J2D6", "value": "82"}, {"type": "inout", "name": "J2D7", "value": "85"}, {"type": "inout", "name": "J2D8", "value": "87"}, {"type": "inout", "name": "J4U1", "value": "89"}, {"type": "inout", "name": "J4U2", "value": "91"}, {"type": "inout", "name": "J4U3", "value": "94"}, {"type": "inout", "name": "J4U4", "value": "96"}, {"type": "inout", "name": "J4U5", "value": "99"}, {"type": "inout", "name": "J4U6", "value": "12"}, {"type": "inout", "name": "J4U8", "value": "18"}, {"type": "inout", "name": "J4D1", "value": "90"}, {"type": "inout", "name": "J4D2", "value": "93"}, {"type": "inout", "name": "J4D3", "value": "95"}, {"type": "inout", "name": "J4D4", "value": "97"}, {"type": "inout", "name": "J4D5", "value": "100"}, {"type": "inout", "name": "J4D6", "value": "15"}, {"type": "inout", "name": "J4D7", "value": "16"}, {"type": "inout", "name": "J4D8", "value": "19"}, {"type": "inout", "name": "D11", "value": "64"}, {"type": "inout", "name": "D10", "value": "62"}, {"type": "inout", "name": "D9", "value": "42"}, {"type": "inout", "name": "D8", "value": "40"}, {"type": "inout", "name": "D7", "value": "36"}, {"type": "inout", "name": "D6", "value": "30"}, {"type": "inout", "name": "D5", "value": "65"}, {"type": "inout", "name": "D4", "value": "63"}, {"type": "inout", "name": "D3", "value": "41"}, {"type": "inout", "name": "D2", "value": "37"}, {"type": "inout", "name": "D1", "value": "34"}, {"type": "inout", "name": "D0", "value": "29"}, {"type": "inout", "name": "J6R1", "value": "25"}, {"type": "inout", "name": "J6R2", "value": "24"}, {"type": "inout", "name": "J6R3", "value": "21"}, {"type": "inout", "name": "J6R4", "value": "20"}, {"type": "inout", "name": "J6L1", "value": "26"}, {"type": "inout", "name": "J6L2", "value": "27"}, {"type": "inout", "name": "J6L3", "value": "28"}, {"type": "inout", "name": "J6L4", "value": "33"}, {"type": "inout", "name": "J1R1", "value": "10"}, {"type": "inout", "name": "J1R2", "value": "9"}, {"type": "inout", "name": "J1R3", "value": "8"}, {"type": "inout", "name": "J1R4", "value": "7"}, {"type": "inout", "name": "J1L1", "value": "4"}, {"type": "inout", "name": "J1L2", "value": "3"}, {"type": "inout", "name": "J1L3", "value": "2"}, {"type": "inout", "name": "J1L4", "value": "1"}, {"type": "inout", "name": "SS", "value": "49"}, {"type": "inout", "name": "SO", "value": "45"}, {"type": "inout", "name": "SI", "value": "46"}, {"type": "inout", "name": "SCK", "value": "48"}] \ No newline at end of file diff --git a/app/resources/boards/_iCEblink40-HX1K/pinout.pcf b/app/resources/boards/_iCEblink40-HX1K/pinout.pcf index 49c40d2f2..57051fa83 100644 --- a/app/resources/boards/_iCEblink40-HX1K/pinout.pcf +++ b/app/resources/boards/_iCEblink40-HX1K/pinout.pcf @@ -12,19 +12,19 @@ # -------------------------- System Clock ------------------------------------- -set_io --warn-no-port CLK 13 # JP3.1 [Config: JP2.1 JP2.2 JP2.3 -> NCC=333kHz, NNN=3.33MHz, CCN=33.3MHz] +set_io --warn-no-port CLK 13 # input JP3.1 [Config: JP2.1 JP2.2 JP2.3 -> NCC=333kHz, NNN=3.33MHz, CCN=33.3MHz] # ------------ User Leds ------------------------------------------------------ -set_io --warn-no-port LED1 59 # J12.1 -set_io --warn-no-port LED2 56 # J12.2 -set_io --warn-no-port LED3 53 # J12.3 -set_io --warn-no-port LED4 51 # J12.4 +set_io --warn-no-port LED1 59 # output J12.1 +set_io --warn-no-port LED2 56 # output J12.2 +set_io --warn-no-port LED3 53 # output J12.3 +set_io --warn-no-port LED4 51 # output J12.4 # ------------ Capacitive buttons --------------------------------------------- -set_io --warn-no-port BTN1 60 # Capacitive button 1 -set_io --warn-no-port BTN2 57 # Capacitive button 2 -set_io --warn-no-port BTN3 54 # Capacitive button 3 -set_io --warn-no-port BTN4 52 # Capacitive button 4 +set_io --warn-no-port BTN1 60 # input Capacitive button 1 +set_io --warn-no-port BTN2 57 # input Capacitive button 2 +set_io --warn-no-port BTN3 54 # input Capacitive button 3 +set_io --warn-no-port BTN4 52 # input Capacitive button 4 # ----------------- Pins I/O -------------------------------------------------- set_io --warn-no-port J2U1 66 # J2.1 diff --git a/app/resources/boards/_iCEblink40-HX1K/rules.json b/app/resources/boards/_iCEblink40-HX1K/rules.json new file mode 100644 index 000000000..b06669765 --- /dev/null +++ b/app/resources/boards/_iCEblink40-HX1K/rules.json @@ -0,0 +1,26 @@ +{ + "input" : [ + { + "port" : "clk", + "pin": "13" + } + ], + "output": [ + { + "pin": "59", + "bit": "0" + }, + { + "pin": "56", + "bit": "0" + }, + { + "pin": "53", + "bit": "0" + }, + { + "pin": "51", + "bit": "0" + } + ] +} diff --git a/app/resources/boards/generator.py b/app/resources/boards/generator.py index e7feb28ad..7382000c9 100755 --- a/app/resources/boards/generator.py +++ b/app/resources/boards/generator.py @@ -1,10 +1,12 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # -- This script generates a board json file from a pcf -# -- Author Jesús Arroyo (C) 2016 +# -- Author Jesús Arroyo (C) 2016-2017 # -- Licence GPLv2 -# set_io --warn-no-port LED1 C8 -> { "name": "LED1", "value": "C8" }, +# set_io LED0 95 # output -> { "name": "LED0", "value": "95", "type": "output" } +# set_io --warn-no-port SW1 10 # input -> { "name": "SW1", "value": "10", "type": "input" } +# set_io --warn-no-port D13 144 -> { "name": "D13", "value": "144", "type": "inout" } import os import re @@ -23,7 +25,7 @@ name = input('Insert board name: ') # eg. icoboard # Regex pattern -pattern = 'set_io\s--warn-no-port\s(?P.*?)\s+(?P.*?)\s' +pattern = 'set_io\s+(--warn-no-port)?\s*(.*?)\s+(.*?)\s+(#+\s+(input|output))?' # Open file with open(os.path.join(name, 'pinout.pcf')) as file: @@ -33,7 +35,7 @@ pinout = re.findall(pattern, data) format_pinout = [] for item in pinout: - format_pinout += [{ 'name': item[0], 'value': item[1] }] + format_pinout += [{ 'name': item[1], 'value': item[2], 'type': item[4] or 'inout' }] # Save json file with open(os.path.join(name, 'pinout.json'), 'w') as outfile: diff --git a/app/resources/boards/go-board/pinout.json b/app/resources/boards/go-board/pinout.json index 3edd96210..1793fa509 100644 --- a/app/resources/boards/go-board/pinout.json +++ b/app/resources/boards/go-board/pinout.json @@ -1 +1 @@ -[{"name": "LED1", "value": "56"}, {"name": "LED2", "value": "57"}, {"name": "LED3", "value": "59"}, {"name": "LED4", "value": "60"}, {"name": "SW1", "value": "53"}, {"name": "SW2", "value": "51"}, {"name": "SW3", "value": "54"}, {"name": "SW4", "value": "52"}, {"name": "S1_A", "value": "3"}, {"name": "S1_B", "value": "4"}, {"name": "S1_C", "value": "93"}, {"name": "S1_D", "value": "91"}, {"name": "S1_E", "value": "90"}, {"name": "S1_F", "value": "1"}, {"name": "S1_G", "value": "2"}, {"name": "S2_A", "value": "100"}, {"name": "S2_B", "value": "99"}, {"name": "S2_C", "value": "97"}, {"name": "S2_D", "value": "95"}, {"name": "S2_E", "value": "94"}, {"name": "S2_F", "value": "8"}, {"name": "S2_G", "value": "96"}, {"name": "CLK", "value": "15"}, {"name": "RX", "value": "73"}, {"name": "TX", "value": "74"}, {"name": "VGA_HS", "value": "26"}, {"name": "VGA_VS", "value": "27"}, {"name": "VGA_R0", "value": "36"}, {"name": "VGA_R1", "value": "37"}, {"name": "VGA_R2", "value": "40"}, {"name": "VGA_G0", "value": "29"}, {"name": "VGA_G1", "value": "30"}, {"name": "VGA_G2", "value": "33"}, {"name": "VGA_B0", "value": "28"}, {"name": "VGA_B1", "value": "41"}, {"name": "VGA_B2", "value": "42"}, {"name": "PMOD1", "value": "65"}, {"name": "PMOD2", "value": "64"}, {"name": "PMOD3", "value": "63"}, {"name": "PMOD4", "value": "62"}, {"name": "PMOD7", "value": "78"}, {"name": "PMOD8", "value": "79"}, {"name": "PMOD9", "value": "80"}, {"name": "PMOD10", "value": "81"}] \ No newline at end of file +[{"type": "output", "name": "LED1", "value": "56"}, {"type": "output", "name": "LED2", "value": "57"}, {"type": "output", "name": "LED3", "value": "59"}, {"type": "output", "name": "LED4", "value": "60"}, {"type": "input", "name": "SW1", "value": "53"}, {"type": "input", "name": "SW2", "value": "51"}, {"type": "input", "name": "SW3", "value": "54"}, {"type": "input", "name": "SW4", "value": "52"}, {"type": "output", "name": "S1_A", "value": "3"}, {"type": "output", "name": "S1_B", "value": "4"}, {"type": "output", "name": "S1_C", "value": "93"}, {"type": "output", "name": "S1_D", "value": "91"}, {"type": "output", "name": "S1_E", "value": "90"}, {"type": "output", "name": "S1_F", "value": "1"}, {"type": "output", "name": "S1_G", "value": "2"}, {"type": "output", "name": "S2_A", "value": "100"}, {"type": "output", "name": "S2_B", "value": "99"}, {"type": "output", "name": "S2_C", "value": "97"}, {"type": "output", "name": "S2_D", "value": "95"}, {"type": "output", "name": "S2_E", "value": "94"}, {"type": "output", "name": "S2_F", "value": "8"}, {"type": "output", "name": "S2_G", "value": "96"}, {"type": "input", "name": "CLK", "value": "15"}, {"type": "input", "name": "RX", "value": "73"}, {"type": "output", "name": "TX", "value": "74"}, {"type": "output", "name": "VGA_HS", "value": "26"}, {"type": "output", "name": "VGA_VS", "value": "27"}, {"type": "output", "name": "VGA_R0", "value": "36"}, {"type": "output", "name": "VGA_R1", "value": "37"}, {"type": "output", "name": "VGA_R2", "value": "40"}, {"type": "output", "name": "VGA_G0", "value": "29"}, {"type": "output", "name": "VGA_G1", "value": "30"}, {"type": "output", "name": "VGA_G2", "value": "33"}, {"type": "output", "name": "VGA_B0", "value": "28"}, {"type": "output", "name": "VGA_B1", "value": "41"}, {"type": "output", "name": "VGA_B2", "value": "42"}, {"type": "inout", "name": "PMOD1", "value": "65"}, {"type": "inout", "name": "PMOD2", "value": "64"}, {"type": "inout", "name": "PMOD3", "value": "63"}, {"type": "inout", "name": "PMOD4", "value": "62"}, {"type": "inout", "name": "PMOD7", "value": "78"}, {"type": "inout", "name": "PMOD8", "value": "79"}, {"type": "inout", "name": "PMOD9", "value": "80"}, {"type": "inout", "name": "PMOD10", "value": "81"}] \ No newline at end of file diff --git a/app/resources/boards/go-board/pinout.pcf b/app/resources/boards/go-board/pinout.pcf index 87a6a8d07..171affdf2 100644 --- a/app/resources/boards/go-board/pinout.pcf +++ b/app/resources/boards/go-board/pinout.pcf @@ -11,53 +11,53 @@ # -- Pinout: https://www.nandland.com/goboard/images/Go_Board_V1.pdf # ------------ User Leds ------------------------------------------------------ -set_io --warn-no-port LED1 56 -set_io --warn-no-port LED2 57 -set_io --warn-no-port LED3 59 -set_io --warn-no-port LED4 60 +set_io --warn-no-port LED1 56 # output +set_io --warn-no-port LED2 57 # output +set_io --warn-no-port LED3 59 # output +set_io --warn-no-port LED4 60 # output # ------------ User push-buttons ---------------------------------------------- -set_io --warn-no-port SW1 53 -set_io --warn-no-port SW2 51 -set_io --warn-no-port SW3 54 -set_io --warn-no-port SW4 52 +set_io --warn-no-port SW1 53 # input +set_io --warn-no-port SW2 51 # input +set_io --warn-no-port SW3 54 # input +set_io --warn-no-port SW4 52 # input # ------------ 7 segments ----------------------------------------------------- -set_io --warn-no-port S1_A 3 -set_io --warn-no-port S1_B 4 -set_io --warn-no-port S1_C 93 -set_io --warn-no-port S1_D 91 -set_io --warn-no-port S1_E 90 -set_io --warn-no-port S1_F 1 -set_io --warn-no-port S1_G 2 +set_io --warn-no-port S1_A 3 # output +set_io --warn-no-port S1_B 4 # output +set_io --warn-no-port S1_C 93 # output +set_io --warn-no-port S1_D 91 # output +set_io --warn-no-port S1_E 90 # output +set_io --warn-no-port S1_F 1 # output +set_io --warn-no-port S1_G 2 # output -set_io --warn-no-port S2_A 100 -set_io --warn-no-port S2_B 99 -set_io --warn-no-port S2_C 97 -set_io --warn-no-port S2_D 95 -set_io --warn-no-port S2_E 94 -set_io --warn-no-port S2_F 8 -set_io --warn-no-port S2_G 96 +set_io --warn-no-port S2_A 100 # output +set_io --warn-no-port S2_B 99 # output +set_io --warn-no-port S2_C 97 # output +set_io --warn-no-port S2_D 95 # output +set_io --warn-no-port S2_E 94 # output +set_io --warn-no-port S2_F 8 # output +set_io --warn-no-port S2_G 96 # output # -------------------------- SYSTEM CLOCK ------------------------------------- -set_io --warn-no-port CLK 15 +set_io --warn-no-port CLK 15 # input # -------------------------- UART --------------------------------------------- -set_io --warn-no-port RX 73 -set_io --warn-no-port TX 74 +set_io --warn-no-port RX 73 # input +set_io --warn-no-port TX 74 # output # -------------------------- VGA ---------------------------------------------- -set_io --warn-no-port VGA_HS 26 -set_io --warn-no-port VGA_VS 27 -set_io --warn-no-port VGA_R0 36 -set_io --warn-no-port VGA_R1 37 -set_io --warn-no-port VGA_R2 40 -set_io --warn-no-port VGA_G0 29 -set_io --warn-no-port VGA_G1 30 -set_io --warn-no-port VGA_G2 33 -set_io --warn-no-port VGA_B0 28 -set_io --warn-no-port VGA_B1 41 -set_io --warn-no-port VGA_B2 42 +set_io --warn-no-port VGA_HS 26 # output +set_io --warn-no-port VGA_VS 27 # output +set_io --warn-no-port VGA_R0 36 # output +set_io --warn-no-port VGA_R1 37 # output +set_io --warn-no-port VGA_R2 40 # output +set_io --warn-no-port VGA_G0 29 # output +set_io --warn-no-port VGA_G1 30 # output +set_io --warn-no-port VGA_G2 33 # output +set_io --warn-no-port VGA_B0 28 # output +set_io --warn-no-port VGA_B1 41 # output +set_io --warn-no-port VGA_B2 42 # output # ------------ PMOD connector ------------------------------------------------- # diff --git a/app/resources/boards/go-board/rules.json b/app/resources/boards/go-board/rules.json new file mode 100644 index 000000000..cd03b8058 --- /dev/null +++ b/app/resources/boards/go-board/rules.json @@ -0,0 +1,26 @@ +{ + "input" : [ + { + "port" : "clk", + "pin": "15" + } + ], + "output": [ + { + "pin": "56", + "bit": "0" + }, + { + "pin": "57", + "bit": "0" + }, + { + "pin": "59", + "bit": "0" + }, + { + "pin": "60", + "bit": "0" + } + ] +} diff --git a/app/resources/boards/iCE40-HX8K/pinout.json b/app/resources/boards/iCE40-HX8K/pinout.json index a537f2df7..916be13b9 100644 --- a/app/resources/boards/iCE40-HX8K/pinout.json +++ b/app/resources/boards/iCE40-HX8K/pinout.json @@ -1 +1 @@ -[{"name": "LED0", "value": "B5"}, {"name": "LED1", "value": "B4"}, {"name": "LED2", "value": "A2"}, {"name": "LED3", "value": "A1"}, {"name": "LED4", "value": "C5"}, {"name": "LED5", "value": "C4"}, {"name": "LED6", "value": "B3"}, {"name": "LED7", "value": "C3"}, {"name": "CLK", "value": "J3"}, {"name": "MISO", "value": "P12"}, {"name": "MOSI", "value": "P11"}, {"name": "SCK", "value": "R11"}, {"name": "SS", "value": "R12"}, {"name": "RTS", "value": "B13"}, {"name": "RESET", "value": "N11"}, {"name": "DONE", "value": "M10"}, {"name": "TX", "value": "B12"}, {"name": "RX", "value": "B10"}, {"name": "DCD", "value": "B15"}, {"name": "DSR", "value": "B14"}, {"name": "DTR", "value": "A16"}, {"name": "CTS", "value": "A15"}, {"name": "A16", "value": "A16"}, {"name": "A15", "value": "A15"}, {"name": "B15", "value": "B15"}, {"name": "B13", "value": "B13"}, {"name": "B14", "value": "B14"}, {"name": "B12", "value": "B12"}, {"name": "B11", "value": "B11"}, {"name": "A11", "value": "A11"}, {"name": "B10", "value": "B10"}, {"name": "A10", "value": "A10"}, {"name": "C9", "value": "C9"}, {"name": "A9", "value": "A9"}, {"name": "B9", "value": "B9"}, {"name": "B8", "value": "B8"}, {"name": "A7", "value": "A7"}, {"name": "B7", "value": "B7"}, {"name": "C7", "value": "C7"}, {"name": "A6", "value": "A6"}, {"name": "C6", "value": "C6"}, {"name": "B6", "value": "B6"}, {"name": "C5", "value": "C5"}, {"name": "A5", "value": "A5"}, {"name": "C4", "value": "C4"}, {"name": "B5", "value": "B5"}, {"name": "C3", "value": "C3"}, {"name": "B4", "value": "B4"}, {"name": "B3", "value": "B3"}, {"name": "A2", "value": "A2"}, {"name": "A1", "value": "A1"}, {"name": "R15", "value": "R15"}, {"name": "P16", "value": "P16"}, {"name": "P15", "value": "P15"}, {"name": "N16", "value": "N16"}, {"name": "M15", "value": "M15"}, {"name": "M16", "value": "M16"}, {"name": "L16", "value": "L16"}, {"name": "K15", "value": "K15"}, {"name": "K16", "value": "K16"}, {"name": "K14", "value": "K14"}, {"name": "J14", "value": "J14"}, {"name": "G14", "value": "G14"}, {"name": "F14", "value": "F14"}, {"name": "J15", "value": "J15"}, {"name": "H14", "value": "H14"}, {"name": "H16", "value": "H16"}, {"name": "G15", "value": "G15"}, {"name": "G16", "value": "G16"}, {"name": "F15", "value": "F15"}, {"name": "F16", "value": "F16"}, {"name": "E14", "value": "E14"}, {"name": "E16", "value": "E16"}, {"name": "D15", "value": "D15"}, {"name": "D16", "value": "D16"}, {"name": "D14", "value": "D14"}, {"name": "C16", "value": "C16"}, {"name": "B16", "value": "B16"}, {"name": "R16", "value": "R16"}, {"name": "T15", "value": "T15"}, {"name": "T16", "value": "T16"}, {"name": "T13", "value": "T13"}, {"name": "T14", "value": "T14"}, {"name": "N12", "value": "N12"}, {"name": "P13", "value": "P13"}, {"name": "N10", "value": "N10"}, {"name": "M11", "value": "M11"}, {"name": "T11", "value": "T11"}, {"name": "P10", "value": "P10"}, {"name": "T10", "value": "T10"}, {"name": "R10", "value": "R10"}, {"name": "P8", "value": "P8"}, {"name": "P9", "value": "P9"}, {"name": "T9", "value": "T9"}, {"name": "R9", "value": "R9"}, {"name": "T7", "value": "T7"}, {"name": "T8", "value": "T8"}, {"name": "T6", "value": "T6"}, {"name": "R6", "value": "R6"}, {"name": "T5", "value": "T5"}, {"name": "R5", "value": "R5"}, {"name": "R3", "value": "R3"}, {"name": "R4", "value": "R4"}, {"name": "R2", "value": "R2"}, {"name": "T3", "value": "T3"}, {"name": "T1", "value": "T1"}, {"name": "T2", "value": "T2"}, {"name": "R1", "value": "R1"}, {"name": "P1", "value": "P1"}, {"name": "P2", "value": "P2"}, {"name": "N3", "value": "N3"}, {"name": "N2", "value": "N2"}, {"name": "M2", "value": "M2"}, {"name": "M1", "value": "M1"}, {"name": "L3", "value": "L3"}, {"name": "L1", "value": "L1"}, {"name": "K3", "value": "K3"}, {"name": "K1", "value": "K1"}, {"name": "J2", "value": "J2"}, {"name": "J1", "value": "J1"}, {"name": "H2", "value": "H2"}, {"name": "J3", "value": "J3"}, {"name": "G2", "value": "G2"}, {"name": "H1", "value": "H1"}, {"name": "F2", "value": "F2"}, {"name": "G1", "value": "G1"}, {"name": "E2", "value": "E2"}, {"name": "F1", "value": "F1"}, {"name": "D1", "value": "D1"}, {"name": "D2", "value": "D2"}, {"name": "C1", "value": "C1"}, {"name": "C2", "value": "C2"}, {"name": "B1", "value": "B1"}, {"name": "B2", "value": "B2"}] \ No newline at end of file +[{"type": "output", "name": "LED0", "value": "B5"}, {"type": "output", "name": "LED1", "value": "B4"}, {"type": "output", "name": "LED2", "value": "A2"}, {"type": "output", "name": "LED3", "value": "A1"}, {"type": "output", "name": "LED4", "value": "C5"}, {"type": "output", "name": "LED5", "value": "C4"}, {"type": "output", "name": "LED6", "value": "B3"}, {"type": "output", "name": "LED7", "value": "C3"}, {"type": "input", "name": "CLK", "value": "J3"}, {"type": "input", "name": "MISO", "value": "P12"}, {"type": "output", "name": "MOSI", "value": "P11"}, {"type": "output", "name": "SCK", "value": "R11"}, {"type": "output", "name": "SS", "value": "R12"}, {"type": "output", "name": "RTS", "value": "B13"}, {"type": "input", "name": "RESET", "value": "N11"}, {"type": "output", "name": "DONE", "value": "M10"}, {"type": "output", "name": "TX", "value": "B12"}, {"type": "input", "name": "RX", "value": "B10"}, {"type": "output", "name": "DCD", "value": "B15"}, {"type": "output", "name": "DSR", "value": "B14"}, {"type": "input", "name": "DTR", "value": "A16"}, {"type": "output", "name": "CTS", "value": "A15"}, {"type": "inout", "name": "A16", "value": "A16"}, {"type": "inout", "name": "A15", "value": "A15"}, {"type": "inout", "name": "B15", "value": "B15"}, {"type": "inout", "name": "B13", "value": "B13"}, {"type": "inout", "name": "B14", "value": "B14"}, {"type": "inout", "name": "B12", "value": "B12"}, {"type": "inout", "name": "B11", "value": "B11"}, {"type": "inout", "name": "A11", "value": "A11"}, {"type": "inout", "name": "B10", "value": "B10"}, {"type": "inout", "name": "A10", "value": "A10"}, {"type": "inout", "name": "C9", "value": "C9"}, {"type": "inout", "name": "A9", "value": "A9"}, {"type": "inout", "name": "B9", "value": "B9"}, {"type": "inout", "name": "B8", "value": "B8"}, {"type": "inout", "name": "A7", "value": "A7"}, {"type": "inout", "name": "B7", "value": "B7"}, {"type": "inout", "name": "C7", "value": "C7"}, {"type": "inout", "name": "A6", "value": "A6"}, {"type": "inout", "name": "C6", "value": "C6"}, {"type": "inout", "name": "B6", "value": "B6"}, {"type": "inout", "name": "C5", "value": "C5"}, {"type": "inout", "name": "A5", "value": "A5"}, {"type": "inout", "name": "C4", "value": "C4"}, {"type": "inout", "name": "B5", "value": "B5"}, {"type": "inout", "name": "C3", "value": "C3"}, {"type": "inout", "name": "B4", "value": "B4"}, {"type": "inout", "name": "B3", "value": "B3"}, {"type": "inout", "name": "A2", "value": "A2"}, {"type": "inout", "name": "A1", "value": "A1"}, {"type": "inout", "name": "R15", "value": "R15"}, {"type": "inout", "name": "P16", "value": "P16"}, {"type": "inout", "name": "P15", "value": "P15"}, {"type": "inout", "name": "N16", "value": "N16"}, {"type": "inout", "name": "M15", "value": "M15"}, {"type": "inout", "name": "M16", "value": "M16"}, {"type": "inout", "name": "L16", "value": "L16"}, {"type": "inout", "name": "K15", "value": "K15"}, {"type": "inout", "name": "K16", "value": "K16"}, {"type": "inout", "name": "K14", "value": "K14"}, {"type": "inout", "name": "J14", "value": "J14"}, {"type": "inout", "name": "G14", "value": "G14"}, {"type": "inout", "name": "F14", "value": "F14"}, {"type": "inout", "name": "J15", "value": "J15"}, {"type": "inout", "name": "H14", "value": "H14"}, {"type": "inout", "name": "H16", "value": "H16"}, {"type": "inout", "name": "G15", "value": "G15"}, {"type": "inout", "name": "G16", "value": "G16"}, {"type": "inout", "name": "F15", "value": "F15"}, {"type": "inout", "name": "F16", "value": "F16"}, {"type": "inout", "name": "E14", "value": "E14"}, {"type": "inout", "name": "E16", "value": "E16"}, {"type": "inout", "name": "D15", "value": "D15"}, {"type": "inout", "name": "D16", "value": "D16"}, {"type": "inout", "name": "D14", "value": "D14"}, {"type": "inout", "name": "C16", "value": "C16"}, {"type": "inout", "name": "B16", "value": "B16"}, {"type": "inout", "name": "R16", "value": "R16"}, {"type": "inout", "name": "T15", "value": "T15"}, {"type": "inout", "name": "T16", "value": "T16"}, {"type": "inout", "name": "T13", "value": "T13"}, {"type": "inout", "name": "T14", "value": "T14"}, {"type": "inout", "name": "N12", "value": "N12"}, {"type": "inout", "name": "P13", "value": "P13"}, {"type": "inout", "name": "N10", "value": "N10"}, {"type": "inout", "name": "M11", "value": "M11"}, {"type": "inout", "name": "T11", "value": "T11"}, {"type": "inout", "name": "P10", "value": "P10"}, {"type": "inout", "name": "T10", "value": "T10"}, {"type": "inout", "name": "R10", "value": "R10"}, {"type": "inout", "name": "P8", "value": "P8"}, {"type": "inout", "name": "P9", "value": "P9"}, {"type": "inout", "name": "T9", "value": "T9"}, {"type": "inout", "name": "R9", "value": "R9"}, {"type": "inout", "name": "T7", "value": "T7"}, {"type": "inout", "name": "T8", "value": "T8"}, {"type": "inout", "name": "T6", "value": "T6"}, {"type": "inout", "name": "R6", "value": "R6"}, {"type": "inout", "name": "T5", "value": "T5"}, {"type": "inout", "name": "R5", "value": "R5"}, {"type": "inout", "name": "R3", "value": "R3"}, {"type": "inout", "name": "R4", "value": "R4"}, {"type": "inout", "name": "R2", "value": "R2"}, {"type": "inout", "name": "T3", "value": "T3"}, {"type": "inout", "name": "T1", "value": "T1"}, {"type": "inout", "name": "T2", "value": "T2"}, {"type": "inout", "name": "R1", "value": "R1"}, {"type": "inout", "name": "P1", "value": "P1"}, {"type": "inout", "name": "P2", "value": "P2"}, {"type": "inout", "name": "N3", "value": "N3"}, {"type": "inout", "name": "N2", "value": "N2"}, {"type": "inout", "name": "M2", "value": "M2"}, {"type": "inout", "name": "M1", "value": "M1"}, {"type": "inout", "name": "L3", "value": "L3"}, {"type": "inout", "name": "L1", "value": "L1"}, {"type": "inout", "name": "K3", "value": "K3"}, {"type": "inout", "name": "K1", "value": "K1"}, {"type": "inout", "name": "J2", "value": "J2"}, {"type": "inout", "name": "J1", "value": "J1"}, {"type": "inout", "name": "H2", "value": "H2"}, {"type": "inout", "name": "J3", "value": "J3"}, {"type": "inout", "name": "G2", "value": "G2"}, {"type": "inout", "name": "H1", "value": "H1"}, {"type": "inout", "name": "F2", "value": "F2"}, {"type": "inout", "name": "G1", "value": "G1"}, {"type": "inout", "name": "E2", "value": "E2"}, {"type": "inout", "name": "F1", "value": "F1"}, {"type": "inout", "name": "D1", "value": "D1"}, {"type": "inout", "name": "D2", "value": "D2"}, {"type": "inout", "name": "C1", "value": "C1"}, {"type": "inout", "name": "C2", "value": "C2"}, {"type": "inout", "name": "B1", "value": "B1"}, {"type": "inout", "name": "B2", "value": "B2"}] \ No newline at end of file diff --git a/app/resources/boards/iCE40-HX8K/pinout.pcf b/app/resources/boards/iCE40-HX8K/pinout.pcf index 4e5bb62b8..d4b51d6e8 100644 --- a/app/resources/boards/iCE40-HX8K/pinout.pcf +++ b/app/resources/boards/iCE40-HX8K/pinout.pcf @@ -7,38 +7,38 @@ #---------------------------- LEDS -------------------------------------------- -set_io --warn-no-port LED0 B5 -set_io --warn-no-port LED1 B4 -set_io --warn-no-port LED2 A2 -set_io --warn-no-port LED3 A1 -set_io --warn-no-port LED4 C5 -set_io --warn-no-port LED5 C4 -set_io --warn-no-port LED6 B3 -set_io --warn-no-port LED7 C3 +set_io --warn-no-port LED0 B5 # output +set_io --warn-no-port LED1 B4 # output +set_io --warn-no-port LED2 A2 # output +set_io --warn-no-port LED3 A1 # output +set_io --warn-no-port LED4 C5 # output +set_io --warn-no-port LED5 C4 # output +set_io --warn-no-port LED6 B3 # output +set_io --warn-no-port LED7 C3 # output # -------------------------- SYSTEM CLOCK ------------------------------------- -set_io --warn-no-port CLK J3 +set_io --warn-no-port CLK J3 # input # ------------------------------ FTDI 0 --------------------------------------- # SPI -set_io --warn-no-port MISO P12 -set_io --warn-no-port MOSI P11 -set_io --warn-no-port SCK R11 -set_io --warn-no-port SS R12 #J7.1 -set_io --warn-no-port RTS B13 +set_io --warn-no-port MISO P12 # input +set_io --warn-no-port MOSI P11 # output +set_io --warn-no-port SCK R11 # output +set_io --warn-no-port SS R12 # output #J7.1 +set_io --warn-no-port RTS B13 # output -set_io --warn-no-port RESET N11 -set_io --warn-no-port DONE M10 +set_io --warn-no-port RESET N11 # input +set_io --warn-no-port DONE M10 # output # ------------------------------ FTDI 1 --------------------------------------- # UART -set_io --warn-no-port TX B12 -set_io --warn-no-port RX B10 -set_io --warn-no-port DCD B15 -set_io --warn-no-port DSR B14 -set_io --warn-no-port DTR A16 -set_io --warn-no-port CTS A15 +set_io --warn-no-port TX B12 # output +set_io --warn-no-port RX B10 # input +set_io --warn-no-port DCD B15 # output +set_io --warn-no-port DSR B14 # output +set_io --warn-no-port DTR A16 # input +set_io --warn-no-port CTS A15 # output # ************************************ diff --git a/app/resources/boards/iCE40-HX8K/rules.json b/app/resources/boards/iCE40-HX8K/rules.json new file mode 100644 index 000000000..9c8f6621d --- /dev/null +++ b/app/resources/boards/iCE40-HX8K/rules.json @@ -0,0 +1,42 @@ +{ + "input" : [ + { + "port" : "clk", + "pin": "J3" + } + ], + "output": [ + { + "pin": "B5", + "bit": "0" + }, + { + "pin": "B4", + "bit": "0" + }, + { + "pin": "A2", + "bit": "0" + }, + { + "pin": "A1", + "bit": "0" + }, + { + "pin": "C5", + "bit": "0" + }, + { + "pin": "C4", + "bit": "0" + }, + { + "pin": "B3", + "bit": "0" + }, + { + "pin": "C3", + "bit": "0" + } + ] +} diff --git a/app/resources/boards/icestick/pinout.json b/app/resources/boards/icestick/pinout.json index b41dce4bf..88b22d63a 100644 --- a/app/resources/boards/icestick/pinout.json +++ b/app/resources/boards/icestick/pinout.json @@ -1 +1 @@ -[{"name": "D1", "value": "99"}, {"name": "D2", "value": "98"}, {"name": "D3", "value": "97"}, {"name": "D4", "value": "96"}, {"name": "D5", "value": "95"}, {"name": "IrDA_TX", "value": "105"}, {"name": "IrDA_RX", "value": "106"}, {"name": "SD", "value": "107"}, {"name": "PMOD1", "value": "78"}, {"name": "PMOD2", "value": "79"}, {"name": "PMOD3", "value": "80"}, {"name": "PMOD4", "value": "81"}, {"name": "PMOD7", "value": "87"}, {"name": "PMOD8", "value": "88"}, {"name": "PMOD9", "value": "90"}, {"name": "PMOD10", "value": "91"}, {"name": "TR3", "value": "112"}, {"name": "TR4", "value": "113"}, {"name": "TR5", "value": "114"}, {"name": "TR6", "value": "115"}, {"name": "TR7", "value": "116"}, {"name": "TR8", "value": "117"}, {"name": "TR9", "value": "118"}, {"name": "TR10", "value": "119"}, {"name": "BR3", "value": "62"}, {"name": "BR4", "value": "61"}, {"name": "BR5", "value": "60"}, {"name": "BR6", "value": "56"}, {"name": "BR7", "value": "48"}, {"name": "BR8", "value": "47"}, {"name": "BR9", "value": "45"}, {"name": "BR10", "value": "44"}, {"name": "CLK", "value": "21"}, {"name": "RES", "value": "66"}, {"name": "DONE", "value": "65"}, {"name": "SS", "value": "71"}, {"name": "MISO", "value": "67"}, {"name": "MOSI", "value": "68"}, {"name": "SCK", "value": "70"}, {"name": "DCD", "value": "1"}, {"name": "DSR", "value": "2"}, {"name": "DTR", "value": "3"}, {"name": "CTS", "value": "4"}, {"name": "RTS", "value": "7"}, {"name": "TX", "value": "8"}, {"name": "RX", "value": "9"}] \ No newline at end of file +[{"type": "output", "name": "D1", "value": "99"}, {"type": "output", "name": "D2", "value": "98"}, {"type": "output", "name": "D3", "value": "97"}, {"type": "output", "name": "D4", "value": "96"}, {"type": "output", "name": "D5", "value": "95"}, {"type": "output", "name": "IrDA_TX", "value": "105"}, {"type": "input", "name": "IrDA_RX", "value": "106"}, {"type": "inout", "name": "SD", "value": "107"}, {"type": "inout", "name": "PMOD1", "value": "78"}, {"type": "inout", "name": "PMOD2", "value": "79"}, {"type": "inout", "name": "PMOD3", "value": "80"}, {"type": "inout", "name": "PMOD4", "value": "81"}, {"type": "inout", "name": "PMOD7", "value": "87"}, {"type": "inout", "name": "PMOD8", "value": "88"}, {"type": "inout", "name": "PMOD9", "value": "90"}, {"type": "inout", "name": "PMOD10", "value": "91"}, {"type": "inout", "name": "TR3", "value": "112"}, {"type": "inout", "name": "TR4", "value": "113"}, {"type": "inout", "name": "TR5", "value": "114"}, {"type": "inout", "name": "TR6", "value": "115"}, {"type": "inout", "name": "TR7", "value": "116"}, {"type": "inout", "name": "TR8", "value": "117"}, {"type": "inout", "name": "TR9", "value": "118"}, {"type": "inout", "name": "TR10", "value": "119"}, {"type": "inout", "name": "BR3", "value": "62"}, {"type": "inout", "name": "BR4", "value": "61"}, {"type": "inout", "name": "BR5", "value": "60"}, {"type": "inout", "name": "BR6", "value": "56"}, {"type": "inout", "name": "BR7", "value": "48"}, {"type": "inout", "name": "BR8", "value": "47"}, {"type": "inout", "name": "BR9", "value": "45"}, {"type": "inout", "name": "BR10", "value": "44"}, {"type": "input", "name": "CLK", "value": "21"}, {"type": "input", "name": "RES", "value": "66"}, {"type": "output", "name": "DONE", "value": "65"}, {"type": "output", "name": "SS", "value": "71"}, {"type": "input", "name": "MISO", "value": "67"}, {"type": "output", "name": "MOSI", "value": "68"}, {"type": "output", "name": "SCK", "value": "70"}, {"type": "output", "name": "DCD", "value": "1"}, {"type": "output", "name": "DSR", "value": "2"}, {"type": "input", "name": "DTR", "value": "3"}, {"type": "output", "name": "CTS", "value": "4"}, {"type": "output", "name": "RTS", "value": "7"}, {"type": "output", "name": "TX", "value": "8"}, {"type": "input", "name": "RX", "value": "9"}] \ No newline at end of file diff --git a/app/resources/boards/icestick/pinout.pcf b/app/resources/boards/icestick/pinout.pcf index 06336e8ac..91bd8ad66 100644 --- a/app/resources/boards/icestick/pinout.pcf +++ b/app/resources/boards/icestick/pinout.pcf @@ -18,17 +18,17 @@ # ------------ Red leds ------------------------------------------------------- -set_io --warn-no-port D1 99 -set_io --warn-no-port D2 98 -set_io --warn-no-port D3 97 -set_io --warn-no-port D4 96 +set_io --warn-no-port D1 99 # output +set_io --warn-no-port D2 98 # output +set_io --warn-no-port D3 97 # output +set_io --warn-no-port D4 96 # output # ------------ Green led ------------------------------------------------------ -set_io --warn-no-port D5 95 +set_io --warn-no-port D5 95 # output # ------------ IrDA ----------------------------------------------------------- -set_io --warn-no-port IrDA_TX 105 -set_io --warn-no-port IrDA_RX 106 +set_io --warn-no-port IrDA_TX 105 # output +set_io --warn-no-port IrDA_RX 106 # input #-- SD = 0, enable IrDA set_io --warn-no-port SD 107 @@ -121,22 +121,22 @@ set_io --warn-no-port BR9 45 set_io --warn-no-port BR10 44 # -------------------------- SYSTEM CLOCK ------------------------------------- -set_io --warn-no-port CLK 21 +set_io --warn-no-port CLK 21 # input # -------------------------- FTDI --------------------------------------------- # --- FTDI 0: -set_io --warn-no-port RES 66 -set_io --warn-no-port DONE 65 -set_io --warn-no-port SS 71 -set_io --warn-no-port MISO 67 -set_io --warn-no-port MOSI 68 -set_io --warn-no-port SCK 70 +set_io --warn-no-port RES 66 # input +set_io --warn-no-port DONE 65 # output +set_io --warn-no-port SS 71 # output +set_io --warn-no-port MISO 67 # input +set_io --warn-no-port MOSI 68 # output +set_io --warn-no-port SCK 70 # output # # --- FTDI 1: (Serial port) -set_io --warn-no-port DCD 1 -set_io --warn-no-port DSR 2 -set_io --warn-no-port DTR 3 -set_io --warn-no-port CTS 4 -set_io --warn-no-port RTS 7 -set_io --warn-no-port TX 8 -set_io --warn-no-port RX 9 +set_io --warn-no-port DCD 1 # output +set_io --warn-no-port DSR 2 # output +set_io --warn-no-port DTR 3 # input +set_io --warn-no-port CTS 4 # output +set_io --warn-no-port RTS 7 # output +set_io --warn-no-port TX 8 # output +set_io --warn-no-port RX 9 # input diff --git a/app/resources/boards/icestick/rules.json b/app/resources/boards/icestick/rules.json new file mode 100644 index 000000000..fcb0d76a0 --- /dev/null +++ b/app/resources/boards/icestick/rules.json @@ -0,0 +1,30 @@ +{ + "input" : [ + { + "port" : "clk", + "pin": "21" + } + ], + "output": [ + { + "pin": "99", + "bit": "0" + }, + { + "pin": "98", + "bit": "0" + }, + { + "pin": "97", + "bit": "0" + }, + { + "pin": "96", + "bit": "0" + }, + { + "pin": "95", + "bit": "0" + } + ] +} diff --git a/app/resources/boards/icezum/pinout.json b/app/resources/boards/icezum/pinout.json index a7fb46502..d8d9f691a 100644 --- a/app/resources/boards/icezum/pinout.json +++ b/app/resources/boards/icezum/pinout.json @@ -1 +1 @@ -[{"name": "LED0", "value": "95"}, {"name": "LED1", "value": "96"}, {"name": "LED2", "value": "97"}, {"name": "LED3", "value": "98"}, {"name": "LED4", "value": "99"}, {"name": "LED5", "value": "101"}, {"name": "LED6", "value": "102"}, {"name": "LED7", "value": "104"}, {"name": "SW1", "value": "10"}, {"name": "SW2", "value": "11"}, {"name": "D13", "value": "144"}, {"name": "D12", "value": "143"}, {"name": "D11", "value": "142"}, {"name": "D10", "value": "141"}, {"name": "D9", "value": "139"}, {"name": "D8", "value": "138"}, {"name": "D7", "value": "112"}, {"name": "D6", "value": "113"}, {"name": "D5", "value": "114"}, {"name": "D4", "value": "115"}, {"name": "D3", "value": "116"}, {"name": "D2", "value": "117"}, {"name": "D1", "value": "118"}, {"name": "D0", "value": "119"}, {"name": "DD0", "value": "78"}, {"name": "DD1", "value": "79"}, {"name": "DD2", "value": "80"}, {"name": "DD3", "value": "81"}, {"name": "DD4", "value": "88"}, {"name": "DD5", "value": "87"}, {"name": "GP0", "value": "37"}, {"name": "GP1", "value": "38"}, {"name": "GP2", "value": "39"}, {"name": "GP3", "value": "41"}, {"name": "GP4", "value": "42"}, {"name": "GP5", "value": "43"}, {"name": "GP6", "value": "49"}, {"name": "GP7", "value": "50"}, {"name": "ADC_SCL", "value": "91"}, {"name": "ADC_SDA", "value": "90"}, {"name": "ADc_INT", "value": "93"}, {"name": "CLK", "value": "21"}, {"name": "RES", "value": "66"}, {"name": "DONE", "value": "65"}, {"name": "SS", "value": "71"}, {"name": "MISO", "value": "67"}, {"name": "MOSI", "value": "68"}, {"name": "SCK", "value": "70"}, {"name": "DCD", "value": "1"}, {"name": "DSR", "value": "2"}, {"name": "DTR", "value": "3"}, {"name": "CTS", "value": "4"}, {"name": "RTS", "value": "7"}, {"name": "TX", "value": "8"}, {"name": "RX", "value": "9"}] \ No newline at end of file +[{"type": "output", "name": "LED0", "value": "95"}, {"type": "output", "name": "LED1", "value": "96"}, {"type": "output", "name": "LED2", "value": "97"}, {"type": "output", "name": "LED3", "value": "98"}, {"type": "output", "name": "LED4", "value": "99"}, {"type": "output", "name": "LED5", "value": "101"}, {"type": "output", "name": "LED6", "value": "102"}, {"type": "output", "name": "LED7", "value": "104"}, {"type": "input", "name": "SW1", "value": "10"}, {"type": "input", "name": "SW2", "value": "11"}, {"type": "inout", "name": "D13", "value": "144"}, {"type": "inout", "name": "D12", "value": "143"}, {"type": "inout", "name": "D11", "value": "142"}, {"type": "inout", "name": "D10", "value": "141"}, {"type": "inout", "name": "D9", "value": "139"}, {"type": "inout", "name": "D8", "value": "138"}, {"type": "inout", "name": "D7", "value": "112"}, {"type": "inout", "name": "D6", "value": "113"}, {"type": "inout", "name": "D5", "value": "114"}, {"type": "inout", "name": "D4", "value": "115"}, {"type": "inout", "name": "D3", "value": "116"}, {"type": "inout", "name": "D2", "value": "117"}, {"type": "inout", "name": "D1", "value": "118"}, {"type": "inout", "name": "D0", "value": "119"}, {"type": "inout", "name": "DD0", "value": "78"}, {"type": "inout", "name": "DD1", "value": "79"}, {"type": "inout", "name": "DD2", "value": "80"}, {"type": "inout", "name": "DD3", "value": "81"}, {"type": "inout", "name": "DD4", "value": "88"}, {"type": "inout", "name": "DD5", "value": "87"}, {"type": "inout", "name": "GP0", "value": "37"}, {"type": "inout", "name": "GP1", "value": "38"}, {"type": "inout", "name": "GP2", "value": "39"}, {"type": "inout", "name": "GP3", "value": "41"}, {"type": "inout", "name": "GP4", "value": "42"}, {"type": "inout", "name": "GP5", "value": "43"}, {"type": "inout", "name": "GP6", "value": "49"}, {"type": "inout", "name": "GP7", "value": "50"}, {"type": "output", "name": "ADC_SCL", "value": "91"}, {"type": "inout", "name": "ADC_SDA", "value": "90"}, {"type": "input", "name": "ADC_INT", "value": "93"}, {"type": "input", "name": "CLK", "value": "21"}, {"type": "input", "name": "RES", "value": "66"}, {"type": "output", "name": "DONE", "value": "65"}, {"type": "output", "name": "SS", "value": "71"}, {"type": "input", "name": "MISO", "value": "67"}, {"type": "output", "name": "MOSI", "value": "68"}, {"type": "output", "name": "SCK", "value": "70"}, {"type": "output", "name": "DCD", "value": "1"}, {"type": "output", "name": "DSR", "value": "2"}, {"type": "input", "name": "DTR", "value": "3"}, {"type": "output", "name": "CTS", "value": "4"}, {"type": "output", "name": "RTS", "value": "7"}, {"type": "output", "name": "TX", "value": "8"}, {"type": "input", "name": "RX", "value": "9"}] \ No newline at end of file diff --git a/app/resources/boards/icezum/pinout.pcf b/app/resources/boards/icezum/pinout.pcf index a3568f334..a18a06d8d 100644 --- a/app/resources/boards/icezum/pinout.pcf +++ b/app/resources/boards/icezum/pinout.pcf @@ -8,18 +8,18 @@ # -- Pinout: https://github.com/FPGAwars/icezum/blob/master/doc/pinout/icezum-pinout.pdf # ------------ User Leds ------------------------------------------------------ -set_io --warn-no-port LED0 95 -set_io --warn-no-port LED1 96 -set_io --warn-no-port LED2 97 -set_io --warn-no-port LED3 98 -set_io --warn-no-port LED4 99 -set_io --warn-no-port LED5 101 -set_io --warn-no-port LED6 102 -set_io --warn-no-port LED7 104 +set_io --warn-no-port LED0 95 # output +set_io --warn-no-port LED1 96 # output +set_io --warn-no-port LED2 97 # output +set_io --warn-no-port LED3 98 # output +set_io --warn-no-port LED4 99 # output +set_io --warn-no-port LED5 101 # output +set_io --warn-no-port LED6 102 # output +set_io --warn-no-port LED7 104 # output # ------------ User push buttons ---------------------------------------------- -set_io --warn-no-port SW1 10 -set_io --warn-no-port SW2 11 +set_io --warn-no-port SW1 10 # input +set_io --warn-no-port SW2 11 # input # ------------ 5v Digital I/O ------------------------------------------------- @@ -85,27 +85,27 @@ set_io --warn-no-port GP6 49 set_io --warn-no-port GP7 50 # -------------------------- I2C ADC ------------------------------------------ -set_io --warn-no-port ADC_SCL 91 +set_io --warn-no-port ADC_SCL 91 # output set_io --warn-no-port ADC_SDA 90 -set_io --warn-no-port ADc_INT 93 +set_io --warn-no-port ADC_INT 93 # input # -------------------------- SYSTEM CLOCK ------------------------------------- -set_io --warn-no-port CLK 21 +set_io --warn-no-port CLK 21 # input # -------------------------- FTDI --------------------------------------------- # --- FTDI 0: -set_io --warn-no-port RES 66 -set_io --warn-no-port DONE 65 -set_io --warn-no-port SS 71 -set_io --warn-no-port MISO 67 -set_io --warn-no-port MOSI 68 -set_io --warn-no-port SCK 70 +set_io --warn-no-port RES 66 # input +set_io --warn-no-port DONE 65 # output +set_io --warn-no-port SS 71 # output +set_io --warn-no-port MISO 67 # input +set_io --warn-no-port MOSI 68 # output +set_io --warn-no-port SCK 70 # output # # --- FTDI 1: (Serial port) -set_io --warn-no-port DCD 1 -set_io --warn-no-port DSR 2 -set_io --warn-no-port DTR 3 -set_io --warn-no-port CTS 4 -set_io --warn-no-port RTS 7 -set_io --warn-no-port TX 8 -set_io --warn-no-port RX 9 +set_io --warn-no-port DCD 1 # output +set_io --warn-no-port DSR 2 # output +set_io --warn-no-port DTR 3 # input +set_io --warn-no-port CTS 4 # output +set_io --warn-no-port RTS 7 # output +set_io --warn-no-port TX 8 # output +set_io --warn-no-port RX 9 # input diff --git a/app/resources/boards/icezum/rules.json b/app/resources/boards/icezum/rules.json new file mode 100644 index 000000000..0d10eb53a --- /dev/null +++ b/app/resources/boards/icezum/rules.json @@ -0,0 +1,42 @@ +{ + "input" : [ + { + "port" : "clk", + "pin": "21" + } + ], + "output": [ + { + "pin": "95", + "bit": "0" + }, + { + "pin": "96", + "bit": "0" + }, + { + "pin": "97", + "bit": "0" + }, + { + "pin": "98", + "bit": "0" + }, + { + "pin": "99", + "bit": "0" + }, + { + "pin": "101", + "bit": "0" + }, + { + "pin": "102", + "bit": "0" + }, + { + "pin": "104", + "bit": "0" + } + ] +} diff --git a/app/resources/boards/icoboard/pinout.json b/app/resources/boards/icoboard/pinout.json index 35e7dfcbf..f987b1615 100644 --- a/app/resources/boards/icoboard/pinout.json +++ b/app/resources/boards/icoboard/pinout.json @@ -1 +1 @@ -[{"name": "CLK", "value": "R9"}, {"name": "LED1", "value": "C8"}, {"name": "LED2", "value": "F7"}, {"name": "LED3", "value": "K9"}, {"name": "P10", "value": "B4"}, {"name": "P11", "value": "C3"}, {"name": "P12", "value": "A2"}, {"name": "P13", "value": "A5"}, {"name": "P14", "value": "B5"}, {"name": "P15", "value": "B3"}, {"name": "P16", "value": "B6"}, {"name": "P17", "value": "B7"}, {"name": "P20", "value": "B11"}, {"name": "P21", "value": "B10"}, {"name": "P22", "value": "B9"}, {"name": "P23", "value": "D8"}, {"name": "P24", "value": "A11"}, {"name": "P25", "value": "A10"}, {"name": "P26", "value": "A9"}, {"name": "P27", "value": "B8"}, {"name": "P30", "value": "N6"}, {"name": "P31", "value": "L7"}, {"name": "P32", "value": "G5"}, {"name": "P33", "value": "L9"}, {"name": "P34", "value": "N7"}, {"name": "P35", "value": "M8"}, {"name": "P36", "value": "P9"}, {"name": "P37", "value": "N9"}, {"name": "P40", "value": "T11"}, {"name": "P41", "value": "T14"}, {"name": "P42", "value": "T15"}, {"name": "P43", "value": "T9"}, {"name": "P44", "value": "T10"}, {"name": "P45", "value": "T13"}, {"name": "P46", "value": "R14"}, {"name": "P47", "value": "R10"}, {"name": "C00", "value": "C13"}, {"name": "C01", "value": "A15"}, {"name": "C02", "value": "L12"}, {"name": "C03", "value": "J16"}, {"name": "C04", "value": "E9"}, {"name": "C05", "value": "C11"}, {"name": "C06", "value": "P14"}, {"name": "C07", "value": "J15"}, {"name": "C08", "value": "B14"}, {"name": "C09", "value": "E10"}, {"name": "C10", "value": "T16"}, {"name": "C11", "value": "J14"}, {"name": "C12", "value": "A16"}, {"name": "C13", "value": "F9"}, {"name": "C14", "value": "F14"}, {"name": "C15", "value": "K16"}, {"name": "C16", "value": "D15"}, {"name": "C17", "value": "B16"}, {"name": "C18", "value": "G13"}, {"name": "C19", "value": "G14"}, {"name": "C20", "value": "D16"}, {"name": "C21", "value": "G11"}, {"name": "C22", "value": "K15"}, {"name": "C23", "value": "L16"}, {"name": "C24", "value": "F16"}, {"name": "C25", "value": "D10"}, {"name": "C26", "value": "H14"}, {"name": "C27", "value": "H13"}, {"name": "C28", "value": "G15"}, {"name": "C29", "value": "D11"}, {"name": "C30", "value": "M16"}, {"name": "C31", "value": "H12"}, {"name": "C32", "value": "G10"}, {"name": "C33", "value": "E11"}, {"name": "C34", "value": "M15"}, {"name": "C35", "value": "N16"}, {"name": "C36", "value": "J10"}, {"name": "C37", "value": "F12"}, {"name": "C38", "value": "J11"}, {"name": "C39", "value": "R16"}, {"name": "C40", "value": "G16"}, {"name": "C41", "value": "E14"}, {"name": "C42", "value": "J13"}, {"name": "C43", "value": "K12"}, {"name": "C44", "value": "H16"}, {"name": "C45", "value": "F11"}, {"name": "C46", "value": "K13"}, {"name": "C47", "value": "K14"}, {"name": "C48", "value": "F15"}, {"name": "C49", "value": "G12"}, {"name": "C50", "value": "L11"}, {"name": "C51", "value": "M9"}, {"name": "C52", "value": "E16"}, {"name": "C53", "value": "B13"}, {"name": "C54", "value": "N12"}, {"name": "C55", "value": "L14"}, {"name": "C56", "value": "D14"}, {"name": "C57", "value": "C12"}, {"name": "C58", "value": "M12"}, {"name": "C59", "value": "M14"}, {"name": "C60", "value": "C16"}, {"name": "C61", "value": "B12"}, {"name": "C62", "value": "R15"}, {"name": "C63", "value": "L10"}] \ No newline at end of file +[{"type": "input", "name": "CLK", "value": "R9"}, {"type": "output", "name": "LED1", "value": "C8"}, {"type": "output", "name": "LED2", "value": "F7"}, {"type": "output", "name": "LED3", "value": "K9"}, {"type": "inout", "name": "P10", "value": "B4"}, {"type": "inout", "name": "P11", "value": "C3"}, {"type": "inout", "name": "P12", "value": "A2"}, {"type": "inout", "name": "P13", "value": "A5"}, {"type": "inout", "name": "P14", "value": "B5"}, {"type": "inout", "name": "P15", "value": "B3"}, {"type": "inout", "name": "P16", "value": "B6"}, {"type": "inout", "name": "P17", "value": "B7"}, {"type": "inout", "name": "P20", "value": "B11"}, {"type": "inout", "name": "P21", "value": "B10"}, {"type": "inout", "name": "P22", "value": "B9"}, {"type": "inout", "name": "P23", "value": "D8"}, {"type": "inout", "name": "P24", "value": "A11"}, {"type": "inout", "name": "P25", "value": "A10"}, {"type": "inout", "name": "P26", "value": "A9"}, {"type": "inout", "name": "P27", "value": "B8"}, {"type": "inout", "name": "P30", "value": "N6"}, {"type": "inout", "name": "P31", "value": "L7"}, {"type": "inout", "name": "P32", "value": "G5"}, {"type": "inout", "name": "P33", "value": "L9"}, {"type": "inout", "name": "P34", "value": "N7"}, {"type": "inout", "name": "P35", "value": "M8"}, {"type": "inout", "name": "P36", "value": "P9"}, {"type": "inout", "name": "P37", "value": "N9"}, {"type": "inout", "name": "P40", "value": "T11"}, {"type": "inout", "name": "P41", "value": "T14"}, {"type": "inout", "name": "P42", "value": "T15"}, {"type": "inout", "name": "P43", "value": "T9"}, {"type": "inout", "name": "P44", "value": "T10"}, {"type": "inout", "name": "P45", "value": "T13"}, {"type": "inout", "name": "P46", "value": "R14"}, {"type": "inout", "name": "P47", "value": "R10"}, {"type": "inout", "name": "C00", "value": "C13"}, {"type": "inout", "name": "C01", "value": "A15"}, {"type": "inout", "name": "C02", "value": "L12"}, {"type": "inout", "name": "C03", "value": "J16"}, {"type": "inout", "name": "C04", "value": "E9"}, {"type": "inout", "name": "C05", "value": "C11"}, {"type": "inout", "name": "C06", "value": "P14"}, {"type": "inout", "name": "C07", "value": "J15"}, {"type": "inout", "name": "C08", "value": "B14"}, {"type": "inout", "name": "C09", "value": "E10"}, {"type": "inout", "name": "C10", "value": "T16"}, {"type": "inout", "name": "C11", "value": "J14"}, {"type": "inout", "name": "C12", "value": "A16"}, {"type": "inout", "name": "C13", "value": "F9"}, {"type": "inout", "name": "C14", "value": "F14"}, {"type": "inout", "name": "C15", "value": "K16"}, {"type": "inout", "name": "C16", "value": "D15"}, {"type": "inout", "name": "C17", "value": "B16"}, {"type": "inout", "name": "C18", "value": "G13"}, {"type": "inout", "name": "C19", "value": "G14"}, {"type": "inout", "name": "C20", "value": "D16"}, {"type": "inout", "name": "C21", "value": "G11"}, {"type": "inout", "name": "C22", "value": "K15"}, {"type": "inout", "name": "C23", "value": "L16"}, {"type": "inout", "name": "C24", "value": "F16"}, {"type": "inout", "name": "C25", "value": "D10"}, {"type": "inout", "name": "C26", "value": "H14"}, {"type": "inout", "name": "C27", "value": "H13"}, {"type": "inout", "name": "C28", "value": "G15"}, {"type": "inout", "name": "C29", "value": "D11"}, {"type": "inout", "name": "C30", "value": "M16"}, {"type": "inout", "name": "C31", "value": "H12"}, {"type": "inout", "name": "C32", "value": "G10"}, {"type": "inout", "name": "C33", "value": "E11"}, {"type": "inout", "name": "C34", "value": "M15"}, {"type": "inout", "name": "C35", "value": "N16"}, {"type": "inout", "name": "C36", "value": "J10"}, {"type": "inout", "name": "C37", "value": "F12"}, {"type": "inout", "name": "C38", "value": "J11"}, {"type": "inout", "name": "C39", "value": "R16"}, {"type": "inout", "name": "C40", "value": "G16"}, {"type": "inout", "name": "C41", "value": "E14"}, {"type": "inout", "name": "C42", "value": "J13"}, {"type": "inout", "name": "C43", "value": "K12"}, {"type": "inout", "name": "C44", "value": "H16"}, {"type": "inout", "name": "C45", "value": "F11"}, {"type": "inout", "name": "C46", "value": "K13"}, {"type": "inout", "name": "C47", "value": "K14"}, {"type": "inout", "name": "C48", "value": "F15"}, {"type": "inout", "name": "C49", "value": "G12"}, {"type": "inout", "name": "C50", "value": "L11"}, {"type": "inout", "name": "C51", "value": "M9"}, {"type": "inout", "name": "C52", "value": "E16"}, {"type": "inout", "name": "C53", "value": "B13"}, {"type": "inout", "name": "C54", "value": "N12"}, {"type": "inout", "name": "C55", "value": "L14"}, {"type": "inout", "name": "C56", "value": "D14"}, {"type": "inout", "name": "C57", "value": "C12"}, {"type": "inout", "name": "C58", "value": "M12"}, {"type": "inout", "name": "C59", "value": "M14"}, {"type": "inout", "name": "C60", "value": "C16"}, {"type": "inout", "name": "C61", "value": "B12"}, {"type": "inout", "name": "C62", "value": "R15"}, {"type": "inout", "name": "C63", "value": "L10"}] \ No newline at end of file diff --git a/app/resources/boards/icoboard/pinout.pcf b/app/resources/boards/icoboard/pinout.pcf index 52ee25490..c421f1b0f 100644 --- a/app/resources/boards/icoboard/pinout.pcf +++ b/app/resources/boards/icoboard/pinout.pcf @@ -8,7 +8,7 @@ # ------------ System clock --------------------------------------------------- -set_io --warn-no-port CLK R9 +set_io --warn-no-port CLK R9 # input # ------------ LEDs map ------------------------------------------------------- @@ -29,11 +29,11 @@ set_io --warn-no-port CLK R9 # -- LED3: Red led # ------------| Green leds |--------------------------------------------------- -set_io --warn-no-port LED1 C8 -set_io --warn-no-port LED2 F7 +set_io --warn-no-port LED1 C8 # output +set_io --warn-no-port LED2 F7 # output # ------------| Red led |------------------------------------------------------ -set_io --warn-no-port LED3 K9 +set_io --warn-no-port LED3 K9 # output # ------------ PMOD connectors ------------------------------------------------ diff --git a/app/resources/boards/icoboard/rules.json b/app/resources/boards/icoboard/rules.json new file mode 100644 index 000000000..fbbff4295 --- /dev/null +++ b/app/resources/boards/icoboard/rules.json @@ -0,0 +1,22 @@ +{ + "input" : [ + { + "port" : "clk", + "pin": "R9" + } + ], + "output": [ + { + "pin": "C8", + "bit": "0" + }, + { + "pin": "F7", + "bit": "0" + }, + { + "pin": "K9", + "bit": "0" + } + ] +} diff --git a/app/resources/boards/kefir/pinout.json b/app/resources/boards/kefir/pinout.json index 04ee67661..1a9d46ba9 100644 --- a/app/resources/boards/kefir/pinout.json +++ b/app/resources/boards/kefir/pinout.json @@ -1 +1 @@ -[{"name": "BTN1", "value": "136"}, {"name": "BTN2", "value": "134"}, {"name": "BTN3", "value": "128"}, {"name": "BTN4", "value": "122"}, {"name": "LED1", "value": "137"}, {"name": "LED2", "value": "135"}, {"name": "LED3", "value": "129"}, {"name": "LED4", "value": "121"}, {"name": "CLK", "value": "49"}, {"name": "SS_B", "value": "71"}, {"name": "AD_CS", "value": "101"}, {"name": "AD_Din", "value": "102"}, {"name": "AD_Dout", "value": "104"}, {"name": "AD_Clk", "value": "105"}, {"name": "USB_Vp_o", "value": "112"}, {"name": "USB_Vm_o", "value": "113"}, {"name": "USB_Vm_i", "value": "114"}, {"name": "USB_Vp_i", "value": "115"}, {"name": "USB_nOE", "value": "116"}, {"name": "ARDU00", "value": "138"}, {"name": "ARDU01", "value": "141"}, {"name": "ARDU02", "value": "143"}, {"name": "ARDU03", "value": "1"}, {"name": "RESET_P2", "value": "73"}, {"name": "Milk_TXD", "value": "37"}, {"name": "Milk_RXD", "value": "38"}] \ No newline at end of file +[{"type": "input", "name": "BTN1", "value": "136"}, {"type": "input", "name": "BTN2", "value": "134"}, {"type": "input", "name": "BTN3", "value": "128"}, {"type": "input", "name": "BTN4", "value": "122"}, {"type": "output", "name": "LED1", "value": "137"}, {"type": "output", "name": "LED2", "value": "135"}, {"type": "output", "name": "LED3", "value": "129"}, {"type": "output", "name": "LED4", "value": "121"}, {"type": "input", "name": "CLK", "value": "49"}, {"type": "inout", "name": "SS_B", "value": "71"}, {"type": "inout", "name": "AD_CS", "value": "101"}, {"type": "inout", "name": "AD_Din", "value": "102"}, {"type": "inout", "name": "AD_Dout", "value": "104"}, {"type": "inout", "name": "AD_Clk", "value": "105"}, {"type": "inout", "name": "USB_Vp_o", "value": "112"}, {"type": "inout", "name": "USB_Vm_o", "value": "113"}, {"type": "inout", "name": "USB_Vm_i", "value": "114"}, {"type": "inout", "name": "USB_Vp_i", "value": "115"}, {"type": "inout", "name": "USB_nOE", "value": "116"}, {"type": "inout", "name": "ARDU00", "value": "138"}, {"type": "inout", "name": "ARDU01", "value": "141"}, {"type": "inout", "name": "ARDU02", "value": "143"}, {"type": "inout", "name": "ARDU03", "value": "1"}, {"type": "inout", "name": "RESET_P2", "value": "73"}, {"type": "inout", "name": "Milk_TXD", "value": "37"}, {"type": "inout", "name": "Milk_RXD", "value": "38"}] \ No newline at end of file diff --git a/app/resources/boards/kefir/pinout.pcf b/app/resources/boards/kefir/pinout.pcf index 6be09fb5c..610078356 100644 --- a/app/resources/boards/kefir/pinout.pcf +++ b/app/resources/boards/kefir/pinout.pcf @@ -3,19 +3,19 @@ # ----------------------------------------------------------------------------- # Capacitive-sense buttons -set_io --warn-no-port BTN1 136 -set_io --warn-no-port BTN2 134 -set_io --warn-no-port BTN3 128 -set_io --warn-no-port BTN4 122 +set_io --warn-no-port BTN1 136 # input +set_io --warn-no-port BTN2 134 # input +set_io --warn-no-port BTN3 128 # input +set_io --warn-no-port BTN4 122 # input # LED outputs -set_io --warn-no-port LED1 137 -set_io --warn-no-port LED2 135 -set_io --warn-no-port LED3 129 -set_io --warn-no-port LED4 121 +set_io --warn-no-port LED1 137 # output +set_io --warn-no-port LED2 135 # output +set_io --warn-no-port LED3 129 # output +set_io --warn-no-port LED4 121 # output # Clock input -set_io --warn-no-port CLK 49 +set_io --warn-no-port CLK 49 # input # SPI Flash enable control set_io --warn-no-port SS_B 71 diff --git a/app/resources/boards/kefir/rules.json b/app/resources/boards/kefir/rules.json new file mode 100644 index 000000000..e08025917 --- /dev/null +++ b/app/resources/boards/kefir/rules.json @@ -0,0 +1,26 @@ +{ + "input" : [ + { + "port" : "clk", + "pin": "49" + } + ], + "output": [ + { + "pin": "137", + "bit": "0" + }, + { + "pin": "135", + "bit": "0" + }, + { + "pin": "129", + "bit": "0" + }, + { + "pin": "121", + "bit": "0" + } + ] +} diff --git a/app/resources/blocks/bit/0.ice b/app/resources/collection/blocks/bit/0.ice similarity index 100% rename from app/resources/blocks/bit/0.ice rename to app/resources/collection/blocks/bit/0.ice diff --git a/app/resources/blocks/bit/1.ice b/app/resources/collection/blocks/bit/1.ice similarity index 100% rename from app/resources/blocks/bit/1.ice rename to app/resources/collection/blocks/bit/1.ice diff --git a/app/resources/blocks/config/pull_up.ice b/app/resources/collection/blocks/config/pull_up.ice similarity index 100% rename from app/resources/blocks/config/pull_up.ice rename to app/resources/collection/blocks/config/pull_up.ice diff --git a/app/resources/blocks/config/pull_up_inv.ice b/app/resources/collection/blocks/config/pull_up_inv.ice similarity index 100% rename from app/resources/blocks/config/pull_up_inv.ice rename to app/resources/collection/blocks/config/pull_up_inv.ice diff --git a/app/resources/blocks/config/tri_state.ice b/app/resources/collection/blocks/config/tri_state.ice similarity index 100% rename from app/resources/blocks/config/tri_state.ice rename to app/resources/collection/blocks/config/tri_state.ice diff --git a/app/resources/blocks/logic/combinational/demux_1_2.ice b/app/resources/collection/blocks/logic/combinational/demux_1_2.ice similarity index 100% rename from app/resources/blocks/logic/combinational/demux_1_2.ice rename to app/resources/collection/blocks/logic/combinational/demux_1_2.ice diff --git a/app/resources/blocks/logic/combinational/demux_1_4.ice b/app/resources/collection/blocks/logic/combinational/demux_1_4.ice similarity index 100% rename from app/resources/blocks/logic/combinational/demux_1_4.ice rename to app/resources/collection/blocks/logic/combinational/demux_1_4.ice diff --git a/app/resources/blocks/logic/combinational/demux_1_8.ice b/app/resources/collection/blocks/logic/combinational/demux_1_8.ice similarity index 100% rename from app/resources/blocks/logic/combinational/demux_1_8.ice rename to app/resources/collection/blocks/logic/combinational/demux_1_8.ice diff --git a/app/resources/blocks/logic/combinational/hex_7seg_ca.ice b/app/resources/collection/blocks/logic/combinational/hex_7seg_ca.ice similarity index 100% rename from app/resources/blocks/logic/combinational/hex_7seg_ca.ice rename to app/resources/collection/blocks/logic/combinational/hex_7seg_ca.ice diff --git a/app/resources/blocks/logic/combinational/hex_7seg_cc.ice b/app/resources/collection/blocks/logic/combinational/hex_7seg_cc.ice similarity index 100% rename from app/resources/blocks/logic/combinational/hex_7seg_cc.ice rename to app/resources/collection/blocks/logic/combinational/hex_7seg_cc.ice diff --git a/app/resources/blocks/logic/combinational/mux_2_1.ice b/app/resources/collection/blocks/logic/combinational/mux_2_1.ice similarity index 100% rename from app/resources/blocks/logic/combinational/mux_2_1.ice rename to app/resources/collection/blocks/logic/combinational/mux_2_1.ice diff --git a/app/resources/blocks/logic/combinational/mux_4_1.ice b/app/resources/collection/blocks/logic/combinational/mux_4_1.ice similarity index 100% rename from app/resources/blocks/logic/combinational/mux_4_1.ice rename to app/resources/collection/blocks/logic/combinational/mux_4_1.ice diff --git a/app/resources/blocks/logic/gate/and.ice b/app/resources/collection/blocks/logic/gate/and.ice similarity index 100% rename from app/resources/blocks/logic/gate/and.ice rename to app/resources/collection/blocks/logic/gate/and.ice diff --git a/app/resources/blocks/logic/gate/nand.ice b/app/resources/collection/blocks/logic/gate/nand.ice similarity index 100% rename from app/resources/blocks/logic/gate/nand.ice rename to app/resources/collection/blocks/logic/gate/nand.ice diff --git a/app/resources/blocks/logic/gate/nor.ice b/app/resources/collection/blocks/logic/gate/nor.ice similarity index 100% rename from app/resources/blocks/logic/gate/nor.ice rename to app/resources/collection/blocks/logic/gate/nor.ice diff --git a/app/resources/blocks/logic/gate/not.ice b/app/resources/collection/blocks/logic/gate/not.ice similarity index 100% rename from app/resources/blocks/logic/gate/not.ice rename to app/resources/collection/blocks/logic/gate/not.ice diff --git a/app/resources/blocks/logic/gate/or.ice b/app/resources/collection/blocks/logic/gate/or.ice similarity index 100% rename from app/resources/blocks/logic/gate/or.ice rename to app/resources/collection/blocks/logic/gate/or.ice diff --git a/app/resources/blocks/logic/gate/xnor.ice b/app/resources/collection/blocks/logic/gate/xnor.ice similarity index 100% rename from app/resources/blocks/logic/gate/xnor.ice rename to app/resources/collection/blocks/logic/gate/xnor.ice diff --git a/app/resources/blocks/logic/gate/xor.ice b/app/resources/collection/blocks/logic/gate/xor.ice similarity index 100% rename from app/resources/blocks/logic/gate/xor.ice rename to app/resources/collection/blocks/logic/gate/xor.ice diff --git a/app/resources/blocks/logic/sequential/debouncer.ice b/app/resources/collection/blocks/logic/sequential/debouncer.ice similarity index 100% rename from app/resources/blocks/logic/sequential/debouncer.ice rename to app/resources/collection/blocks/logic/sequential/debouncer.ice diff --git a/app/resources/blocks/logic/sequential/dff_ar.ice b/app/resources/collection/blocks/logic/sequential/dff_ar.ice similarity index 99% rename from app/resources/blocks/logic/sequential/dff_ar.ice rename to app/resources/collection/blocks/logic/sequential/dff_ar.ice index e623bf232..50c524dd9 100644 --- a/app/resources/blocks/logic/sequential/dff_ar.ice +++ b/app/resources/collection/blocks/logic/sequential/dff_ar.ice @@ -108,7 +108,7 @@ "id": "07105e68-401b-49e9-b85f-2cddbfee9fbe", "type": "basic.input", "data": { - "name": "rst*", + "name": "rst_n", "pins": [ { "index": "0", @@ -127,7 +127,7 @@ "id": "4a261f0b-523c-4fe0-ae1c-de05b8eb7e8a", "type": "basic.output", "data": { - "name": "Q*", + "name": "Q_n", "pins": [ { "index": "0", @@ -234,4 +234,4 @@ } }, "dependencies": {} -} \ No newline at end of file +} diff --git a/app/resources/blocks/logic/sequential/dff_sr.ice b/app/resources/collection/blocks/logic/sequential/dff_sr.ice similarity index 99% rename from app/resources/blocks/logic/sequential/dff_sr.ice rename to app/resources/collection/blocks/logic/sequential/dff_sr.ice index 10d174586..e61d5f64a 100644 --- a/app/resources/blocks/logic/sequential/dff_sr.ice +++ b/app/resources/collection/blocks/logic/sequential/dff_sr.ice @@ -108,7 +108,7 @@ "id": "07105e68-401b-49e9-b85f-2cddbfee9fbe", "type": "basic.input", "data": { - "name": "rst*", + "name": "rst_n", "pins": [ { "index": "0", @@ -127,7 +127,7 @@ "id": "4a261f0b-523c-4fe0-ae1c-de05b8eb7e8a", "type": "basic.output", "data": { - "name": "Q*", + "name": "Q_n", "pins": [ { "index": "0", @@ -234,4 +234,4 @@ } }, "dependencies": {} -} \ No newline at end of file +} diff --git a/app/resources/blocks/logic/sequential/tff_ar.ice b/app/resources/collection/blocks/logic/sequential/tff_ar.ice similarity index 99% rename from app/resources/blocks/logic/sequential/tff_ar.ice rename to app/resources/collection/blocks/logic/sequential/tff_ar.ice index 4ddcd0ea2..14fc69586 100644 --- a/app/resources/blocks/logic/sequential/tff_ar.ice +++ b/app/resources/collection/blocks/logic/sequential/tff_ar.ice @@ -108,7 +108,7 @@ "id": "8fa94192-fba9-4c2a-be61-b8ca88389423", "type": "basic.input", "data": { - "name": "rst*", + "name": "rst_n", "pins": [ { "index": "0", @@ -127,7 +127,7 @@ "id": "4a261f0b-523c-4fe0-ae1c-de05b8eb7e8a", "type": "basic.output", "data": { - "name": "Q*", + "name": "Q_n", "pins": [ { "index": "0", @@ -234,4 +234,4 @@ } }, "dependencies": {} -} \ No newline at end of file +} diff --git a/app/resources/blocks/logic/sequential/tff_sr.ice b/app/resources/collection/blocks/logic/sequential/tff_sr.ice similarity index 99% rename from app/resources/blocks/logic/sequential/tff_sr.ice rename to app/resources/collection/blocks/logic/sequential/tff_sr.ice index 1d2786f39..002d98cb7 100644 --- a/app/resources/blocks/logic/sequential/tff_sr.ice +++ b/app/resources/collection/blocks/logic/sequential/tff_sr.ice @@ -108,7 +108,7 @@ "id": "8fa94192-fba9-4c2a-be61-b8ca88389423", "type": "basic.input", "data": { - "name": "rst*", + "name": "rst_n", "pins": [ { "index": "0", @@ -127,7 +127,7 @@ "id": "4a261f0b-523c-4fe0-ae1c-de05b8eb7e8a", "type": "basic.output", "data": { - "name": "Q*", + "name": "Q_n", "pins": [ { "index": "0", @@ -234,4 +234,4 @@ } }, "dependencies": {} -} \ No newline at end of file +} diff --git a/app/resources/examples/icezum/1_basic/1_led_on.ice b/app/resources/collection/examples/1_basic/1_led_on.ice similarity index 100% rename from app/resources/examples/icezum/1_basic/1_led_on.ice rename to app/resources/collection/examples/1_basic/1_led_on.ice diff --git a/app/resources/examples/icezum/1_basic/2_switch_led.ice b/app/resources/collection/examples/1_basic/2_switch_led.ice similarity index 100% rename from app/resources/examples/icezum/1_basic/2_switch_led.ice rename to app/resources/collection/examples/1_basic/2_switch_led.ice diff --git a/app/resources/examples/icezum/1_basic/3_switch_and_gate.ice b/app/resources/collection/examples/1_basic/3_switch_and_gate.ice similarity index 100% rename from app/resources/examples/icezum/1_basic/3_switch_and_gate.ice rename to app/resources/collection/examples/1_basic/3_switch_and_gate.ice diff --git a/app/resources/examples/icestick/1_basic/contadorAsc.ice b/app/resources/collection/examples/2_counter/contadorAsc.ice similarity index 100% rename from app/resources/examples/icestick/1_basic/contadorAsc.ice rename to app/resources/collection/examples/2_counter/contadorAsc.ice diff --git a/app/resources/examples/icestick/1_basic/contadorDes.ice b/app/resources/collection/examples/2_counter/contadorDes.ice similarity index 100% rename from app/resources/examples/icestick/1_basic/contadorDes.ice rename to app/resources/collection/examples/2_counter/contadorDes.ice diff --git a/app/resources/collection/locale/en/en.po b/app/resources/collection/locale/en/en.po new file mode 100644 index 000000000..f4992c297 --- /dev/null +++ b/app/resources/collection/locale/en/en.po @@ -0,0 +1,195 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2017-02-11 18:14+0100\n" +"PO-Revision-Date: 2017-02-11 18:14+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-Basepath: ..\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-KeywordsList: gettext\n" +"X-Poedit-SearchPath-0: translation.js\n" + +#. / Bit +#: translation.js:14 +msgid "bit" +msgstr "Bit" + +#: translation.js:15 +msgid "Assign 0 to the output wire" +msgstr "Assign 0 to the output wire" + +#. / Config +#: translation.js:17 +msgid "config" +msgstr "Config" + +#. / Pull up +#: translation.js:19 +msgid "pull_up" +msgstr "Pull up" + +#. / Pull up inv +#: translation.js:21 +msgid "pull_up_inv" +msgstr "Pull up inv" + +#. / Tri-state +#: translation.js:23 +msgid "tri_state" +msgstr "Tri-state" + +#. / Logic +#: translation.js:25 +msgid "logic" +msgstr "Logic" + +#. / Combinational +#: translation.js:27 +msgid "combinational" +msgstr "Combinational" + +#. / Demux 1:2 +#: translation.js:29 +msgid "demux_1_2" +msgstr "Demux 1:2" + +#. / Demux 1:4 +#: translation.js:31 +msgid "demux_1_4" +msgstr "Demux 1:4" + +#. / Demux 1:8 +#: translation.js:33 +msgid "demux_1_8" +msgstr "Demux 1:8" + +#. / Hex 7 Segment CC +#: translation.js:35 +msgid "hex_7seg_cc" +msgstr "Hex 7 Segment CC" + +#. / Hex 7 Segment CA +#: translation.js:37 +msgid "hex_7seg_ca" +msgstr "Hex 7 Segment CA" + +#. / Mux 2:1 +#: translation.js:39 +msgid "mux_2_1" +msgstr "Mux 2:1" + +#. / Mux 4:1 +#: translation.js:41 +msgid "mux_4_1" +msgstr "Mux 4:1" + +#. / Gate +#: translation.js:43 +msgid "gate" +msgstr "Gate" + +#. / And +#: translation.js:45 +msgid "and" +msgstr "And" + +#. / Nand +#: translation.js:47 +msgid "nand" +msgstr "Nand" + +#. / Nor +#: translation.js:49 +msgid "nor" +msgstr "Nor" + +#. / Not +#: translation.js:51 +msgid "not" +msgstr "Not" + +#. / Or +#: translation.js:53 +msgid "or" +msgstr "Or" + +#. / Xnor +#: translation.js:55 +msgid "xnor" +msgstr "Xnor" + +#. / Xor +#: translation.js:57 +msgid "xor" +msgstr "Xor" + +#. / Sequential +#: translation.js:59 +msgid "sequential" +msgstr "Sequential" + +#. / D flip-flop async +#: translation.js:61 +msgid "dff_ar" +msgstr "D flip-flop async" + +#. / D flip-flop +#: translation.js:63 +msgid "dff_sr" +msgstr "D flip-flop" + +#. / T flip-flop async +#: translation.js:65 +msgid "tff_ar" +msgstr "T flip-flop async" + +#. / T flip-flop +#: translation.js:67 +msgid "tff_sr" +msgstr "T flip-flop" + +#. / Debouncer +#: translation.js:69 +msgid "debouncer" +msgstr "Debouncer" + +#. / 1. Basic +#: translation.js:71 +msgid "1_basic" +msgstr "1. Basic" + +#. / 2. Counter +#: translation.js:73 +msgid "2_counter" +msgstr "2. Counter" + +#. / 1. Led on +#: translation.js:75 +msgid "1_led_on" +msgstr "1. Led on" + +#. / 2. Switch led +#: translation.js:77 +msgid "2_switch_led" +msgstr "2. Switch led" + +#. / 3. Switch and gate +#: translation.js:79 +msgid "3_switch_and_gate" +msgstr "3. Switch and gate" + +#. / contadorAsc +#: translation.js:81 +msgid "contadorAsc" +msgstr "contadorAsc" + +#. / contadorDes +#: translation.js:83 +msgid "contadorDes" +msgstr "contadorDes" diff --git a/app/resources/collection/locale/es_ES/es_ES.po b/app/resources/collection/locale/es_ES/es_ES.po new file mode 100644 index 000000000..5e7a80c78 --- /dev/null +++ b/app/resources/collection/locale/es_ES/es_ES.po @@ -0,0 +1,194 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2017-02-11 18:14+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-SearchPath-0: translation.js\n" + +#. / Bit +#: translation.js:14 +msgid "bit" +msgstr "Bit" + +#: translation.js:15 +msgid "Assign 0 to the output wire" +msgstr "Asignar 0 al cable de salida" + +#. / Config +#: translation.js:17 +msgid "config" +msgstr "Config" + +#. / Pull up +#: translation.js:19 +msgid "pull_up" +msgstr "Pull up" + +#. / Pull up inv +#: translation.js:21 +msgid "pull_up_inv" +msgstr "Pull up inv" + +#. / Tri-state +#: translation.js:23 +msgid "tri_state" +msgstr "Tri-estado" + +#. / Logic +#: translation.js:25 +msgid "logic" +msgstr "Lógica" + +#. / Combinational +#: translation.js:27 +msgid "combinational" +msgstr "Combinacional" + +#. / Demux 1:2 +#: translation.js:29 +msgid "demux_1_2" +msgstr "Demux 1:2" + +#. / Demux 1:4 +#: translation.js:31 +msgid "demux_1_4" +msgstr "Demux 1:4" + +#. / Demux 1:8 +#: translation.js:33 +msgid "demux_1_8" +msgstr "Demux 1:8" + +#. / Hex 7 Segment CC +#: translation.js:35 +msgid "hex_7seg_cc" +msgstr "Hex 7 Segment CC" + +#. / Hex 7 Segment CA +#: translation.js:37 +msgid "hex_7seg_ca" +msgstr "Hex 7 Segment AC" + +#. / Mux 2:1 +#: translation.js:39 +msgid "mux_2_1" +msgstr "Mux 2:1" + +#. / Mux 4:1 +#: translation.js:41 +msgid "mux_4_1" +msgstr "Mux 4:1" + +#. / Gate +#: translation.js:43 +msgid "gate" +msgstr "Puerta" + +#. / And +#: translation.js:45 +msgid "and" +msgstr "And" + +#. / Nand +#: translation.js:47 +msgid "nand" +msgstr "Nand" + +#. / Nor +#: translation.js:49 +msgid "nor" +msgstr "Nor" + +#. / Not +#: translation.js:51 +msgid "not" +msgstr "Not" + +#. / Or +#: translation.js:53 +msgid "or" +msgstr "Or" + +#. / Xnor +#: translation.js:55 +msgid "xnor" +msgstr "Xnor" + +#. / Xor +#: translation.js:57 +msgid "xor" +msgstr "Xor" + +#. / Sequential +#: translation.js:59 +msgid "sequential" +msgstr "Secuencial" + +#. / D flip-flop async +#: translation.js:61 +msgid "dff_ar" +msgstr "Biestable D asinc" + +#. / D flip-flop +#: translation.js:63 +msgid "dff_sr" +msgstr "Biestable D" + +#. / T flip-flop async +#: translation.js:65 +msgid "tff_ar" +msgstr "Biestable T asinc" + +#. / T flip-flop +#: translation.js:67 +msgid "tff_sr" +msgstr "Biestable T" + +#. / Debouncer +#: translation.js:69 +msgid "debouncer" +msgstr "Antirrebotes" + +#. / 1. Basic +#: translation.js:71 +msgid "1_basic" +msgstr "1. Básico" + +#. / 2. Counter +#: translation.js:73 +msgid "2_counter" +msgstr "2. Counter" + +#. / 1. Led on +#: translation.js:75 +msgid "1_led_on" +msgstr "1. Encender led" + +#. / 2. Switch led +#: translation.js:77 +msgid "2_switch_led" +msgstr "2. Interruptor con led" + +#. / 3. Switch and gate +#: translation.js:79 +msgid "3_switch_and_gate" +msgstr "3. Interruptor con puerta and" + +#. / contadorAsc +#: translation.js:81 +msgid "contadorAsc" +msgstr "Contador ascendente" + +#. / contadorDes +#: translation.js:83 +msgid "contadorDes" +msgstr "Contador descendente" diff --git a/app/resources/collection/locale/eu_ES/eu_ES.po b/app/resources/collection/locale/eu_ES/eu_ES.po new file mode 100644 index 000000000..ed5531314 --- /dev/null +++ b/app/resources/collection/locale/eu_ES/eu_ES.po @@ -0,0 +1,190 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2017-02-08 18:07+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: eu_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-SearchPath-0: translation.js\n" + +#. / Bit +#: translation.js:14 +msgid "bit" +msgstr "Bit" + +#. / Config +#: translation.js:16 +msgid "config" +msgstr "Config" + +#. / Pull up +#: translation.js:18 +msgid "pull_up" +msgstr "Pull up" + +#. / Pull up inv +#: translation.js:20 +msgid "pull_up_inv" +msgstr "Pull up inv" + +#. / Tri-state +#: translation.js:22 +msgid "tri_state" +msgstr "Tri-state" + +#. / Logic +#: translation.js:24 +msgid "logic" +msgstr "Logika" + +#. / Combinational +#: translation.js:26 +msgid "combinational" +msgstr "Konbinazionala" + +#. / Demux 1:2 +#: translation.js:28 +msgid "demux_1_2" +msgstr "Demux 1:2" + +#. / Demux 1:4 +#: translation.js:30 +msgid "demux_1_4" +msgstr "Demux 1:4" + +#. / Demux 1:8 +#: translation.js:32 +msgid "demux_1_8" +msgstr "Demux 1:8" + +#. / Hex 7 Segment CC +#: translation.js:34 +msgid "hex_7seg_cc" +msgstr "Hex 7 Segment CC" + +#. / Hex 7 Segment CA +#: translation.js:36 +msgid "hex_7seg_ca" +msgstr "Hex 7 Segment CA" + +#. / Mux 2:1 +#: translation.js:38 +msgid "mux_2_1" +msgstr "Mux 2:1" + +#. / Mux 4:1 +#: translation.js:40 +msgid "mux_4_1" +msgstr "Mux 4:1" + +#. / Gate +#: translation.js:42 +msgid "gate" +msgstr "Atea" + +#. / And +#: translation.js:44 +msgid "and" +msgstr "And" + +#. / Nand +#: translation.js:46 +msgid "nand" +msgstr "Nand" + +#. / Nor +#: translation.js:48 +msgid "nor" +msgstr "Nor" + +#. / Not +#: translation.js:50 +msgid "not" +msgstr "Not" + +#. / Or +#: translation.js:52 +msgid "or" +msgstr "Or" + +#. / Xnor +#: translation.js:54 +msgid "xnor" +msgstr "Xnor" + +#. / Xor +#: translation.js:56 +msgid "xor" +msgstr "Xor" + +#. / Sequential +#: translation.js:58 +msgid "sequential" +msgstr "Sekuentziala" + +#. / D flip-flop async +#: translation.js:60 +msgid "dff_ar" +msgstr "D biegonkor asink" + +#. / D flip-flop +#: translation.js:62 +msgid "dff_sr" +msgstr "D biegonkorra" + +#. / T flip-flop async +#: translation.js:64 +msgid "tff_ar" +msgstr "T biegonkor asink" + +#. / T flip-flop +#: translation.js:66 +msgid "tff_sr" +msgstr "T biegonkorra" + +#. / Debouncer +#: translation.js:68 +msgid "debouncer" +msgstr "Erreboteen aurkakoa" + +#. / 1. Basic +#: translation.js:70 +msgid "1_basic" +msgstr "1. Oinarrizkoa" + +#. / 2. Counter +#: translation.js:72 +msgid "2_counter" +msgstr "" + +#. / 1. Led on +#: translation.js:74 +msgid "1_led_on" +msgstr "1. Leda piztu" + +#. / 2. Switch led +#: translation.js:76 +msgid "2_switch_led" +msgstr "2. Pultsadorea leda" + +#. / 3. Switch and gate +#: translation.js:78 +msgid "3_switch_and_gate" +msgstr "3. Pultsadorea eta AND atea" + +#. / contadorAsc +#: translation.js:80 +msgid "contadorAsc" +msgstr "Goranzko zenbatzailea" + +#. / contadorDes +#: translation.js:82 +msgid "contadorDes" +msgstr "Beheranzko zenbatzailea" diff --git a/app/resources/collection/locale/fr_FR/fr_FR.po b/app/resources/collection/locale/fr_FR/fr_FR.po new file mode 100644 index 000000000..b27e50a30 --- /dev/null +++ b/app/resources/collection/locale/fr_FR/fr_FR.po @@ -0,0 +1,190 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2017-02-08 18:08+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-SearchPath-0: translation.js\n" + +#. / Bit +#: translation.js:14 +msgid "bit" +msgstr "Bit" + +#. / Config +#: translation.js:16 +msgid "config" +msgstr "Configuration" + +#. / Pull up +#: translation.js:18 +msgid "pull_up" +msgstr "Pull up" + +#. / Pull up inv +#: translation.js:20 +msgid "pull_up_inv" +msgstr "Pull up inv" + +#. / Tri-state +#: translation.js:22 +msgid "tri_state" +msgstr "Tri-state" + +#. / Logic +#: translation.js:24 +msgid "logic" +msgstr "Logique" + +#. / Combinational +#: translation.js:26 +msgid "combinational" +msgstr "Combinatoire" + +#. / Demux 1:2 +#: translation.js:28 +msgid "demux_1_2" +msgstr "Démultiplexeur 1:2" + +#. / Demux 1:4 +#: translation.js:30 +msgid "demux_1_4" +msgstr "Démultiplexeur 1:4" + +#. / Demux 1:8 +#: translation.js:32 +msgid "demux_1_8" +msgstr "Démultiplexeur 1:8" + +#. / Hex 7 Segment CC +#: translation.js:34 +msgid "hex_7seg_cc" +msgstr "Hex 7 Segment CC" + +#. / Hex 7 Segment CA +#: translation.js:36 +msgid "hex_7seg_ca" +msgstr "Hex 7 Segment CA" + +#. / Mux 2:1 +#: translation.js:38 +msgid "mux_2_1" +msgstr "Multiplexeur 2:1" + +#. / Mux 4:1 +#: translation.js:40 +msgid "mux_4_1" +msgstr "Multiplexeur 4:1" + +#. / Gate +#: translation.js:42 +msgid "gate" +msgstr "Porte" + +#. / And +#: translation.js:44 +msgid "and" +msgstr "Et" + +#. / Nand +#: translation.js:46 +msgid "nand" +msgstr "Non Et" + +#. / Nor +#: translation.js:48 +msgid "nor" +msgstr "Non Ou" + +#. / Not +#: translation.js:50 +msgid "not" +msgstr "Non" + +#. / Or +#: translation.js:52 +msgid "or" +msgstr "Ou" + +#. / Xnor +#: translation.js:54 +msgid "xnor" +msgstr "Xnor" + +#. / Xor +#: translation.js:56 +msgid "xor" +msgstr "Xor" + +#. / Sequential +#: translation.js:58 +msgid "sequential" +msgstr "Séquentiel" + +#. / D flip-flop async +#: translation.js:60 +msgid "dff_ar" +msgstr "D flip-flop async" + +#. / D flip-flop +#: translation.js:62 +msgid "dff_sr" +msgstr "D flip-flop" + +#. / T flip-flop async +#: translation.js:64 +msgid "tff_ar" +msgstr "T flip-flop async" + +#. / T flip-flop +#: translation.js:66 +msgid "tff_sr" +msgstr "T flip-flop" + +#. / Debouncer +#: translation.js:68 +msgid "debouncer" +msgstr "" + +#. / 1. Basic +#: translation.js:70 +msgid "1_basic" +msgstr "1. Basique" + +#. / 2. Counter +#: translation.js:72 +msgid "2_counter" +msgstr "" + +#. / 1. Led on +#: translation.js:74 +msgid "1_led_on" +msgstr "1. Led on" + +#. / 2. Switch led +#: translation.js:76 +msgid "2_switch_led" +msgstr "2. Switch led" + +#. / 3. Switch and gate +#: translation.js:78 +msgid "3_switch_and_gate" +msgstr "3. Switch and gate" + +#. / contadorAsc +#: translation.js:80 +msgid "contadorAsc" +msgstr "" + +#. / contadorDes +#: translation.js:82 +msgid "contadorDes" +msgstr "" diff --git a/app/resources/collection/locale/gl_ES/gl_ES.po b/app/resources/collection/locale/gl_ES/gl_ES.po new file mode 100644 index 000000000..c85d7487e --- /dev/null +++ b/app/resources/collection/locale/gl_ES/gl_ES.po @@ -0,0 +1,190 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2017-02-08 18:08+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: gl_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-SearchPath-0: translation.js\n" + +#. / Bit +#: translation.js:14 +msgid "bit" +msgstr "Bit" + +#. / Config +#: translation.js:16 +msgid "config" +msgstr "Config" + +#. / Pull up +#: translation.js:18 +msgid "pull_up" +msgstr "Pull up" + +#. / Pull up inv +#: translation.js:20 +msgid "pull_up_inv" +msgstr "Pull up inv" + +#. / Tri-state +#: translation.js:22 +msgid "tri_state" +msgstr "Tri-state" + +#. / Logic +#: translation.js:24 +msgid "logic" +msgstr "Lóxica" + +#. / Combinational +#: translation.js:26 +msgid "combinational" +msgstr "" + +#. / Demux 1:2 +#: translation.js:28 +msgid "demux_1_2" +msgstr "Demux 1:2" + +#. / Demux 1:4 +#: translation.js:30 +msgid "demux_1_4" +msgstr "Demux 1:4" + +#. / Demux 1:8 +#: translation.js:32 +msgid "demux_1_8" +msgstr "Demux 1:8" + +#. / Hex 7 Segment CC +#: translation.js:34 +msgid "hex_7seg_cc" +msgstr "Hex 7 Segment CC" + +#. / Hex 7 Segment CA +#: translation.js:36 +msgid "hex_7seg_ca" +msgstr "Hex 7 Segment CA" + +#. / Mux 2:1 +#: translation.js:38 +msgid "mux_2_1" +msgstr "Mux 2:1" + +#. / Mux 4:1 +#: translation.js:40 +msgid "mux_4_1" +msgstr "Mux 4:1" + +#. / Gate +#: translation.js:42 +msgid "gate" +msgstr "Gate" + +#. / And +#: translation.js:44 +msgid "and" +msgstr "And" + +#. / Nand +#: translation.js:46 +msgid "nand" +msgstr "Nand" + +#. / Nor +#: translation.js:48 +msgid "nor" +msgstr "Nor" + +#. / Not +#: translation.js:50 +msgid "not" +msgstr "Not" + +#. / Or +#: translation.js:52 +msgid "or" +msgstr "Or" + +#. / Xnor +#: translation.js:54 +msgid "xnor" +msgstr "Xnor" + +#. / Xor +#: translation.js:56 +msgid "xor" +msgstr "Xor" + +#. / Sequential +#: translation.js:58 +msgid "sequential" +msgstr "" + +#. / D flip-flop async +#: translation.js:60 +msgid "dff_ar" +msgstr "Bistable D asinc" + +#. / D flip-flop +#: translation.js:62 +msgid "dff_sr" +msgstr "Bistable D" + +#. / T flip-flop async +#: translation.js:64 +msgid "tff_ar" +msgstr "Bistable T asinc" + +#. / T flip-flop +#: translation.js:66 +msgid "tff_sr" +msgstr "Bistable T" + +#. / Debouncer +#: translation.js:68 +msgid "debouncer" +msgstr "" + +#. / 1. Basic +#: translation.js:70 +msgid "1_basic" +msgstr "1. Básico" + +#. / 2. Counter +#: translation.js:72 +msgid "2_counter" +msgstr "" + +#. / 1. Led on +#: translation.js:74 +msgid "1_led_on" +msgstr "1. Acender led" + +#. / 2. Switch led +#: translation.js:76 +msgid "2_switch_led" +msgstr "2. Interruptor con led" + +#. / 3. Switch and gate +#: translation.js:78 +msgid "3_switch_and_gate" +msgstr "3. Interruptor con porta and" + +#. / contadorAsc +#: translation.js:80 +msgid "contadorAsc" +msgstr "" + +#. / contadorDes +#: translation.js:82 +msgid "contadorDes" +msgstr "" diff --git a/app/resources/blocks/labels.js b/app/resources/collection/locale/translation.js similarity index 53% rename from app/resources/blocks/labels.js rename to app/resources/collection/locale/translation.js index f45415c3d..4edecf710 100644 --- a/app/resources/blocks/labels.js +++ b/app/resources/collection/locale/translation.js @@ -1,7 +1,18 @@ -// In this file the blocks labels are annotated for translation +// Translation document for the Default collection +// =============================================== +// This file contains the labels and comments annotated for translation +// +// IMPORTANT: Configure Poedit: +// 1. Go to Edit > Preferences > Extractors +// 2. Select "JavaScript" and press "Edit" +// 3. Change the "Command to extract translations:" field: +// - Replace the text "TRANSLATORS:" by a slash +// 4. Press "OK" and "Close" + /// Bit gettext('bit'); +gettext('Assign 0 to the output wire'); /// Config gettext('config'); /// Pull up @@ -48,7 +59,7 @@ gettext('xor'); gettext('sequential'); /// D flip-flop async gettext('dff_ar'); -/// D flip-flop async +/// D flip-flop gettext('dff_sr'); /// T flip-flop async gettext('tff_ar'); @@ -56,3 +67,17 @@ gettext('tff_ar'); gettext('tff_sr'); /// Debouncer gettext('debouncer'); +/// 1. Basic +gettext('1_basic'); +/// 2. Counter +gettext('2_counter'); +/// 1. Led on +gettext('1_led_on'); +/// 2. Switch led +gettext('2_switch_led'); +/// 3. Switch and gate +gettext('3_switch_and_gate'); +/// contadorAsc +gettext('contadorAsc'); +/// contadorDes +gettext('contadorDes'); diff --git a/app/resources/collection/package.json b/app/resources/collection/package.json new file mode 100644 index 000000000..0c75aa0ab --- /dev/null +++ b/app/resources/collection/package.json @@ -0,0 +1,33 @@ +{ + "name": "Default", + "version": "0.0.1", + "description": "Default collection", + "keywords": "default, collection", + "license": "GPL-2.0", + "authors" : [ + { + "name": "Jesús Arroyo", + "email": "", + "url": "" + }, + { + "name": "Juan González", + "email": "", + "url": "" + }, + { + "name": "Carlos Díaz", + "email": "", + "url": "" + }, + { + "name": "Salvador E. Tropea", + "email": "", + "url": "" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/FPGAwars/icestudio" + } +} diff --git a/app/resources/examples/icestick/1_basic/1_led_on.ice b/app/resources/examples/icestick/1_basic/1_led_on.ice deleted file mode 100644 index d7e220c22..000000000 --- a/app/resources/examples/icestick/1_basic/1_led_on.ice +++ /dev/null @@ -1,152 +0,0 @@ -{ - "version": "1.1", - "package": { - "name": "Led on", - "version": "1.0.0", - "description": "", - "author": "", - "image": "" - }, - "design": { - "board": "icestick", - "graph": { - "blocks": [ - { - "id": "eaf792b5-de98-4e2f-b78a-4023eb9a7f2b", - "type": "3e6c249e205080168c1bf4ee8dbc33b50653d5f4", - "position": { - "x": 80, - "y": 64 - } - }, - { - "id": "949075cb-26c0-49da-ba76-2496ea9aa7cc", - "type": "basic.output", - "data": { - "name": "led", - "pins": [ - { - "index": "0", - "name": "D1", - "value": "99" - } - ], - "virtual": false - }, - "position": { - "x": 352, - "y": 64 - } - }, - { - "id": "a538a5b4-d5d5-4ace-a593-efb1fa9b930c", - "type": "basic.info", - "data": { - "info": "LED-ON Hello world circuit example!\n\nThe simplest digital circuit that turns a \nled on\n\nA bit set to 1 is wired directly to the\noutput FPGA pin, where the led is connected\n\nThe blue box is the bit (set to 1)\nIt is inside the FPGA\n\nThe yellow box is the output FPGA pin. Using\nthe bottom menu the pin can be changed\n\nEXERCISE 1: Upload this circuit into your \nFPGA board and watch the led. \nIt should be turned on\n\nEXERCISE 2: Change the pin number to turn\nanother led on and upload it again" - }, - "position": { - "x": 40, - "y": 208 - } - }, - { - "id": "0d05784e-8e32-4c80-b85d-cde4e892dbf3", - "type": "basic.info", - "data": { - "info": "Ejemplo de circuito Hola mundo: LED-ON\n\nEs el circuito digital más sencillo que\nenciende un led\n\nUn bit a 1 se cablea directamente a una\nsalida de la FPGA, donde está conectado\nel LED\n\nLa caja azul es el bit a 1\nEstá dentro de la FPGA\n\nLa caja amarilla es el pin de salida de\nla FPGA. Por medio del menú desplegable\ninferior se puede cambiar el pin\n\nEJERCICIO 1: Carga este circuito en la FPGA\ny observa el LED0. Debe estar encendido\n\nEJERCICIO 2: Cambia el pin de salida para\nencender otro led (por ejemplo el LED1)\ny cárgalo en la FPGA de nuevo" - }, - "position": { - "x": 464, - "y": 208 - } - } - ], - "wires": [ - { - "source": { - "block": "eaf792b5-de98-4e2f-b78a-4023eb9a7f2b", - "port": "19c8f68d-5022-487f-9ab0-f0a3cd58bead" - }, - "target": { - "block": "949075cb-26c0-49da-ba76-2496ea9aa7cc", - "port": "in" - } - } - ] - }, - "state": { - "pan": { - "x": 0, - "y": 0 - }, - "zoom": 1 - } - }, - "dependencies": { - "3e6c249e205080168c1bf4ee8dbc33b50653d5f4": { - "package": { - "name": "Bit 1", - "version": "1.0.0", - "description": "Assign 1 to the output wire", - "author": "Jesús Arroyo", - "image": "%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2247.303%22%20height=%2227.648%22%20viewBox=%220%200%2044.346456%2025.919999%22%3E%3Ctext%20style=%22line-height:125%25%22%20x=%22325.218%22%20y=%22315.455%22%20font-weight=%22400%22%20font-size=%2212.669%22%20font-family=%22sans-serif%22%20letter-spacing=%220%22%20word-spacing=%220%22%20transform=%22translate(-307.01%20-298.51)%22%3E%3Ctspan%20x=%22325.218%22%20y=%22315.455%22%20style=%22-inkscape-font-specification:'Courier%2010%20Pitch'%22%20font-family=%22Courier%2010%20Pitch%22%3E1%3C/tspan%3E%3C/text%3E%3C/svg%3E" - }, - "design": { - "graph": { - "blocks": [ - { - "id": "b959fb96-ac67-4aea-90b3-ed35a4c17bf5", - "type": "basic.code", - "data": { - "code": "// Bit 1\n\nassign v = 1'b1;", - "params": [], - "ports": { - "in": [], - "out": [ - { - "name": "v" - } - ] - } - }, - "position": { - "x": 96, - "y": 96 - } - }, - { - "id": "19c8f68d-5022-487f-9ab0-f0a3cd58bead", - "type": "basic.output", - "data": { - "name": "" - }, - "position": { - "x": 608, - "y": 192 - } - } - ], - "wires": [ - { - "source": { - "block": "b959fb96-ac67-4aea-90b3-ed35a4c17bf5", - "port": "v" - }, - "target": { - "block": "19c8f68d-5022-487f-9ab0-f0a3cd58bead", - "port": "in" - } - } - ] - }, - "state": { - "pan": { - "x": 0, - "y": 0 - }, - "zoom": 1 - } - } - } - } -} \ No newline at end of file diff --git a/app/resources/examples/labels.js b/app/resources/examples/labels.js deleted file mode 100644 index 5d2b29508..000000000 --- a/app/resources/examples/labels.js +++ /dev/null @@ -1,14 +0,0 @@ -// In this file the examples labels are annotated for translation - -/// 1. Basic -gettext('1_basic'); -/// 1. Led on -gettext('1_led_on'); -/// 2. Switch led -gettext('2_switch_led'); -/// 3. Switch and gate -gettext('3_switch_and_gate'); -/// contadorAsc -gettext('contadorAsc'); -/// contadorDes -gettext('contadorDes'); diff --git a/app/resources/images/icestudio-logo.ico b/app/resources/images/icestudio-logo.ico new file mode 100644 index 000000000..f8dbf862d Binary files /dev/null and b/app/resources/images/icestudio-logo.ico differ diff --git a/app/resources/locale/en/en.po b/app/resources/locale/en/en.po index 2a09756ad..91b53736d 100644 --- a/app/resources/locale/en/en.po +++ b/app/resources/locale/en/en.po @@ -12,32 +12,11 @@ msgstr "" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#. 1. Basic -#: app/resources/examples/labels.js:4 -msgid "1_basic" -msgstr "1. Basic" - -#. 1. Led on -#: app/resources/examples/labels.js:6 -msgid "1_led_on" -msgstr "1. Led on" - -#. 2. Switch led -#: app/resources/examples/labels.js:8 -msgid "2_switch_led" -msgstr "2. Switch led" - -#. 3. Switch and gate -#: app/resources/examples/labels.js:10 -msgid "3_switch_and_gate" -msgstr "3. Switch and gate" - -#: app/scripts/services/utils.service.js:452 -#: app/scripts/services/utils.service.js:532 +#: app/scripts/services/utils.js:456 app/scripts/services/utils.js:536 msgid "Unplug and reconnect the board" msgstr "Unplug and reconnect the board" -#: app/scripts/services/utils.service.js:523 +#: app/scripts/services/utils.js:527 msgid "" "

FTDI driver installation instructions

  1. Connect the FPGA " "board
  2. Replace the (Interface 0) driver of the board by " @@ -47,7 +26,7 @@ msgstr "" "board
  3. Replace the (Interface 0) driver of the board by " "libusbK
  4. Unplug and reconnect the board
" -#: app/scripts/services/utils.service.js:539 +#: app/scripts/services/utils.js:543 msgid "" "

FTDI driver uninstallation instructions

  1. Find the FPGA USB " "Device
  2. Select the board interface and uninstall the driver
" @@ -55,66 +34,81 @@ msgstr "" "

FTDI driver uninstallation instructions

  1. Find the FPGA USB " "Device
  2. Select the board interface and uninstall the driver
" -#: app/views/menu.html:321 +#: app/views/menu.html:336 msgid "About Icestudio" msgstr "About Icestudio" -#: app/views/menu.html:275 +#: app/views/menu.html:290 msgid "Add" msgstr "Add" -#: app/scripts/controllers/menu.js:431 +#: app/scripts/controllers/menu.js:471 msgid "Add a block to start" msgstr "Add a block to start" -#: app/views/menu.html:35 +#: app/views/menu.html:43 msgid "Add as block" msgstr "Add as block" -#: app/scripts/services/tools.service.js:590 +#: app/scripts/services/tools.js:682 msgid "All collections removed" msgstr "All collections removed" -#: app/scripts/controllers/menu.js:455 +#: app/scripts/controllers/menu.js:495 msgid "All stored collections will be lost. Do you want to continue?" msgstr "All stored collections will be lost. Do you want to continue?" -#: app/scripts/services/utils.service.js:681 +#: app/scripts/services/utils.js:723 msgid "Author" msgstr "Author" -#: app/views/menu.html:331 +#: app/views/menu.html:347 msgid "Basic" msgstr "Basic" -#: app/views/menu.html:154 +#: app/views/menu.html:155 msgid "Basque" msgstr "Basque" -#: app/scripts/services/blocks.service.js:680 -#: app/scripts/services/blocks.service.js:699 -#: app/scripts/services/blocks.service.js:730 -#: app/scripts/services/blocks.service.js:750 +#: app/scripts/services/blocks.js:742 app/scripts/services/blocks.js:763 +#: app/scripts/services/blocks.js:818 app/scripts/services/blocks.js:837 +#: app/scripts/services/blocks.js:872 app/scripts/services/blocks.js:911 msgid "Block updated" msgstr "Block updated" -#: app/scripts/services/project.service.js:402 +#: app/scripts/services/project.js:418 msgid "Block {{name}} imported" msgstr "Block {{name}} imported" -#: app/scripts/services/tools.service.js:227 +#: app/views/menu.html:35 +msgid "Blocks" +msgstr "Blocks" + +#: app/views/menu.html:201 +msgid "Board" +msgstr "Board" + +#: app/views/menu.html:115 app/views/menu.html:192 +msgid "Board rules" +msgstr "Board rules" + +#: app/scripts/controllers/menu.js:334 +msgid "Board rules disabled" +msgstr "Board rules disabled" + +#: app/scripts/controllers/menu.js:329 +msgid "Board rules enabled" +msgstr "Board rules enabled" + +#: app/scripts/services/tools.js:234 msgid "Board {{name}} not detected" msgstr "Board {{name}} not detected" -#: app/scripts/controllers/menu.js:399 +#: app/scripts/controllers/menu.js:435 msgid "Board {{name}} selected" msgstr "Board {{name}} selected" -#: app/views/menu.html:203 -msgid "Boards" -msgstr "Boards" - -#: app/views/menu.html:221 +#: app/views/menu.html:236 msgid "Build" msgstr "Build" @@ -122,59 +116,71 @@ msgstr "Build" msgid "Cancel" msgstr "Cancel" -#: app/scripts/services/tools.service.js:438 +#: app/scripts/services/tools.js:446 msgid "Check Internet connection..." msgstr "Check Internet connection..." -#: app/scripts/services/tools.service.js:446 +#: app/scripts/services/tools.js:454 msgid "Check Python..." msgstr "Check Python..." -#: app/views/menu.html:337 +#: app/views/menu.html:361 msgid "Code" msgstr "Code" -#: app/scripts/services/tools.service.js:577 -msgid "Collection file {{name}} added" -msgstr "Collection file {{name}} added" +#: app/views/menu.html:212 +msgid "Collection" +msgstr "Collection" -#: app/scripts/services/tools.service.js:584 +#: app/scripts/services/tools.js:631 +msgid "Collection {{name}} added" +msgstr "Collection {{name}} added" + +#: app/scripts/services/tools.js:625 +msgid "Collection {{name}} not replaced" +msgstr "Collection {{name}} not replaced" + +#: app/scripts/services/tools.js:676 msgid "Collection {{name}} removed" msgstr "Collection {{name}} removed" -#: app/scripts/controllers/menu.js:374 +#: app/scripts/services/tools.js:621 +msgid "Collection {{name}} replaced" +msgstr "Collection {{name}} replaced" + +#: app/scripts/controllers/menu.js:410 msgid "Collection {{name}} selected" msgstr "Collection {{name}} selected" -#: app/views/menu.html:185 app/views/menu.html:271 +#: app/views/menu.html:286 msgid "Collections" msgstr "Collections" -#: app/views/menu.html:317 +#: app/views/menu.html:332 msgid "Community forum" msgstr "Community forum" -#: app/views/menu.html:336 +#: app/views/menu.html:358 msgid "Constant" msgstr "Constant" -#: app/views/menu.html:101 +#: app/views/menu.html:91 msgid "Copy" msgstr "Copy" -#: app/views/menu.html:98 +#: app/views/menu.html:88 msgid "Cut" msgstr "Cut" -#: app/views/menu.html:181 +#: app/views/menu.html:189 msgid "Datasheet" msgstr "Datasheet" -#: app/views/menu.html:189 +#: app/views/menu.html:216 msgid "Default" msgstr "Default" -#: app/scripts/services/tools.service.js:315 +#: app/scripts/services/tools.js:322 msgid "" "Default toolchain not found. Toolchain will be downloaded. This operation " "requires Internet connection. Do you want to continue?" @@ -182,123 +188,132 @@ msgstr "" "Default toolchain not found. Toolchain will be downloaded. This operation " "requires Internet connection. Do you want to continue?" -#: app/scripts/services/utils.service.js:680 +#: app/scripts/services/utils.js:722 msgid "Description" msgstr "Description" -#: app/views/menu.html:264 +#: app/views/menu.html:126 app/views/menu.html:279 msgid "Disable" msgstr "Disable" -#: app/scripts/controllers/menu.js:218 +#: app/scripts/controllers/menu.js:234 msgid "Do you want to close the application?" msgstr "Do you want to close the application?" -#: app/scripts/controllers/menu.js:445 +#: app/scripts/services/project.js:104 +msgid "Do you want to convert it?" +msgstr "Do you want to convert it?" + +#: app/scripts/controllers/menu.js:485 msgid "Do you want to remove the {{name}} collection?" msgstr "Do you want to remove the {{name}} collection?" -#: app/views/menu.html:310 +#: app/scripts/services/tools.js:617 +msgid "Do you want to replace it?" +msgstr "Do you want to replace it?" + +#: app/views/menu.html:325 msgid "Documentation" msgstr "Documentation" -#: app/views/menu.html:255 +#: app/views/menu.html:270 msgid "Drivers" msgstr "Drivers" -#: app/scripts/services/utils.service.js:449 -#: app/scripts/services/utils.service.js:517 +#: app/scripts/services/utils.js:453 app/scripts/services/utils.js:521 msgid "Drivers disabled" msgstr "Drivers disabled" -#: app/scripts/services/utils.service.js:446 -#: app/scripts/services/utils.service.js:498 +#: app/scripts/services/utils.js:450 app/scripts/services/utils.js:502 msgid "Drivers enabled" msgstr "Drivers enabled" -#: app/scripts/services/tools.service.js:239 +#: app/scripts/services/tools.js:246 msgid "Duplicated FPGA I/O ports" msgstr "Duplicated FPGA I/O ports" -#: app/scripts/services/blocks.service.js:314 +#: app/scripts/services/blocks.js:370 msgid "Duplicated block attributes" msgstr "Duplicated block attributes" -#: app/views/menu.html:88 +#: app/views/menu.html:78 msgid "Edit" msgstr "Edit" -#: app/views/menu.html:259 +#: app/views/menu.html:121 app/views/menu.html:274 msgid "Enable" msgstr "Enable" -#: app/views/menu.html:136 +#: app/views/menu.html:137 msgid "English" msgstr "English" -#: app/scripts/services/blocks.service.js:126 +#: app/scripts/services/blocks.js:181 msgid "Enter the constant blocks" msgstr "Enter the constant blocks" -#: app/scripts/services/blocks.service.js:213 +#: app/scripts/services/blocks.js:52 +msgid "Enter the input blocks" +msgstr "Enter the input blocks" + +#: app/scripts/services/blocks.js:269 msgid "Enter the input ports" msgstr "Enter the input ports" -#: app/scripts/services/blocks.service.js:214 +#: app/scripts/services/blocks.js:112 +msgid "Enter the output blocks" +msgstr "Enter the output blocks" + +#: app/scripts/services/blocks.js:270 msgid "Enter the output ports" msgstr "Enter the output ports" -#: app/scripts/services/blocks.service.js:215 +#: app/scripts/services/blocks.js:271 msgid "Enter the parameters" msgstr "Enter the parameters" -#: app/scripts/services/blocks.service.js:57 -msgid "Enter the ports" -msgstr "Enter the ports" - -#: app/scripts/controllers/menu.js:314 +#: app/scripts/controllers/menu.js:321 msgid "Enter the remote hostname user@host (experimental)" msgstr "Enter the remote hostname user@host (experimental)" -#: app/scripts/services/tools.service.js:338 +#: app/scripts/services/tools.js:345 msgid "Error: default toolchain not found in '{{dir}}'" msgstr "Error: default toolchain not found in '{{dir}}'" -#: app/scripts/services/utils.service.js:813 +#: app/scripts/services/utils.js:855 msgid "Error: {{error}}" msgstr "Error: {{error}}" -#: app/views/menu.html:38 +#: app/views/menu.html:39 msgid "Examples" msgstr "Examples" -#: app/scripts/services/tools.service.js:196 +#: app/scripts/services/tools.js:204 msgid "Execute remote {{label}} ..." msgstr "Execute remote {{label}} ..." -#: app/views/menu.html:64 +#: app/views/menu.html:54 msgid "Export" msgstr "Export" -#: app/scripts/services/tools.service.js:470 +#: app/scripts/services/tools.js:478 msgid "Extract default apio files..." msgstr "Extract default apio files..." -#: app/scripts/services/tools.service.js:480 +#: app/scripts/services/tools.js:488 msgid "Extract default apio packages..." msgstr "Extract default apio packages..." -#: app/scripts/services/tools.service.js:458 +#: app/scripts/services/tools.js:466 msgid "Extract virtual env files..." msgstr "Extract virtual env files..." -#: app/scripts/services/tools.service.js:233 -#: app/scripts/services/tools.service.js:236 +#: app/scripts/services/tools.js:240 app/scripts/services/tools.js:243 msgid "FPGA I/O ports not defined" msgstr "FPGA I/O ports not defined" -#: app/scripts/services/blocks.service.js:58 -#: app/scripts/services/blocks.service.js:640 +#: app/scripts/services/blocks.js:113 app/scripts/services/blocks.js:53 +#: app/scripts/services/blocks.js:698 app/scripts/services/blocks.js:778 msgid "FPGA pin" msgstr "FPGA pin" @@ -306,122 +321,126 @@ msgstr "FPGA pin" msgid "File" msgstr "File" -#: app/scripts/services/project.service.js:360 +#: app/scripts/services/project.js:376 msgid "" "File {{file}} already exists in the project path. Do you want to replace it?" msgstr "" "File {{file}} already exists in the project path. Do you want to replace it?" -#: app/scripts/services/tools.service.js:172 +#: app/scripts/services/tools.js:180 msgid "File {{file}} does not exist" msgstr "File {{file}} does not exist" -#: app/scripts/services/project.service.js:392 +#: app/scripts/services/project.js:408 msgid "File {{file}} imported" msgstr "File {{file}} imported" -#: app/views/menu.html:114 +#: app/views/menu.html:104 msgid "Fit content" msgstr "Fit content" -#: app/views/menu.html:160 +#: app/views/menu.html:161 msgid "French" msgstr "French" -#: app/scripts/controllers/menu.js:197 +#: app/scripts/controllers/menu.js:213 msgid "GTKWave exported" msgstr "GTKWave exported" -#: app/views/menu.html:148 +#: app/views/menu.html:149 msgid "Galician" msgstr "Galician" -#: app/views/menu.html:300 +#: app/views/menu.html:315 msgid "Help" msgstr "Help" -#: app/scripts/services/utils.service.js:487 +#: app/scripts/services/utils.js:491 msgid "Homebrew is required" msgstr "Homebrew is required" -#: app/scripts/services/utils.service.js:694 +#: app/scripts/services/utils.js:736 msgid "Image" msgstr "Image" -#: app/scripts/controllers/menu.js:647 +#: app/scripts/controllers/menu.js:642 msgid "Image {{name}} saved" msgstr "Image {{name}} saved" -#: app/views/menu.html:338 +#: app/views/menu.html:364 msgid "Information" msgstr "Information" -#: app/views/menu.html:334 +#: app/views/menu.html:352 msgid "Input" msgstr "Input" -#: app/views/menu.html:232 +#: app/views/menu.html:247 msgid "Install" msgstr "Install" -#: app/scripts/services/tools.service.js:475 +#: app/scripts/services/tools.js:483 msgid "Install default apio..." msgstr "Install default apio..." -#: app/scripts/services/tools.service.js:524 +#: app/scripts/services/tools.js:532 msgid "Installation completed" msgstr "Installation completed" -#: app/scripts/services/tools.service.js:367 -#: app/scripts/services/tools.service.js:404 +#: app/scripts/services/tools.js:375 app/scripts/services/tools.js:412 msgid "Installing toolchain" msgstr "Installing toolchain" -#: app/scripts/services/tools.service.js:440 -#: app/scripts/services/utils.service.js:491 +#: app/scripts/services/tools.js:448 app/scripts/services/utils.js:495 msgid "Internet connection required" msgstr "Internet connection required" -#: app/scripts/services/graph.service.js:186 +#: app/scripts/services/graph.js:175 msgid "Invalid Pull up connection:
block already connected" msgstr "Invalid Pull up connection:
block already connected" -#: app/scripts/services/graph.service.js:200 +#: app/scripts/services/graph.js:189 msgid "Invalid Pull up connection:
only Input blocks allowed" msgstr "Invalid Pull up connection:
only Input blocks allowed" -#: app/scripts/services/graph.service.js:192 +#: app/scripts/services/graph.js:181 msgid "Invalid block connection:
Pull up already connected" msgstr "Invalid block connection:
Pull up already connected" -#: app/scripts/services/graph.service.js:151 -#: app/scripts/services/graph.service.js:158 -#: app/scripts/services/graph.service.js:165 +#: app/scripts/services/tools.js:636 +msgid "Invalid collection {{name}}" +msgstr "Invalid collection {{name}}" + +#: app/scripts/services/graph.js:140 app/scripts/services/graph.js:147 +#: app/scripts/services/graph.js:154 msgid "Invalid connection" msgstr "Invalid connection" -#: app/scripts/services/graph.service.js:219 +#: app/scripts/services/graph.js:208 msgid "Invalid connection: {{a}} → {{b}}" msgstr "Invalid connection: {{a}} → {{b}}" -#: app/scripts/services/graph.service.js:180 +#: app/scripts/services/graph.js:169 msgid "Invalid multiple input connections" msgstr "Invalid multiple input connections" -#: app/views/menu.html:132 +#: app/views/menu.html:133 msgid "Language" msgstr "Language" -#: app/scripts/services/blocks.service.js:127 -#: app/scripts/services/blocks.service.js:713 +#: app/scripts/services/tools.js:579 +msgid "Load {{name}} ..." +msgstr "Load {{name}} ..." + +#: app/scripts/services/blocks.js:182 app/scripts/services/blocks.js:851 msgid "Local parameter" msgstr "Local parameter" -#: app/scripts/services/tools.service.js:463 +#: app/scripts/services/tools.js:471 msgid "Make virtual env..." msgstr "Make virtual env..." -#: app/scripts/services/utils.service.js:678 +#: app/scripts/services/utils.js:720 msgid "Name" msgstr "Name" @@ -429,11 +448,11 @@ msgstr "Name" msgid "New" msgstr "New" -#: app/scripts/services/project.service.js:85 +#: app/scripts/services/project.js:80 msgid "New project {{name}} created" msgstr "New project {{name}} created" -#: app/scripts/controllers/menu.js:463 +#: app/scripts/controllers/menu.js:503 msgid "No collections stored" msgstr "No collections stored" @@ -441,8 +460,7 @@ msgstr "No collections stored" msgid "OK" msgstr "OK" -#: app/scripts/services/project.service.js:101 -#: app/scripts/services/project.service.js:308 +#: app/scripts/services/project.js:323 app/scripts/services/project.js:97 msgid "Old project format {{version}}" msgstr "Old project format {{version}}" @@ -450,123 +468,135 @@ msgstr "Old project format {{version}}" msgid "Open" msgstr "Open" -#: app/scripts/services/utils.service.js:701 +#: app/scripts/services/utils.js:743 msgid "Open SVG" msgstr "Open SVG" -#: app/scripts/services/project.service.js:395 +#: app/scripts/services/project.js:411 msgid "Original file {{file}} does not exist" msgstr "Original file {{file}} does not exist" -#: app/views/menu.html:335 +#: app/views/menu.html:355 msgid "Output" msgstr "Output" -#: app/scripts/controllers/menu.js:179 +#: app/scripts/controllers/menu.js:195 msgid "PCF file exported" msgstr "PCF file exported" -#: app/views/menu.html:104 +#: app/views/menu.html:94 msgid "Paste" msgstr "Paste" -#: app/views/menu.html:118 +#: app/views/menu.html:108 msgid "Preferences" msgstr "Preferences" -#: app/views/menu.html:121 +#: app/views/menu.html:111 msgid "Project information" msgstr "Project information" -#: app/scripts/services/project.service.js:108 +#: app/scripts/services/project.js:122 msgid "Project {{name}} loaded" msgstr "Project {{name}} loaded" -#: app/scripts/services/project.service.js:280 +#: app/scripts/services/project.js:295 msgid "Project {{name}} saved" msgstr "Project {{name}} saved" -#: app/scripts/services/tools.service.js:451 +#: app/scripts/services/tools.js:459 msgid "Python 2.7 is required" msgstr "Python 2.7 is required" -#: app/views/menu.html:82 +#: app/views/menu.html:72 msgid "Quit" msgstr "Quit" -#: app/views/design.html:4 +#: app/views/design.html:5 msgid "Read only" msgstr "Read only" -#: app/views/menu.html:94 +#: app/views/menu.html:84 msgid "Redo" msgstr "Redo" -#: app/scripts/services/tools.service.js:264 +#: app/scripts/services/tools.js:271 msgid "Remote host {{name}} not connected" msgstr "Remote host {{name}} not connected" -#: app/views/menu.html:126 +#: app/views/menu.html:170 msgid "Remote hostname" msgstr "Remote hostname" -#: app/views/menu.html:240 app/views/menu.html:279 +#: app/views/menu.html:255 app/views/menu.html:294 msgid "Remove" msgstr "Remove" -#: app/views/menu.html:291 +#: app/views/menu.html:306 msgid "Remove all" msgstr "Remove all" -#: app/scripts/services/utils.service.js:703 +#: app/scripts/services/utils.js:745 msgid "Reset SVG" msgstr "Reset SVG" -#: app/views/menu.html:245 +#: app/views/menu.html:260 msgid "Reset default" msgstr "Reset default" -#: app/views/menu.html:111 +#: app/views/menu.html:101 msgid "Reset view" msgstr "Reset view" -#: app/views/menu.html:57 +#: app/views/menu.html:47 msgid "Save" msgstr "Save" -#: app/scripts/services/utils.service.js:702 +#: app/scripts/services/utils.js:744 msgid "Save SVG" msgstr "Save SVG" -#: app/views/menu.html:60 +#: app/views/menu.html:50 msgid "Save as" msgstr "Save as" -#: app/views/menu.html:107 +#: app/views/menu.html:198 +msgid "Select" +msgstr "Select" + +#: app/views/menu.html:97 msgid "Select all" msgstr "Select all" -#: app/views/menu.html:313 +#: app/scripts/services/blocks.js:54 app/scripts/services/blocks.js:699 +msgid "Show clock" +msgstr "Show clock" + +#: app/views/menu.html:328 msgid "Source code" msgstr "Source code" -#: app/views/menu.html:142 +#: app/views/menu.html:143 msgid "Spanish" msgstr "Spanish" -#: app/scripts/services/tools.service.js:185 +#: app/scripts/services/tools.js:193 msgid "Synchronize remote files ..." msgstr "Synchronize remote files ..." -#: app/views/menu.html:73 +#: app/views/menu.html:63 msgid "Testbench" msgstr "Testbench" -#: app/scripts/controllers/menu.js:188 +#: app/scripts/controllers/menu.js:204 msgid "Testbench exported" msgstr "Testbench exported" -#: app/scripts/controllers/menu.js:388 +#: app/scripts/services/tools.js:616 +msgid "The collection {{name}} already exists." +msgstr "The collection {{name}} already exists." + +#: app/scripts/controllers/menu.js:424 msgid "" "The current FPGA I/O configuration will be lost. Do you want to change to " "{{name}} board?" @@ -574,15 +604,15 @@ msgstr "" "The current FPGA I/O configuration will be lost. Do you want to change to " "{{name}} board?" -#: app/scripts/services/tools.service.js:343 +#: app/scripts/services/tools.js:350 msgid "The toolchain will be removed. Do you want to continue?" msgstr "The toolchain will be removed. Do you want to continue?" -#: app/scripts/services/tools.service.js:331 +#: app/scripts/services/tools.js:338 msgid "The toolchain will be restored to default. Do you want to continue?" msgstr "The toolchain will be restored to default. Do you want to continue?" -#: app/scripts/services/tools.service.js:323 +#: app/scripts/services/tools.js:330 msgid "" "The toolchain will be updated. This operation requires Internet connection. " "Do you want to continue?" @@ -590,7 +620,7 @@ msgstr "" "The toolchain will be updated. This operation requires Internet connection. " "Do you want to continue?" -#: app/scripts/services/project.service.js:329 +#: app/scripts/services/project.js:345 msgid "" "This import operation requires a project path. You need to save the current " "project. Do you want to continue?" @@ -598,299 +628,272 @@ msgstr "" "This import operation requires a project path. You need to save the current " "project. Do you want to continue?" -#: app/views/menu.html:228 +#: app/scripts/services/project.js:103 +msgid "This project is designed for the {{name}} board." +msgstr "This project is designed for the {{name}} board." + +#: app/views/menu.html:243 msgid "Toolchain" msgstr "Toolchain" -#: app/scripts/services/tools.service.js:525 +#: app/scripts/services/tools.js:533 msgid "Toolchain installed" msgstr "Toolchain installed" -#: app/scripts/services/tools.service.js:529 +#: app/scripts/services/tools.js:536 msgid "Toolchain not installed" msgstr "Toolchain not installed" -#: app/scripts/services/tools.service.js:100 -#: app/scripts/services/utils.service.js:529 -#: app/scripts/services/utils.service.js:545 +#: app/scripts/services/tools.js:92 app/scripts/services/utils.js:533 +#: app/scripts/services/utils.js:549 msgid "Toolchain not installed. Please, install the toolchain" msgstr "Toolchain not installed. Please, install the toolchain" -#: app/scripts/services/tools.service.js:347 +#: app/scripts/services/tools.js:355 msgid "Toolchain removed" msgstr "Toolchain removed" -#: app/views/menu.html:215 +#: app/views/menu.html:230 msgid "Tools" msgstr "Tools" -#: app/views/menu.html:91 +#: app/views/menu.html:81 msgid "Undo" msgstr "Undo" -#: app/scripts/services/tools.service.js:230 +#: app/scripts/services/tools.js:237 msgid "Unknown board" msgstr "Unknown board" -#: app/scripts/app.js:42 +#: app/scripts/app.js:43 msgid "Untitled" msgstr "Untitled" -#: app/views/menu.html:235 +#: app/views/menu.html:250 msgid "Update" msgstr "Update" -#: app/scripts/services/blocks.service.js:712 -msgid "Update the block label" -msgstr "Update the block label" - -#: app/scripts/services/blocks.service.js:639 -msgid "Update the port" -msgstr "Update the port" +#: app/scripts/services/blocks.js:697 app/scripts/services/blocks.js:777 +#: app/scripts/services/blocks.js:850 +msgid "Update the block name" +msgstr "Update the block name" -#: app/views/menu.html:224 +#: app/views/menu.html:239 msgid "Upload" msgstr "Upload" -#: app/views/menu.html:218 +#: app/views/menu.html:233 msgid "Verify" msgstr "Verify" -#: app/scripts/controllers/menu.js:170 +#: app/scripts/controllers/menu.js:186 msgid "Verilog code exported" msgstr "Verilog code exported" -#: app/scripts/services/utils.service.js:679 app/views/menu.html:306 +#: app/scripts/services/utils.js:721 app/views/menu.html:321 msgid "Version" msgstr "Version" -#: app/views/menu.html:172 +#: app/views/menu.html:180 msgid "View" msgstr "View" -#: app/views/menu.html:303 +#: app/views/menu.html:318 msgid "View license" msgstr "View license" -#: app/scripts/services/blocks.service.js:347 +#: app/scripts/services/blocks.js:404 msgid "Wrong block format: {{type}}" msgstr "Wrong block format: {{type}}" -#: app/scripts/services/blocks.service.js:146 -#: app/scripts/services/blocks.service.js:263 +#: app/scripts/services/blocks.js:132 app/scripts/services/blocks.js:201 +#: app/scripts/services/blocks.js:75 app/scripts/services/blocks.js:768 +#: app/scripts/services/blocks.js:842 app/scripts/services/blocks.js:877 +msgid "Wrong block name {{name}}" +msgstr "Wrong block name {{name}}" + +#: app/scripts/services/blocks.js:319 msgid "Wrong parameter name {{name}}" msgstr "Wrong parameter name {{name}}" -#: app/scripts/services/blocks.service.js:233 -#: app/scripts/services/blocks.service.js:248 -#: app/scripts/services/blocks.service.js:704 -#: app/scripts/services/blocks.service.js:77 +#: app/scripts/services/blocks.js:289 app/scripts/services/blocks.js:304 msgid "Wrong port name {{name}}" msgstr "Wrong port name {{name}}" -#: app/scripts/services/project.service.js:116 +#: app/scripts/services/project.js:130 msgid "Wrong project format: {{name}}" msgstr "Wrong project format: {{name}}" -#: app/scripts/services/tools.service.js:261 +#: app/scripts/services/tools.js:268 msgid "Wrong remote hostname {{name}}" msgstr "Wrong remote hostname {{name}}" -#: app/scripts/controllers/menu.js:219 +#: app/scripts/controllers/menu.js:235 msgid "Your changes will be lost if you don’t save them" msgstr "Your changes will be lost if you don’t save them" -#. And -#: app/resources/blocks/labels.js:34 -msgid "and" -msgstr "And" - -#: app/views/design.html:5 +#: app/views/design.html:6 msgid "back" msgstr "back" -#. Bit -#: app/resources/blocks/labels.js:4 -msgid "bit" -msgstr "Bit" - -#. Combinational -#: app/resources/blocks/labels.js:16 -msgid "combinational" -msgstr "Combinational" - -#. Config -#: app/resources/blocks/labels.js:6 -msgid "config" -msgstr "Config" - -#. contadorAsc -#: app/resources/examples/labels.js:12 -msgid "contadorAsc" -msgstr "contadorAsc" - -#. contadorDes -#: app/resources/examples/labels.js:14 -msgid "contadorDes" -msgstr "contadorDes" - -#. Debouncer -#: app/resources/blocks/labels.js:58 -msgid "debouncer" -msgstr "Debouncer" - -#. Demux 1:2 -#: app/resources/blocks/labels.js:18 -msgid "demux_1_2" -msgstr "Demux 1:2" - -#. Demux 1:4 -#: app/resources/blocks/labels.js:20 -msgid "demux_1_4" -msgstr "Demux 1:4" - -#. Demux 1:8 -#: app/resources/blocks/labels.js:22 -msgid "demux_1_8" -msgstr "Demux 1:8" - -#. D flip-flop async -#: app/resources/blocks/labels.js:50 -msgid "dff_ar" -msgstr "D flip-flop async" - -#. D flip-flop async -#: app/resources/blocks/labels.js:52 -msgid "dff_sr" -msgstr "D flip-flop" - #. Build done -#: app/scripts/services/tools.service.js:276 +#: app/scripts/services/tools.js:283 msgid "done_build" msgstr "Build done" #. Upload done -#: app/scripts/services/tools.service.js:278 +#: app/scripts/services/tools.js:285 msgid "done_upload" msgstr "Upload done" #. Verification done -#: app/scripts/services/tools.service.js:274 +#: app/scripts/services/tools.js:281 msgid "done_verify" msgstr "Verification done" -#. Gate -#: app/resources/blocks/labels.js:32 -msgid "gate" -msgstr "Gate" - -#. Hex 7 Segment CA -#: app/resources/blocks/labels.js:26 -msgid "hex_7seg_ca" -msgstr "Hex 7 Segment CA" - -#. Hex 7 Segment CC -#: app/resources/blocks/labels.js:24 -msgid "hex_7seg_cc" -msgstr "Hex 7 Segment CC" - -#. Logic -#: app/resources/blocks/labels.js:14 -msgid "logic" -msgstr "Logic" - -#. Mux 2:1 -#: app/resources/blocks/labels.js:28 -msgid "mux_2_1" -msgstr "Mux 2:1" - -#. Mux 4:1 -#: app/resources/blocks/labels.js:30 -msgid "mux_4_1" -msgstr "Mux 4:1" - -#. Nand -#: app/resources/blocks/labels.js:36 -msgid "nand" -msgstr "Nand" - -#. Nor -#: app/resources/blocks/labels.js:38 -msgid "nor" -msgstr "Nor" - -#. Not -#: app/resources/blocks/labels.js:40 -msgid "not" -msgstr "Not" - -#. Or -#: app/resources/blocks/labels.js:42 -msgid "or" -msgstr "Or" - -#. Pull up -#: app/resources/blocks/labels.js:8 -msgid "pull_up" -msgstr "Pull up" - -#. Pull up inv -#: app/resources/blocks/labels.js:10 -msgid "pull_up_inv" -msgstr "Pull up inv" - -#. Sequential -#: app/resources/blocks/labels.js:48 -msgid "sequential" -msgstr "Sequential" - #. Start building ... -#: app/scripts/services/tools.service.js:64 +#: app/scripts/services/tools.js:60 msgid "start_build" msgstr "Start building ..." #. Start uploading ... -#: app/scripts/services/tools.service.js:66 +#: app/scripts/services/tools.js:62 msgid "start_upload" msgstr "Start uploading ..." #. Start verification ... -#: app/scripts/services/tools.service.js:62 +#: app/scripts/services/tools.js:58 msgid "start_verify" msgstr "Start verification ..." -#. T flip-flop async -#: app/resources/blocks/labels.js:54 -msgid "tff_ar" -msgstr "T flip-flop async" +#: app/scripts/controllers/menu.js:383 +msgid "{{board}} datasheet not defined" +msgstr "{{board}} datasheet not defined" -#. T flip-flop -#: app/resources/blocks/labels.js:56 -msgid "tff_sr" -msgstr "T flip-flop" +#: app/scripts/controllers/menu.js:373 +msgid "{{board}} pinout not defined" +msgstr "{{board}} pinout not defined" -#. Tri-state -#: app/resources/blocks/labels.js:12 -msgid "tri_state" -msgstr "Tri-state" +#: app/scripts/controllers/menu.js:402 +msgid "{{board}} rules not defined" +msgstr "{{board}} rules not defined" -#. Xnor -#: app/resources/blocks/labels.js:44 -msgid "xnor" -msgstr "Xnor" +#~ msgid "1_basic" +#~ msgstr "1. Basic" -#. Xor -#: app/resources/blocks/labels.js:46 -msgid "xor" -msgstr "Xor" +#~ msgid "1_led_on" +#~ msgstr "1. Led on" -#: app/scripts/controllers/menu.js:366 -msgid "{{board}} datasheet not defined" -msgstr "{{board}} datasheet not defined" +#~ msgid "2_switch_led" +#~ msgstr "2. Switch led" -#: app/scripts/controllers/menu.js:356 -msgid "{{board}} pinout not defined" -msgstr "{{board}} pinout not defined" +#~ msgid "3_switch_and_gate" +#~ msgstr "3. Switch and gate" + +#~ msgid "and" +#~ msgstr "And" + +#~ msgid "bit" +#~ msgstr "Bit" + +#~ msgid "combinational" +#~ msgstr "Combinational" + +#~ msgid "config" +#~ msgstr "Config" + +#~ msgid "contadorAsc" +#~ msgstr "contadorAsc" + +#~ msgid "contadorDes" +#~ msgstr "contadorDes" + +#~ msgid "debouncer" +#~ msgstr "Debouncer" + +#~ msgid "demux_1_2" +#~ msgstr "Demux 1:2" + +#~ msgid "demux_1_4" +#~ msgstr "Demux 1:4" + +#~ msgid "demux_1_8" +#~ msgstr "Demux 1:8" + +#~ msgid "dff_ar" +#~ msgstr "D flip-flop async" + +#~ msgid "dff_sr" +#~ msgstr "D flip-flop" + +#~ msgid "gate" +#~ msgstr "Gate" + +#~ msgid "hex_7seg_ca" +#~ msgstr "Hex 7 Segment CA" + +#~ msgid "hex_7seg_cc" +#~ msgstr "Hex 7 Segment CC" + +#~ msgid "logic" +#~ msgstr "Logic" + +#~ msgid "mux_2_1" +#~ msgstr "Mux 2:1" + +#~ msgid "mux_4_1" +#~ msgstr "Mux 4:1" + +#~ msgid "nand" +#~ msgstr "Nand" + +#~ msgid "nor" +#~ msgstr "Nor" + +#~ msgid "not" +#~ msgstr "Not" + +#~ msgid "or" +#~ msgstr "Or" + +#~ msgid "pull_up" +#~ msgstr "Pull up" + +#~ msgid "pull_up_inv" +#~ msgstr "Pull up inv" + +#~ msgid "sequential" +#~ msgstr "Sequential" + +#~ msgid "tff_ar" +#~ msgstr "T flip-flop async" + +#~ msgid "tff_sr" +#~ msgstr "T flip-flop" + +#~ msgid "tri_state" +#~ msgstr "Tri-state" + +#~ msgid "xnor" +#~ msgstr "Xnor" + +#~ msgid "xor" +#~ msgstr "Xor" + +#~ msgid "Boards" +#~ msgstr "Boards" + +#~ msgid "Collection file {{name}} added" +#~ msgstr "Collection file {{name}} added" + +#~ msgid "Enter the ports" +#~ msgstr "Enter the ports" + +#~ msgid "Update the block label" +#~ msgstr "Update the block label" + +#~ msgid "Update the port" +#~ msgstr "Update the port" #~ msgid "Info" #~ msgstr "Info" diff --git a/app/resources/locale/es_ES/es_ES.po b/app/resources/locale/es_ES/es_ES.po index 320a5f54b..8ed771f38 100644 --- a/app/resources/locale/es_ES/es_ES.po +++ b/app/resources/locale/es_ES/es_ES.po @@ -12,32 +12,11 @@ msgstr "" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#. 1. Basic -#: app/resources/examples/labels.js:4 -msgid "1_basic" -msgstr "1. Básico" - -#. 1. Led on -#: app/resources/examples/labels.js:6 -msgid "1_led_on" -msgstr "1. Encender led" - -#. 2. Switch led -#: app/resources/examples/labels.js:8 -msgid "2_switch_led" -msgstr "2. Interruptor con led" - -#. 3. Switch and gate -#: app/resources/examples/labels.js:10 -msgid "3_switch_and_gate" -msgstr "3. Interruptor con puerta and" - -#: app/scripts/services/utils.service.js:452 -#: app/scripts/services/utils.service.js:532 +#: app/scripts/services/utils.js:456 app/scripts/services/utils.js:536 msgid "Unplug and reconnect the board" msgstr "Desconecta y conecta la placa" -#: app/scripts/services/utils.service.js:523 +#: app/scripts/services/utils.js:527 msgid "" "

FTDI driver installation instructions

  1. Connect the FPGA " "board
  2. Replace the (Interface 0) driver of the board by " @@ -47,7 +26,7 @@ msgstr "" "placa FPGA
  3. Reemplaza el driver de la (Interface 0) de la " "placa por libusbK
  4. Desconecta y conecta la placa
" -#: app/scripts/services/utils.service.js:539 +#: app/scripts/services/utils.js:543 msgid "" "

FTDI driver uninstallation instructions

  1. Find the FPGA USB " "Device
  2. Select the board interface and uninstall the driver
" @@ -56,66 +35,81 @@ msgstr "" "dispositivo USB FPGA
  • Selecciona la interfaz de la placa y desinstala " "el driver
  • " -#: app/views/menu.html:321 +#: app/views/menu.html:336 msgid "About Icestudio" msgstr "Sobre Icestudio" -#: app/views/menu.html:275 +#: app/views/menu.html:290 msgid "Add" msgstr "Añadir" -#: app/scripts/controllers/menu.js:431 +#: app/scripts/controllers/menu.js:471 msgid "Add a block to start" msgstr "Añade un bloque para comenzar" -#: app/views/menu.html:35 +#: app/views/menu.html:43 msgid "Add as block" msgstr "Añadir como bloque" -#: app/scripts/services/tools.service.js:590 +#: app/scripts/services/tools.js:682 msgid "All collections removed" msgstr "Colecciones eliminadas" -#: app/scripts/controllers/menu.js:455 +#: app/scripts/controllers/menu.js:495 msgid "All stored collections will be lost. Do you want to continue?" msgstr "Todas las colecciones almacenadas se perderán. ¿Deseas continuar?" -#: app/scripts/services/utils.service.js:681 +#: app/scripts/services/utils.js:723 msgid "Author" msgstr "Autor" -#: app/views/menu.html:331 +#: app/views/menu.html:347 msgid "Basic" msgstr "Básico" -#: app/views/menu.html:154 +#: app/views/menu.html:155 msgid "Basque" msgstr "Euskera" -#: app/scripts/services/blocks.service.js:680 -#: app/scripts/services/blocks.service.js:699 -#: app/scripts/services/blocks.service.js:730 -#: app/scripts/services/blocks.service.js:750 +#: app/scripts/services/blocks.js:742 app/scripts/services/blocks.js:763 +#: app/scripts/services/blocks.js:818 app/scripts/services/blocks.js:837 +#: app/scripts/services/blocks.js:872 app/scripts/services/blocks.js:911 msgid "Block updated" msgstr "Bloque actualizado" -#: app/scripts/services/project.service.js:402 +#: app/scripts/services/project.js:418 msgid "Block {{name}} imported" msgstr "Bloque {{name}} importado" -#: app/scripts/services/tools.service.js:227 +#: app/views/menu.html:35 +msgid "Blocks" +msgstr "Bloques" + +#: app/views/menu.html:201 +msgid "Board" +msgstr "Placa" + +#: app/views/menu.html:115 app/views/menu.html:192 +msgid "Board rules" +msgstr "Reglas de la placa" + +#: app/scripts/controllers/menu.js:334 +msgid "Board rules disabled" +msgstr "Reglas de la placa deshabilitadas" + +#: app/scripts/controllers/menu.js:329 +msgid "Board rules enabled" +msgstr "Reglas de la placa habilitadas" + +#: app/scripts/services/tools.js:234 msgid "Board {{name}} not detected" msgstr "Placa {{name}} no detectada" -#: app/scripts/controllers/menu.js:399 +#: app/scripts/controllers/menu.js:435 msgid "Board {{name}} selected" msgstr "Placa {{name}} seleccionada" -#: app/views/menu.html:203 -msgid "Boards" -msgstr "Placas" - -#: app/views/menu.html:221 +#: app/views/menu.html:236 msgid "Build" msgstr "Sintetizar" @@ -123,59 +117,71 @@ msgstr "Sintetizar" msgid "Cancel" msgstr "Cancelar" -#: app/scripts/services/tools.service.js:438 +#: app/scripts/services/tools.js:446 msgid "Check Internet connection..." msgstr "Comprobando conexión a Internet..." -#: app/scripts/services/tools.service.js:446 +#: app/scripts/services/tools.js:454 msgid "Check Python..." msgstr "Comprobando Python..." -#: app/views/menu.html:337 +#: app/views/menu.html:361 msgid "Code" msgstr "Código" -#: app/scripts/services/tools.service.js:577 -msgid "Collection file {{name}} added" -msgstr "Fichero de colecciones {{name}} añadido" +#: app/views/menu.html:212 +msgid "Collection" +msgstr "Colección" + +#: app/scripts/services/tools.js:631 +msgid "Collection {{name}} added" +msgstr "Colección {{name}} añadida" + +#: app/scripts/services/tools.js:625 +msgid "Collection {{name}} not replaced" +msgstr "Colección {{name}} no reemplazada" -#: app/scripts/services/tools.service.js:584 +#: app/scripts/services/tools.js:676 msgid "Collection {{name}} removed" msgstr "Colección {{name}} eliminada" -#: app/scripts/controllers/menu.js:374 +#: app/scripts/services/tools.js:621 +msgid "Collection {{name}} replaced" +msgstr "Colección {{name}} reemplazada" + +#: app/scripts/controllers/menu.js:410 msgid "Collection {{name}} selected" msgstr "Colección {{name}} seleccionada" -#: app/views/menu.html:185 app/views/menu.html:271 +#: app/views/menu.html:286 msgid "Collections" msgstr "Colecciones" -#: app/views/menu.html:317 +#: app/views/menu.html:332 msgid "Community forum" msgstr "Foro de la comunidad" -#: app/views/menu.html:336 +#: app/views/menu.html:358 msgid "Constant" msgstr "Constante" -#: app/views/menu.html:101 +#: app/views/menu.html:91 msgid "Copy" msgstr "Copiar" -#: app/views/menu.html:98 +#: app/views/menu.html:88 msgid "Cut" msgstr "Cortar" -#: app/views/menu.html:181 +#: app/views/menu.html:189 msgid "Datasheet" msgstr "Datasheet" -#: app/views/menu.html:189 +#: app/views/menu.html:216 msgid "Default" msgstr "Por defecto" -#: app/scripts/services/tools.service.js:315 +#: app/scripts/services/tools.js:322 msgid "" "Default toolchain not found. Toolchain will be downloaded. This operation " "requires Internet connection. Do you want to continue?" @@ -183,123 +189,132 @@ msgstr "" "No se encuentra la toolchain por defecto, por lo que será descargada. Esta " "operación requiere conexión a Internet. ¿Deseas continuar?" -#: app/scripts/services/utils.service.js:680 +#: app/scripts/services/utils.js:722 msgid "Description" msgstr "Descripción" -#: app/views/menu.html:264 +#: app/views/menu.html:126 app/views/menu.html:279 msgid "Disable" msgstr "Deshabilitar" -#: app/scripts/controllers/menu.js:218 +#: app/scripts/controllers/menu.js:234 msgid "Do you want to close the application?" msgstr "¿Deseas cerrar la aplicación?" -#: app/scripts/controllers/menu.js:445 +#: app/scripts/services/project.js:104 +msgid "Do you want to convert it?" +msgstr "¿Deseas convertirlo?" + +#: app/scripts/controllers/menu.js:485 msgid "Do you want to remove the {{name}} collection?" msgstr "¿Deseas eliminar la colección {{name}}?" -#: app/views/menu.html:310 +#: app/scripts/services/tools.js:617 +msgid "Do you want to replace it?" +msgstr "¿Deseas reemplazarla?" + +#: app/views/menu.html:325 msgid "Documentation" msgstr "Documentación" -#: app/views/menu.html:255 +#: app/views/menu.html:270 msgid "Drivers" msgstr "Drivers" -#: app/scripts/services/utils.service.js:449 -#: app/scripts/services/utils.service.js:517 +#: app/scripts/services/utils.js:453 app/scripts/services/utils.js:521 msgid "Drivers disabled" msgstr "Drivers deshabilitados" -#: app/scripts/services/utils.service.js:446 -#: app/scripts/services/utils.service.js:498 +#: app/scripts/services/utils.js:450 app/scripts/services/utils.js:502 msgid "Drivers enabled" msgstr "Drivers habilitados" -#: app/scripts/services/tools.service.js:239 +#: app/scripts/services/tools.js:246 msgid "Duplicated FPGA I/O ports" msgstr "Puertos E/S de la FPGA duplicados" -#: app/scripts/services/blocks.service.js:314 +#: app/scripts/services/blocks.js:370 msgid "Duplicated block attributes" msgstr "Atributos del bloque duplicados" -#: app/views/menu.html:88 +#: app/views/menu.html:78 msgid "Edit" msgstr "Editar" -#: app/views/menu.html:259 +#: app/views/menu.html:121 app/views/menu.html:274 msgid "Enable" msgstr "Habilitar" -#: app/views/menu.html:136 +#: app/views/menu.html:137 msgid "English" msgstr "Inglés" -#: app/scripts/services/blocks.service.js:126 +#: app/scripts/services/blocks.js:181 msgid "Enter the constant blocks" msgstr "Introduce los bloques constante" -#: app/scripts/services/blocks.service.js:213 +#: app/scripts/services/blocks.js:52 +msgid "Enter the input blocks" +msgstr "Introduce los bloques de entrada" + +#: app/scripts/services/blocks.js:269 msgid "Enter the input ports" msgstr "Introduce los puertos de entrada" -#: app/scripts/services/blocks.service.js:214 +#: app/scripts/services/blocks.js:112 +msgid "Enter the output blocks" +msgstr "Introduce los bloques de salida" + +#: app/scripts/services/blocks.js:270 msgid "Enter the output ports" msgstr "Introduce los puertos de salida" -#: app/scripts/services/blocks.service.js:215 +#: app/scripts/services/blocks.js:271 msgid "Enter the parameters" msgstr "Introduce los parámetros" -#: app/scripts/services/blocks.service.js:57 -msgid "Enter the ports" -msgstr "Introduce los puertos" - -#: app/scripts/controllers/menu.js:314 +#: app/scripts/controllers/menu.js:321 msgid "Enter the remote hostname user@host (experimental)" msgstr "Introduce el nombre del host remoto usuario@host (experimental)" -#: app/scripts/services/tools.service.js:338 +#: app/scripts/services/tools.js:345 msgid "Error: default toolchain not found in '{{dir}}'" msgstr "Error: toolchain por defecto no encontrada en '{{dir}}'" -#: app/scripts/services/utils.service.js:813 +#: app/scripts/services/utils.js:855 msgid "Error: {{error}}" msgstr "Error: {{error}}" -#: app/views/menu.html:38 +#: app/views/menu.html:39 msgid "Examples" msgstr "Ejemplos" -#: app/scripts/services/tools.service.js:196 +#: app/scripts/services/tools.js:204 msgid "Execute remote {{label}} ..." msgstr "Ejecutar {{label}} remoto ..." -#: app/views/menu.html:64 +#: app/views/menu.html:54 msgid "Export" msgstr "Exportar" -#: app/scripts/services/tools.service.js:470 +#: app/scripts/services/tools.js:478 msgid "Extract default apio files..." msgstr "Extraer ficheros de apio..." -#: app/scripts/services/tools.service.js:480 +#: app/scripts/services/tools.js:488 msgid "Extract default apio packages..." msgstr "Extraer paquetes de apio..." -#: app/scripts/services/tools.service.js:458 +#: app/scripts/services/tools.js:466 msgid "Extract virtual env files..." msgstr "Extraer ficheros del virtual env" -#: app/scripts/services/tools.service.js:233 -#: app/scripts/services/tools.service.js:236 +#: app/scripts/services/tools.js:240 app/scripts/services/tools.js:243 msgid "FPGA I/O ports not defined" msgstr "Puertos E/S de la FPGA no definidos" -#: app/scripts/services/blocks.service.js:58 -#: app/scripts/services/blocks.service.js:640 +#: app/scripts/services/blocks.js:113 app/scripts/services/blocks.js:53 +#: app/scripts/services/blocks.js:698 app/scripts/services/blocks.js:778 msgid "FPGA pin" msgstr "FPGA pin" @@ -307,125 +322,129 @@ msgstr "FPGA pin" msgid "File" msgstr "Archivo" -#: app/scripts/services/project.service.js:360 +#: app/scripts/services/project.js:376 msgid "" "File {{file}} already exists in the project path. Do you want to replace it?" msgstr "" "El archivo {{file}} ya existe en el directorio del proyecto. ¿Deseas " "reemplazarlo?" -#: app/scripts/services/tools.service.js:172 +#: app/scripts/services/tools.js:180 msgid "File {{file}} does not exist" msgstr "El archivo {{file}} no existe" -#: app/scripts/services/project.service.js:392 +#: app/scripts/services/project.js:408 msgid "File {{file}} imported" msgstr "Archivo {{file}} importado" -#: app/views/menu.html:114 +#: app/views/menu.html:104 msgid "Fit content" msgstr "Ajustar contenido" -#: app/views/menu.html:160 +#: app/views/menu.html:161 msgid "French" msgstr "Francés" -#: app/scripts/controllers/menu.js:197 +#: app/scripts/controllers/menu.js:213 msgid "GTKWave exported" msgstr "GTKWave exportado" -#: app/views/menu.html:148 +#: app/views/menu.html:149 msgid "Galician" msgstr "Gallego" -#: app/views/menu.html:300 +#: app/views/menu.html:315 msgid "Help" msgstr "Ayuda" -#: app/scripts/services/utils.service.js:487 +#: app/scripts/services/utils.js:491 msgid "Homebrew is required" msgstr "Es necesario Homebrew" -#: app/scripts/services/utils.service.js:694 +#: app/scripts/services/utils.js:736 msgid "Image" msgstr "Imagen" -#: app/scripts/controllers/menu.js:647 +#: app/scripts/controllers/menu.js:642 msgid "Image {{name}} saved" msgstr "Imagen {{name}} guardada" -#: app/views/menu.html:338 +#: app/views/menu.html:364 msgid "Information" msgstr "Información" -#: app/views/menu.html:334 +#: app/views/menu.html:352 msgid "Input" msgstr "Entrada" -#: app/views/menu.html:232 +#: app/views/menu.html:247 msgid "Install" msgstr "Instalar" -#: app/scripts/services/tools.service.js:475 +#: app/scripts/services/tools.js:483 msgid "Install default apio..." msgstr "Instalar apio..." -#: app/scripts/services/tools.service.js:524 +#: app/scripts/services/tools.js:532 msgid "Installation completed" msgstr "Instalación completada" -#: app/scripts/services/tools.service.js:367 -#: app/scripts/services/tools.service.js:404 +#: app/scripts/services/tools.js:375 app/scripts/services/tools.js:412 msgid "Installing toolchain" msgstr "Instalando la toolchain" -#: app/scripts/services/tools.service.js:440 -#: app/scripts/services/utils.service.js:491 +#: app/scripts/services/tools.js:448 app/scripts/services/utils.js:495 msgid "Internet connection required" msgstr "Es necesario conexión a Internet" -#: app/scripts/services/graph.service.js:186 +#: app/scripts/services/graph.js:175 msgid "Invalid Pull up connection:
    block already connected" msgstr "Conexión de Pull up no válida:
    hay un bloque conectado" -#: app/scripts/services/graph.service.js:200 +#: app/scripts/services/graph.js:189 msgid "Invalid Pull up connection:
    only Input blocks allowed" msgstr "" "Conexión de Pull up no válida:
    sólo se permiten bloques " "Entrada" -#: app/scripts/services/graph.service.js:192 +#: app/scripts/services/graph.js:181 msgid "Invalid block connection:
    Pull up already connected" msgstr "Conexión de bloque no válida:
    hay un Pull up conectado" -#: app/scripts/services/graph.service.js:151 -#: app/scripts/services/graph.service.js:158 -#: app/scripts/services/graph.service.js:165 +#: app/scripts/services/tools.js:636 +msgid "Invalid collection {{name}}" +msgstr "Colección {{name}} inválida" + +#: app/scripts/services/graph.js:140 app/scripts/services/graph.js:147 +#: app/scripts/services/graph.js:154 msgid "Invalid connection" msgstr "Conexión no válida" -#: app/scripts/services/graph.service.js:219 +#: app/scripts/services/graph.js:208 msgid "Invalid connection: {{a}} → {{b}}" msgstr "Conexión no válida: {{a}} → {{b}}" -#: app/scripts/services/graph.service.js:180 +#: app/scripts/services/graph.js:169 msgid "Invalid multiple input connections" msgstr "Conexiones de entrada múltiple no válidas" -#: app/views/menu.html:132 +#: app/views/menu.html:133 msgid "Language" msgstr "Idioma" -#: app/scripts/services/blocks.service.js:127 -#: app/scripts/services/blocks.service.js:713 +#: app/scripts/services/tools.js:579 +msgid "Load {{name}} ..." +msgstr "Cargar {{name}} ..." + +#: app/scripts/services/blocks.js:182 app/scripts/services/blocks.js:851 msgid "Local parameter" msgstr "Parámetro local" -#: app/scripts/services/tools.service.js:463 +#: app/scripts/services/tools.js:471 msgid "Make virtual env..." msgstr "Crear virtual env..." -#: app/scripts/services/utils.service.js:678 +#: app/scripts/services/utils.js:720 msgid "Name" msgstr "Nombre" @@ -433,11 +452,11 @@ msgstr "Nombre" msgid "New" msgstr "Nuevo" -#: app/scripts/services/project.service.js:85 +#: app/scripts/services/project.js:80 msgid "New project {{name}} created" msgstr "Nuevo proyecto {{name}} creado" -#: app/scripts/controllers/menu.js:463 +#: app/scripts/controllers/menu.js:503 msgid "No collections stored" msgstr "Ninguna colección almacenada" @@ -445,8 +464,7 @@ msgstr "Ninguna colección almacenada" msgid "OK" msgstr "OK" -#: app/scripts/services/project.service.js:101 -#: app/scripts/services/project.service.js:308 +#: app/scripts/services/project.js:323 app/scripts/services/project.js:97 msgid "Old project format {{version}}" msgstr "Formato de proyecto antiguo {{version}}" @@ -454,123 +472,135 @@ msgstr "Formato de proyecto antiguo {{version}}" msgid "Open" msgstr "Abrir" -#: app/scripts/services/utils.service.js:701 +#: app/scripts/services/utils.js:743 msgid "Open SVG" msgstr "Abrir SVG" -#: app/scripts/services/project.service.js:395 +#: app/scripts/services/project.js:411 msgid "Original file {{file}} does not exist" msgstr "El archivo original {{file}} no existe" -#: app/views/menu.html:335 +#: app/views/menu.html:355 msgid "Output" msgstr "Salida" -#: app/scripts/controllers/menu.js:179 +#: app/scripts/controllers/menu.js:195 msgid "PCF file exported" msgstr "Fichero PCF exportado" -#: app/views/menu.html:104 +#: app/views/menu.html:94 msgid "Paste" msgstr "Pegar" -#: app/views/menu.html:118 +#: app/views/menu.html:108 msgid "Preferences" msgstr "Preferencias" -#: app/views/menu.html:121 +#: app/views/menu.html:111 msgid "Project information" msgstr "Información del proyecto" -#: app/scripts/services/project.service.js:108 +#: app/scripts/services/project.js:122 msgid "Project {{name}} loaded" msgstr "Proyecto {{name}} cargado" -#: app/scripts/services/project.service.js:280 +#: app/scripts/services/project.js:295 msgid "Project {{name}} saved" msgstr "Proyecto {{name}} guardado" -#: app/scripts/services/tools.service.js:451 +#: app/scripts/services/tools.js:459 msgid "Python 2.7 is required" msgstr "Es necesario Python 2.7" -#: app/views/menu.html:82 +#: app/views/menu.html:72 msgid "Quit" msgstr "Salir" -#: app/views/design.html:4 +#: app/views/design.html:5 msgid "Read only" msgstr "Solo lectura" -#: app/views/menu.html:94 +#: app/views/menu.html:84 msgid "Redo" msgstr "Rehacer" -#: app/scripts/services/tools.service.js:264 +#: app/scripts/services/tools.js:271 msgid "Remote host {{name}} not connected" msgstr "Host remoto {{name}} no conectado" -#: app/views/menu.html:126 +#: app/views/menu.html:170 msgid "Remote hostname" msgstr "Nombre del host remoto" -#: app/views/menu.html:240 app/views/menu.html:279 +#: app/views/menu.html:255 app/views/menu.html:294 msgid "Remove" msgstr "Eliminar" -#: app/views/menu.html:291 +#: app/views/menu.html:306 msgid "Remove all" msgstr "Eliminar todo" -#: app/scripts/services/utils.service.js:703 +#: app/scripts/services/utils.js:745 msgid "Reset SVG" msgstr "Resetear SVG" -#: app/views/menu.html:245 +#: app/views/menu.html:260 msgid "Reset default" msgstr "Reset default" -#: app/views/menu.html:111 +#: app/views/menu.html:101 msgid "Reset view" msgstr "Resetear vista" -#: app/views/menu.html:57 +#: app/views/menu.html:47 msgid "Save" msgstr "Guardar" -#: app/scripts/services/utils.service.js:702 +#: app/scripts/services/utils.js:744 msgid "Save SVG" msgstr "Guardar SVG" -#: app/views/menu.html:60 +#: app/views/menu.html:50 msgid "Save as" msgstr "Guardar como" -#: app/views/menu.html:107 +#: app/views/menu.html:198 +msgid "Select" +msgstr "Seleccionar" + +#: app/views/menu.html:97 msgid "Select all" msgstr "Seleccionar todo" -#: app/views/menu.html:313 +#: app/scripts/services/blocks.js:54 app/scripts/services/blocks.js:699 +msgid "Show clock" +msgstr "Mostrar reloj" + +#: app/views/menu.html:328 msgid "Source code" msgstr "Código fuente" -#: app/views/menu.html:142 +#: app/views/menu.html:143 msgid "Spanish" msgstr "Español" -#: app/scripts/services/tools.service.js:185 +#: app/scripts/services/tools.js:193 msgid "Synchronize remote files ..." msgstr "Sincronizando ficheros remotos ..." -#: app/views/menu.html:73 +#: app/views/menu.html:63 msgid "Testbench" msgstr "Testbench" -#: app/scripts/controllers/menu.js:188 +#: app/scripts/controllers/menu.js:204 msgid "Testbench exported" msgstr "Testbench exportado" -#: app/scripts/controllers/menu.js:388 +#: app/scripts/services/tools.js:616 +msgid "The collection {{name}} already exists." +msgstr "La colección {{name}} ya existe." + +#: app/scripts/controllers/menu.js:424 msgid "" "The current FPGA I/O configuration will be lost. Do you want to change to " "{{name}} board?" @@ -578,16 +608,16 @@ msgstr "" "La configuración actual de E/S de la FPGA se perderá. ¿Deseas cambiar a la " "placa {{name}}?" -#: app/scripts/services/tools.service.js:343 +#: app/scripts/services/tools.js:350 msgid "The toolchain will be removed. Do you want to continue?" msgstr "La toolchain será eliminada. ¿Deseas continuar?" -#: app/scripts/services/tools.service.js:331 +#: app/scripts/services/tools.js:338 msgid "The toolchain will be restored to default. Do you want to continue?" msgstr "" "La toolchain será restaurada a los valores por defecto: ¿Deseas continuar?" -#: app/scripts/services/tools.service.js:323 +#: app/scripts/services/tools.js:330 msgid "" "The toolchain will be updated. This operation requires Internet connection. " "Do you want to continue?" @@ -595,7 +625,7 @@ msgstr "" "La toolchain será actualizada. Esta operación requiere conexión a Internet. " "¿Deseas continuar?" -#: app/scripts/services/project.service.js:329 +#: app/scripts/services/project.js:345 msgid "" "This import operation requires a project path. You need to save the current " "project. Do you want to continue?" @@ -603,299 +633,272 @@ msgstr "" "Esta operación de importación requiere una ruta del proyecto. Debes guardar " "el proyecto actual. ¿Deseas continuar?" -#: app/views/menu.html:228 +#: app/scripts/services/project.js:103 +msgid "This project is designed for the {{name}} board." +msgstr "Este proyecto está diseñado para la placa {{name}}." + +#: app/views/menu.html:243 msgid "Toolchain" msgstr "Toolchain" -#: app/scripts/services/tools.service.js:525 +#: app/scripts/services/tools.js:533 msgid "Toolchain installed" msgstr "Toolchain instalada" -#: app/scripts/services/tools.service.js:529 +#: app/scripts/services/tools.js:536 msgid "Toolchain not installed" msgstr "La toolchain no está instalada" -#: app/scripts/services/tools.service.js:100 -#: app/scripts/services/utils.service.js:529 -#: app/scripts/services/utils.service.js:545 +#: app/scripts/services/tools.js:92 app/scripts/services/utils.js:533 +#: app/scripts/services/utils.js:549 msgid "Toolchain not installed. Please, install the toolchain" msgstr "La toolchain no está instalada. Por favor, instala la toolchain" -#: app/scripts/services/tools.service.js:347 +#: app/scripts/services/tools.js:355 msgid "Toolchain removed" msgstr "Toolchain eliminada" -#: app/views/menu.html:215 +#: app/views/menu.html:230 msgid "Tools" msgstr "Herramientas" -#: app/views/menu.html:91 +#: app/views/menu.html:81 msgid "Undo" msgstr "Deshacer" -#: app/scripts/services/tools.service.js:230 +#: app/scripts/services/tools.js:237 msgid "Unknown board" msgstr "Placa desconocida" -#: app/scripts/app.js:42 +#: app/scripts/app.js:43 msgid "Untitled" msgstr "Sin título" -#: app/views/menu.html:235 +#: app/views/menu.html:250 msgid "Update" msgstr "Actualizar" -#: app/scripts/services/blocks.service.js:712 -msgid "Update the block label" -msgstr "Actualizar la etiqueta del bloque" +#: app/scripts/services/blocks.js:697 app/scripts/services/blocks.js:777 +#: app/scripts/services/blocks.js:850 +msgid "Update the block name" +msgstr "Actualiza el nombre del bloque" -#: app/scripts/services/blocks.service.js:639 -msgid "Update the port" -msgstr "Actualizar el puerto" - -#: app/views/menu.html:224 +#: app/views/menu.html:239 msgid "Upload" msgstr "Cargar" -#: app/views/menu.html:218 +#: app/views/menu.html:233 msgid "Verify" msgstr "Verificar" -#: app/scripts/controllers/menu.js:170 +#: app/scripts/controllers/menu.js:186 msgid "Verilog code exported" msgstr "Código Verilog exportado" -#: app/scripts/services/utils.service.js:679 app/views/menu.html:306 +#: app/scripts/services/utils.js:721 app/views/menu.html:321 msgid "Version" msgstr "Versión" -#: app/views/menu.html:172 +#: app/views/menu.html:180 msgid "View" msgstr "Ver" -#: app/views/menu.html:303 +#: app/views/menu.html:318 msgid "View license" msgstr "Ver licencia" -#: app/scripts/services/blocks.service.js:347 +#: app/scripts/services/blocks.js:404 msgid "Wrong block format: {{type}}" msgstr "Formato de bloque incorrecto: {{type}}" -#: app/scripts/services/blocks.service.js:146 -#: app/scripts/services/blocks.service.js:263 +#: app/scripts/services/blocks.js:132 app/scripts/services/blocks.js:201 +#: app/scripts/services/blocks.js:75 app/scripts/services/blocks.js:768 +#: app/scripts/services/blocks.js:842 app/scripts/services/blocks.js:877 +msgid "Wrong block name {{name}}" +msgstr "Nombre del bloque {{name}} incorrecto" + +#: app/scripts/services/blocks.js:319 msgid "Wrong parameter name {{name}}" msgstr "Nombre del parámetro {{name}} incorrecto" -#: app/scripts/services/blocks.service.js:233 -#: app/scripts/services/blocks.service.js:248 -#: app/scripts/services/blocks.service.js:704 -#: app/scripts/services/blocks.service.js:77 +#: app/scripts/services/blocks.js:289 app/scripts/services/blocks.js:304 msgid "Wrong port name {{name}}" msgstr "Nombre del puerto {{name}} incorrecto" -#: app/scripts/services/project.service.js:116 +#: app/scripts/services/project.js:130 msgid "Wrong project format: {{name}}" msgstr "Formato de proyecto incorrecto: {{name}}" -#: app/scripts/services/tools.service.js:261 +#: app/scripts/services/tools.js:268 msgid "Wrong remote hostname {{name}}" msgstr "Nombre del host remoto incorrecto {{name}}" -#: app/scripts/controllers/menu.js:219 +#: app/scripts/controllers/menu.js:235 msgid "Your changes will be lost if you don’t save them" msgstr "Tus cambios se perderán si no los guardas" -#. And -#: app/resources/blocks/labels.js:34 -msgid "and" -msgstr "And" - -#: app/views/design.html:5 +#: app/views/design.html:6 msgid "back" msgstr "volver" -#. Bit -#: app/resources/blocks/labels.js:4 -msgid "bit" -msgstr "Bit" - -#. Combinational -#: app/resources/blocks/labels.js:16 -msgid "combinational" -msgstr "Combinacional" - -#. Config -#: app/resources/blocks/labels.js:6 -msgid "config" -msgstr "Config" - -#. contadorAsc -#: app/resources/examples/labels.js:12 -msgid "contadorAsc" -msgstr "Contador ascendente" - -#. contadorDes -#: app/resources/examples/labels.js:14 -msgid "contadorDes" -msgstr "Contador descendente" - -#. Debouncer -#: app/resources/blocks/labels.js:58 -msgid "debouncer" -msgstr "Antirrebotes" - -#. Demux 1:2 -#: app/resources/blocks/labels.js:18 -msgid "demux_1_2" -msgstr "Demux 1:2" - -#. Demux 1:4 -#: app/resources/blocks/labels.js:20 -msgid "demux_1_4" -msgstr "Demux 1:4" - -#. Demux 1:8 -#: app/resources/blocks/labels.js:22 -msgid "demux_1_8" -msgstr "Demux 1:8" - -#. D flip-flop async -#: app/resources/blocks/labels.js:50 -msgid "dff_ar" -msgstr "Biestable D asinc" - -#. D flip-flop async -#: app/resources/blocks/labels.js:52 -msgid "dff_sr" -msgstr "Biestable D" - #. Build done -#: app/scripts/services/tools.service.js:276 +#: app/scripts/services/tools.js:283 msgid "done_build" msgstr "Sintetizado realizado" #. Upload done -#: app/scripts/services/tools.service.js:278 +#: app/scripts/services/tools.js:285 msgid "done_upload" msgstr "Carga realizada" #. Verification done -#: app/scripts/services/tools.service.js:274 +#: app/scripts/services/tools.js:281 msgid "done_verify" msgstr "Verificación realizada" -#. Gate -#: app/resources/blocks/labels.js:32 -msgid "gate" -msgstr "Puerta" - -#. Hex 7 Segment CA -#: app/resources/blocks/labels.js:26 -msgid "hex_7seg_ca" -msgstr "Hex 7 Segment AC" - -#. Hex 7 Segment CC -#: app/resources/blocks/labels.js:24 -msgid "hex_7seg_cc" -msgstr "Hex 7 Segment CC" - -#. Logic -#: app/resources/blocks/labels.js:14 -msgid "logic" -msgstr "Lógica" - -#. Mux 2:1 -#: app/resources/blocks/labels.js:28 -msgid "mux_2_1" -msgstr "Mux 2:1" - -#. Mux 4:1 -#: app/resources/blocks/labels.js:30 -msgid "mux_4_1" -msgstr "Mux 4:1" - -#. Nand -#: app/resources/blocks/labels.js:36 -msgid "nand" -msgstr "Nand" - -#. Nor -#: app/resources/blocks/labels.js:38 -msgid "nor" -msgstr "Nor" - -#. Not -#: app/resources/blocks/labels.js:40 -msgid "not" -msgstr "Not" - -#. Or -#: app/resources/blocks/labels.js:42 -msgid "or" -msgstr "Or" - -#. Pull up -#: app/resources/blocks/labels.js:8 -msgid "pull_up" -msgstr "Pull up" - -#. Pull up inv -#: app/resources/blocks/labels.js:10 -msgid "pull_up_inv" -msgstr "Pull up inv" - -#. Sequential -#: app/resources/blocks/labels.js:48 -msgid "sequential" -msgstr "Secuencial" - #. Start building ... -#: app/scripts/services/tools.service.js:64 +#: app/scripts/services/tools.js:60 msgid "start_build" msgstr "Comenzar sintetizado ..." #. Start uploading ... -#: app/scripts/services/tools.service.js:66 +#: app/scripts/services/tools.js:62 msgid "start_upload" msgstr "Comenzar carga ..." #. Start verification ... -#: app/scripts/services/tools.service.js:62 +#: app/scripts/services/tools.js:58 msgid "start_verify" msgstr "Comenzar verificación ..." -#. T flip-flop async -#: app/resources/blocks/labels.js:54 -msgid "tff_ar" -msgstr "Biestable T asinc" +#: app/scripts/controllers/menu.js:383 +msgid "{{board}} datasheet not defined" +msgstr "{{board}} datasheet no definido" -#. T flip-flop -#: app/resources/blocks/labels.js:56 -msgid "tff_sr" -msgstr "Biestable T" +#: app/scripts/controllers/menu.js:373 +msgid "{{board}} pinout not defined" +msgstr "{{board}} pinout no definido" -#. Tri-state -#: app/resources/blocks/labels.js:12 -msgid "tri_state" -msgstr "Tri-estado" +#: app/scripts/controllers/menu.js:402 +msgid "{{board}} rules not defined" +msgstr "Reglas de {{board}} no definidas" -#. Xnor -#: app/resources/blocks/labels.js:44 -msgid "xnor" -msgstr "Xnor" +#~ msgid "1_basic" +#~ msgstr "1. Básico" -#. Xor -#: app/resources/blocks/labels.js:46 -msgid "xor" -msgstr "Xor" +#~ msgid "1_led_on" +#~ msgstr "1. Encender led" -#: app/scripts/controllers/menu.js:366 -msgid "{{board}} datasheet not defined" -msgstr "{{board}} datasheet no definido" +#~ msgid "2_switch_led" +#~ msgstr "2. Interruptor con led" -#: app/scripts/controllers/menu.js:356 -msgid "{{board}} pinout not defined" -msgstr "{{board}} pinout no definido" +#~ msgid "3_switch_and_gate" +#~ msgstr "3. Interruptor con puerta and" + +#~ msgid "and" +#~ msgstr "And" + +#~ msgid "bit" +#~ msgstr "Bit" + +#~ msgid "combinational" +#~ msgstr "Combinacional" + +#~ msgid "config" +#~ msgstr "Config" + +#~ msgid "contadorAsc" +#~ msgstr "Contador ascendente" + +#~ msgid "contadorDes" +#~ msgstr "Contador descendente" + +#~ msgid "debouncer" +#~ msgstr "Antirrebotes" + +#~ msgid "demux_1_2" +#~ msgstr "Demux 1:2" + +#~ msgid "demux_1_4" +#~ msgstr "Demux 1:4" + +#~ msgid "demux_1_8" +#~ msgstr "Demux 1:8" + +#~ msgid "dff_ar" +#~ msgstr "Biestable D asinc" + +#~ msgid "dff_sr" +#~ msgstr "Biestable D" + +#~ msgid "gate" +#~ msgstr "Puerta" + +#~ msgid "hex_7seg_ca" +#~ msgstr "Hex 7 Segment AC" + +#~ msgid "hex_7seg_cc" +#~ msgstr "Hex 7 Segment CC" + +#~ msgid "logic" +#~ msgstr "Lógica" + +#~ msgid "mux_2_1" +#~ msgstr "Mux 2:1" + +#~ msgid "mux_4_1" +#~ msgstr "Mux 4:1" + +#~ msgid "nand" +#~ msgstr "Nand" + +#~ msgid "nor" +#~ msgstr "Nor" + +#~ msgid "not" +#~ msgstr "Not" + +#~ msgid "or" +#~ msgstr "Or" + +#~ msgid "pull_up" +#~ msgstr "Pull up" + +#~ msgid "pull_up_inv" +#~ msgstr "Pull up inv" + +#~ msgid "sequential" +#~ msgstr "Secuencial" + +#~ msgid "tff_ar" +#~ msgstr "Biestable T asinc" + +#~ msgid "tff_sr" +#~ msgstr "Biestable T" + +#~ msgid "tri_state" +#~ msgstr "Tri-estado" + +#~ msgid "xnor" +#~ msgstr "Xnor" + +#~ msgid "xor" +#~ msgstr "Xor" + +#~ msgid "Boards" +#~ msgstr "Placas" + +#~ msgid "Collection file {{name}} added" +#~ msgstr "Fichero de colecciones {{name}} añadido" + +#~ msgid "Enter the ports" +#~ msgstr "Introduce los puertos" + +#~ msgid "Update the block label" +#~ msgstr "Actualizar la etiqueta del bloque" + +#~ msgid "Update the port" +#~ msgstr "Actualizar el puerto" #~ msgid "Info" #~ msgstr "Info" diff --git a/app/resources/locale/eu_ES/eu_ES.po b/app/resources/locale/eu_ES/eu_ES.po index 03b6e220d..0d503d7b8 100644 --- a/app/resources/locale/eu_ES/eu_ES.po +++ b/app/resources/locale/eu_ES/eu_ES.po @@ -12,32 +12,11 @@ msgstr "" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#. 1. Basic -#: app/resources/examples/labels.js:4 -msgid "1_basic" -msgstr "1. Oinarrizkoa" - -#. 1. Led on -#: app/resources/examples/labels.js:6 -msgid "1_led_on" -msgstr "1. Leda piztu" - -#. 2. Switch led -#: app/resources/examples/labels.js:8 -msgid "2_switch_led" -msgstr "2. Pultsadorea leda" - -#. 3. Switch and gate -#: app/resources/examples/labels.js:10 -msgid "3_switch_and_gate" -msgstr "3. Pultsadorea eta AND atea" - -#: app/scripts/services/utils.service.js:452 -#: app/scripts/services/utils.service.js:532 +#: app/scripts/services/utils.js:456 app/scripts/services/utils.js:536 msgid "Unplug and reconnect the board" msgstr "Plaka deskonektatu eta konekta ezazu berriro" -#: app/scripts/services/utils.service.js:523 +#: app/scripts/services/utils.js:527 msgid "" "

    FTDI driver installation instructions

    1. Connect the FPGA " "board
    2. Replace the (Interface 0) driver of the board by " @@ -48,7 +27,7 @@ msgstr "" "honakoa: libusbK
    3. Plaka deskonektatu eta konekta ezazu " "berriro
    " -#: app/scripts/services/utils.service.js:539 +#: app/scripts/services/utils.js:543 msgid "" "

    FTDI driver uninstallation instructions

    1. Find the FPGA USB " "Device
    2. Select the board interface and uninstall the driver
    " @@ -57,66 +36,81 @@ msgstr "" "gailua bila ezazu
  • Plakaren interfazea hauta ezazu eta driver-a " "desinstalatu
  • " -#: app/views/menu.html:321 +#: app/views/menu.html:336 msgid "About Icestudio" msgstr "Icestudio-ri buruz..." -#: app/views/menu.html:275 +#: app/views/menu.html:290 msgid "Add" -msgstr "" +msgstr "Gehitu" -#: app/scripts/controllers/menu.js:431 +#: app/scripts/controllers/menu.js:471 msgid "Add a block to start" msgstr "Gehi ezazu bloke bat hasteko" -#: app/views/menu.html:35 +#: app/views/menu.html:43 msgid "Add as block" msgstr "Blokea sortu" -#: app/scripts/services/tools.service.js:590 +#: app/scripts/services/tools.js:682 msgid "All collections removed" -msgstr "" +msgstr "Bildumak ezabatu dira" -#: app/scripts/controllers/menu.js:455 +#: app/scripts/controllers/menu.js:495 msgid "All stored collections will be lost. Do you want to continue?" -msgstr "" +msgstr "Gordetako bildumak galduko dira. Jarraitu nahi al duzu?" -#: app/scripts/services/utils.service.js:681 +#: app/scripts/services/utils.js:723 msgid "Author" msgstr "Egilea" -#: app/views/menu.html:331 +#: app/views/menu.html:347 msgid "Basic" msgstr "Oinarrizkoa" -#: app/views/menu.html:154 +#: app/views/menu.html:155 msgid "Basque" msgstr "Euskara" -#: app/scripts/services/blocks.service.js:680 -#: app/scripts/services/blocks.service.js:699 -#: app/scripts/services/blocks.service.js:730 -#: app/scripts/services/blocks.service.js:750 +#: app/scripts/services/blocks.js:742 app/scripts/services/blocks.js:763 +#: app/scripts/services/blocks.js:818 app/scripts/services/blocks.js:837 +#: app/scripts/services/blocks.js:872 app/scripts/services/blocks.js:911 msgid "Block updated" msgstr "Etiketa freskatua dago" -#: app/scripts/services/project.service.js:402 +#: app/scripts/services/project.js:418 msgid "Block {{name}} imported" msgstr "{{name}} blokea inportatu duzu" -#: app/scripts/services/tools.service.js:227 +#: app/views/menu.html:35 +msgid "Blocks" +msgstr "" + +#: app/views/menu.html:201 +msgid "Board" +msgstr "" + +#: app/views/menu.html:115 app/views/menu.html:192 +msgid "Board rules" +msgstr "" + +#: app/scripts/controllers/menu.js:334 +msgid "Board rules disabled" +msgstr "" + +#: app/scripts/controllers/menu.js:329 +msgid "Board rules enabled" +msgstr "" + +#: app/scripts/services/tools.js:234 msgid "Board {{name}} not detected" msgstr "{{name}} plaka ez da aurkitu" -#: app/scripts/controllers/menu.js:399 +#: app/scripts/controllers/menu.js:435 msgid "Board {{name}} selected" msgstr "{{name}} plaka hautatu duzu" -#: app/views/menu.html:203 -msgid "Boards" -msgstr "Plakak" - -#: app/views/menu.html:221 +#: app/views/menu.html:236 msgid "Build" msgstr "Sintetizatu" @@ -124,59 +118,71 @@ msgstr "Sintetizatu" msgid "Cancel" msgstr "Utzi" -#: app/scripts/services/tools.service.js:438 +#: app/scripts/services/tools.js:446 msgid "Check Internet connection..." msgstr "Interneteko sarbidea egiaztatu..." -#: app/scripts/services/tools.service.js:446 +#: app/scripts/services/tools.js:454 msgid "Check Python..." msgstr "Python egiaztatu..." -#: app/views/menu.html:337 +#: app/views/menu.html:361 msgid "Code" msgstr "Kodea" -#: app/scripts/services/tools.service.js:577 -msgid "Collection file {{name}} added" +#: app/views/menu.html:212 +msgid "Collection" +msgstr "" + +#: app/scripts/services/tools.js:631 +msgid "Collection {{name}} added" +msgstr "" + +#: app/scripts/services/tools.js:625 +msgid "Collection {{name}} not replaced" msgstr "" -#: app/scripts/services/tools.service.js:584 +#: app/scripts/services/tools.js:676 msgid "Collection {{name}} removed" +msgstr "{{name}} bilduma ezabatu da" + +#: app/scripts/services/tools.js:621 +msgid "Collection {{name}} replaced" msgstr "" -#: app/scripts/controllers/menu.js:374 +#: app/scripts/controllers/menu.js:410 msgid "Collection {{name}} selected" -msgstr "" +msgstr "{{name}} bilduma hautatu da" -#: app/views/menu.html:185 app/views/menu.html:271 +#: app/views/menu.html:286 msgid "Collections" -msgstr "" +msgstr "Bildumak" -#: app/views/menu.html:317 +#: app/views/menu.html:332 msgid "Community forum" msgstr "Komunitatearen foroa" -#: app/views/menu.html:336 +#: app/views/menu.html:358 msgid "Constant" msgstr "Konstantea" -#: app/views/menu.html:101 +#: app/views/menu.html:91 msgid "Copy" -msgstr "" +msgstr "Kopiatu" -#: app/views/menu.html:98 +#: app/views/menu.html:88 msgid "Cut" -msgstr "" +msgstr "Ebaki" -#: app/views/menu.html:181 +#: app/views/menu.html:189 msgid "Datasheet" msgstr "Datu-fitxa" -#: app/views/menu.html:189 +#: app/views/menu.html:216 msgid "Default" -msgstr "" +msgstr "Lehenetsia" -#: app/scripts/services/tools.service.js:315 +#: app/scripts/services/tools.js:322 msgid "" "Default toolchain not found. Toolchain will be downloaded. This operation " "requires Internet connection. Do you want to continue?" @@ -184,251 +190,264 @@ msgstr "" "Toolchain lehenetsia ez da aurkitu. Hortaz, deskargatu egingo da. Eragiketak " "Interneteko sarbidea behar du, jarraitu nahi al duzu?" -#: app/scripts/services/utils.service.js:680 +#: app/scripts/services/utils.js:722 msgid "Description" msgstr "Azalpena" -#: app/views/menu.html:264 +#: app/views/menu.html:126 app/views/menu.html:279 msgid "Disable" msgstr "Desgaitu" -#: app/scripts/controllers/menu.js:218 +#: app/scripts/controllers/menu.js:234 msgid "Do you want to close the application?" +msgstr "Aplikazioa itxi nahi al duzu?" + +#: app/scripts/services/project.js:104 +msgid "Do you want to convert it?" msgstr "" -#: app/scripts/controllers/menu.js:445 +#: app/scripts/controllers/menu.js:485 msgid "Do you want to remove the {{name}} collection?" +msgstr "{{name}} bilduma ezabatu nahi al duzu?" + +#: app/scripts/services/tools.js:617 +msgid "Do you want to replace it?" msgstr "" -#: app/views/menu.html:310 +#: app/views/menu.html:325 msgid "Documentation" msgstr "Dokumentazioa" -#: app/views/menu.html:255 +#: app/views/menu.html:270 msgid "Drivers" msgstr "Driverrak" -#: app/scripts/services/utils.service.js:449 -#: app/scripts/services/utils.service.js:517 +#: app/scripts/services/utils.js:453 app/scripts/services/utils.js:521 msgid "Drivers disabled" msgstr "Driverrak desgaitu dira" -#: app/scripts/services/utils.service.js:446 -#: app/scripts/services/utils.service.js:498 +#: app/scripts/services/utils.js:450 app/scripts/services/utils.js:502 msgid "Drivers enabled" msgstr "Driverrak gaitu dira" -#: app/scripts/services/tools.service.js:239 +#: app/scripts/services/tools.js:246 msgid "Duplicated FPGA I/O ports" msgstr "FPGAren E/S portuak bikoiztu dira" -#: app/scripts/services/blocks.service.js:314 +#: app/scripts/services/blocks.js:370 msgid "Duplicated block attributes" msgstr "Blokearen ezaugarriak bikoiztu dira" -#: app/views/menu.html:88 +#: app/views/menu.html:78 msgid "Edit" msgstr "Editatu" -#: app/views/menu.html:259 +#: app/views/menu.html:121 app/views/menu.html:274 msgid "Enable" msgstr "Onartu" -#: app/views/menu.html:136 +#: app/views/menu.html:137 msgid "English" msgstr "Ingelesa" -#: app/scripts/services/blocks.service.js:126 +#: app/scripts/services/blocks.js:181 msgid "Enter the constant blocks" msgstr "Konstante-blokeak sar itzazu" -#: app/scripts/services/blocks.service.js:213 +#: app/scripts/services/blocks.js:52 +msgid "Enter the input blocks" +msgstr "" + +#: app/scripts/services/blocks.js:269 msgid "Enter the input ports" msgstr "Sarrerako portuak sar itzazu" -#: app/scripts/services/blocks.service.js:214 +#: app/scripts/services/blocks.js:112 +msgid "Enter the output blocks" +msgstr "" + +#: app/scripts/services/blocks.js:270 msgid "Enter the output ports" msgstr "Irteerako portuak sar itzazu" -#: app/scripts/services/blocks.service.js:215 +#: app/scripts/services/blocks.js:271 msgid "Enter the parameters" msgstr "Parametroak sar itzazu" -#: app/scripts/services/blocks.service.js:57 -msgid "Enter the ports" -msgstr "Portuak sar itzazu" - -#: app/scripts/controllers/menu.js:314 +#: app/scripts/controllers/menu.js:321 msgid "Enter the remote hostname user@host (experimental)" msgstr "" "Urrutiko ostalariaren izena sar ezazu erabiltzailea@host (esperimentala)" -#: app/scripts/services/tools.service.js:338 +#: app/scripts/services/tools.js:345 msgid "Error: default toolchain not found in '{{dir}}'" msgstr "Errorea: Toolchain lehenetsia ez da '{{dir}}'-en aurkitu" -#: app/scripts/services/utils.service.js:813 +#: app/scripts/services/utils.js:855 msgid "Error: {{error}}" msgstr "Errorea: {{error}}" -#: app/views/menu.html:38 +#: app/views/menu.html:39 msgid "Examples" msgstr "Adibideak" -#: app/scripts/services/tools.service.js:196 +#: app/scripts/services/tools.js:204 msgid "Execute remote {{label}} ..." msgstr "Exekutatu urrutiko {{label}} ..." -#: app/views/menu.html:64 +#: app/views/menu.html:54 msgid "Export" msgstr "Esportatu" -#: app/scripts/services/tools.service.js:470 +#: app/scripts/services/tools.js:478 msgid "Extract default apio files..." msgstr "Apio fitxategiak atera..." -#: app/scripts/services/tools.service.js:480 +#: app/scripts/services/tools.js:488 msgid "Extract default apio packages..." msgstr "Apio pakete lehenetsiak atera..." -#: app/scripts/services/tools.service.js:458 +#: app/scripts/services/tools.js:466 msgid "Extract virtual env files..." msgstr "Env birtualaren fitxategiak atera..." -#: app/scripts/services/tools.service.js:233 -#: app/scripts/services/tools.service.js:236 +#: app/scripts/services/tools.js:240 app/scripts/services/tools.js:243 msgid "FPGA I/O ports not defined" msgstr "FPGAren E/S portuak definitu gabe daude" -#: app/scripts/services/blocks.service.js:58 -#: app/scripts/services/blocks.service.js:640 +#: app/scripts/services/blocks.js:113 app/scripts/services/blocks.js:53 +#: app/scripts/services/blocks.js:698 app/scripts/services/blocks.js:778 msgid "FPGA pin" -msgstr "" +msgstr "FPGA pina" #: app/views/menu.html:26 msgid "File" msgstr "Fitxategia" -#: app/scripts/services/project.service.js:360 +#: app/scripts/services/project.js:376 msgid "" "File {{file}} already exists in the project path. Do you want to replace it?" msgstr "" "Proiektuaren direktorioan {{file}} fitxategia dagoeneko bada. Fitxategia " "ordeztu nahi al duzu?" -#: app/scripts/services/tools.service.js:172 +#: app/scripts/services/tools.js:180 msgid "File {{file}} does not exist" msgstr "Ez dago {{file}} izeneko fitxategirik" -#: app/scripts/services/project.service.js:392 +#: app/scripts/services/project.js:408 msgid "File {{file}} imported" msgstr "{{file}} fitxategia inportatu da" -#: app/views/menu.html:114 +#: app/views/menu.html:104 msgid "Fit content" -msgstr "" +msgstr "Edukia doitu" -#: app/views/menu.html:160 +#: app/views/menu.html:161 msgid "French" msgstr "Frantsesa" -#: app/scripts/controllers/menu.js:197 +#: app/scripts/controllers/menu.js:213 msgid "GTKWave exported" msgstr "GTKWave-a esportatu da" -#: app/views/menu.html:148 +#: app/views/menu.html:149 msgid "Galician" msgstr "Galegoa" -#: app/views/menu.html:300 +#: app/views/menu.html:315 msgid "Help" msgstr "Laguntza" -#: app/scripts/services/utils.service.js:487 +#: app/scripts/services/utils.js:491 msgid "Homebrew is required" msgstr "Homebrew-a behar da" -#: app/scripts/services/utils.service.js:694 +#: app/scripts/services/utils.js:736 msgid "Image" msgstr "Irudia" -#: app/scripts/controllers/menu.js:647 +#: app/scripts/controllers/menu.js:642 msgid "Image {{name}} saved" msgstr "{{name}} izeneko irudia gorde da" -#: app/views/menu.html:338 +#: app/views/menu.html:364 msgid "Information" -msgstr "" +msgstr "Informazioa" -#: app/views/menu.html:334 +#: app/views/menu.html:352 msgid "Input" msgstr "Sarrera" -#: app/views/menu.html:232 +#: app/views/menu.html:247 msgid "Install" msgstr "Instalatu" -#: app/scripts/services/tools.service.js:475 +#: app/scripts/services/tools.js:483 msgid "Install default apio..." msgstr "Apio lehenetsia instalatu..." -#: app/scripts/services/tools.service.js:524 +#: app/scripts/services/tools.js:532 msgid "Installation completed" msgstr "Instalazioa amaitu da" -#: app/scripts/services/tools.service.js:367 -#: app/scripts/services/tools.service.js:404 +#: app/scripts/services/tools.js:375 app/scripts/services/tools.js:412 msgid "Installing toolchain" msgstr "Toolchain-a instalatzen ari da" -#: app/scripts/services/tools.service.js:440 -#: app/scripts/services/utils.service.js:491 +#: app/scripts/services/tools.js:448 app/scripts/services/utils.js:495 msgid "Internet connection required" msgstr "Interneteko sarbidea behar da" -#: app/scripts/services/graph.service.js:186 +#: app/scripts/services/graph.js:175 msgid "Invalid Pull up connection:
    block already connected" msgstr "Pull up konexio baliogabea:
    blokea dagoeneko konektatua dago" -#: app/scripts/services/graph.service.js:200 +#: app/scripts/services/graph.js:189 msgid "Invalid Pull up connection:
    only Input blocks allowed" msgstr "" "Pull up konexio baliogabea:
    sarrera blokeak soilik dira " "onargarriak" -#: app/scripts/services/graph.service.js:192 +#: app/scripts/services/graph.js:181 msgid "Invalid block connection:
    Pull up already connected" msgstr "" "Bloke konexio baliogabeak:
    Pull up -a dagoeneko konektatua dago" -#: app/scripts/services/graph.service.js:151 -#: app/scripts/services/graph.service.js:158 -#: app/scripts/services/graph.service.js:165 +#: app/scripts/services/tools.js:636 +msgid "Invalid collection {{name}}" +msgstr "" + +#: app/scripts/services/graph.js:140 app/scripts/services/graph.js:147 +#: app/scripts/services/graph.js:154 msgid "Invalid connection" msgstr "Konexio baliogabea" -#: app/scripts/services/graph.service.js:219 +#: app/scripts/services/graph.js:208 msgid "Invalid connection: {{a}} → {{b}}" msgstr "Konexio baliogabea: {{a}} → {{b}}" -#: app/scripts/services/graph.service.js:180 +#: app/scripts/services/graph.js:169 msgid "Invalid multiple input connections" msgstr "Sarrerako konexio anitzak baliogabeak" -#: app/views/menu.html:132 +#: app/views/menu.html:133 msgid "Language" msgstr "Hizkuntza" -#: app/scripts/services/blocks.service.js:127 -#: app/scripts/services/blocks.service.js:713 +#: app/scripts/services/tools.js:579 +msgid "Load {{name}} ..." +msgstr "" + +#: app/scripts/services/blocks.js:182 app/scripts/services/blocks.js:851 msgid "Local parameter" msgstr "Parametro lokala" -#: app/scripts/services/tools.service.js:463 +#: app/scripts/services/tools.js:471 msgid "Make virtual env..." msgstr "Env birtuala sortu..." -#: app/scripts/services/utils.service.js:678 +#: app/scripts/services/utils.js:720 msgid "Name" msgstr "Izena" @@ -436,160 +455,171 @@ msgstr "Izena" msgid "New" msgstr "Berria" -#: app/scripts/services/project.service.js:85 +#: app/scripts/services/project.js:80 msgid "New project {{name}} created" msgstr "{{name}} proiektua sortu da" -#: app/scripts/controllers/menu.js:463 +#: app/scripts/controllers/menu.js:503 msgid "No collections stored" -msgstr "" +msgstr "Ez dago gordeta bildumarik" #: app/scripts/controllers/main.js:15 msgid "OK" msgstr "Ok" -#: app/scripts/services/project.service.js:101 -#: app/scripts/services/project.service.js:308 +#: app/scripts/services/project.js:323 app/scripts/services/project.js:97 msgid "Old project format {{version}}" -msgstr "" +msgstr "{{version}} formatuko proiektu zaharra" #: app/views/menu.html:32 msgid "Open" msgstr "Ireki" -#: app/scripts/services/utils.service.js:701 +#: app/scripts/services/utils.js:743 msgid "Open SVG" msgstr "SVGa ireki" -#: app/scripts/services/project.service.js:395 +#: app/scripts/services/project.js:411 msgid "Original file {{file}} does not exist" msgstr "Jatorrizko {{file}} fitxategia ez dago" -#: app/views/menu.html:335 +#: app/views/menu.html:355 msgid "Output" msgstr "Irteera" -#: app/scripts/controllers/menu.js:179 +#: app/scripts/controllers/menu.js:195 msgid "PCF file exported" msgstr "PCF fitxategia esportatu da" -#: app/views/menu.html:104 +#: app/views/menu.html:94 msgid "Paste" -msgstr "" +msgstr "Itsatsi" -#: app/views/menu.html:118 +#: app/views/menu.html:108 msgid "Preferences" msgstr "Lehentasunak" -#: app/views/menu.html:121 +#: app/views/menu.html:111 msgid "Project information" msgstr "Proiektuaren informazioa" -#: app/scripts/services/project.service.js:108 +#: app/scripts/services/project.js:122 msgid "Project {{name}} loaded" msgstr "{{name}} proiektua kargatu da" -#: app/scripts/services/project.service.js:280 +#: app/scripts/services/project.js:295 msgid "Project {{name}} saved" msgstr "{{name}} proiektua gorde da" -#: app/scripts/services/tools.service.js:451 +#: app/scripts/services/tools.js:459 msgid "Python 2.7 is required" msgstr "Python 2.7 behar da" -#: app/views/menu.html:82 +#: app/views/menu.html:72 msgid "Quit" msgstr "Utzi" -#: app/views/design.html:4 +#: app/views/design.html:5 msgid "Read only" msgstr "Irakurtzeko soilik" -#: app/views/menu.html:94 +#: app/views/menu.html:84 msgid "Redo" -msgstr "" +msgstr "Berregin" -#: app/scripts/services/tools.service.js:264 +#: app/scripts/services/tools.js:271 msgid "Remote host {{name}} not connected" msgstr "{{name}} urrutiko ostalaria ez dago konektatua" -#: app/views/menu.html:126 +#: app/views/menu.html:170 msgid "Remote hostname" msgstr "Urrutiko ostalariaren izena" -#: app/views/menu.html:240 app/views/menu.html:279 +#: app/views/menu.html:255 app/views/menu.html:294 msgid "Remove" msgstr "Ezabatu" -#: app/views/menu.html:291 +#: app/views/menu.html:306 msgid "Remove all" -msgstr "" +msgstr "Dena ezabatu" -#: app/scripts/services/utils.service.js:703 +#: app/scripts/services/utils.js:745 msgid "Reset SVG" msgstr "SVGa berrezarri" -#: app/views/menu.html:245 +#: app/views/menu.html:260 msgid "Reset default" msgstr "Jatorrizkoa berrezarri" -#: app/views/menu.html:111 +#: app/views/menu.html:101 msgid "Reset view" msgstr "Bista berrezarri" -#: app/views/menu.html:57 +#: app/views/menu.html:47 msgid "Save" msgstr "Gorde" -#: app/scripts/services/utils.service.js:702 +#: app/scripts/services/utils.js:744 msgid "Save SVG" msgstr "SVGa gorde" -#: app/views/menu.html:60 +#: app/views/menu.html:50 msgid "Save as" msgstr "Gorde honela" -#: app/views/menu.html:107 +#: app/views/menu.html:198 +msgid "Select" +msgstr "" + +#: app/views/menu.html:97 msgid "Select all" +msgstr "Dena hautatu" + +#: app/scripts/services/blocks.js:54 app/scripts/services/blocks.js:699 +msgid "Show clock" msgstr "" -#: app/views/menu.html:313 +#: app/views/menu.html:328 msgid "Source code" msgstr "Iturburu kodea" -#: app/views/menu.html:142 +#: app/views/menu.html:143 msgid "Spanish" msgstr "Gaztelera" -#: app/scripts/services/tools.service.js:185 +#: app/scripts/services/tools.js:193 msgid "Synchronize remote files ..." msgstr "Urrutiko fitxategiak sinkronizatu..." -#: app/views/menu.html:73 +#: app/views/menu.html:63 msgid "Testbench" msgstr "Testbench " -#: app/scripts/controllers/menu.js:188 +#: app/scripts/controllers/menu.js:204 msgid "Testbench exported" msgstr "Testbench-a esportatu da" -#: app/scripts/controllers/menu.js:388 +#: app/scripts/services/tools.js:616 +msgid "The collection {{name}} already exists." +msgstr "" + +#: app/scripts/controllers/menu.js:424 msgid "" "The current FPGA I/O configuration will be lost. Do you want to change to " "{{name}} board?" msgstr "" "FPGAaren E/S konfigurazioa galduko da. {{name}} plaka aldatu nahi duzu?" -#: app/scripts/services/tools.service.js:343 +#: app/scripts/services/tools.js:350 msgid "The toolchain will be removed. Do you want to continue?" msgstr "Toolchain-a ezabatuko da. Jarraitu nahi al duzu?" -#: app/scripts/services/tools.service.js:331 +#: app/scripts/services/tools.js:338 msgid "The toolchain will be restored to default. Do you want to continue?" msgstr "" "Toolchain-aren jatorrizko balioak berrezarriko dira. Jarraitu nahi al duzu?" -#: app/scripts/services/tools.service.js:323 +#: app/scripts/services/tools.js:330 msgid "" "The toolchain will be updated. This operation requires Internet connection. " "Do you want to continue?" @@ -597,7 +627,7 @@ msgstr "" "Toolchain-a eguneratuko da. Operazio horrek Interneteko sarbidea behar du. " "Jarraitu nahi al duzu?" -#: app/scripts/services/project.service.js:329 +#: app/scripts/services/project.js:345 msgid "" "This import operation requires a project path. You need to save the current " "project. Do you want to continue?" @@ -605,299 +635,272 @@ msgstr "" "Inportazio operazioak proiektu-bidea behar du. Uneko proiektua gorde " "beharko duzu. Jarraitu nahi al duzu?" -#: app/views/menu.html:228 +#: app/scripts/services/project.js:103 +msgid "This project is designed for the {{name}} board." +msgstr "" + +#: app/views/menu.html:243 msgid "Toolchain" msgstr "Toolchain" -#: app/scripts/services/tools.service.js:525 +#: app/scripts/services/tools.js:533 msgid "Toolchain installed" msgstr "Toolchain-a instalatu da" -#: app/scripts/services/tools.service.js:529 +#: app/scripts/services/tools.js:536 msgid "Toolchain not installed" msgstr "Toolchain-a ez da instalatu" -#: app/scripts/services/tools.service.js:100 -#: app/scripts/services/utils.service.js:529 -#: app/scripts/services/utils.service.js:545 +#: app/scripts/services/tools.js:92 app/scripts/services/utils.js:533 +#: app/scripts/services/utils.js:549 msgid "Toolchain not installed. Please, install the toolchain" msgstr "Toolchain-a ez da instalatu. Mesedez, toolchaina instala ezazu" -#: app/scripts/services/tools.service.js:347 +#: app/scripts/services/tools.js:355 msgid "Toolchain removed" msgstr "Toolchain-a ezabatu da" -#: app/views/menu.html:215 +#: app/views/menu.html:230 msgid "Tools" msgstr "Tresnak" -#: app/views/menu.html:91 +#: app/views/menu.html:81 msgid "Undo" -msgstr "" +msgstr "Desegin" -#: app/scripts/services/tools.service.js:230 +#: app/scripts/services/tools.js:237 msgid "Unknown board" msgstr "Plaka ezezaguna" -#: app/scripts/app.js:42 +#: app/scripts/app.js:43 msgid "Untitled" -msgstr "" +msgstr "Izenik gabe" -#: app/views/menu.html:235 +#: app/views/menu.html:250 msgid "Update" msgstr "Eguneratu" -#: app/scripts/services/blocks.service.js:712 -msgid "Update the block label" -msgstr "Blokearen etiketa eguneratu" - -#: app/scripts/services/blocks.service.js:639 -msgid "Update the port" -msgstr "Portua eguneratu" +#: app/scripts/services/blocks.js:697 app/scripts/services/blocks.js:777 +#: app/scripts/services/blocks.js:850 +msgid "Update the block name" +msgstr "" -#: app/views/menu.html:224 +#: app/views/menu.html:239 msgid "Upload" msgstr "Kargatu" -#: app/views/menu.html:218 +#: app/views/menu.html:233 msgid "Verify" msgstr "Egiaztatu" -#: app/scripts/controllers/menu.js:170 +#: app/scripts/controllers/menu.js:186 msgid "Verilog code exported" msgstr "Verilog kodea esportatu da" -#: app/scripts/services/utils.service.js:679 app/views/menu.html:306 +#: app/scripts/services/utils.js:721 app/views/menu.html:321 msgid "Version" msgstr "Bertsioa" -#: app/views/menu.html:172 +#: app/views/menu.html:180 msgid "View" msgstr "Ikusi" -#: app/views/menu.html:303 +#: app/views/menu.html:318 msgid "View license" msgstr "Lizentzia ikusi" -#: app/scripts/services/blocks.service.js:347 +#: app/scripts/services/blocks.js:404 msgid "Wrong block format: {{type}}" msgstr "Blokearen formatua okerra da: {{type}}" -#: app/scripts/services/blocks.service.js:146 -#: app/scripts/services/blocks.service.js:263 +#: app/scripts/services/blocks.js:132 app/scripts/services/blocks.js:201 +#: app/scripts/services/blocks.js:75 app/scripts/services/blocks.js:768 +#: app/scripts/services/blocks.js:842 app/scripts/services/blocks.js:877 +msgid "Wrong block name {{name}}" +msgstr "" + +#: app/scripts/services/blocks.js:319 msgid "Wrong parameter name {{name}}" msgstr "Parametroaren formatua okerra da: {{name}}" -#: app/scripts/services/blocks.service.js:233 -#: app/scripts/services/blocks.service.js:248 -#: app/scripts/services/blocks.service.js:704 -#: app/scripts/services/blocks.service.js:77 +#: app/scripts/services/blocks.js:289 app/scripts/services/blocks.js:304 msgid "Wrong port name {{name}}" msgstr "Portuaren izena okerra da: {{name}}" -#: app/scripts/services/project.service.js:116 +#: app/scripts/services/project.js:130 msgid "Wrong project format: {{name}}" msgstr "Proiektuaren formatua okerra da: {{name}}" -#: app/scripts/services/tools.service.js:261 +#: app/scripts/services/tools.js:268 msgid "Wrong remote hostname {{name}}" msgstr "Urrutiko ostalariaren {{name}} izena okerra da" -#: app/scripts/controllers/menu.js:219 +#: app/scripts/controllers/menu.js:235 msgid "Your changes will be lost if you don’t save them" -msgstr "" +msgstr "Aldaketak galduko dituzu gordetzen ez badituzu" -#. And -#: app/resources/blocks/labels.js:34 -msgid "and" -msgstr "And" - -#: app/views/design.html:5 +#: app/views/design.html:6 msgid "back" msgstr "atzera" -#. Bit -#: app/resources/blocks/labels.js:4 -msgid "bit" -msgstr "Bit" - -#. Combinational -#: app/resources/blocks/labels.js:16 -msgid "combinational" -msgstr "Konbinazionala" - -#. Config -#: app/resources/blocks/labels.js:6 -msgid "config" -msgstr "Config" - -#. contadorAsc -#: app/resources/examples/labels.js:12 -msgid "contadorAsc" -msgstr "Goranzko zenbatzailea" - -#. contadorDes -#: app/resources/examples/labels.js:14 -msgid "contadorDes" -msgstr "Beheranzko zenbatzailea" - -#. Debouncer -#: app/resources/blocks/labels.js:58 -msgid "debouncer" -msgstr "Erreboteen aurkakoa" - -#. Demux 1:2 -#: app/resources/blocks/labels.js:18 -msgid "demux_1_2" -msgstr "Demux 1:2" - -#. Demux 1:4 -#: app/resources/blocks/labels.js:20 -msgid "demux_1_4" -msgstr "Demux 1:4" - -#. Demux 1:8 -#: app/resources/blocks/labels.js:22 -msgid "demux_1_8" -msgstr "Demux 1:8" - -#. D flip-flop async -#: app/resources/blocks/labels.js:50 -msgid "dff_ar" -msgstr "D biegonkor asink" - -#. D flip-flop async -#: app/resources/blocks/labels.js:52 -msgid "dff_sr" -msgstr "D biegonkorra" - #. Build done -#: app/scripts/services/tools.service.js:276 +#: app/scripts/services/tools.js:283 msgid "done_build" msgstr "Sintetizatua egin da" #. Upload done -#: app/scripts/services/tools.service.js:278 +#: app/scripts/services/tools.js:285 msgid "done_upload" msgstr "Karga egin da" #. Verification done -#: app/scripts/services/tools.service.js:274 +#: app/scripts/services/tools.js:281 msgid "done_verify" msgstr "Egiaztapena egin da" -#. Gate -#: app/resources/blocks/labels.js:32 -msgid "gate" -msgstr "Atea" - -#. Hex 7 Segment CA -#: app/resources/blocks/labels.js:26 -msgid "hex_7seg_ca" -msgstr "Hex 7 Segment CA" - -#. Hex 7 Segment CC -#: app/resources/blocks/labels.js:24 -msgid "hex_7seg_cc" -msgstr "Hex 7 Segment CC" - -#. Logic -#: app/resources/blocks/labels.js:14 -msgid "logic" -msgstr "Logika" - -#. Mux 2:1 -#: app/resources/blocks/labels.js:28 -msgid "mux_2_1" -msgstr "Mux 2:1" - -#. Mux 4:1 -#: app/resources/blocks/labels.js:30 -msgid "mux_4_1" -msgstr "Mux 4:1" - -#. Nand -#: app/resources/blocks/labels.js:36 -msgid "nand" -msgstr "Nand" - -#. Nor -#: app/resources/blocks/labels.js:38 -msgid "nor" -msgstr "Nor" - -#. Not -#: app/resources/blocks/labels.js:40 -msgid "not" -msgstr "Not" - -#. Or -#: app/resources/blocks/labels.js:42 -msgid "or" -msgstr "Or" - -#. Pull up -#: app/resources/blocks/labels.js:8 -msgid "pull_up" -msgstr "Pull up" - -#. Pull up inv -#: app/resources/blocks/labels.js:10 -msgid "pull_up_inv" -msgstr "Pull up inv" - -#. Sequential -#: app/resources/blocks/labels.js:48 -msgid "sequential" -msgstr "Sekuentziala" - #. Start building ... -#: app/scripts/services/tools.service.js:64 +#: app/scripts/services/tools.js:60 msgid "start_build" msgstr "Sintetizatua hasi ..." #. Start uploading ... -#: app/scripts/services/tools.service.js:66 +#: app/scripts/services/tools.js:62 msgid "start_upload" msgstr "Karga hasi ..." #. Start verification ... -#: app/scripts/services/tools.service.js:62 +#: app/scripts/services/tools.js:58 msgid "start_verify" msgstr "Egiaztapena hasi ..." -#. T flip-flop async -#: app/resources/blocks/labels.js:54 -msgid "tff_ar" -msgstr "T biegonkor asink" +#: app/scripts/controllers/menu.js:383 +msgid "{{board}} datasheet not defined" +msgstr "{{board}} ez zehaztua" -#. T flip-flop -#: app/resources/blocks/labels.js:56 -msgid "tff_sr" -msgstr "T biegonkorra" +#: app/scripts/controllers/menu.js:373 +msgid "{{board}} pinout not defined" +msgstr "{{board}} pinout ez zehaztua" -#. Tri-state -#: app/resources/blocks/labels.js:12 -msgid "tri_state" -msgstr "Tri-state" +#: app/scripts/controllers/menu.js:402 +msgid "{{board}} rules not defined" +msgstr "" -#. Xnor -#: app/resources/blocks/labels.js:44 -msgid "xnor" -msgstr "Xnor" +#~ msgid "1_basic" +#~ msgstr "1. Oinarrizkoa" -#. Xor -#: app/resources/blocks/labels.js:46 -msgid "xor" -msgstr "Xor" +#~ msgid "1_led_on" +#~ msgstr "1. Leda piztu" -#: app/scripts/controllers/menu.js:366 -msgid "{{board}} datasheet not defined" -msgstr "{{board}} ez zehaztua" +#~ msgid "2_switch_led" +#~ msgstr "2. Pultsadorea leda" -#: app/scripts/controllers/menu.js:356 -msgid "{{board}} pinout not defined" -msgstr "{{board}} pinout ez zehaztua" +#~ msgid "3_switch_and_gate" +#~ msgstr "3. Pultsadorea eta AND atea" + +#~ msgid "Boards" +#~ msgstr "Plakak" + +#~ msgid "Collection file {{name}} added" +#~ msgstr "{{name}} bildumen fitxategia gehitu da" + +#~ msgid "Enter the ports" +#~ msgstr "Portuak sar itzazu" + +#~ msgid "Update the block label" +#~ msgstr "Blokearen etiketa eguneratu" + +#~ msgid "Update the port" +#~ msgstr "Portua eguneratu" + +#~ msgid "and" +#~ msgstr "And" + +#~ msgid "bit" +#~ msgstr "Bit" + +#~ msgid "combinational" +#~ msgstr "Konbinazionala" + +#~ msgid "config" +#~ msgstr "Config" + +#~ msgid "contadorAsc" +#~ msgstr "Goranzko zenbatzailea" + +#~ msgid "contadorDes" +#~ msgstr "Beheranzko zenbatzailea" + +#~ msgid "debouncer" +#~ msgstr "Erreboteen aurkakoa" + +#~ msgid "demux_1_2" +#~ msgstr "Demux 1:2" + +#~ msgid "demux_1_4" +#~ msgstr "Demux 1:4" + +#~ msgid "demux_1_8" +#~ msgstr "Demux 1:8" + +#~ msgid "dff_ar" +#~ msgstr "D biegonkor asink" + +#~ msgid "dff_sr" +#~ msgstr "D biegonkorra" + +#~ msgid "gate" +#~ msgstr "Atea" + +#~ msgid "hex_7seg_ca" +#~ msgstr "Hex 7 Segment CA" + +#~ msgid "hex_7seg_cc" +#~ msgstr "Hex 7 Segment CC" + +#~ msgid "logic" +#~ msgstr "Logika" + +#~ msgid "mux_2_1" +#~ msgstr "Mux 2:1" + +#~ msgid "mux_4_1" +#~ msgstr "Mux 4:1" + +#~ msgid "nand" +#~ msgstr "Nand" + +#~ msgid "nor" +#~ msgstr "Nor" + +#~ msgid "not" +#~ msgstr "Not" + +#~ msgid "or" +#~ msgstr "Or" + +#~ msgid "pull_up" +#~ msgstr "Pull up" + +#~ msgid "pull_up_inv" +#~ msgstr "Pull up inv" + +#~ msgid "sequential" +#~ msgstr "Sekuentziala" + +#~ msgid "tff_ar" +#~ msgstr "T biegonkor asink" + +#~ msgid "tff_sr" +#~ msgstr "T biegonkorra" + +#~ msgid "tri_state" +#~ msgstr "Tri-state" + +#~ msgid "xnor" +#~ msgstr "Xnor" + +#~ msgid "xor" +#~ msgstr "Xor" #~ msgid "Info" #~ msgstr "Info" diff --git a/app/resources/locale/fr_FR/fr_FR.po b/app/resources/locale/fr_FR/fr_FR.po index fd9bbf312..7d5ddb00b 100644 --- a/app/resources/locale/fr_FR/fr_FR.po +++ b/app/resources/locale/fr_FR/fr_FR.po @@ -12,32 +12,11 @@ msgstr "" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#. 1. Basic -#: app/resources/examples/labels.js:4 -msgid "1_basic" -msgstr "1. Basique" - -#. 1. Led on -#: app/resources/examples/labels.js:6 -msgid "1_led_on" -msgstr "1. Led on" - -#. 2. Switch led -#: app/resources/examples/labels.js:8 -msgid "2_switch_led" -msgstr "2. Switch led" - -#. 3. Switch and gate -#: app/resources/examples/labels.js:10 -msgid "3_switch_and_gate" -msgstr "3. Switch and gate" - -#: app/scripts/services/utils.service.js:452 -#: app/scripts/services/utils.service.js:532 +#: app/scripts/services/utils.js:456 app/scripts/services/utils.js:536 msgid "Unplug and reconnect the board" msgstr "Débrancher et reconnecter la carte" -#: app/scripts/services/utils.service.js:523 +#: app/scripts/services/utils.js:527 msgid "" "

    FTDI driver installation instructions

    1. Connect the FPGA " "board
    2. Replace the (Interface 0) driver of the board by " @@ -47,7 +26,7 @@ msgstr "" "carte FPGA
    3. Remplacer le pilote (Interface 0) de la carte par " "libusbK
    4. Débrancher puis rebrancher la carte
    " -#: app/scripts/services/utils.service.js:539 +#: app/scripts/services/utils.js:543 msgid "" "

    FTDI driver uninstallation instructions

    1. Find the FPGA USB " "Device
    2. Select the board interface and uninstall the driver
    " @@ -56,68 +35,83 @@ msgstr "" "périphérique USB FPGA
  • Sélectionner la carte interface et " "désinstaller le pilote
  • " -#: app/views/menu.html:321 +#: app/views/menu.html:336 msgid "About Icestudio" msgstr "À propos d'Icestudio" -#: app/views/menu.html:275 +#: app/views/menu.html:290 msgid "Add" msgstr "" -#: app/scripts/controllers/menu.js:431 +#: app/scripts/controllers/menu.js:471 msgid "Add a block to start" msgstr "Ajouter un bloc pour commencer" -#: app/views/menu.html:35 +#: app/views/menu.html:43 #, fuzzy msgid "Add as block" msgstr "Ajouter un bloc pour commencer" -#: app/scripts/services/tools.service.js:590 +#: app/scripts/services/tools.js:682 msgid "All collections removed" msgstr "" -#: app/scripts/controllers/menu.js:455 +#: app/scripts/controllers/menu.js:495 msgid "All stored collections will be lost. Do you want to continue?" msgstr "" -#: app/scripts/services/utils.service.js:681 +#: app/scripts/services/utils.js:723 msgid "Author" msgstr "" -#: app/views/menu.html:331 +#: app/views/menu.html:347 msgid "Basic" msgstr "Basique" -#: app/views/menu.html:154 +#: app/views/menu.html:155 msgid "Basque" msgstr "Basque" -#: app/scripts/services/blocks.service.js:680 -#: app/scripts/services/blocks.service.js:699 -#: app/scripts/services/blocks.service.js:730 -#: app/scripts/services/blocks.service.js:750 +#: app/scripts/services/blocks.js:742 app/scripts/services/blocks.js:763 +#: app/scripts/services/blocks.js:818 app/scripts/services/blocks.js:837 +#: app/scripts/services/blocks.js:872 app/scripts/services/blocks.js:911 #, fuzzy msgid "Block updated" msgstr "Titre mis à jour" -#: app/scripts/services/project.service.js:402 +#: app/scripts/services/project.js:418 msgid "Block {{name}} imported" msgstr "Bloc {{name}} importé" -#: app/scripts/services/tools.service.js:227 +#: app/views/menu.html:35 +msgid "Blocks" +msgstr "" + +#: app/views/menu.html:201 +msgid "Board" +msgstr "" + +#: app/views/menu.html:115 app/views/menu.html:192 +msgid "Board rules" +msgstr "" + +#: app/scripts/controllers/menu.js:334 +msgid "Board rules disabled" +msgstr "" + +#: app/scripts/controllers/menu.js:329 +msgid "Board rules enabled" +msgstr "" + +#: app/scripts/services/tools.js:234 msgid "Board {{name}} not detected" msgstr "Carte {{name}} non détectée" -#: app/scripts/controllers/menu.js:399 +#: app/scripts/controllers/menu.js:435 msgid "Board {{name}} selected" msgstr "Carte {{name}} séléctionnée" -#: app/views/menu.html:203 -msgid "Boards" -msgstr "Cartes" - -#: app/views/menu.html:221 +#: app/views/menu.html:236 msgid "Build" msgstr "Construire" @@ -125,59 +119,71 @@ msgstr "Construire" msgid "Cancel" msgstr "Annuler" -#: app/scripts/services/tools.service.js:438 +#: app/scripts/services/tools.js:446 msgid "Check Internet connection..." msgstr "Vérifier la connexion Internet..." -#: app/scripts/services/tools.service.js:446 +#: app/scripts/services/tools.js:454 msgid "Check Python..." msgstr "Vérifier Python..." -#: app/views/menu.html:337 +#: app/views/menu.html:361 msgid "Code" msgstr "Code" -#: app/scripts/services/tools.service.js:577 -msgid "Collection file {{name}} added" +#: app/views/menu.html:212 +msgid "Collection" +msgstr "" + +#: app/scripts/services/tools.js:631 +msgid "Collection {{name}} added" msgstr "" -#: app/scripts/services/tools.service.js:584 +#: app/scripts/services/tools.js:625 +msgid "Collection {{name}} not replaced" +msgstr "" + +#: app/scripts/services/tools.js:676 msgid "Collection {{name}} removed" msgstr "" -#: app/scripts/controllers/menu.js:374 +#: app/scripts/services/tools.js:621 +msgid "Collection {{name}} replaced" +msgstr "" + +#: app/scripts/controllers/menu.js:410 msgid "Collection {{name}} selected" msgstr "" -#: app/views/menu.html:185 app/views/menu.html:271 +#: app/views/menu.html:286 msgid "Collections" msgstr "" -#: app/views/menu.html:317 +#: app/views/menu.html:332 msgid "Community forum" msgstr "Forum communautaire" -#: app/views/menu.html:336 +#: app/views/menu.html:358 msgid "Constant" msgstr "" -#: app/views/menu.html:101 +#: app/views/menu.html:91 msgid "Copy" msgstr "" -#: app/views/menu.html:98 +#: app/views/menu.html:88 msgid "Cut" msgstr "" -#: app/views/menu.html:181 +#: app/views/menu.html:189 msgid "Datasheet" msgstr "Documentation" -#: app/views/menu.html:189 +#: app/views/menu.html:216 msgid "Default" msgstr "" -#: app/scripts/services/tools.service.js:315 +#: app/scripts/services/tools.js:322 msgid "" "Default toolchain not found. Toolchain will be downloaded. This operation " "requires Internet connection. Do you want to continue?" @@ -186,126 +192,134 @@ msgstr "" "téléchargée. Cette operation nécessite une connexion internet.Voulez-vous " "continuer ?" -#: app/scripts/services/utils.service.js:680 +#: app/scripts/services/utils.js:722 msgid "Description" msgstr "" -#: app/views/menu.html:264 +#: app/views/menu.html:126 app/views/menu.html:279 msgid "Disable" msgstr "Désactiver" -#: app/scripts/controllers/menu.js:218 +#: app/scripts/controllers/menu.js:234 msgid "Do you want to close the application?" msgstr "" -#: app/scripts/controllers/menu.js:445 +#: app/scripts/services/project.js:104 +msgid "Do you want to convert it?" +msgstr "" + +#: app/scripts/controllers/menu.js:485 msgid "Do you want to remove the {{name}} collection?" msgstr "" -#: app/views/menu.html:310 +#: app/scripts/services/tools.js:617 +msgid "Do you want to replace it?" +msgstr "" + +#: app/views/menu.html:325 msgid "Documentation" msgstr "Documentation" -#: app/views/menu.html:255 +#: app/views/menu.html:270 msgid "Drivers" msgstr "Pilote" -#: app/scripts/services/utils.service.js:449 -#: app/scripts/services/utils.service.js:517 +#: app/scripts/services/utils.js:453 app/scripts/services/utils.js:521 msgid "Drivers disabled" msgstr "Pilote désactivé" -#: app/scripts/services/utils.service.js:446 -#: app/scripts/services/utils.service.js:498 +#: app/scripts/services/utils.js:450 app/scripts/services/utils.js:502 msgid "Drivers enabled" msgstr "Pilote activé" -#: app/scripts/services/tools.service.js:239 +#: app/scripts/services/tools.js:246 msgid "Duplicated FPGA I/O ports" msgstr "Ports d'entrée sortie FPGA dupliqué" -#: app/scripts/services/blocks.service.js:314 +#: app/scripts/services/blocks.js:370 msgid "Duplicated block attributes" msgstr "" -#: app/views/menu.html:88 +#: app/views/menu.html:78 msgid "Edit" msgstr "Édition" -#: app/views/menu.html:259 +#: app/views/menu.html:121 app/views/menu.html:274 msgid "Enable" msgstr "Activer" -#: app/views/menu.html:136 +#: app/views/menu.html:137 msgid "English" msgstr "Anglais" -#: app/scripts/services/blocks.service.js:126 +#: app/scripts/services/blocks.js:181 #, fuzzy msgid "Enter the constant blocks" msgstr "Entrer les ports de sortie" -#: app/scripts/services/blocks.service.js:213 +#: app/scripts/services/blocks.js:52 +msgid "Enter the input blocks" +msgstr "" + +#: app/scripts/services/blocks.js:269 msgid "Enter the input ports" msgstr "Entrer les ports d'entrée" -#: app/scripts/services/blocks.service.js:214 +#: app/scripts/services/blocks.js:112 +msgid "Enter the output blocks" +msgstr "" + +#: app/scripts/services/blocks.js:270 msgid "Enter the output ports" msgstr "Entrer les ports de sortie" -#: app/scripts/services/blocks.service.js:215 +#: app/scripts/services/blocks.js:271 #, fuzzy msgid "Enter the parameters" msgstr "Entrer les ports d'entrée" -#: app/scripts/services/blocks.service.js:57 -#, fuzzy -msgid "Enter the ports" -msgstr "Entrer les ports d'entrée" - -#: app/scripts/controllers/menu.js:314 +#: app/scripts/controllers/menu.js:321 msgid "Enter the remote hostname user@host (experimental)" msgstr "Entrer le hostname distant user@host (experimentale)" -#: app/scripts/services/tools.service.js:338 +#: app/scripts/services/tools.js:345 msgid "Error: default toolchain not found in '{{dir}}'" msgstr "Erreur: La toolchaine par défaut n'a pas été trouvée dans '{{dir}}'" -#: app/scripts/services/utils.service.js:813 +#: app/scripts/services/utils.js:855 msgid "Error: {{error}}" msgstr "Erreur: {{error}}" -#: app/views/menu.html:38 +#: app/views/menu.html:39 msgid "Examples" msgstr "Exemples" -#: app/scripts/services/tools.service.js:196 +#: app/scripts/services/tools.js:204 msgid "Execute remote {{label}} ..." msgstr "Executer à distance {{label}} ..." -#: app/views/menu.html:64 +#: app/views/menu.html:54 msgid "Export" msgstr "Exporter" -#: app/scripts/services/tools.service.js:470 +#: app/scripts/services/tools.js:478 msgid "Extract default apio files..." msgstr "Extraction des fichiers apio par défaut..." -#: app/scripts/services/tools.service.js:480 +#: app/scripts/services/tools.js:488 msgid "Extract default apio packages..." msgstr "Extraction des packets apio par défaut" -#: app/scripts/services/tools.service.js:458 +#: app/scripts/services/tools.js:466 msgid "Extract virtual env files..." msgstr "Extraction des fichiers d'environnement virtuels" -#: app/scripts/services/tools.service.js:233 -#: app/scripts/services/tools.service.js:236 +#: app/scripts/services/tools.js:240 app/scripts/services/tools.js:243 msgid "FPGA I/O ports not defined" msgstr "Ports d'entrée sortie FPGA non définits" -#: app/scripts/services/blocks.service.js:58 -#: app/scripts/services/blocks.service.js:640 +#: app/scripts/services/blocks.js:113 app/scripts/services/blocks.js:53 +#: app/scripts/services/blocks.js:698 app/scripts/services/blocks.js:778 msgid "FPGA pin" msgstr "" @@ -313,125 +327,129 @@ msgstr "" msgid "File" msgstr "Fichier" -#: app/scripts/services/project.service.js:360 +#: app/scripts/services/project.js:376 msgid "" "File {{file}} already exists in the project path. Do you want to replace it?" msgstr "" "Le Fichier {{file}} existe déjà dans le chemin du projet. Voulez vous " "leremplacer ?" -#: app/scripts/services/tools.service.js:172 +#: app/scripts/services/tools.js:180 msgid "File {{file}} does not exist" msgstr "Le fichier {{file}} n'existe pas" -#: app/scripts/services/project.service.js:392 +#: app/scripts/services/project.js:408 msgid "File {{file}} imported" msgstr "Fichier {{file}} importé" -#: app/views/menu.html:114 +#: app/views/menu.html:104 msgid "Fit content" msgstr "" -#: app/views/menu.html:160 +#: app/views/menu.html:161 msgid "French" msgstr "Français" -#: app/scripts/controllers/menu.js:197 +#: app/scripts/controllers/menu.js:213 msgid "GTKWave exported" msgstr "GTKWave exporté" -#: app/views/menu.html:148 +#: app/views/menu.html:149 msgid "Galician" msgstr "Galois" -#: app/views/menu.html:300 +#: app/views/menu.html:315 msgid "Help" msgstr "Aide" -#: app/scripts/services/utils.service.js:487 +#: app/scripts/services/utils.js:491 msgid "Homebrew is required" msgstr "Homebrew est requis" -#: app/scripts/services/utils.service.js:694 +#: app/scripts/services/utils.js:736 #, fuzzy msgid "Image" msgstr "Chemin image" -#: app/scripts/controllers/menu.js:647 +#: app/scripts/controllers/menu.js:642 msgid "Image {{name}} saved" msgstr "Image {{name}} sauvée" -#: app/views/menu.html:338 +#: app/views/menu.html:364 msgid "Information" msgstr "" -#: app/views/menu.html:334 +#: app/views/menu.html:352 msgid "Input" msgstr "Entrée" -#: app/views/menu.html:232 +#: app/views/menu.html:247 msgid "Install" msgstr "Installation" -#: app/scripts/services/tools.service.js:475 +#: app/scripts/services/tools.js:483 msgid "Install default apio..." msgstr "Installer l'apio par défaut..." -#: app/scripts/services/tools.service.js:524 +#: app/scripts/services/tools.js:532 msgid "Installation completed" msgstr "Installation terminée" -#: app/scripts/services/tools.service.js:367 -#: app/scripts/services/tools.service.js:404 +#: app/scripts/services/tools.js:375 app/scripts/services/tools.js:412 msgid "Installing toolchain" msgstr "Installation de la toolchain" -#: app/scripts/services/tools.service.js:440 -#: app/scripts/services/utils.service.js:491 +#: app/scripts/services/tools.js:448 app/scripts/services/utils.js:495 msgid "Internet connection required" msgstr "Une connexion internet est requise" -#: app/scripts/services/graph.service.js:186 +#: app/scripts/services/graph.js:175 msgid "Invalid Pull up connection:
    block already connected" msgstr "Connexion de Pull up invalide:
    Le bloc est déjà connecté" -#: app/scripts/services/graph.service.js:200 +#: app/scripts/services/graph.js:189 msgid "Invalid Pull up connection:
    only Input blocks allowed" msgstr "Connexion de Pull up invalide:
    Une seule entrée autorisée" -#: app/scripts/services/graph.service.js:192 +#: app/scripts/services/graph.js:181 msgid "Invalid block connection:
    Pull up already connected" msgstr "Connexion de bloc invalide:
    Pull up déjà connectée" -#: app/scripts/services/graph.service.js:151 -#: app/scripts/services/graph.service.js:158 -#: app/scripts/services/graph.service.js:165 +#: app/scripts/services/tools.js:636 +msgid "Invalid collection {{name}}" +msgstr "" + +#: app/scripts/services/graph.js:140 app/scripts/services/graph.js:147 +#: app/scripts/services/graph.js:154 msgid "Invalid connection" msgstr "Connexion invalide" -#: app/scripts/services/graph.service.js:219 +#: app/scripts/services/graph.js:208 #, fuzzy msgid "Invalid connection: {{a}} → {{b}}" msgstr "Connexion invalide" -#: app/scripts/services/graph.service.js:180 +#: app/scripts/services/graph.js:169 msgid "Invalid multiple input connections" msgstr "Connexions de multiples entrées invalides" -#: app/views/menu.html:132 +#: app/views/menu.html:133 msgid "Language" msgstr "Langage" -#: app/scripts/services/blocks.service.js:127 -#: app/scripts/services/blocks.service.js:713 +#: app/scripts/services/tools.js:579 +msgid "Load {{name}} ..." +msgstr "" + +#: app/scripts/services/blocks.js:182 app/scripts/services/blocks.js:851 msgid "Local parameter" msgstr "" -#: app/scripts/services/tools.service.js:463 +#: app/scripts/services/tools.js:471 msgid "Make virtual env..." msgstr "Faire l'environnement virtuel..." -#: app/scripts/services/utils.service.js:678 +#: app/scripts/services/utils.js:720 msgid "Name" msgstr "" @@ -439,11 +457,11 @@ msgstr "" msgid "New" msgstr "" -#: app/scripts/services/project.service.js:85 +#: app/scripts/services/project.js:80 msgid "New project {{name}} created" msgstr "Nouveau projet {{name}} créé" -#: app/scripts/controllers/menu.js:463 +#: app/scripts/controllers/menu.js:503 msgid "No collections stored" msgstr "" @@ -451,8 +469,7 @@ msgstr "" msgid "OK" msgstr "OK" -#: app/scripts/services/project.service.js:101 -#: app/scripts/services/project.service.js:308 +#: app/scripts/services/project.js:323 app/scripts/services/project.js:97 msgid "Old project format {{version}}" msgstr "" @@ -460,125 +477,137 @@ msgstr "" msgid "Open" msgstr "" -#: app/scripts/services/utils.service.js:701 +#: app/scripts/services/utils.js:743 msgid "Open SVG" msgstr "" -#: app/scripts/services/project.service.js:395 +#: app/scripts/services/project.js:411 msgid "Original file {{file}} does not exist" msgstr "Le fichier originel {{file}} n'éxiste pas" -#: app/views/menu.html:335 +#: app/views/menu.html:355 msgid "Output" msgstr "Sortie" -#: app/scripts/controllers/menu.js:179 +#: app/scripts/controllers/menu.js:195 msgid "PCF file exported" msgstr "Fichier PCF exporté" -#: app/views/menu.html:104 +#: app/views/menu.html:94 msgid "Paste" msgstr "" -#: app/views/menu.html:118 +#: app/views/menu.html:108 msgid "Preferences" msgstr "Préférences" -#: app/views/menu.html:121 +#: app/views/menu.html:111 msgid "Project information" msgstr "" -#: app/scripts/services/project.service.js:108 +#: app/scripts/services/project.js:122 msgid "Project {{name}} loaded" msgstr "Projet {{name}} chargé" -#: app/scripts/services/project.service.js:280 +#: app/scripts/services/project.js:295 msgid "Project {{name}} saved" msgstr "Projet {{name}} sauvegardé" -#: app/scripts/services/tools.service.js:451 +#: app/scripts/services/tools.js:459 msgid "Python 2.7 is required" msgstr "Python 2.7 est requis" -#: app/views/menu.html:82 +#: app/views/menu.html:72 msgid "Quit" msgstr "" -#: app/views/design.html:4 +#: app/views/design.html:5 msgid "Read only" msgstr "Lecture seule" -#: app/views/menu.html:94 +#: app/views/menu.html:84 msgid "Redo" msgstr "" -#: app/scripts/services/tools.service.js:264 +#: app/scripts/services/tools.js:271 msgid "Remote host {{name}} not connected" msgstr "Remote host {{name}} not connected" -#: app/views/menu.html:126 +#: app/views/menu.html:170 msgid "Remote hostname" msgstr "Hostname distant" -#: app/views/menu.html:240 app/views/menu.html:279 +#: app/views/menu.html:255 app/views/menu.html:294 msgid "Remove" msgstr "Supprimer" -#: app/views/menu.html:291 +#: app/views/menu.html:306 msgid "Remove all" msgstr "" -#: app/scripts/services/utils.service.js:703 +#: app/scripts/services/utils.js:745 #, fuzzy msgid "Reset SVG" msgstr "Reinitialiser la vue" -#: app/views/menu.html:245 +#: app/views/menu.html:260 msgid "Reset default" msgstr "Réinitialiser avec les paramètres par défaut" -#: app/views/menu.html:111 +#: app/views/menu.html:101 msgid "Reset view" msgstr "Reinitialiser la vue" -#: app/views/menu.html:57 +#: app/views/menu.html:47 msgid "Save" msgstr "Sauvegarder" -#: app/scripts/services/utils.service.js:702 +#: app/scripts/services/utils.js:744 #, fuzzy msgid "Save SVG" msgstr "Sauvegarder sous" -#: app/views/menu.html:60 +#: app/views/menu.html:50 msgid "Save as" msgstr "Sauvegarder sous" -#: app/views/menu.html:107 +#: app/views/menu.html:198 +msgid "Select" +msgstr "" + +#: app/views/menu.html:97 msgid "Select all" msgstr "" -#: app/views/menu.html:313 +#: app/scripts/services/blocks.js:54 app/scripts/services/blocks.js:699 +msgid "Show clock" +msgstr "" + +#: app/views/menu.html:328 msgid "Source code" msgstr "Code source" -#: app/views/menu.html:142 +#: app/views/menu.html:143 msgid "Spanish" msgstr "Espagnole" -#: app/scripts/services/tools.service.js:185 +#: app/scripts/services/tools.js:193 msgid "Synchronize remote files ..." msgstr "Synchroniser les fichiers distants ..." -#: app/views/menu.html:73 +#: app/views/menu.html:63 msgid "Testbench" msgstr "Banc de tests exporté" -#: app/scripts/controllers/menu.js:188 +#: app/scripts/controllers/menu.js:204 msgid "Testbench exported" msgstr "Banc de tests exporté" -#: app/scripts/controllers/menu.js:388 +#: app/scripts/services/tools.js:616 +msgid "The collection {{name}} already exists." +msgstr "" + +#: app/scripts/controllers/menu.js:424 msgid "" "The current FPGA I/O configuration will be lost. Do you want to change to " "{{name}} board?" @@ -586,23 +615,23 @@ msgstr "" "La configuration des entrées sorties du FPGA actuel va être perdue. Voulez " "vous changer pour la carte {{name}}?" -#: app/scripts/services/tools.service.js:343 +#: app/scripts/services/tools.js:350 msgid "The toolchain will be removed. Do you want to continue?" msgstr "" "Les répertoires de configuration d'Icestudio et apio vont être supprimés. " "Voulez-vous continuer?" -#: app/scripts/services/tools.service.js:331 +#: app/scripts/services/tools.js:338 msgid "The toolchain will be restored to default. Do you want to continue?" msgstr "La toolchain va être restaurée par défaut. Voulez vous continuer ?" -#: app/scripts/services/tools.service.js:323 +#: app/scripts/services/tools.js:330 msgid "" "The toolchain will be updated. This operation requires Internet connection. " "Do you want to continue?" msgstr "" -#: app/scripts/services/project.service.js:329 +#: app/scripts/services/project.js:345 msgid "" "This import operation requires a project path. You need to save the current " "project. Do you want to continue?" @@ -610,303 +639,265 @@ msgstr "" "Cette opération d'import requière un chemin de projet (path). Vous devez " "sauvez le projet actuel. Voulez vous continuer ?" -#: app/views/menu.html:228 +#: app/scripts/services/project.js:103 +msgid "This project is designed for the {{name}} board." +msgstr "" + +#: app/views/menu.html:243 msgid "Toolchain" msgstr "Toolchain" -#: app/scripts/services/tools.service.js:525 +#: app/scripts/services/tools.js:533 msgid "Toolchain installed" msgstr "La toolchain est installée" -#: app/scripts/services/tools.service.js:529 +#: app/scripts/services/tools.js:536 msgid "Toolchain not installed" msgstr "La toolchain n'est pas à jour" -#: app/scripts/services/tools.service.js:100 -#: app/scripts/services/utils.service.js:529 -#: app/scripts/services/utils.service.js:545 +#: app/scripts/services/tools.js:92 app/scripts/services/utils.js:533 +#: app/scripts/services/utils.js:549 msgid "Toolchain not installed. Please, install the toolchain" msgstr "La toolchain n'est pas à jour. Installer, ou mettre à jour svp" -#: app/scripts/services/tools.service.js:347 +#: app/scripts/services/tools.js:355 msgid "Toolchain removed" msgstr "Toolchain supprimée" -#: app/views/menu.html:215 +#: app/views/menu.html:230 msgid "Tools" msgstr "Outils" -#: app/views/menu.html:91 +#: app/views/menu.html:81 msgid "Undo" msgstr "" -#: app/scripts/services/tools.service.js:230 +#: app/scripts/services/tools.js:237 msgid "Unknown board" msgstr "Carte inconnue" -#: app/scripts/app.js:42 +#: app/scripts/app.js:43 msgid "Untitled" msgstr "" -#: app/views/menu.html:235 +#: app/views/menu.html:250 msgid "Update" msgstr "" -#: app/scripts/services/blocks.service.js:712 -#, fuzzy -msgid "Update the block label" -msgstr "Entrer le titre du bloc" - -#: app/scripts/services/blocks.service.js:639 -#, fuzzy -msgid "Update the port" -msgstr "Entrer les ports d'entrée" +#: app/scripts/services/blocks.js:697 app/scripts/services/blocks.js:777 +#: app/scripts/services/blocks.js:850 +msgid "Update the block name" +msgstr "" -#: app/views/menu.html:224 +#: app/views/menu.html:239 msgid "Upload" msgstr "Télécharger" -#: app/views/menu.html:218 +#: app/views/menu.html:233 msgid "Verify" msgstr "Verifier" -#: app/scripts/controllers/menu.js:170 +#: app/scripts/controllers/menu.js:186 msgid "Verilog code exported" msgstr "Code Verilog exporté" -#: app/scripts/services/utils.service.js:679 app/views/menu.html:306 +#: app/scripts/services/utils.js:721 app/views/menu.html:321 msgid "Version" msgstr "Version" -#: app/views/menu.html:172 +#: app/views/menu.html:180 msgid "View" msgstr "Vue" -#: app/views/menu.html:303 +#: app/views/menu.html:318 msgid "View license" msgstr "Voir la licence" -#: app/scripts/services/blocks.service.js:347 +#: app/scripts/services/blocks.js:404 msgid "Wrong block format: {{type}}" msgstr "Mauvais format de bloc: {{type}}" -#: app/scripts/services/blocks.service.js:146 -#: app/scripts/services/blocks.service.js:263 +#: app/scripts/services/blocks.js:132 app/scripts/services/blocks.js:201 +#: app/scripts/services/blocks.js:75 app/scripts/services/blocks.js:768 +#: app/scripts/services/blocks.js:842 app/scripts/services/blocks.js:877 +msgid "Wrong block name {{name}}" +msgstr "" + +#: app/scripts/services/blocks.js:319 #, fuzzy msgid "Wrong parameter name {{name}}" msgstr "Mauvais hostname distant {{name}}" -#: app/scripts/services/blocks.service.js:233 -#: app/scripts/services/blocks.service.js:248 -#: app/scripts/services/blocks.service.js:704 -#: app/scripts/services/blocks.service.js:77 +#: app/scripts/services/blocks.js:289 app/scripts/services/blocks.js:304 #, fuzzy msgid "Wrong port name {{name}}" msgstr "Mauvais hostname distant {{name}}" -#: app/scripts/services/project.service.js:116 +#: app/scripts/services/project.js:130 msgid "Wrong project format: {{name}}" msgstr "Mauvais format de projet: {{name}}" -#: app/scripts/services/tools.service.js:261 +#: app/scripts/services/tools.js:268 msgid "Wrong remote hostname {{name}}" msgstr "Mauvais hostname distant {{name}}" -#: app/scripts/controllers/menu.js:219 +#: app/scripts/controllers/menu.js:235 msgid "Your changes will be lost if you don’t save them" msgstr "" -#. And -#: app/resources/blocks/labels.js:34 -msgid "and" -msgstr "Et" - -#: app/views/design.html:5 +#: app/views/design.html:6 msgid "back" msgstr "retour" -#. Bit -#: app/resources/blocks/labels.js:4 -msgid "bit" -msgstr "Bit" - -#. Combinational -#: app/resources/blocks/labels.js:16 -msgid "combinational" -msgstr "Combinatoire" - -#. Config -#: app/resources/blocks/labels.js:6 -msgid "config" -msgstr "Configuration" - -#. contadorAsc -#: app/resources/examples/labels.js:12 -msgid "contadorAsc" -msgstr "" - -#. contadorDes -#: app/resources/examples/labels.js:14 -msgid "contadorDes" -msgstr "" - -#. Debouncer -#: app/resources/blocks/labels.js:58 -msgid "debouncer" -msgstr "" - -#. Demux 1:2 -#: app/resources/blocks/labels.js:18 -msgid "demux_1_2" -msgstr "Démultiplexeur 1:2" - -#. Demux 1:4 -#: app/resources/blocks/labels.js:20 -msgid "demux_1_4" -msgstr "Démultiplexeur 1:4" - -#. Demux 1:8 -#: app/resources/blocks/labels.js:22 -msgid "demux_1_8" -msgstr "Démultiplexeur 1:8" - -#. D flip-flop async -#: app/resources/blocks/labels.js:50 -msgid "dff_ar" -msgstr "D flip-flop async" - -#. D flip-flop async -#: app/resources/blocks/labels.js:52 -msgid "dff_sr" -msgstr "D flip-flop" - #. Build done -#: app/scripts/services/tools.service.js:276 +#: app/scripts/services/tools.js:283 msgid "done_build" msgstr "Construction terminée" #. Upload done -#: app/scripts/services/tools.service.js:278 +#: app/scripts/services/tools.js:285 msgid "done_upload" msgstr "Téléchargement terminé" #. Verification done -#: app/scripts/services/tools.service.js:274 +#: app/scripts/services/tools.js:281 msgid "done_verify" msgstr "Vérification faite" -#. Gate -#: app/resources/blocks/labels.js:32 -msgid "gate" -msgstr "Porte" - -#. Hex 7 Segment CA -#: app/resources/blocks/labels.js:26 -msgid "hex_7seg_ca" -msgstr "Hex 7 Segment CA" - -#. Hex 7 Segment CC -#: app/resources/blocks/labels.js:24 -msgid "hex_7seg_cc" -msgstr "Hex 7 Segment CC" - -#. Logic -#: app/resources/blocks/labels.js:14 -msgid "logic" -msgstr "Logique" - -#. Mux 2:1 -#: app/resources/blocks/labels.js:28 -msgid "mux_2_1" -msgstr "Multiplexeur 2:1" - -#. Mux 4:1 -#: app/resources/blocks/labels.js:30 -msgid "mux_4_1" -msgstr "Multiplexeur 4:1" - -#. Nand -#: app/resources/blocks/labels.js:36 -msgid "nand" -msgstr "Non Et" - -#. Nor -#: app/resources/blocks/labels.js:38 -msgid "nor" -msgstr "Non Ou" - -#. Not -#: app/resources/blocks/labels.js:40 -msgid "not" -msgstr "Non" - -#. Or -#: app/resources/blocks/labels.js:42 -msgid "or" -msgstr "Ou" - -#. Pull up -#: app/resources/blocks/labels.js:8 -msgid "pull_up" -msgstr "Pull up" - -#. Pull up inv -#: app/resources/blocks/labels.js:10 -msgid "pull_up_inv" -msgstr "Pull up inv" - -#. Sequential -#: app/resources/blocks/labels.js:48 -msgid "sequential" -msgstr "Séquentiel" - #. Start building ... -#: app/scripts/services/tools.service.js:64 +#: app/scripts/services/tools.js:60 msgid "start_build" msgstr "Début de la construction ..." #. Start uploading ... -#: app/scripts/services/tools.service.js:66 +#: app/scripts/services/tools.js:62 msgid "start_upload" msgstr "Début du téléchargement ..." #. Start verification ... -#: app/scripts/services/tools.service.js:62 +#: app/scripts/services/tools.js:58 msgid "start_verify" msgstr "Début de la verification ..." -#. T flip-flop async -#: app/resources/blocks/labels.js:54 -msgid "tff_ar" -msgstr "T flip-flop async" +#: app/scripts/controllers/menu.js:383 +msgid "{{board}} datasheet not defined" +msgstr "" + +#: app/scripts/controllers/menu.js:373 +msgid "{{board}} pinout not defined" +msgstr "" + +#: app/scripts/controllers/menu.js:402 +msgid "{{board}} rules not defined" +msgstr "" -#. T flip-flop -#: app/resources/blocks/labels.js:56 -msgid "tff_sr" -msgstr "T flip-flop" +#~ msgid "1_basic" +#~ msgstr "1. Basique" -#. Tri-state -#: app/resources/blocks/labels.js:12 -msgid "tri_state" -msgstr "Tri-state" +#~ msgid "1_led_on" +#~ msgstr "1. Led on" -#. Xnor -#: app/resources/blocks/labels.js:44 -msgid "xnor" -msgstr "Xnor" +#~ msgid "2_switch_led" +#~ msgstr "2. Switch led" -#. Xor -#: app/resources/blocks/labels.js:46 -msgid "xor" -msgstr "Xor" +#~ msgid "3_switch_and_gate" +#~ msgstr "3. Switch and gate" -#: app/scripts/controllers/menu.js:366 -msgid "{{board}} datasheet not defined" -msgstr "" +#~ msgid "Boards" +#~ msgstr "Cartes" -#: app/scripts/controllers/menu.js:356 -msgid "{{board}} pinout not defined" -msgstr "" +#, fuzzy +#~ msgid "Enter the ports" +#~ msgstr "Entrer les ports d'entrée" + +#, fuzzy +#~ msgid "Update the block label" +#~ msgstr "Entrer le titre du bloc" + +#, fuzzy +#~ msgid "Update the port" +#~ msgstr "Entrer les ports d'entrée" + +#~ msgid "and" +#~ msgstr "Et" + +#~ msgid "bit" +#~ msgstr "Bit" + +#~ msgid "combinational" +#~ msgstr "Combinatoire" + +#~ msgid "config" +#~ msgstr "Configuration" + +#~ msgid "demux_1_2" +#~ msgstr "Démultiplexeur 1:2" + +#~ msgid "demux_1_4" +#~ msgstr "Démultiplexeur 1:4" + +#~ msgid "demux_1_8" +#~ msgstr "Démultiplexeur 1:8" + +#~ msgid "dff_ar" +#~ msgstr "D flip-flop async" + +#~ msgid "dff_sr" +#~ msgstr "D flip-flop" + +#~ msgid "gate" +#~ msgstr "Porte" + +#~ msgid "hex_7seg_ca" +#~ msgstr "Hex 7 Segment CA" + +#~ msgid "hex_7seg_cc" +#~ msgstr "Hex 7 Segment CC" + +#~ msgid "logic" +#~ msgstr "Logique" + +#~ msgid "mux_2_1" +#~ msgstr "Multiplexeur 2:1" + +#~ msgid "mux_4_1" +#~ msgstr "Multiplexeur 4:1" + +#~ msgid "nand" +#~ msgstr "Non Et" + +#~ msgid "nor" +#~ msgstr "Non Ou" + +#~ msgid "not" +#~ msgstr "Non" + +#~ msgid "or" +#~ msgstr "Ou" + +#~ msgid "pull_up" +#~ msgstr "Pull up" + +#~ msgid "pull_up_inv" +#~ msgstr "Pull up inv" + +#~ msgid "sequential" +#~ msgstr "Séquentiel" + +#~ msgid "tff_ar" +#~ msgstr "T flip-flop async" + +#~ msgid "tff_sr" +#~ msgstr "T flip-flop" + +#~ msgid "tri_state" +#~ msgstr "Tri-state" + +#~ msgid "xnor" +#~ msgstr "Xnor" + +#~ msgid "xor" +#~ msgstr "Xor" #~ msgid "Info" #~ msgstr "Info" diff --git a/app/resources/locale/gl_ES/gl_ES.po b/app/resources/locale/gl_ES/gl_ES.po index 3e804f266..8d6e5cb38 100644 --- a/app/resources/locale/gl_ES/gl_ES.po +++ b/app/resources/locale/gl_ES/gl_ES.po @@ -12,106 +12,100 @@ msgstr "" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#. 1. Basic -#: app/resources/examples/labels.js:4 -msgid "1_basic" -msgstr "1. Básico" - -#. 1. Led on -#: app/resources/examples/labels.js:6 -msgid "1_led_on" -msgstr "1. Acender led" - -#. 2. Switch led -#: app/resources/examples/labels.js:8 -msgid "2_switch_led" -msgstr "2. Interruptor con led" - -#. 3. Switch and gate -#: app/resources/examples/labels.js:10 -msgid "3_switch_and_gate" -msgstr "3. Interruptor con porta and" - -#: app/scripts/services/utils.service.js:452 -#: app/scripts/services/utils.service.js:532 +#: app/scripts/services/utils.js:456 app/scripts/services/utils.js:536 msgid "Unplug and reconnect the board" msgstr "" -#: app/scripts/services/utils.service.js:523 +#: app/scripts/services/utils.js:527 msgid "" "

    FTDI driver installation instructions

    1. Connect the FPGA " "board
    2. Replace the (Interface 0) driver of the board by " "libusbK
    3. Unplug and reconnect the board
    " msgstr "" -#: app/scripts/services/utils.service.js:539 +#: app/scripts/services/utils.js:543 msgid "" "

    FTDI driver uninstallation instructions

    1. Find the FPGA USB " "Device
    2. Select the board interface and uninstall the driver
    " msgstr "" -#: app/views/menu.html:321 +#: app/views/menu.html:336 msgid "About Icestudio" msgstr "Acerca de Icestudio" -#: app/views/menu.html:275 +#: app/views/menu.html:290 msgid "Add" msgstr "" -#: app/scripts/controllers/menu.js:431 +#: app/scripts/controllers/menu.js:471 msgid "Add a block to start" msgstr "" -#: app/views/menu.html:35 +#: app/views/menu.html:43 #, fuzzy msgid "Add as block" msgstr "Exportar como bloque" -#: app/scripts/services/tools.service.js:590 +#: app/scripts/services/tools.js:682 msgid "All collections removed" msgstr "" -#: app/scripts/controllers/menu.js:455 +#: app/scripts/controllers/menu.js:495 msgid "All stored collections will be lost. Do you want to continue?" msgstr "" -#: app/scripts/services/utils.service.js:681 +#: app/scripts/services/utils.js:723 msgid "Author" msgstr "" -#: app/views/menu.html:331 +#: app/views/menu.html:347 msgid "Basic" msgstr "Básico" -#: app/views/menu.html:154 +#: app/views/menu.html:155 msgid "Basque" msgstr "Euskera" -#: app/scripts/services/blocks.service.js:680 -#: app/scripts/services/blocks.service.js:699 -#: app/scripts/services/blocks.service.js:730 -#: app/scripts/services/blocks.service.js:750 +#: app/scripts/services/blocks.js:742 app/scripts/services/blocks.js:763 +#: app/scripts/services/blocks.js:818 app/scripts/services/blocks.js:837 +#: app/scripts/services/blocks.js:872 app/scripts/services/blocks.js:911 #, fuzzy msgid "Block updated" msgstr "Etiqueta actualizada" -#: app/scripts/services/project.service.js:402 +#: app/scripts/services/project.js:418 msgid "Block {{name}} imported" msgstr "Bloque {{name}} importado" -#: app/scripts/services/tools.service.js:227 +#: app/views/menu.html:35 +msgid "Blocks" +msgstr "" + +#: app/views/menu.html:201 +msgid "Board" +msgstr "" + +#: app/views/menu.html:115 app/views/menu.html:192 +msgid "Board rules" +msgstr "" + +#: app/scripts/controllers/menu.js:334 +msgid "Board rules disabled" +msgstr "" + +#: app/scripts/controllers/menu.js:329 +msgid "Board rules enabled" +msgstr "" + +#: app/scripts/services/tools.js:234 msgid "Board {{name}} not detected" msgstr "Placa {{name}} non detectada" -#: app/scripts/controllers/menu.js:399 +#: app/scripts/controllers/menu.js:435 msgid "Board {{name}} selected" msgstr "Placa {{name}} seleccionada" -#: app/views/menu.html:203 -msgid "Boards" -msgstr "Placas" - -#: app/views/menu.html:221 +#: app/views/menu.html:236 msgid "Build" msgstr "Sintetizar" @@ -119,184 +113,204 @@ msgstr "Sintetizar" msgid "Cancel" msgstr "" -#: app/scripts/services/tools.service.js:438 +#: app/scripts/services/tools.js:446 msgid "Check Internet connection..." msgstr "" -#: app/scripts/services/tools.service.js:446 +#: app/scripts/services/tools.js:454 msgid "Check Python..." msgstr "" -#: app/views/menu.html:337 +#: app/views/menu.html:361 msgid "Code" msgstr "Código" -#: app/scripts/services/tools.service.js:577 -msgid "Collection file {{name}} added" +#: app/views/menu.html:212 +msgid "Collection" +msgstr "" + +#: app/scripts/services/tools.js:631 +msgid "Collection {{name}} added" msgstr "" -#: app/scripts/services/tools.service.js:584 +#: app/scripts/services/tools.js:625 +msgid "Collection {{name}} not replaced" +msgstr "" + +#: app/scripts/services/tools.js:676 msgid "Collection {{name}} removed" msgstr "" -#: app/scripts/controllers/menu.js:374 +#: app/scripts/services/tools.js:621 +msgid "Collection {{name}} replaced" +msgstr "" + +#: app/scripts/controllers/menu.js:410 msgid "Collection {{name}} selected" msgstr "" -#: app/views/menu.html:185 app/views/menu.html:271 +#: app/views/menu.html:286 msgid "Collections" msgstr "" -#: app/views/menu.html:317 +#: app/views/menu.html:332 msgid "Community forum" msgstr "Foro da comunidade" -#: app/views/menu.html:336 +#: app/views/menu.html:358 msgid "Constant" msgstr "" -#: app/views/menu.html:101 +#: app/views/menu.html:91 msgid "Copy" msgstr "" -#: app/views/menu.html:98 +#: app/views/menu.html:88 msgid "Cut" msgstr "" -#: app/views/menu.html:181 +#: app/views/menu.html:189 msgid "Datasheet" msgstr "" -#: app/views/menu.html:189 +#: app/views/menu.html:216 msgid "Default" msgstr "" -#: app/scripts/services/tools.service.js:315 +#: app/scripts/services/tools.js:322 msgid "" "Default toolchain not found. Toolchain will be downloaded. This operation " "requires Internet connection. Do you want to continue?" msgstr "" -#: app/scripts/services/utils.service.js:680 +#: app/scripts/services/utils.js:722 msgid "Description" msgstr "" -#: app/views/menu.html:264 +#: app/views/menu.html:126 app/views/menu.html:279 msgid "Disable" msgstr "" -#: app/scripts/controllers/menu.js:218 +#: app/scripts/controllers/menu.js:234 msgid "Do you want to close the application?" msgstr "" -#: app/scripts/controllers/menu.js:445 +#: app/scripts/services/project.js:104 +msgid "Do you want to convert it?" +msgstr "" + +#: app/scripts/controllers/menu.js:485 msgid "Do you want to remove the {{name}} collection?" msgstr "" -#: app/views/menu.html:310 +#: app/scripts/services/tools.js:617 +msgid "Do you want to replace it?" +msgstr "" + +#: app/views/menu.html:325 msgid "Documentation" msgstr "Documentación" -#: app/views/menu.html:255 +#: app/views/menu.html:270 msgid "Drivers" msgstr "" -#: app/scripts/services/utils.service.js:449 -#: app/scripts/services/utils.service.js:517 +#: app/scripts/services/utils.js:453 app/scripts/services/utils.js:521 msgid "Drivers disabled" msgstr "" -#: app/scripts/services/utils.service.js:446 -#: app/scripts/services/utils.service.js:498 +#: app/scripts/services/utils.js:450 app/scripts/services/utils.js:502 msgid "Drivers enabled" msgstr "" -#: app/scripts/services/tools.service.js:239 +#: app/scripts/services/tools.js:246 msgid "Duplicated FPGA I/O ports" msgstr "Portos E/S da FPGA duplicados" -#: app/scripts/services/blocks.service.js:314 +#: app/scripts/services/blocks.js:370 msgid "Duplicated block attributes" msgstr "" -#: app/views/menu.html:88 +#: app/views/menu.html:78 msgid "Edit" msgstr "Editar" -#: app/views/menu.html:259 +#: app/views/menu.html:121 app/views/menu.html:274 msgid "Enable" msgstr "" -#: app/views/menu.html:136 +#: app/views/menu.html:137 msgid "English" msgstr "Inglés" -#: app/scripts/services/blocks.service.js:126 +#: app/scripts/services/blocks.js:181 #, fuzzy msgid "Enter the constant blocks" msgstr "Introduza a etiqueta para o bloque" -#: app/scripts/services/blocks.service.js:213 +#: app/scripts/services/blocks.js:52 +msgid "Enter the input blocks" +msgstr "" + +#: app/scripts/services/blocks.js:269 msgid "Enter the input ports" msgstr "" -#: app/scripts/services/blocks.service.js:214 +#: app/scripts/services/blocks.js:112 +msgid "Enter the output blocks" +msgstr "" + +#: app/scripts/services/blocks.js:270 msgid "Enter the output ports" msgstr "" -#: app/scripts/services/blocks.service.js:215 +#: app/scripts/services/blocks.js:271 #, fuzzy msgid "Enter the parameters" msgstr "Introduza o título do proxecto" -#: app/scripts/services/blocks.service.js:57 -#, fuzzy -msgid "Enter the ports" -msgstr "Introduza os portos para o bloque" - -#: app/scripts/controllers/menu.js:314 +#: app/scripts/controllers/menu.js:321 msgid "Enter the remote hostname user@host (experimental)" msgstr "Enter the remote hostname user@host (experimental)" -#: app/scripts/services/tools.service.js:338 +#: app/scripts/services/tools.js:345 msgid "Error: default toolchain not found in '{{dir}}'" msgstr "" -#: app/scripts/services/utils.service.js:813 +#: app/scripts/services/utils.js:855 msgid "Error: {{error}}" msgstr "Error: {{error}}" -#: app/views/menu.html:38 +#: app/views/menu.html:39 msgid "Examples" msgstr "Exemplos" -#: app/scripts/services/tools.service.js:196 +#: app/scripts/services/tools.js:204 msgid "Execute remote {{label}} ..." msgstr "Execute remote {{label}} ..." -#: app/views/menu.html:64 +#: app/views/menu.html:54 msgid "Export" msgstr "Exportar" -#: app/scripts/services/tools.service.js:470 +#: app/scripts/services/tools.js:478 msgid "Extract default apio files..." msgstr "" -#: app/scripts/services/tools.service.js:480 +#: app/scripts/services/tools.js:488 msgid "Extract default apio packages..." msgstr "" -#: app/scripts/services/tools.service.js:458 +#: app/scripts/services/tools.js:466 msgid "Extract virtual env files..." msgstr "" -#: app/scripts/services/tools.service.js:233 -#: app/scripts/services/tools.service.js:236 +#: app/scripts/services/tools.js:240 app/scripts/services/tools.js:243 msgid "FPGA I/O ports not defined" msgstr "Portos E/S da FPGA non definidos" -#: app/scripts/services/blocks.service.js:58 -#: app/scripts/services/blocks.service.js:640 +#: app/scripts/services/blocks.js:113 app/scripts/services/blocks.js:53 +#: app/scripts/services/blocks.js:698 app/scripts/services/blocks.js:778 msgid "FPGA pin" msgstr "" @@ -304,122 +318,126 @@ msgstr "" msgid "File" msgstr "Ficheiro" -#: app/scripts/services/project.service.js:360 +#: app/scripts/services/project.js:376 msgid "" "File {{file}} already exists in the project path. Do you want to replace it?" msgstr "" -#: app/scripts/services/tools.service.js:172 +#: app/scripts/services/tools.js:180 msgid "File {{file}} does not exist" msgstr "O ficheiro {{file}} non existe" -#: app/scripts/services/project.service.js:392 +#: app/scripts/services/project.js:408 msgid "File {{file}} imported" msgstr "" -#: app/views/menu.html:114 +#: app/views/menu.html:104 msgid "Fit content" msgstr "" -#: app/views/menu.html:160 +#: app/views/menu.html:161 msgid "French" msgstr "" -#: app/scripts/controllers/menu.js:197 +#: app/scripts/controllers/menu.js:213 msgid "GTKWave exported" msgstr "GTKWave exportado" -#: app/views/menu.html:148 +#: app/views/menu.html:149 msgid "Galician" msgstr "Galego" -#: app/views/menu.html:300 +#: app/views/menu.html:315 msgid "Help" msgstr "Axuda" -#: app/scripts/services/utils.service.js:487 +#: app/scripts/services/utils.js:491 msgid "Homebrew is required" msgstr "" -#: app/scripts/services/utils.service.js:694 +#: app/scripts/services/utils.js:736 #, fuzzy msgid "Image" msgstr "Ruta da imaxe" -#: app/scripts/controllers/menu.js:647 +#: app/scripts/controllers/menu.js:642 msgid "Image {{name}} saved" msgstr "" -#: app/views/menu.html:338 +#: app/views/menu.html:364 msgid "Information" msgstr "" -#: app/views/menu.html:334 +#: app/views/menu.html:352 msgid "Input" msgstr "Entrada" -#: app/views/menu.html:232 +#: app/views/menu.html:247 msgid "Install" msgstr "" -#: app/scripts/services/tools.service.js:475 +#: app/scripts/services/tools.js:483 msgid "Install default apio..." msgstr "" -#: app/scripts/services/tools.service.js:524 +#: app/scripts/services/tools.js:532 msgid "Installation completed" msgstr "Instalación completada" -#: app/scripts/services/tools.service.js:367 -#: app/scripts/services/tools.service.js:404 +#: app/scripts/services/tools.js:375 app/scripts/services/tools.js:412 msgid "Installing toolchain" msgstr "Instalando a toolchain" -#: app/scripts/services/tools.service.js:440 -#: app/scripts/services/utils.service.js:491 +#: app/scripts/services/tools.js:448 app/scripts/services/utils.js:495 msgid "Internet connection required" msgstr "Requírese dunha conexión a Internet" -#: app/scripts/services/graph.service.js:186 +#: app/scripts/services/graph.js:175 msgid "Invalid Pull up connection:
    block already connected" msgstr "" -#: app/scripts/services/graph.service.js:200 +#: app/scripts/services/graph.js:189 msgid "Invalid Pull up connection:
    only Input blocks allowed" msgstr "" -#: app/scripts/services/graph.service.js:192 +#: app/scripts/services/graph.js:181 msgid "Invalid block connection:
    Pull up already connected" msgstr "" -#: app/scripts/services/graph.service.js:151 -#: app/scripts/services/graph.service.js:158 -#: app/scripts/services/graph.service.js:165 +#: app/scripts/services/tools.js:636 +msgid "Invalid collection {{name}}" +msgstr "" + +#: app/scripts/services/graph.js:140 app/scripts/services/graph.js:147 +#: app/scripts/services/graph.js:154 msgid "Invalid connection" msgstr "" -#: app/scripts/services/graph.service.js:219 +#: app/scripts/services/graph.js:208 msgid "Invalid connection: {{a}} → {{b}}" msgstr "" -#: app/scripts/services/graph.service.js:180 +#: app/scripts/services/graph.js:169 msgid "Invalid multiple input connections" msgstr "" -#: app/views/menu.html:132 +#: app/views/menu.html:133 msgid "Language" msgstr "Idioma" -#: app/scripts/services/blocks.service.js:127 -#: app/scripts/services/blocks.service.js:713 +#: app/scripts/services/tools.js:579 +msgid "Load {{name}} ..." +msgstr "" + +#: app/scripts/services/blocks.js:182 app/scripts/services/blocks.js:851 msgid "Local parameter" msgstr "" -#: app/scripts/services/tools.service.js:463 +#: app/scripts/services/tools.js:471 msgid "Make virtual env..." msgstr "" -#: app/scripts/services/utils.service.js:678 +#: app/scripts/services/utils.js:720 msgid "Name" msgstr "" @@ -427,11 +445,11 @@ msgstr "" msgid "New" msgstr "" -#: app/scripts/services/project.service.js:85 +#: app/scripts/services/project.js:80 msgid "New project {{name}} created" msgstr "Novo proxecto {{name}} creado" -#: app/scripts/controllers/menu.js:463 +#: app/scripts/controllers/menu.js:503 msgid "No collections stored" msgstr "" @@ -439,8 +457,7 @@ msgstr "" msgid "OK" msgstr "" -#: app/scripts/services/project.service.js:101 -#: app/scripts/services/project.service.js:308 +#: app/scripts/services/project.js:323 app/scripts/services/project.js:97 msgid "Old project format {{version}}" msgstr "" @@ -448,125 +465,137 @@ msgstr "" msgid "Open" msgstr "" -#: app/scripts/services/utils.service.js:701 +#: app/scripts/services/utils.js:743 msgid "Open SVG" msgstr "" -#: app/scripts/services/project.service.js:395 +#: app/scripts/services/project.js:411 msgid "Original file {{file}} does not exist" msgstr "" -#: app/views/menu.html:335 +#: app/views/menu.html:355 msgid "Output" msgstr "Saída" -#: app/scripts/controllers/menu.js:179 +#: app/scripts/controllers/menu.js:195 msgid "PCF file exported" msgstr "Ficheiro PCF exportado" -#: app/views/menu.html:104 +#: app/views/menu.html:94 msgid "Paste" msgstr "" -#: app/views/menu.html:118 +#: app/views/menu.html:108 msgid "Preferences" msgstr "" -#: app/views/menu.html:121 +#: app/views/menu.html:111 msgid "Project information" msgstr "" -#: app/scripts/services/project.service.js:108 +#: app/scripts/services/project.js:122 msgid "Project {{name}} loaded" msgstr "Proxecto {{name}} cargado" -#: app/scripts/services/project.service.js:280 +#: app/scripts/services/project.js:295 msgid "Project {{name}} saved" msgstr "Proxecto {{name}} gardado" -#: app/scripts/services/tools.service.js:451 +#: app/scripts/services/tools.js:459 msgid "Python 2.7 is required" msgstr "" -#: app/views/menu.html:82 +#: app/views/menu.html:72 msgid "Quit" msgstr "" -#: app/views/design.html:4 +#: app/views/design.html:5 msgid "Read only" msgstr "Só lectura" -#: app/views/menu.html:94 +#: app/views/menu.html:84 msgid "Redo" msgstr "" -#: app/scripts/services/tools.service.js:264 +#: app/scripts/services/tools.js:271 msgid "Remote host {{name}} not connected" msgstr "" -#: app/views/menu.html:126 +#: app/views/menu.html:170 msgid "Remote hostname" msgstr "" -#: app/views/menu.html:240 app/views/menu.html:279 +#: app/views/menu.html:255 app/views/menu.html:294 msgid "Remove" msgstr "Eliminar" -#: app/views/menu.html:291 +#: app/views/menu.html:306 msgid "Remove all" msgstr "" -#: app/scripts/services/utils.service.js:703 +#: app/scripts/services/utils.js:745 #, fuzzy msgid "Reset SVG" msgstr "Restablecer vista" -#: app/views/menu.html:245 +#: app/views/menu.html:260 msgid "Reset default" msgstr "" -#: app/views/menu.html:111 +#: app/views/menu.html:101 msgid "Reset view" msgstr "Restablecer vista" -#: app/views/menu.html:57 +#: app/views/menu.html:47 msgid "Save" msgstr "Gardar" -#: app/scripts/services/utils.service.js:702 +#: app/scripts/services/utils.js:744 #, fuzzy msgid "Save SVG" msgstr "Gardar como" -#: app/views/menu.html:60 +#: app/views/menu.html:50 msgid "Save as" msgstr "Gardar como" -#: app/views/menu.html:107 +#: app/views/menu.html:198 +msgid "Select" +msgstr "" + +#: app/views/menu.html:97 msgid "Select all" msgstr "" -#: app/views/menu.html:313 +#: app/scripts/services/blocks.js:54 app/scripts/services/blocks.js:699 +msgid "Show clock" +msgstr "" + +#: app/views/menu.html:328 msgid "Source code" msgstr "Código fonte" -#: app/views/menu.html:142 +#: app/views/menu.html:143 msgid "Spanish" msgstr "Castelán" -#: app/scripts/services/tools.service.js:185 +#: app/scripts/services/tools.js:193 msgid "Synchronize remote files ..." msgstr "Synchronize remote files ..." -#: app/views/menu.html:73 +#: app/views/menu.html:63 msgid "Testbench" msgstr "Testbench" -#: app/scripts/controllers/menu.js:188 +#: app/scripts/controllers/menu.js:204 msgid "Testbench exported" msgstr "Testbench exportado" -#: app/scripts/controllers/menu.js:388 +#: app/scripts/services/tools.js:616 +msgid "The collection {{name}} already exists." +msgstr "" + +#: app/scripts/controllers/menu.js:424 msgid "" "The current FPGA I/O configuration will be lost. Do you want to change to " "{{name}} board?" @@ -574,322 +603,275 @@ msgstr "" "A configuración actual de E/S da FPGA perderase. ¿Desexa cambiar á placa " "{{name}}?" -#: app/scripts/services/tools.service.js:343 +#: app/scripts/services/tools.js:350 msgid "The toolchain will be removed. Do you want to continue?" msgstr "" -#: app/scripts/services/tools.service.js:331 +#: app/scripts/services/tools.js:338 msgid "The toolchain will be restored to default. Do you want to continue?" msgstr "" -#: app/scripts/services/tools.service.js:323 +#: app/scripts/services/tools.js:330 msgid "" "The toolchain will be updated. This operation requires Internet connection. " "Do you want to continue?" msgstr "" -#: app/scripts/services/project.service.js:329 +#: app/scripts/services/project.js:345 msgid "" "This import operation requires a project path. You need to save the current " "project. Do you want to continue?" msgstr "" -#: app/views/menu.html:228 +#: app/scripts/services/project.js:103 +msgid "This project is designed for the {{name}} board." +msgstr "" + +#: app/views/menu.html:243 msgid "Toolchain" msgstr "Toolchain" -#: app/scripts/services/tools.service.js:525 +#: app/scripts/services/tools.js:533 msgid "Toolchain installed" msgstr "Toolchain instalada" -#: app/scripts/services/tools.service.js:529 +#: app/scripts/services/tools.js:536 msgid "Toolchain not installed" msgstr "" -#: app/scripts/services/tools.service.js:100 -#: app/scripts/services/utils.service.js:529 -#: app/scripts/services/utils.service.js:545 +#: app/scripts/services/tools.js:92 app/scripts/services/utils.js:533 +#: app/scripts/services/utils.js:549 msgid "Toolchain not installed. Please, install the toolchain" msgstr "" -#: app/scripts/services/tools.service.js:347 +#: app/scripts/services/tools.js:355 msgid "Toolchain removed" msgstr "Toolchain eliminada" -#: app/views/menu.html:215 +#: app/views/menu.html:230 msgid "Tools" msgstr "Ferramentas" -#: app/views/menu.html:91 +#: app/views/menu.html:81 msgid "Undo" msgstr "" -#: app/scripts/services/tools.service.js:230 +#: app/scripts/services/tools.js:237 msgid "Unknown board" msgstr "Placa desconocida" -#: app/scripts/app.js:42 +#: app/scripts/app.js:43 msgid "Untitled" msgstr "" -#: app/views/menu.html:235 +#: app/views/menu.html:250 msgid "Update" msgstr "" -#: app/scripts/services/blocks.service.js:712 -#, fuzzy -msgid "Update the block label" -msgstr "Introduza a etiqueta para o bloque" - -#: app/scripts/services/blocks.service.js:639 -msgid "Update the port" +#: app/scripts/services/blocks.js:697 app/scripts/services/blocks.js:777 +#: app/scripts/services/blocks.js:850 +msgid "Update the block name" msgstr "" -#: app/views/menu.html:224 +#: app/views/menu.html:239 msgid "Upload" msgstr "Cargar" -#: app/views/menu.html:218 +#: app/views/menu.html:233 msgid "Verify" msgstr "Verificar" -#: app/scripts/controllers/menu.js:170 +#: app/scripts/controllers/menu.js:186 msgid "Verilog code exported" msgstr "Código Verilog exportado" -#: app/scripts/services/utils.service.js:679 app/views/menu.html:306 +#: app/scripts/services/utils.js:721 app/views/menu.html:321 msgid "Version" msgstr "Versión" -#: app/views/menu.html:172 +#: app/views/menu.html:180 msgid "View" msgstr "Ver" -#: app/views/menu.html:303 +#: app/views/menu.html:318 msgid "View license" msgstr "Ver licenza" -#: app/scripts/services/blocks.service.js:347 +#: app/scripts/services/blocks.js:404 msgid "Wrong block format: {{type}}" msgstr "Formato de bloque incorrecto: {{type}}" -#: app/scripts/services/blocks.service.js:146 -#: app/scripts/services/blocks.service.js:263 +#: app/scripts/services/blocks.js:132 app/scripts/services/blocks.js:201 +#: app/scripts/services/blocks.js:75 app/scripts/services/blocks.js:768 +#: app/scripts/services/blocks.js:842 app/scripts/services/blocks.js:877 +msgid "Wrong block name {{name}}" +msgstr "" + +#: app/scripts/services/blocks.js:319 #, fuzzy msgid "Wrong parameter name {{name}}" msgstr "Formato de proxecto incorrecto: {{name}}\"" -#: app/scripts/services/blocks.service.js:233 -#: app/scripts/services/blocks.service.js:248 -#: app/scripts/services/blocks.service.js:704 -#: app/scripts/services/blocks.service.js:77 +#: app/scripts/services/blocks.js:289 app/scripts/services/blocks.js:304 #, fuzzy msgid "Wrong port name {{name}}" msgstr "Formato de proxecto incorrecto: {{name}}\"" -#: app/scripts/services/project.service.js:116 +#: app/scripts/services/project.js:130 msgid "Wrong project format: {{name}}" msgstr "Formato de proxecto incorrecto: {{name}}\"" -#: app/scripts/services/tools.service.js:261 +#: app/scripts/services/tools.js:268 msgid "Wrong remote hostname {{name}}" msgstr "" -#: app/scripts/controllers/menu.js:219 +#: app/scripts/controllers/menu.js:235 msgid "Your changes will be lost if you don’t save them" msgstr "" -#. And -#: app/resources/blocks/labels.js:34 -msgid "and" -msgstr "And" - -#: app/views/design.html:5 +#: app/views/design.html:6 msgid "back" msgstr "" -#. Bit -#: app/resources/blocks/labels.js:4 -msgid "bit" -msgstr "Bit" - -#. Combinational -#: app/resources/blocks/labels.js:16 -msgid "combinational" -msgstr "" - -#. Config -#: app/resources/blocks/labels.js:6 -msgid "config" -msgstr "Config" - -#. contadorAsc -#: app/resources/examples/labels.js:12 -msgid "contadorAsc" -msgstr "" - -#. contadorDes -#: app/resources/examples/labels.js:14 -msgid "contadorDes" -msgstr "" - -#. Debouncer -#: app/resources/blocks/labels.js:58 -msgid "debouncer" -msgstr "" - -#. Demux 1:2 -#: app/resources/blocks/labels.js:18 -msgid "demux_1_2" -msgstr "Demux 1:2" - -#. Demux 1:4 -#: app/resources/blocks/labels.js:20 -msgid "demux_1_4" -msgstr "Demux 1:4" - -#. Demux 1:8 -#: app/resources/blocks/labels.js:22 -msgid "demux_1_8" -msgstr "Demux 1:8" - -#. D flip-flop async -#: app/resources/blocks/labels.js:50 -msgid "dff_ar" -msgstr "Bistable D asinc" - -#. D flip-flop async -#: app/resources/blocks/labels.js:52 -msgid "dff_sr" -msgstr "Bistable D" - #. Build done -#: app/scripts/services/tools.service.js:276 +#: app/scripts/services/tools.js:283 msgid "done_build" msgstr "Sintetizado realizado" #. Upload done -#: app/scripts/services/tools.service.js:278 +#: app/scripts/services/tools.js:285 msgid "done_upload" msgstr "Carga realizada" #. Verification done -#: app/scripts/services/tools.service.js:274 +#: app/scripts/services/tools.js:281 msgid "done_verify" msgstr "Verificación realizada" -#. Gate -#: app/resources/blocks/labels.js:32 -msgid "gate" -msgstr "Gate" - -#. Hex 7 Segment CA -#: app/resources/blocks/labels.js:26 -msgid "hex_7seg_ca" -msgstr "Hex 7 Segment CA" - -#. Hex 7 Segment CC -#: app/resources/blocks/labels.js:24 -msgid "hex_7seg_cc" -msgstr "Hex 7 Segment CC" - -#. Logic -#: app/resources/blocks/labels.js:14 -msgid "logic" -msgstr "Lóxica" - -#. Mux 2:1 -#: app/resources/blocks/labels.js:28 -msgid "mux_2_1" -msgstr "Mux 2:1" - -#. Mux 4:1 -#: app/resources/blocks/labels.js:30 -msgid "mux_4_1" -msgstr "Mux 4:1" - -#. Nand -#: app/resources/blocks/labels.js:36 -msgid "nand" -msgstr "Nand" - -#. Nor -#: app/resources/blocks/labels.js:38 -msgid "nor" -msgstr "Nor" - -#. Not -#: app/resources/blocks/labels.js:40 -msgid "not" -msgstr "Not" - -#. Or -#: app/resources/blocks/labels.js:42 -msgid "or" -msgstr "Or" - -#. Pull up -#: app/resources/blocks/labels.js:8 -msgid "pull_up" -msgstr "Pull up" - -#. Pull up inv -#: app/resources/blocks/labels.js:10 -msgid "pull_up_inv" -msgstr "Pull up inv" - -#. Sequential -#: app/resources/blocks/labels.js:48 -msgid "sequential" -msgstr "" - #. Start building ... -#: app/scripts/services/tools.service.js:64 +#: app/scripts/services/tools.js:60 msgid "start_build" msgstr "Iniciar a sintetizado ..." #. Start uploading ... -#: app/scripts/services/tools.service.js:66 +#: app/scripts/services/tools.js:62 msgid "start_upload" msgstr "Iniciar a carga ..." #. Start verification ... -#: app/scripts/services/tools.service.js:62 +#: app/scripts/services/tools.js:58 msgid "start_verify" msgstr "Iniciar a verificación ..." -#. T flip-flop async -#: app/resources/blocks/labels.js:54 -msgid "tff_ar" -msgstr "Bistable T asinc" +#: app/scripts/controllers/menu.js:383 +msgid "{{board}} datasheet not defined" +msgstr "" -#. T flip-flop -#: app/resources/blocks/labels.js:56 -msgid "tff_sr" -msgstr "Bistable T" +#: app/scripts/controllers/menu.js:373 +msgid "{{board}} pinout not defined" +msgstr "" -#. Tri-state -#: app/resources/blocks/labels.js:12 -msgid "tri_state" -msgstr "Tri-state" +#: app/scripts/controllers/menu.js:402 +msgid "{{board}} rules not defined" +msgstr "" -#. Xnor -#: app/resources/blocks/labels.js:44 -msgid "xnor" -msgstr "Xnor" +#~ msgid "1_basic" +#~ msgstr "1. Básico" -#. Xor -#: app/resources/blocks/labels.js:46 -msgid "xor" -msgstr "Xor" +#~ msgid "1_led_on" +#~ msgstr "1. Acender led" -#: app/scripts/controllers/menu.js:366 -msgid "{{board}} datasheet not defined" -msgstr "" +#~ msgid "2_switch_led" +#~ msgstr "2. Interruptor con led" -#: app/scripts/controllers/menu.js:356 -msgid "{{board}} pinout not defined" -msgstr "" +#~ msgid "3_switch_and_gate" +#~ msgstr "3. Interruptor con porta and" + +#~ msgid "Boards" +#~ msgstr "Placas" + +#, fuzzy +#~ msgid "Enter the ports" +#~ msgstr "Introduza os portos para o bloque" + +#, fuzzy +#~ msgid "Update the block label" +#~ msgstr "Introduza a etiqueta para o bloque" + +#~ msgid "and" +#~ msgstr "And" + +#~ msgid "bit" +#~ msgstr "Bit" + +#~ msgid "config" +#~ msgstr "Config" + +#~ msgid "demux_1_2" +#~ msgstr "Demux 1:2" + +#~ msgid "demux_1_4" +#~ msgstr "Demux 1:4" + +#~ msgid "demux_1_8" +#~ msgstr "Demux 1:8" + +#~ msgid "dff_ar" +#~ msgstr "Bistable D asinc" + +#~ msgid "dff_sr" +#~ msgstr "Bistable D" + +#~ msgid "gate" +#~ msgstr "Gate" + +#~ msgid "hex_7seg_ca" +#~ msgstr "Hex 7 Segment CA" + +#~ msgid "hex_7seg_cc" +#~ msgstr "Hex 7 Segment CC" + +#~ msgid "logic" +#~ msgstr "Lóxica" + +#~ msgid "mux_2_1" +#~ msgstr "Mux 2:1" + +#~ msgid "mux_4_1" +#~ msgstr "Mux 4:1" + +#~ msgid "nand" +#~ msgstr "Nand" + +#~ msgid "nor" +#~ msgstr "Nor" + +#~ msgid "not" +#~ msgstr "Not" + +#~ msgid "or" +#~ msgstr "Or" + +#~ msgid "pull_up" +#~ msgstr "Pull up" + +#~ msgid "pull_up_inv" +#~ msgstr "Pull up inv" + +#~ msgid "tff_ar" +#~ msgstr "Bistable T asinc" + +#~ msgid "tff_sr" +#~ msgstr "Bistable T" + +#~ msgid "tri_state" +#~ msgstr "Tri-state" + +#~ msgid "xnor" +#~ msgstr "Xnor" + +#~ msgid "xor" +#~ msgstr "Xor" #~ msgid "Info" #~ msgstr "Info" diff --git a/app/resources/locale/template.pot b/app/resources/locale/template.pot index f3f41363b..6c18ab3bf 100644 --- a/app/resources/locale/template.pot +++ b/app/resources/locale/template.pot @@ -4,99 +4,98 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Project-Id-Version: \n" -#. 1. Basic -#: app/resources/examples/labels.js:4 -msgid "1_basic" -msgstr "" - -#. 1. Led on -#: app/resources/examples/labels.js:6 -msgid "1_led_on" -msgstr "" - -#. 2. Switch led -#: app/resources/examples/labels.js:8 -msgid "2_switch_led" -msgstr "" - -#. 3. Switch and gate -#: app/resources/examples/labels.js:10 -msgid "3_switch_and_gate" -msgstr "" - -#: app/scripts/services/utils.service.js:452 -#: app/scripts/services/utils.service.js:532 +#: app/scripts/services/utils.js:456 +#: app/scripts/services/utils.js:536 msgid "Unplug and reconnect the board" msgstr "" -#: app/scripts/services/utils.service.js:523 +#: app/scripts/services/utils.js:527 msgid "

    FTDI driver installation instructions

    1. Connect the FPGA board
    2. Replace the (Interface 0) driver of the board by libusbK
    3. Unplug and reconnect the board
    " msgstr "" -#: app/scripts/services/utils.service.js:539 +#: app/scripts/services/utils.js:543 msgid "

    FTDI driver uninstallation instructions

    1. Find the FPGA USB Device
    2. Select the board interface and uninstall the driver
    " msgstr "" -#: app/views/menu.html:321 +#: app/views/menu.html:336 msgid "About Icestudio" msgstr "" -#: app/views/menu.html:275 +#: app/views/menu.html:290 msgid "Add" msgstr "" -#: app/scripts/controllers/menu.js:431 +#: app/scripts/controllers/menu.js:471 msgid "Add a block to start" msgstr "" -#: app/views/menu.html:35 +#: app/views/menu.html:43 msgid "Add as block" msgstr "" -#: app/scripts/services/tools.service.js:590 +#: app/scripts/services/tools.js:682 msgid "All collections removed" msgstr "" -#: app/scripts/controllers/menu.js:455 +#: app/scripts/controllers/menu.js:495 msgid "All stored collections will be lost. Do you want to continue?" msgstr "" -#: app/scripts/services/utils.service.js:681 +#: app/scripts/services/utils.js:723 msgid "Author" msgstr "" -#: app/views/menu.html:331 +#: app/views/menu.html:347 msgid "Basic" msgstr "" -#: app/views/menu.html:154 +#: app/views/menu.html:155 msgid "Basque" msgstr "" -#: app/scripts/services/blocks.service.js:680 -#: app/scripts/services/blocks.service.js:699 -#: app/scripts/services/blocks.service.js:730 -#: app/scripts/services/blocks.service.js:750 +#: app/scripts/services/blocks.js:742 +#: app/scripts/services/blocks.js:763 +#: app/scripts/services/blocks.js:818 +#: app/scripts/services/blocks.js:837 +#: app/scripts/services/blocks.js:872 +#: app/scripts/services/blocks.js:911 msgid "Block updated" msgstr "" -#: app/scripts/services/project.service.js:402 +#: app/scripts/services/project.js:418 msgid "Block {{name}} imported" msgstr "" -#: app/scripts/services/tools.service.js:227 -msgid "Board {{name}} not detected" +#: app/views/menu.html:35 +msgid "Blocks" msgstr "" -#: app/scripts/controllers/menu.js:399 -msgid "Board {{name}} selected" +#: app/views/menu.html:201 +msgid "Board" msgstr "" -#: app/views/menu.html:203 -msgid "Boards" +#: app/views/menu.html:115 +#: app/views/menu.html:192 +msgid "Board rules" msgstr "" -#: app/views/menu.html:221 +#: app/scripts/controllers/menu.js:334 +msgid "Board rules disabled" +msgstr "" + +#: app/scripts/controllers/menu.js:329 +msgid "Board rules enabled" +msgstr "" + +#: app/scripts/services/tools.js:234 +msgid "Board {{name}} not detected" +msgstr "" + +#: app/scripts/controllers/menu.js:435 +msgid "Board {{name}} selected" +msgstr "" + +#: app/views/menu.html:236 msgid "Build" msgstr "" @@ -104,180 +103,207 @@ msgstr "" msgid "Cancel" msgstr "" -#: app/scripts/services/tools.service.js:438 +#: app/scripts/services/tools.js:446 msgid "Check Internet connection..." msgstr "" -#: app/scripts/services/tools.service.js:446 +#: app/scripts/services/tools.js:454 msgid "Check Python..." msgstr "" -#: app/views/menu.html:337 +#: app/views/menu.html:361 msgid "Code" msgstr "" -#: app/scripts/services/tools.service.js:577 -msgid "Collection file {{name}} added" +#: app/views/menu.html:212 +msgid "Collection" +msgstr "" + +#: app/scripts/services/tools.js:631 +msgid "Collection {{name}} added" +msgstr "" + +#: app/scripts/services/tools.js:625 +msgid "Collection {{name}} not replaced" msgstr "" -#: app/scripts/services/tools.service.js:584 +#: app/scripts/services/tools.js:676 msgid "Collection {{name}} removed" msgstr "" -#: app/scripts/controllers/menu.js:374 +#: app/scripts/services/tools.js:621 +msgid "Collection {{name}} replaced" +msgstr "" + +#: app/scripts/controllers/menu.js:410 msgid "Collection {{name}} selected" msgstr "" -#: app/views/menu.html:185 -#: app/views/menu.html:271 +#: app/views/menu.html:286 msgid "Collections" msgstr "" -#: app/views/menu.html:317 +#: app/views/menu.html:332 msgid "Community forum" msgstr "" -#: app/views/menu.html:336 +#: app/views/menu.html:358 msgid "Constant" msgstr "" -#: app/views/menu.html:101 +#: app/views/menu.html:91 msgid "Copy" msgstr "" -#: app/views/menu.html:98 +#: app/views/menu.html:88 msgid "Cut" msgstr "" -#: app/views/menu.html:181 +#: app/views/menu.html:189 msgid "Datasheet" msgstr "" -#: app/views/menu.html:189 +#: app/views/menu.html:216 msgid "Default" msgstr "" -#: app/scripts/services/tools.service.js:315 +#: app/scripts/services/tools.js:322 msgid "Default toolchain not found. Toolchain will be downloaded. This operation requires Internet connection. Do you want to continue?" msgstr "" -#: app/scripts/services/utils.service.js:680 +#: app/scripts/services/utils.js:722 msgid "Description" msgstr "" -#: app/views/menu.html:264 +#: app/views/menu.html:126 +#: app/views/menu.html:279 msgid "Disable" msgstr "" -#: app/scripts/controllers/menu.js:218 +#: app/scripts/controllers/menu.js:234 msgid "Do you want to close the application?" msgstr "" -#: app/scripts/controllers/menu.js:445 +#: app/scripts/services/project.js:104 +msgid "Do you want to convert it?" +msgstr "" + +#: app/scripts/controllers/menu.js:485 msgid "Do you want to remove the {{name}} collection?" msgstr "" -#: app/views/menu.html:310 +#: app/scripts/services/tools.js:617 +msgid "Do you want to replace it?" +msgstr "" + +#: app/views/menu.html:325 msgid "Documentation" msgstr "" -#: app/views/menu.html:255 +#: app/views/menu.html:270 msgid "Drivers" msgstr "" -#: app/scripts/services/utils.service.js:449 -#: app/scripts/services/utils.service.js:517 +#: app/scripts/services/utils.js:453 +#: app/scripts/services/utils.js:521 msgid "Drivers disabled" msgstr "" -#: app/scripts/services/utils.service.js:446 -#: app/scripts/services/utils.service.js:498 +#: app/scripts/services/utils.js:450 +#: app/scripts/services/utils.js:502 msgid "Drivers enabled" msgstr "" -#: app/scripts/services/tools.service.js:239 +#: app/scripts/services/tools.js:246 msgid "Duplicated FPGA I/O ports" msgstr "" -#: app/scripts/services/blocks.service.js:314 +#: app/scripts/services/blocks.js:370 msgid "Duplicated block attributes" msgstr "" -#: app/views/menu.html:88 +#: app/views/menu.html:78 msgid "Edit" msgstr "" -#: app/views/menu.html:259 +#: app/views/menu.html:121 +#: app/views/menu.html:274 msgid "Enable" msgstr "" -#: app/views/menu.html:136 +#: app/views/menu.html:137 msgid "English" msgstr "" -#: app/scripts/services/blocks.service.js:126 +#: app/scripts/services/blocks.js:181 msgid "Enter the constant blocks" msgstr "" -#: app/scripts/services/blocks.service.js:213 +#: app/scripts/services/blocks.js:52 +msgid "Enter the input blocks" +msgstr "" + +#: app/scripts/services/blocks.js:269 msgid "Enter the input ports" msgstr "" -#: app/scripts/services/blocks.service.js:214 -msgid "Enter the output ports" +#: app/scripts/services/blocks.js:112 +msgid "Enter the output blocks" msgstr "" -#: app/scripts/services/blocks.service.js:215 -msgid "Enter the parameters" +#: app/scripts/services/blocks.js:270 +msgid "Enter the output ports" msgstr "" -#: app/scripts/services/blocks.service.js:57 -msgid "Enter the ports" +#: app/scripts/services/blocks.js:271 +msgid "Enter the parameters" msgstr "" -#: app/scripts/controllers/menu.js:314 +#: app/scripts/controllers/menu.js:321 msgid "Enter the remote hostname user@host (experimental)" msgstr "" -#: app/scripts/services/tools.service.js:338 +#: app/scripts/services/tools.js:345 msgid "Error: default toolchain not found in '{{dir}}'" msgstr "" -#: app/scripts/services/utils.service.js:813 +#: app/scripts/services/utils.js:855 msgid "Error: {{error}}" msgstr "" -#: app/views/menu.html:38 +#: app/views/menu.html:39 msgid "Examples" msgstr "" -#: app/scripts/services/tools.service.js:196 +#: app/scripts/services/tools.js:204 msgid "Execute remote {{label}} ..." msgstr "" -#: app/views/menu.html:64 +#: app/views/menu.html:54 msgid "Export" msgstr "" -#: app/scripts/services/tools.service.js:470 +#: app/scripts/services/tools.js:478 msgid "Extract default apio files..." msgstr "" -#: app/scripts/services/tools.service.js:480 +#: app/scripts/services/tools.js:488 msgid "Extract default apio packages..." msgstr "" -#: app/scripts/services/tools.service.js:458 +#: app/scripts/services/tools.js:466 msgid "Extract virtual env files..." msgstr "" -#: app/scripts/services/tools.service.js:233 -#: app/scripts/services/tools.service.js:236 +#: app/scripts/services/tools.js:240 +#: app/scripts/services/tools.js:243 msgid "FPGA I/O ports not defined" msgstr "" -#: app/scripts/services/blocks.service.js:58 -#: app/scripts/services/blocks.service.js:640 +#: app/scripts/services/blocks.js:113 +#: app/scripts/services/blocks.js:53 +#: app/scripts/services/blocks.js:698 +#: app/scripts/services/blocks.js:778 msgid "FPGA pin" msgstr "" @@ -285,120 +311,128 @@ msgstr "" msgid "File" msgstr "" -#: app/scripts/services/project.service.js:360 +#: app/scripts/services/project.js:376 msgid "File {{file}} already exists in the project path. Do you want to replace it?" msgstr "" -#: app/scripts/services/tools.service.js:172 +#: app/scripts/services/tools.js:180 msgid "File {{file}} does not exist" msgstr "" -#: app/scripts/services/project.service.js:392 +#: app/scripts/services/project.js:408 msgid "File {{file}} imported" msgstr "" -#: app/views/menu.html:114 +#: app/views/menu.html:104 msgid "Fit content" msgstr "" -#: app/views/menu.html:160 +#: app/views/menu.html:161 msgid "French" msgstr "" -#: app/scripts/controllers/menu.js:197 +#: app/scripts/controllers/menu.js:213 msgid "GTKWave exported" msgstr "" -#: app/views/menu.html:148 +#: app/views/menu.html:149 msgid "Galician" msgstr "" -#: app/views/menu.html:300 +#: app/views/menu.html:315 msgid "Help" msgstr "" -#: app/scripts/services/utils.service.js:487 +#: app/scripts/services/utils.js:491 msgid "Homebrew is required" msgstr "" -#: app/scripts/services/utils.service.js:694 +#: app/scripts/services/utils.js:736 msgid "Image" msgstr "" -#: app/scripts/controllers/menu.js:647 +#: app/scripts/controllers/menu.js:642 msgid "Image {{name}} saved" msgstr "" -#: app/views/menu.html:338 +#: app/views/menu.html:364 msgid "Information" msgstr "" -#: app/views/menu.html:334 +#: app/views/menu.html:352 msgid "Input" msgstr "" -#: app/views/menu.html:232 +#: app/views/menu.html:247 msgid "Install" msgstr "" -#: app/scripts/services/tools.service.js:475 +#: app/scripts/services/tools.js:483 msgid "Install default apio..." msgstr "" -#: app/scripts/services/tools.service.js:524 +#: app/scripts/services/tools.js:532 msgid "Installation completed" msgstr "" -#: app/scripts/services/tools.service.js:367 -#: app/scripts/services/tools.service.js:404 +#: app/scripts/services/tools.js:375 +#: app/scripts/services/tools.js:412 msgid "Installing toolchain" msgstr "" -#: app/scripts/services/tools.service.js:440 -#: app/scripts/services/utils.service.js:491 +#: app/scripts/services/tools.js:448 +#: app/scripts/services/utils.js:495 msgid "Internet connection required" msgstr "" -#: app/scripts/services/graph.service.js:186 +#: app/scripts/services/graph.js:175 msgid "Invalid Pull up connection:
    block already connected" msgstr "" -#: app/scripts/services/graph.service.js:200 +#: app/scripts/services/graph.js:189 msgid "Invalid Pull up connection:
    only Input blocks allowed" msgstr "" -#: app/scripts/services/graph.service.js:192 +#: app/scripts/services/graph.js:181 msgid "Invalid block connection:
    Pull up already connected" msgstr "" -#: app/scripts/services/graph.service.js:151 -#: app/scripts/services/graph.service.js:158 -#: app/scripts/services/graph.service.js:165 +#: app/scripts/services/tools.js:636 +msgid "Invalid collection {{name}}" +msgstr "" + +#: app/scripts/services/graph.js:140 +#: app/scripts/services/graph.js:147 +#: app/scripts/services/graph.js:154 msgid "Invalid connection" msgstr "" -#: app/scripts/services/graph.service.js:219 +#: app/scripts/services/graph.js:208 msgid "Invalid connection: {{a}} → {{b}}" msgstr "" -#: app/scripts/services/graph.service.js:180 +#: app/scripts/services/graph.js:169 msgid "Invalid multiple input connections" msgstr "" -#: app/views/menu.html:132 +#: app/views/menu.html:133 msgid "Language" msgstr "" -#: app/scripts/services/blocks.service.js:127 -#: app/scripts/services/blocks.service.js:713 +#: app/scripts/services/tools.js:579 +msgid "Load {{name}} ..." +msgstr "" + +#: app/scripts/services/blocks.js:182 +#: app/scripts/services/blocks.js:851 msgid "Local parameter" msgstr "" -#: app/scripts/services/tools.service.js:463 +#: app/scripts/services/tools.js:471 msgid "Make virtual env..." msgstr "" -#: app/scripts/services/utils.service.js:678 +#: app/scripts/services/utils.js:720 msgid "Name" msgstr "" @@ -406,11 +440,11 @@ msgstr "" msgid "New" msgstr "" -#: app/scripts/services/project.service.js:85 +#: app/scripts/services/project.js:80 msgid "New project {{name}} created" msgstr "" -#: app/scripts/controllers/menu.js:463 +#: app/scripts/controllers/menu.js:503 msgid "No collections stored" msgstr "" @@ -418,8 +452,8 @@ msgstr "" msgid "OK" msgstr "" -#: app/scripts/services/project.service.js:101 -#: app/scripts/services/project.service.js:308 +#: app/scripts/services/project.js:323 +#: app/scripts/services/project.js:97 msgid "Old project format {{version}}" msgstr "" @@ -427,434 +461,309 @@ msgstr "" msgid "Open" msgstr "" -#: app/scripts/services/utils.service.js:701 +#: app/scripts/services/utils.js:743 msgid "Open SVG" msgstr "" -#: app/scripts/services/project.service.js:395 +#: app/scripts/services/project.js:411 msgid "Original file {{file}} does not exist" msgstr "" -#: app/views/menu.html:335 +#: app/views/menu.html:355 msgid "Output" msgstr "" -#: app/scripts/controllers/menu.js:179 +#: app/scripts/controllers/menu.js:195 msgid "PCF file exported" msgstr "" -#: app/views/menu.html:104 +#: app/views/menu.html:94 msgid "Paste" msgstr "" -#: app/views/menu.html:118 +#: app/views/menu.html:108 msgid "Preferences" msgstr "" -#: app/views/menu.html:121 +#: app/views/menu.html:111 msgid "Project information" msgstr "" -#: app/scripts/services/project.service.js:108 +#: app/scripts/services/project.js:122 msgid "Project {{name}} loaded" msgstr "" -#: app/scripts/services/project.service.js:280 +#: app/scripts/services/project.js:295 msgid "Project {{name}} saved" msgstr "" -#: app/scripts/services/tools.service.js:451 +#: app/scripts/services/tools.js:459 msgid "Python 2.7 is required" msgstr "" -#: app/views/menu.html:82 +#: app/views/menu.html:72 msgid "Quit" msgstr "" -#: app/views/design.html:4 +#: app/views/design.html:5 msgid "Read only" msgstr "" -#: app/views/menu.html:94 +#: app/views/menu.html:84 msgid "Redo" msgstr "" -#: app/scripts/services/tools.service.js:264 +#: app/scripts/services/tools.js:271 msgid "Remote host {{name}} not connected" msgstr "" -#: app/views/menu.html:126 +#: app/views/menu.html:170 msgid "Remote hostname" msgstr "" -#: app/views/menu.html:240 -#: app/views/menu.html:279 +#: app/views/menu.html:255 +#: app/views/menu.html:294 msgid "Remove" msgstr "" -#: app/views/menu.html:291 +#: app/views/menu.html:306 msgid "Remove all" msgstr "" -#: app/scripts/services/utils.service.js:703 +#: app/scripts/services/utils.js:745 msgid "Reset SVG" msgstr "" -#: app/views/menu.html:245 +#: app/views/menu.html:260 msgid "Reset default" msgstr "" -#: app/views/menu.html:111 +#: app/views/menu.html:101 msgid "Reset view" msgstr "" -#: app/views/menu.html:57 +#: app/views/menu.html:47 msgid "Save" msgstr "" -#: app/scripts/services/utils.service.js:702 +#: app/scripts/services/utils.js:744 msgid "Save SVG" msgstr "" -#: app/views/menu.html:60 +#: app/views/menu.html:50 msgid "Save as" msgstr "" -#: app/views/menu.html:107 +#: app/views/menu.html:198 +msgid "Select" +msgstr "" + +#: app/views/menu.html:97 msgid "Select all" msgstr "" -#: app/views/menu.html:313 +#: app/scripts/services/blocks.js:54 +#: app/scripts/services/blocks.js:699 +msgid "Show clock" +msgstr "" + +#: app/views/menu.html:328 msgid "Source code" msgstr "" -#: app/views/menu.html:142 +#: app/views/menu.html:143 msgid "Spanish" msgstr "" -#: app/scripts/services/tools.service.js:185 +#: app/scripts/services/tools.js:193 msgid "Synchronize remote files ..." msgstr "" -#: app/views/menu.html:73 +#: app/views/menu.html:63 msgid "Testbench" msgstr "" -#: app/scripts/controllers/menu.js:188 +#: app/scripts/controllers/menu.js:204 msgid "Testbench exported" msgstr "" -#: app/scripts/controllers/menu.js:388 +#: app/scripts/services/tools.js:616 +msgid "The collection {{name}} already exists." +msgstr "" + +#: app/scripts/controllers/menu.js:424 msgid "The current FPGA I/O configuration will be lost. Do you want to change to {{name}} board?" msgstr "" -#: app/scripts/services/tools.service.js:343 +#: app/scripts/services/tools.js:350 msgid "The toolchain will be removed. Do you want to continue?" msgstr "" -#: app/scripts/services/tools.service.js:331 +#: app/scripts/services/tools.js:338 msgid "The toolchain will be restored to default. Do you want to continue?" msgstr "" -#: app/scripts/services/tools.service.js:323 +#: app/scripts/services/tools.js:330 msgid "The toolchain will be updated. This operation requires Internet connection. Do you want to continue?" msgstr "" -#: app/scripts/services/project.service.js:329 +#: app/scripts/services/project.js:345 msgid "This import operation requires a project path. You need to save the current project. Do you want to continue?" msgstr "" -#: app/views/menu.html:228 +#: app/scripts/services/project.js:103 +msgid "This project is designed for the {{name}} board." +msgstr "" + +#: app/views/menu.html:243 msgid "Toolchain" msgstr "" -#: app/scripts/services/tools.service.js:525 +#: app/scripts/services/tools.js:533 msgid "Toolchain installed" msgstr "" -#: app/scripts/services/tools.service.js:529 +#: app/scripts/services/tools.js:536 msgid "Toolchain not installed" msgstr "" -#: app/scripts/services/tools.service.js:100 -#: app/scripts/services/utils.service.js:529 -#: app/scripts/services/utils.service.js:545 +#: app/scripts/services/tools.js:92 +#: app/scripts/services/utils.js:533 +#: app/scripts/services/utils.js:549 msgid "Toolchain not installed. Please, install the toolchain" msgstr "" -#: app/scripts/services/tools.service.js:347 +#: app/scripts/services/tools.js:355 msgid "Toolchain removed" msgstr "" -#: app/views/menu.html:215 +#: app/views/menu.html:230 msgid "Tools" msgstr "" -#: app/views/menu.html:91 +#: app/views/menu.html:81 msgid "Undo" msgstr "" -#: app/scripts/services/tools.service.js:230 +#: app/scripts/services/tools.js:237 msgid "Unknown board" msgstr "" -#: app/scripts/app.js:42 +#: app/scripts/app.js:43 msgid "Untitled" msgstr "" -#: app/views/menu.html:235 +#: app/views/menu.html:250 msgid "Update" msgstr "" -#: app/scripts/services/blocks.service.js:712 -msgid "Update the block label" -msgstr "" - -#: app/scripts/services/blocks.service.js:639 -msgid "Update the port" +#: app/scripts/services/blocks.js:697 +#: app/scripts/services/blocks.js:777 +#: app/scripts/services/blocks.js:850 +msgid "Update the block name" msgstr "" -#: app/views/menu.html:224 +#: app/views/menu.html:239 msgid "Upload" msgstr "" -#: app/views/menu.html:218 +#: app/views/menu.html:233 msgid "Verify" msgstr "" -#: app/scripts/controllers/menu.js:170 +#: app/scripts/controllers/menu.js:186 msgid "Verilog code exported" msgstr "" -#: app/scripts/services/utils.service.js:679 -#: app/views/menu.html:306 +#: app/scripts/services/utils.js:721 +#: app/views/menu.html:321 msgid "Version" msgstr "" -#: app/views/menu.html:172 +#: app/views/menu.html:180 msgid "View" msgstr "" -#: app/views/menu.html:303 +#: app/views/menu.html:318 msgid "View license" msgstr "" -#: app/scripts/services/blocks.service.js:347 +#: app/scripts/services/blocks.js:404 msgid "Wrong block format: {{type}}" msgstr "" -#: app/scripts/services/blocks.service.js:146 -#: app/scripts/services/blocks.service.js:263 +#: app/scripts/services/blocks.js:132 +#: app/scripts/services/blocks.js:201 +#: app/scripts/services/blocks.js:75 +#: app/scripts/services/blocks.js:768 +#: app/scripts/services/blocks.js:842 +#: app/scripts/services/blocks.js:877 +msgid "Wrong block name {{name}}" +msgstr "" + +#: app/scripts/services/blocks.js:319 msgid "Wrong parameter name {{name}}" msgstr "" -#: app/scripts/services/blocks.service.js:233 -#: app/scripts/services/blocks.service.js:248 -#: app/scripts/services/blocks.service.js:704 -#: app/scripts/services/blocks.service.js:77 +#: app/scripts/services/blocks.js:289 +#: app/scripts/services/blocks.js:304 msgid "Wrong port name {{name}}" msgstr "" -#: app/scripts/services/project.service.js:116 +#: app/scripts/services/project.js:130 msgid "Wrong project format: {{name}}" msgstr "" -#: app/scripts/services/tools.service.js:261 +#: app/scripts/services/tools.js:268 msgid "Wrong remote hostname {{name}}" msgstr "" -#: app/scripts/controllers/menu.js:219 +#: app/scripts/controllers/menu.js:235 msgid "Your changes will be lost if you don’t save them" msgstr "" -#. And -#: app/resources/blocks/labels.js:34 -msgid "and" -msgstr "" - -#: app/views/design.html:5 +#: app/views/design.html:6 msgid "back" msgstr "" -#. Bit -#: app/resources/blocks/labels.js:4 -msgid "bit" -msgstr "" - -#. Combinational -#: app/resources/blocks/labels.js:16 -msgid "combinational" -msgstr "" - -#. Config -#: app/resources/blocks/labels.js:6 -msgid "config" -msgstr "" - -#. contadorAsc -#: app/resources/examples/labels.js:12 -msgid "contadorAsc" -msgstr "" - -#. contadorDes -#: app/resources/examples/labels.js:14 -msgid "contadorDes" -msgstr "" - -#. Debouncer -#: app/resources/blocks/labels.js:58 -msgid "debouncer" -msgstr "" - -#. Demux 1:2 -#: app/resources/blocks/labels.js:18 -msgid "demux_1_2" -msgstr "" - -#. Demux 1:4 -#: app/resources/blocks/labels.js:20 -msgid "demux_1_4" -msgstr "" - -#. Demux 1:8 -#: app/resources/blocks/labels.js:22 -msgid "demux_1_8" -msgstr "" - -#. D flip-flop async -#: app/resources/blocks/labels.js:50 -msgid "dff_ar" -msgstr "" - -#. D flip-flop async -#: app/resources/blocks/labels.js:52 -msgid "dff_sr" -msgstr "" - #. Build done -#: app/scripts/services/tools.service.js:276 +#: app/scripts/services/tools.js:283 msgid "done_build" msgstr "" #. Upload done -#: app/scripts/services/tools.service.js:278 +#: app/scripts/services/tools.js:285 msgid "done_upload" msgstr "" #. Verification done -#: app/scripts/services/tools.service.js:274 +#: app/scripts/services/tools.js:281 msgid "done_verify" msgstr "" -#. Gate -#: app/resources/blocks/labels.js:32 -msgid "gate" -msgstr "" - -#. Hex 7 Segment CA -#: app/resources/blocks/labels.js:26 -msgid "hex_7seg_ca" -msgstr "" - -#. Hex 7 Segment CC -#: app/resources/blocks/labels.js:24 -msgid "hex_7seg_cc" -msgstr "" - -#. Logic -#: app/resources/blocks/labels.js:14 -msgid "logic" -msgstr "" - -#. Mux 2:1 -#: app/resources/blocks/labels.js:28 -msgid "mux_2_1" -msgstr "" - -#. Mux 4:1 -#: app/resources/blocks/labels.js:30 -msgid "mux_4_1" -msgstr "" - -#. Nand -#: app/resources/blocks/labels.js:36 -msgid "nand" -msgstr "" - -#. Nor -#: app/resources/blocks/labels.js:38 -msgid "nor" -msgstr "" - -#. Not -#: app/resources/blocks/labels.js:40 -msgid "not" -msgstr "" - -#. Or -#: app/resources/blocks/labels.js:42 -msgid "or" -msgstr "" - -#. Pull up -#: app/resources/blocks/labels.js:8 -msgid "pull_up" -msgstr "" - -#. Pull up inv -#: app/resources/blocks/labels.js:10 -msgid "pull_up_inv" -msgstr "" - -#. Sequential -#: app/resources/blocks/labels.js:48 -msgid "sequential" -msgstr "" - #. Start building ... -#: app/scripts/services/tools.service.js:64 +#: app/scripts/services/tools.js:60 msgid "start_build" msgstr "" #. Start uploading ... -#: app/scripts/services/tools.service.js:66 +#: app/scripts/services/tools.js:62 msgid "start_upload" msgstr "" #. Start verification ... -#: app/scripts/services/tools.service.js:62 +#: app/scripts/services/tools.js:58 msgid "start_verify" msgstr "" -#. T flip-flop async -#: app/resources/blocks/labels.js:54 -msgid "tff_ar" -msgstr "" - -#. T flip-flop -#: app/resources/blocks/labels.js:56 -msgid "tff_sr" -msgstr "" - -#. Tri-state -#: app/resources/blocks/labels.js:12 -msgid "tri_state" -msgstr "" - -#. Xnor -#: app/resources/blocks/labels.js:44 -msgid "xnor" -msgstr "" - -#. Xor -#: app/resources/blocks/labels.js:46 -msgid "xor" -msgstr "" - -#: app/scripts/controllers/menu.js:366 +#: app/scripts/controllers/menu.js:383 msgid "{{board}} datasheet not defined" msgstr "" -#: app/scripts/controllers/menu.js:356 +#: app/scripts/controllers/menu.js:373 msgid "{{board}} pinout not defined" msgstr "" + +#: app/scripts/controllers/menu.js:402 +msgid "{{board}} rules not defined" +msgstr "" diff --git a/app/resources/viewers/plain/pcf.html b/app/resources/viewers/plain/pcf.html index 98945b6ae..f2967dfb9 100644 --- a/app/resources/viewers/plain/pcf.html +++ b/app/resources/viewers/plain/pcf.html @@ -24,21 +24,22 @@ diff --git a/app/resources/viewers/svg/pinout.html b/app/resources/viewers/svg/pinout.html index 6ac3e7b6b..d273cdccd 100644 --- a/app/resources/viewers/svg/pinout.html +++ b/app/resources/viewers/svg/pinout.html @@ -8,12 +8,13 @@ + + diff --git a/app/scripts/app.js b/app/scripts/app.js index 5cb83d51b..6f54dd8cc 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -20,25 +20,26 @@ angular ]) .run(function(profile, project, + resources, utils, gettextCatalog, nodeLangInfo) { // Load language profile.load(function() { - var lang = profile.data.language; + var lang = profile.get('language'); if (lang) { - utils.setLocale(lang); + utils.setLocale(lang, resources.collections); } else { // If lang is empty, use the system language nodeLangInfo(function(err, sysLang) { if (!err) { - profile.data.language = utils.setLocale(sysLang); + profile.set('language', utils.setLocale(sysLang, resources.collections)); } }); } }); setTimeout(function() { project.updateTitle(gettextCatalog.getString('Untitled')); - }, 100); + }, 200); }); diff --git a/app/scripts/controllers/design.js b/app/scripts/controllers/design.js index 2d4db5053..fc7adaaac 100644 --- a/app/scripts/controllers/design.js +++ b/app/scripts/controllers/design.js @@ -4,12 +4,13 @@ angular.module('icestudio') .controller('DesignCtrl', function ($rootScope, $scope, project, - boards, graph, - utils) { + utils, + common) { - $scope.boards = boards; + $scope.common = common; $scope.graph = graph; + $scope.information = {}; // Intialization @@ -34,19 +35,33 @@ angular.module('icestudio') function loadSelectedGraph() { var n = graph.breadcrumbs.length; + var opt = { disabled: true }; if (n === 1) { var design = project.get('design'); - graph.loadDesign(design, false); + opt.disabled = false; + graph.loadDesign(design, opt); } else { - var dependencies = project.getAllDependencies(); var type = graph.breadcrumbs[n-1].type; - graph.loadDesign(dependencies[type].design, true); + var dependency = common.allDependencies[type]; + graph.loadDesign(dependency.design, opt); + $scope.information = dependency.package; } } - $rootScope.$on('updateProject', function(event, callback) { - project.update(callback, false); + $rootScope.$on('navigateProject', function(event, args) { + var opt = { disabled: true }; + if (args.update) { + // Update the main project + project.update({ deps: false }, function() { + graph.loadDesign(args.project.design, opt); + }); + } + else { + graph.loadDesign(args.project.design, opt); + } + $scope.information = args.project.package; + utils.rootScopeSafeApply(); }); $rootScope.$on('breadcrumbsBack', function(/*event*/) { diff --git a/app/scripts/controllers/menu.js b/app/scripts/controllers/menu.js index 6aaba2cea..f33e0553c 100644 --- a/app/scripts/controllers/menu.js +++ b/app/scripts/controllers/menu.js @@ -11,6 +11,8 @@ angular.module('icestudio') graph, tools, utils, + common, + shortcuts, gettextCatalog, gui, _package, @@ -24,6 +26,7 @@ angular.module('icestudio') $scope.project = project; $scope.tools = tools; $scope.resources = resources; + $scope.common = common; $scope.version = _package.version; $scope.toolchain = tools.toolchain; @@ -33,7 +36,8 @@ angular.module('icestudio') var zeroProject = true; // New project without changes - // Initialize selected collection + // Initialize + updateSelectedBoard(); updateSelectedCollection(); // Window events @@ -69,8 +73,17 @@ angular.module('icestudio') // Load app arguments setTimeout(function() { + var local = false; for (var i in gui.App.argv) { - processArg(gui.App.argv[i]); + var arg = gui.App.argv[i]; + processArg(arg); + local = arg === 'local' || local; + } + if (local) { + project.path = ''; + } + else { + updateWorkingdir(project.path); } }, 0); @@ -78,12 +91,8 @@ angular.module('icestudio') if (nodeFs.existsSync(arg)) { // Open filepath var filepath = arg; - var emptyPath = filepath.startsWith('resources'); // it is an example - if (!emptyPath) { - updateWorkingdir(filepath); - } - project.open(filepath, emptyPath); - zeroProject = false; + project.open(filepath); + //zeroProject = false; } else { // Move window @@ -103,14 +112,14 @@ angular.module('icestudio') utils.newWindow(); }; - $scope.openProject = function() { + $scope.openProjectDialog = function() { utils.openDialog('#input-open-project', '.ice', function(filepath) { if (zeroProject) { // If this is the first action, open // the projec in the same window updateWorkingdir(filepath); project.open(filepath); - zeroProject = false; + //zeroProject = false; } else if (project.changed || !equalWorkingFilepath(filepath)) { // If this is not the first action, and @@ -121,18 +130,18 @@ angular.module('icestudio') }); }; - $scope.openExample = function(filepath) { + $scope.openProject = function(filepath) { if (zeroProject) { // If this is the first action, open // the projec in the same window project.open(filepath, true); - zeroProject = false; + //zeroProject = false; } else { // If this is not the first action, and // the file path is different, open // the project in a new window - utils.newWindow(filepath); + utils.newWindow(filepath, true); } }; @@ -222,7 +231,7 @@ angular.module('icestudio') function exit() { if (project.changed) { alertify.confirm( - '' + gettextCatalog.getString('Do you want to close the application?') + '
    ' + + utils.bold(gettextCatalog.getString('Do you want to close the application?')) + '
    ' + gettextCatalog.getString('Your changes will be lost if you don’t save them'), function() { _exit(); @@ -233,7 +242,7 @@ angular.module('icestudio') } function _exit() { //win.hide(); - profile.save(); + //profile.save(); win.close(true); } } @@ -250,15 +259,11 @@ angular.module('icestudio') }; $scope.cutSelected = function() { - if (graph.hasSelection()) { - graph.cutSelected(); - } + graph.cutSelected(); }; $scope.copySelected = function() { - if (graph.hasSelection()) { - graph.copySelected(); - } + graph.copySelected(); }; var paste = true; @@ -280,12 +285,7 @@ angular.module('icestudio') }; function removeSelected() { - if (graph.hasSelection()) { - //alertify.confirm(gettextCatalog.getString('Do you want to remove the selected block?'), - //function() { - project.removeSelected(); - //}); - } + project.removeSelected(); } $scope.resetView = function() { @@ -317,17 +317,27 @@ angular.module('icestudio') }; $scope.setRemoteHostname = function() { - var current = profile.data.remoteHostname; + var current = profile.get('remoteHostname'); alertify.prompt(gettextCatalog.getString('Enter the remote hostname user@host (experimental)'), (current) ? current : '', function(evt, remoteHostname) { - profile.data.remoteHostname = remoteHostname; + profile.set('remoteHostname', remoteHostname); }); }; + $scope.enableBoardRules = function() { + graph.setBoardRules(true); + alertify.success(gettextCatalog.getString('Board rules enabled')); + }; + + $scope.disableBoardRules = function() { + graph.setBoardRules(false); + alertify.success(gettextCatalog.getString('Board rules disabled')); + }; + $scope.selectLanguage = function(language) { - if (profile.data.language !== language) { - profile.data.language = language; - utils.setLocale(language); + if (profile.get('language') !== language) { + profile.set('language', language); + utils.setLocale(language, resources.collections); } }; @@ -335,8 +345,8 @@ angular.module('icestudio') //-- View $scope.showPCF = function() { - gui.Window.open('resources/viewers/plain/pcf.html?board=' + boards.selectedBoard.name, { - title: boards.selectedBoard.info.label + ' - PCF', + gui.Window.open('resources/viewers/plain/pcf.html?board=' + common.selectedBoard.name, { + title: common.selectedBoard.info.label + ' - PCF', focus: true, toolbar: false, resizable: true, @@ -347,10 +357,10 @@ angular.module('icestudio') }; $scope.showPinout = function() { - var board = boards.selectedBoard; + var board = common.selectedBoard; if (nodeFs.existsSync(nodePath.join('resources', 'boards', board.name, 'pinout.svg'))) { gui.Window.open('resources/viewers/svg/pinout.html?board=' + board.name, { - title: boards.selectedBoard.info.label + ' - Pinout', + title: common.selectedBoard.info.label + ' - Pinout', focus: true, toolbar: false, resizable: true, @@ -360,37 +370,56 @@ angular.module('icestudio') }); } else { - alertify.notify(gettextCatalog.getString('{{board}} pinout not defined', { board: utils.bold(board.info.label) }), 'warning', 5); + alertify.warning(gettextCatalog.getString('{{board}} pinout not defined', { board: utils.bold(board.info.label) }), 5); } }; $scope.showDatasheet = function() { - var board = boards.selectedBoard; + var board = common.selectedBoard; if (board.info.datasheet) { gui.Shell.openExternal(board.info.datasheet); } else { - alertify.notify(gettextCatalog.getString('{{board}} datasheet not defined', { board: utils.bold(board.info.label) }), 'error', 5); + alertify.error(gettextCatalog.getString('{{board}} datasheet not defined', { board: utils.bold(board.info.label) }), 5); + } + }; + + $scope.showBoardRules = function() { + var board = common.selectedBoard; + var rules = JSON.stringify(board.rules); + if (rules !== '{}') { + gui.Window.open('resources/viewers/table/rules.html?rules=' + rules, { + title: common.selectedBoard.info.label + ' - Rules', + focus: true, + toolbar: false, + resizable: false, + width: 500, + height: 500, + icon: 'resources/images/icestudio-logo.png' + }); + } + else { + alertify.error(gettextCatalog.getString('{{board}} rules not defined', { board: utils.bold(board.info.label) }), 5); } }; $scope.selectCollection = function(collection) { if (resources.selectedCollection.name !== collection.name) { var name = resources.selectCollection(collection.name); - profile.data.collection = name; + profile.set('collection', name); alertify.success(gettextCatalog.getString('Collection {{name}} selected', { name: utils.bold(name) })); } }; function updateSelectedCollection() { - profile.data.collection = resources.selectCollection(profile.data.collection); + profile.set('collection', resources.selectCollection(profile.get('collection'))); } //-- Boards $scope.selectBoard = function(board) { - if (boards.selectedBoard.name !== board.name) { + if (common.selectedBoard.name !== board.name) { if (!graph.isEmpty()) { alertify.confirm(gettextCatalog.getString('The current FPGA I/O configuration will be lost. Do you want to change to {{name}} board?', { name: utils.bold(board.info.label) }), function() { @@ -402,11 +431,15 @@ angular.module('icestudio') } } function _boardSelected() { - graph.selectBoard(board.name); + profile.set('board', graph.selectBoard(board.name)); alertify.success(gettextCatalog.getString('Board {{name}} selected', { name: utils.bold(board.info.label) })); } }; + function updateSelectedBoard() { + profile.set('board', boards.selectBoard(profile.get('board'))); + } + //-- Tools @@ -435,15 +468,15 @@ angular.module('icestudio') } } else { - alertify.notify(gettextCatalog.getString('Add a block to start'), 'warning', 5); + alertify.warning(gettextCatalog.getString('Add a block to start'), 5); } } - $scope.addCollection = function() { + $scope.addCollections = function() { utils.openDialog('#input-add-collection', '.zip', function(filepaths) { filepaths = filepaths.split(';'); for (var i in filepaths) { - tools.addCollection(filepaths[i]); + tools.addCollections(filepaths[i]); } }); }; @@ -458,7 +491,7 @@ angular.module('icestudio') }; $scope.removeAllCollections = function() { - if (resources.currentCollections.length > 1) { + if (resources.collections.length > 1) { alertify.confirm(gettextCatalog.getString('All stored collections will be lost. Do you want to continue?'), function() { tools.removeAllCollections(); @@ -467,7 +500,7 @@ angular.module('icestudio') }); } else { - alertify.notify(gettextCatalog.getString('No collections stored'), 'warning', 5); + alertify.warning(gettextCatalog.getString('No collections stored'), 5); } }; @@ -517,7 +550,7 @@ angular.module('icestudio') zeroProject = false; } - // Shortcuts + // Detect prompt var promptShown = false; @@ -530,111 +563,66 @@ angular.module('icestudio') } }); - $(document).on('keydown', function(event) { - if (!promptShown) { - if (graph.isEnabled()) { - if (event.ctrlKey) { - switch (event.keyCode) { - case 78: // Ctrl+N - $scope.newProject(); - break; - case 79: // Ctrl+O - $scope.openProject(); - break; - case 83: - if (event.shiftKey) { // Ctrl+Shift+S - $scope.saveProjectAs(); - } - else { // Ctrl+S - $scope.saveProject(); - } - break; - case 81: // Ctrl+Q - $scope.quit(); - break; - case 90: - if (event.shiftKey) { // Ctrl+Shift+Z - $scope.redoGraph(); - event.preventDefault(); - } - else { // Ctrl+Z - $scope.undoGraph(); - event.preventDefault(); - } - break; - case 89: // Ctrl+Y - $scope.redoGraph(); - event.preventDefault(); - break; - case 88: // Ctrl+X - $scope.cutSelected(); - break; - case 67: // Ctrl+C - $scope.copySelected(); - break; - case 86: // Ctrl+V - $scope.pasteSelected(); - break; - case 65: // Ctrl+A - $scope.selectAll(); - break; - case 82: // Ctrl+R - $scope.verifyCode(); - break; - case 66: // Ctrl+B - $scope.buildCode(); - break; - case 85: // Ctrl+U - $scope.uploadCode(); - break; - } - } - - if (graph.hasSelection()) { - switch (event.keyCode) { - case 37: // Arrow Left - graph.stepLeft(); - break; - case 38: // Arrow Up - graph.stepUp(); - break; - case 39: // Arrow Right - graph.stepRight(); - break; - case 40: // Arrow Down - graph.stepDown(); - break; - } - } + alertify.confirm().set({ + onshow: function() { + promptShown = true; + }, + onclose: function() { + promptShown = false; + } + }); - if (event.keyCode === 46) { // Supr - removeSelected(); - } - } - if (event.ctrlKey) { - switch (event.keyCode) { - case 48: // Ctrl+0 - $scope.resetView(); - break; - case 70: // Ctrl+F - $scope.fitContent(); - break; - } - } - if (event.keyCode === 8) { // Back - if (!graph.isEnabled()) { - $rootScope.$broadcast('breadcrumbsBack'); - } - else { - if (process.platform === 'darwin') { - removeSelected(); - } - } - } + // Configure all shortcuts + + // -- File + shortcuts.method('newProject', $scope.newProject); + shortcuts.method('openProject', $scope.openProjectDialog); + shortcuts.method('saveProject', $scope.saveProject); + shortcuts.method('saveProjectAs', $scope.saveProjectAs); + shortcuts.method('quit', $scope.quit); + + // -- Edit + shortcuts.method('undoGraph', $scope.undoGraph); + shortcuts.method('redoGraph', $scope.redoGraph); + shortcuts.method('redoGraph2', $scope.redoGraph); + shortcuts.method('cutSelected', $scope.cutSelected); + shortcuts.method('copySelected', $scope.copySelected); + shortcuts.method('pasteSelected', $scope.pasteSelected); + shortcuts.method('selectAll', $scope.selectAll); + shortcuts.method('resetView', $scope.resetView); + shortcuts.method('fitContent', $scope.fitContent); + + // -- Tools + shortcuts.method('verifyCode', $scope.verifyCode); + shortcuts.method('buildCode', $scope.buildCode); + shortcuts.method('uploadCode', $scope.uploadCode); + + // -- Misc + shortcuts.method('stepUp', graph.stepUp); + shortcuts.method('stepDown', graph.stepDown); + shortcuts.method('stepLeft', graph.stepLeft); + shortcuts.method('stepRight', graph.stepRight); + + shortcuts.method('removeSelected', removeSelected); + shortcuts.method('breadcrumbsBack', function() { + if (!graph.isEnabled()) { + $rootScope.$broadcast('breadcrumbsBack'); } - if (event.ctrlKey && event.keyCode === 80) { // Ctrl+P - // Print and save a window snapshot - takeSnapshot(); + }); + + shortcuts.method('takeSnapshot', takeSnapshot); + + // Detect shortcuts + + $(document).on('keydown', function(event) { + var opt = { + prompt: promptShown, + disabled: !graph.isEnabled() + }; + + var ret = shortcuts.execute(event, opt); + if (ret.preventDefault) { + event.preventDefault(); } }); diff --git a/app/scripts/directives/menutree.js b/app/scripts/directives/menutree.js new file mode 100644 index 000000000..2d04a1e91 --- /dev/null +++ b/app/scripts/directives/menutree.js @@ -0,0 +1,46 @@ +'use strict'; + +angular.module('icestudio') + .directive('menutree', function () { + return { + restrict: 'E', + replace: true, + scope: { + data: '=', + right: '=', + callback: '&' + }, + template: '
      ' + + '' + + '
    ', + link: function (scope/*, element, attrs*/) { + scope.click = function(path) { + scope.callback({ path: path }); + }; + } + }; + }) + .directive('child', function ($compile) { + return { + restrict: 'E', + replace: true, + scope: { + child: '=', + right: '=', + callback: '&' + }, + template: '
  • ' + + '{{ child.name | translate }}' + + '{{ child.name | translate }}' + + '
  • ', + link: function (scope, element/*, attrs*/) { + scope.click = function(path) { + scope.callback({ path: path }); + }; + if (angular.isArray(scope.child.children)) { + element.append(''); + $compile(element.contents())(scope); + } + } + }; + }); diff --git a/app/scripts/factories/joint.factory.js b/app/scripts/factories/joint.js similarity index 100% rename from app/scripts/factories/joint.factory.js rename to app/scripts/factories/joint.js diff --git a/app/scripts/factories/node.factory.js b/app/scripts/factories/node.js similarity index 84% rename from app/scripts/factories/node.factory.js rename to app/scripts/factories/node.js index 7f0facf3d..76c0e064a 100644 --- a/app/scripts/factories/node.factory.js +++ b/app/scripts/factories/node.js @@ -13,18 +13,12 @@ angular.module('icestudio') .factory('nodeSha1', function() { return require('sha1'); }) - .factory('nodeOs', function() { - return require('os'); - }) .factory('nodePath', function() { return require('path'); }) .factory('nodeChildProcess', function() { return require('child_process'); }) - .factory('nodeProcess', function() { - return require('process'); - }) .factory('nodeTarball', function() { return require('tarball-extract'); }) @@ -49,8 +43,14 @@ angular.module('icestudio') .factory('nodeLangInfo', function() { return require('node-lang-info'); }) - .factory('nodeUnzip', function() { - return require('unzip'); + .factory('nodeAdmZip', function() { + return require('adm-zip'); + }) + .factory('nodeGettext', function() { + return require('angular-gettext-tools'); + }) + .factory('nodeCP', function() { + return require('copy-paste'); }) .factory('SVGO', function() { return require('svgo'); diff --git a/app/scripts/factories/window.factory.js b/app/scripts/factories/window.js similarity index 100% rename from app/scripts/factories/window.factory.js rename to app/scripts/factories/window.js diff --git a/app/scripts/plugins/dia/joint.dia.command.js b/app/scripts/graphics/joint.command.js similarity index 89% rename from app/scripts/plugins/dia/joint.dia.command.js rename to app/scripts/graphics/joint.command.js index 224d1e2e8..6c459937e 100755 --- a/app/scripts/plugins/dia/joint.dia.command.js +++ b/app/scripts/graphics/joint.command.js @@ -28,6 +28,8 @@ joint.dia.CommandManager = Backbone.Model.extend({ listen: function() { + this.listenTo(this.graph, 'state', this.updateState, this); + this.listenTo(this.graph, 'all', this.addCommand, this); this.listenTo(this.graph, 'batch:start', this.initBatchCommand, this); @@ -45,6 +47,10 @@ joint.dia.CommandManager = Backbone.Model.extend({ return cmd; }, + updateState: function(state) { + this.state = state; + }, + addCommand: function(cmdName, cell, graph, options) { if (cmdName === 'change:labels' || @@ -65,13 +71,13 @@ joint.dia.CommandManager = Backbone.Model.extend({ this.redoStack = []; if (!cmd.batch) { - this.undoStack.push(cmd); + this.undoStack.push(cmd); this.triggerChange(); - this.trigger('add', cmd); + this.trigger('add', cmd); } else { this.lastCmdIndex = Math.max(this.lastCmdIndex, 0); - // Commands possible thrown away. Someone might be interested. - this.trigger('batch', cmd); + // Commands possible thrown away. Someone might be interested. + this.trigger('batch', cmd); } }, this); @@ -110,17 +116,20 @@ joint.dia.CommandManager = Backbone.Model.extend({ command.batch = false; } - if (cmdName === 'add' || cmdName === 'remove') { - - // In a batch: delete an "add-remove" sequence if it is applied to the same cell - if (cmdName === 'remove' && this.batchCommand && this.lastCmdIndex > 0) { - var prevCommand = this.batchCommand[this.lastCmdIndex-1]; + // In a batch: delete an "add-*-remove" sequence if it is applied to the same cell + if (cmdName === 'remove' && this.batchCommand && this.lastCmdIndex > 0) { + for (var i = 0; i < this.lastCmdIndex; i++) { + var prevCommand = this.batchCommand[i]; if (prevCommand.action === 'add' && prevCommand.data.id === cell.id) { - this.batchCommand.pop(); - this.batchCommand.pop(); + delete this.batchCommand; + delete this.lastCmdIndex; + delete this.batchLevel; return; } } + } + + if (cmdName === 'add' || cmdName === 'remove') { command.action = cmdName; command.data.id = cell.id; @@ -239,8 +248,9 @@ joint.dia.CommandManager = Backbone.Model.extend({ break; case 'remove': - this.graph.addCell(cmd.data.attributes); - break; + cmd.data.attributes.state = this.state; + this.graph.addCell(cmd.data.attributes); + break; case 'board': this.triggerBoard(cmd.data.previous); @@ -256,20 +266,18 @@ joint.dia.CommandManager = Backbone.Model.extend({ cmd.options.ty *= -1; options = cmd.options; } - if (attribute === 'data' && - (cmd.data.type === 'ice.Code' || - cmd.data.type === 'ice.Info')) { + if (attribute === 'deltas') { // Ace editor requires the next deltas to revert data = cmd.data.next[attribute]; } else { data = cmd.data.previous[attribute]; } - cell.set(attribute, data, options); if (cell) { + cell.set(attribute, data, options); var cellView = this.paper.findViewByModel(cell); if (cellView) { - cellView.apply({ undo: true }); + cellView.apply({ undo: true, attribute: attribute }); } } break; @@ -298,6 +306,7 @@ joint.dia.CommandManager = Backbone.Model.extend({ switch (cmd.action) { case 'add': + cmd.data.attributes.state = this.state; this.graph.addCell(cmd.data.attributes); break; @@ -319,11 +328,11 @@ joint.dia.CommandManager = Backbone.Model.extend({ options = cmd.options; } data = cmd.data.next[attribute]; - cell.set(attribute, data, options); if (cell) { + cell.set(attribute, data, options); var cellView = this.paper.findViewByModel(cell); if (cellView) { - cellView.apply({ undo: false }); + cellView.apply({ undo: false, attribute: attribute }); } } break; @@ -333,33 +342,23 @@ joint.dia.CommandManager = Backbone.Model.extend({ this.listen(); }, - undo: function(state) { + undo: function() { var command = this.undoStack.pop(); this.triggerChange(); if (command) { - - if (command.action === 'add') { - command.data.attributes.state = state; - } - this.revertCommand(command); this.redoStack.push(command); } }, - redo: function(state) { + redo: function() { var command = this.redoStack.pop(); if (command) { - - if (command.action === 'add') { - command.data.attributes.state = state; - } - this.applyCommand(command); this.undoStack.push(command); this.triggerChange(); diff --git a/app/scripts/plugins/connectors/joint.connectors.js b/app/scripts/graphics/joint.connectors.js similarity index 100% rename from app/scripts/plugins/connectors/joint.connectors.js rename to app/scripts/graphics/joint.connectors.js diff --git a/app/scripts/plugins/routers/joint.routers.js b/app/scripts/graphics/joint.routers.js similarity index 100% rename from app/scripts/plugins/routers/joint.routers.js rename to app/scripts/graphics/joint.routers.js diff --git a/app/scripts/plugins/ui/joint.ui.js b/app/scripts/graphics/joint.selection.js similarity index 99% rename from app/scripts/plugins/ui/joint.ui.js rename to app/scripts/graphics/joint.selection.js index 9bac273e7..c88737235 100644 --- a/app/scripts/plugins/ui/joint.ui.js +++ b/app/scripts/graphics/joint.selection.js @@ -115,8 +115,6 @@ joint.ui.SelectionView = Backbone.View.extend({ this.model.each(function(element) { - // TODO: snap to grid. - // Translate the element itself. element.translate(dx, dy); diff --git a/app/scripts/plugins/shapes/joint.shapes.js b/app/scripts/graphics/joint.shapes.js similarity index 62% rename from app/scripts/plugins/shapes/joint.shapes.js rename to app/scripts/graphics/joint.shapes.js index 2fb7a5683..8f6c61de4 100644 --- a/app/scripts/plugins/shapes/joint.shapes.js +++ b/app/scripts/graphics/joint.shapes.js @@ -3,6 +3,7 @@ var os = require('os'); var sha1 = require('sha1'); +const WIRE_WIDTH = 1.5; const DARWIN = Boolean(os.platform().indexOf('darwin') > -1); if (DARWIN) { @@ -18,7 +19,12 @@ joint.shapes.ice = {}; joint.shapes.ice.Model = joint.shapes.basic.Generic.extend({ markup: '', - portMarkup: '', + portMarkup: ' \ + \ + \ + \ + \ + ', defaults: joint.util.deepSupplement({ type: 'ice.Model', @@ -31,7 +37,6 @@ joint.shapes.ice.Model = joint.shapes.basic.Generic.extend({ topPorts: [], bottomPorts: [], attrs: { - gridUnits: 1, '.': { magnet: false }, @@ -66,19 +71,41 @@ joint.shapes.ice.Model = joint.shapes.basic.Generic.extend({ magnet: true }, '.port-label': { - fill: '#888' + fill: '#777' }, '.port-wire': { - stroke: '#888', - 'stroke-width': 2 + stroke: '#777', + 'stroke-width': WIRE_WIDTH + }, + '.port-default': { + display: 'none' + }, + '.port-default rect': { + x: '-40', + y: '-10', + width: '20', + height: '20', + rx: '3', + ry: '3', + stroke: '#777', + 'stroke-width': 1, + fill: '#FBFBC9' + }, + '.port-default path': { + d: 'M 0 0 L -20 0', + stroke: '#777', + 'stroke-width': WIRE_WIDTH } + } }, joint.shapes.basic.Generic.prototype.defaults), initialize: function() { this.updatePortsAttrs(); - this.on('change:leftPorts change:rightPorts change:topPorts change:bottomPorts', this.updatePortsAttrs, this); + this.processPorts(); + this.trigger('process:ports'); + this.on('change:size change:leftPorts change:rightPorts change:topPorts change:bottomPorts', this.updatePortsAttrs, this); this.constructor.__super__.constructor.__super__.initialize.apply(this, arguments); }, @@ -87,32 +114,43 @@ joint.shapes.ice.Model = joint.shapes.basic.Generic.extend({ var newAttrs = _.omit(this.get('attrs'), this._portSelectors); this.set('attrs', newAttrs, { silent: true }); } - this._portSelectors = []; + var attrs = {}; + this._portSelectors = []; + + _.each(['left', 'right'], function(type) { + var port = type + 'Ports'; + _.each(this.get(port), function(portName, index, ports) { + var portAttributes = this.getPortAttrs(portName, index, ports.length, '.' + port, type, this.get('size').height); + this._portSelectors = this._portSelectors.concat(_.keys(portAttributes)); + _.extend(attrs, portAttributes); + }, this); + }, this); - _.each(['left', 'right', 'top', 'bottom'], function(type) { + _.each(['top', 'bottom'], function(type) { var port = type + 'Ports'; _.each(this.get(port), function(portName, index, ports) { - var portAttributes = this.getPortAttrs(portName, index, ports.length, '.' + port, type); + var portAttributes = this.getPortAttrs(portName, index, ports.length, '.' + port, type, this.get('size').width); this._portSelectors = this._portSelectors.concat(_.keys(portAttributes)); _.extend(attrs, portAttributes); }, this); }, this); this.attr(attrs, { silent: true }); - this.processPorts(); - this.trigger('process:ports'); }, - getPortAttrs: function(port, index, total, selector, type) { + getPortAttrs: function(port, index, total, selector, type, length) { var attrs = {}; + var gridsize = 8; + var gridunits = length / gridsize; var portClass = 'port' + index; var portSelector = selector + '>.' + portClass; var portLabelSelector = portSelector + '>.port-label'; var portWireSelector = portSelector + '>.port-wire'; var portBodySelector = portSelector + '>.port-body'; + var portDefaultSelector = portSelector + '>.port-default'; attrs[portSelector] = { ref: '.body' @@ -131,49 +169,53 @@ joint.shapes.ice.Model = joint.shapes.basic.Generic.extend({ } }; + attrs[portDefaultSelector] = { + display: (port.default && port.default.apply) ? 'inline' : 'none' + }; + if ((type === 'leftPorts') || (type === 'topPorts')) { attrs[portSelector]['pointer-events'] = 'none'; attrs[portWireSelector]['pointer-events'] = 'none'; } - var offset = (port.size && port.size > 1) ? 6 : 0; - var pos = Math.round((index + 0.5) / total * port.gridUnits) / port.gridUnits; + var offset = (port.size && port.size > 1) ? 4 : 1; + var position = Math.round((index + 0.5) / total * gridunits) / gridunits; switch (type) { case 'left': attrs[portSelector]['ref-x'] = -8; - attrs[portSelector]['ref-y'] = pos; + attrs[portSelector]['ref-y'] = position; attrs[portLabelSelector]['dx'] = 4; attrs[portLabelSelector]['y'] = -5-offset; attrs[portLabelSelector]['text-anchor'] = 'end'; - attrs[portWireSelector]['y'] = pos; + attrs[portWireSelector]['y'] = position; attrs[portWireSelector]['d'] = 'M 0 0 L 16 0'; break; case 'right': attrs[portSelector]['ref-dx'] = 8; - attrs[portSelector]['ref-y'] = pos; + attrs[portSelector]['ref-y'] = position; attrs[portLabelSelector]['dx'] = -4; attrs[portLabelSelector]['y'] = -5-offset; attrs[portLabelSelector]['text-anchor'] = 'start'; - attrs[portWireSelector]['y'] = pos; + attrs[portWireSelector]['y'] = position; attrs[portWireSelector]['d'] = 'M 0 0 L -16 0'; break; case 'top': attrs[portSelector]['ref-y'] = -8; - attrs[portSelector]['ref-x'] = pos; + attrs[portSelector]['ref-x'] = position; attrs[portLabelSelector]['dx'] = 5+offset; - attrs[portLabelSelector]['y'] = 4; + attrs[portLabelSelector]['y'] = 2; attrs[portLabelSelector]['text-anchor'] = 'start'; - attrs[portWireSelector]['x'] = pos; + attrs[portWireSelector]['x'] = position; attrs[portWireSelector]['d'] = 'M 0 0 L 0 16'; break; case 'bottom': attrs[portSelector]['ref-dy'] = 8; - attrs[portSelector]['ref-x'] = pos; + attrs[portSelector]['ref-x'] = position; attrs[portLabelSelector]['dx'] = 5+offset; - attrs[portLabelSelector]['y'] = -4; + attrs[portLabelSelector]['y'] = -2; attrs[portLabelSelector]['text-anchor'] = 'start'; - attrs[portWireSelector]['x'] = pos; + attrs[portWireSelector]['x'] = position; attrs[portWireSelector]['d'] = 'M 0 0 L 0 -16'; break; } @@ -198,11 +240,85 @@ joint.shapes.ice.ModelView = joint.dia.ElementView.extend({ this.updateBox(); this.listenTo(this.model, 'process:ports', this.update); - joint.dia.ElementView.prototype.initialize.apply(this, arguments); + }, + + setupResizer: function() { + // Resizer + if (!this.model.get('disabled')) { + this.resizing = false; + this.resizer = this.$box.find('.resizer'); + this.resizer.css('cursor', 'se-resize'); + this.resizer.on('mousedown', { self: this }, this.startResizing); + $(document).on('mousemove', { self: this }, this.performResizing); + $(document).on('mouseup', { self: this }, this.stopResizing); + } }, apply: function() { - // No operation required + }, + + updateContent: function() { + }, + + startResizing: function(event) { + var self = event.data.self; + + self.model.graph.trigger('batch:start'); + + self.resizing = true; + self._clientX = event.clientX; + self._clientY = event.clientY; + }, + + performResizing: function(event) { + var self = event.data.self; + + if (!self.resizing) { + return; + } + + var size = self.model.get('size'); + var state = self.model.get('state'); + var gridstep = 8 * 2; + var minSize = { width: 64, height: 32 }; + + var clientCoords = snapToGrid({ x: event.clientX, y: event.clientY }); + var oldClientCoords = snapToGrid({ x: self._clientX, y: self._clientY }); + + var dx = clientCoords.x - oldClientCoords.x; + var dy = clientCoords.y - oldClientCoords.y; + + var width = Math.max(size.width + dx, minSize.width); + var height = Math.max(size.height + dy, minSize.height); + + if (width > minSize.width) { + self._clientX = event.clientX; + } + + if (height > minSize.height) { + self._clientY = event.clientY; + } + + self.model.resize(width, height); + self.updateContent(); + + function snapToGrid(coords) { + return { + x: Math.round(coords.x / state.zoom / gridstep) * gridstep, + y: Math.round(coords.y / state.zoom / gridstep) * gridstep + }; + } + }, + + stopResizing: function(event) { + var self = event.data.self; + + if (!self.resizing) { + return; + } + + self.resizing = false; + self.model.graph.trigger('batch:stop'); }, render: function() { @@ -239,28 +355,44 @@ joint.shapes.ice.ModelView = joint.dia.ElementView.extend({ }, updateBox: function() { - var port, wireWidth; + var i, port; var bbox = this.model.getBBox(); + var data = this.model.get('data'); var state = this.model.get('state'); + var rules = this.model.get('rules'); var leftPorts = this.model.get('leftPorts'); var rightPorts = this.model.get('rightPorts'); // Render ports width - this.$('.port-wire').css('stroke-width', 2 * state.zoom); - for (var i in leftPorts) { + var width = WIRE_WIDTH * state.zoom; + this.$('.port-wire').css('stroke-width', width); + // Set buses + for (i in leftPorts) { port = leftPorts[i]; - wireWidth = (port.size > 1) ? 8 : 2; - this.$('#port-wire-' + port.id).css('stroke-width', wireWidth * state.zoom); + if (port.size > 1) { + this.$('#port-wire-' + port.id).css('stroke-width', width * 3); + } } - for (var o in rightPorts) { - port = rightPorts[o]; - wireWidth = (port.size > 1) ? 8 : 2; - this.$('#port-wire-' + port.id).css('stroke-width', wireWidth * state.zoom); + for (i in rightPorts) { + port = rightPorts[i]; + if (port.size > 1) { + this.$('#port-wire-' + port.id).css('stroke-width', width * 3); + } + } + // Render rules + if (data && data.ports && data.ports.in) { + for (i in data.ports.in) { + port = data.ports.in[i]; + if (rules && port.default && port.default.apply) { + this.$('#port-default-' + port.name).css('display', 'inline'); + this.$('#port-default-wire-' + port.name).css('stroke-width', width); + this.$('#port-default-rect-' + port.name).css('stroke-width', state.zoom); + } + else { + this.$('#port-default-' + port.name).css('display', 'none'); + } + } } - - /*if (this.$box.css('z-index') > this.model.attributes.zindex) { - this.$box.css('z-index', ++this.model.attributes.zindex); - }*/ this.$box.css({ left: bbox.x * state.zoom + state.pan.x + bbox.width / 2.0 * (state.zoom - 1), @@ -271,7 +403,7 @@ joint.shapes.ice.ModelView = joint.dia.ElementView.extend({ }); }, - removeBox: function(/*evt*/) { + removeBox: function(/*event*/) { this.$box.remove(); } }); @@ -287,9 +419,16 @@ joint.shapes.ice.Generic = joint.shapes.ice.Model.extend({ joint.shapes.ice.GenericView = joint.shapes.ice.ModelView.extend({ + // Image comments: + // - img: fast load, no interactive + // - object: slow load, interactive + // - inline SVG: fast load, interactive, but... + // old SVG files have no viewBox, therefore no properly resize + // Inkscape adds this field saving as "Optimize SVG" ("Enable viewboxing") + template: '\
    \ - \ +
    \ \ \
    \ @@ -306,7 +445,7 @@ joint.shapes.ice.GenericView = joint.shapes.ice.ModelView.extend({ down: false, timer: null, - mouseovercard: function(/*evt, x, y*/) { + mouseovercard: function(/*event, x, y*/) { if (this.tooltip) { this.enter = true; var self = this; @@ -325,7 +464,7 @@ joint.shapes.ice.GenericView = joint.shapes.ice.ModelView.extend({ } }, - mouseoutcard: function(/*evt, x, y*/) { + mouseoutcard: function(/*event, x, y*/) { if (this.tooltip) { this.enter = false; if (this.timer) { @@ -336,11 +475,12 @@ joint.shapes.ice.GenericView = joint.shapes.ice.ModelView.extend({ } }, - mouseupcard: function(/*evt, x, y*/) { + mouseupcard: function(/*event, x, y*/) { this.down = false; + this.mouseovercard(); }, - mousedowncard: function(/*evt, x, y*/) { + mousedowncard: function(/*event, x, y*/) { this.down = true; this.mouseoutcard(); }, @@ -348,23 +488,56 @@ joint.shapes.ice.GenericView = joint.shapes.ice.ModelView.extend({ initialize: function() { joint.shapes.ice.ModelView.prototype.initialize.apply(this, arguments); - var image = this.model.get('image'); - var name = this.model.get('label'); this.tooltip = this.model.get('tooltip'); this.tooltiptext = this.$box.find('.tooltiptext'); + if (this.model.get('config')) { + this.$box.addClass('config-block'); + } + + // Initialize content + this.initializeContent(); + }, + + initializeContent: function() { + var image = this.model.get('image'); + var label = this.model.get('label'); + var ports = this.model.get('leftPorts'); + + var imageSelector = this.$box.find('img'); + var labelSelector = this.$box.find('label'); + if (image) { - this.$box.find('img').attr('src', 'data:image/svg+xml,' + image); - this.$box.find('img').removeClass('hidden'); - this.$box.find('label').addClass('hidden'); + // Render img + imageSelector.attr('src', 'data:image/svg+xml,' + image); + + // Render SVG + //imageSelector.append(decodeURI(image)); + + imageSelector.removeClass('hidden'); + labelSelector.addClass('hidden'); } else { - this.$box.find('label').html(name); - this.$box.find('img').addClass('hidden'); - this.$box.find('label').removeClass('hidden'); + // Render label + labelSelector.html(label); + labelSelector.removeClass('hidden'); + imageSelector.addClass('hidden'); } - if (this.model.get('config')) { - this.$box.addClass('config-block'); + + // Render clocks + this.$box.find('.clock').remove(); + var n = ports.length; + var gridsize = 8; + var height = this.model.get('size').height; + for (var i in ports) { + var port = ports[i]; + if (port.clock) { + var top = Math.round((parseInt(i) + 0.5) * height / n / gridsize) * gridsize - 12; + this.$box.append('\ +
    \ + \ +
    '); + } } } }); @@ -410,23 +583,30 @@ joint.shapes.ice.IOView = joint.shapes.ice.ModelView.extend({ if (data.pins) { for (var i in data.pins) { - //selectCode += '

    ' + this.pins[i].index + '

    '; selectCode +=''; selectScript += '$("#' + comboId + data.pins[i].index + '").select2('; - selectScript += '{placeholder: "", allowClear: true, dropdownCssClass: "bigdrop"});'; + selectScript += '{placeholder: "", allowClear: true, dropdownCssClass: "bigdrop",'; + // Match only words that start with the selected search term + // http://stackoverflow.com/questions/31571864/select2-search-match-only-words-that-start-with-search-term + selectScript += 'matcher: function(params, data) {'; + selectScript += ' params.term = params.term || "";'; + selectScript += ' if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) == 0) { return data; }'; + selectScript += ' return false; } });'; } } this.$box = $(joint.util.template( '\
    \ +

    >

    \ \
    \
    \ - \ +

    >

    \ + \
    ' + selectCode + '
    \ \
    \ @@ -437,11 +617,11 @@ joint.shapes.ice.IOView = joint.shapes.ice.ModelView.extend({ // Prevent paper from handling pointerdown. var self = this; - var comboSelector = this.$box.find('.select2'); - comboSelector.on('mousedown click', function(evt) { evt.stopPropagation(); }); - comboSelector.on('change', function(evt) { + var selector = this.$box.find('.select2'); + selector.on('mousedown click', function(event) { event.stopPropagation(); }); + selector.on('change', function(event) { if (!self.updating) { - var target = $(evt.target); + var target = $(event.target); var i = target.attr('i'); var name = target.find('option:selected').text(); var value = target.val(); @@ -460,6 +640,7 @@ joint.shapes.ice.IOView = joint.shapes.ice.ModelView.extend({ this.applyValues(); this.applyShape(); } + this.applyClock(); }, applyShape: function() { @@ -509,6 +690,15 @@ joint.shapes.ice.IOView = joint.shapes.ice.ModelView.extend({ this.updating = false; }, + applyClock: function() { + if (this.model.get('data').clock) { + this.$box.find('p').removeClass('hidden'); + } + else { + this.$box.find('p').addClass('hidden'); + } + }, + clearValues: function() { this.updating = true; var name = ''; @@ -526,14 +716,10 @@ joint.shapes.ice.IOView = joint.shapes.ice.ModelView.extend({ this.updating = false; }, - computeFontSize: function(name) { - var n = name.length; - return Math.min(13, 17-n).toString() + 'px'; - }, - apply: function() { this.applyChoices(); this.applyValues(); + this.applyClock(); this.applyShape(); this.render(); }, @@ -541,7 +727,14 @@ joint.shapes.ice.IOView = joint.shapes.ice.ModelView.extend({ update: function() { this.renderPorts(); joint.dia.ElementView.prototype.update.apply(this, arguments); + }, + + removeBox: function() { + // Close select options on remove + this.$box.find('select').select2('close'); + this.$box.remove(); } + }); joint.shapes.ice.InputView = joint.shapes.ice.IOView; @@ -565,7 +758,7 @@ joint.shapes.ice.ConstantView = joint.shapes.ice.ModelView.extend({ template: '\
    \ -

    *

    \ +

    \ \ \
    \ @@ -578,15 +771,23 @@ joint.shapes.ice.ConstantView = joint.shapes.ice.ModelView.extend({ // Prevent paper from handling pointerdown. var self = this; - this.$box.find('.constant-input').on('mousedown click', function(evt) { evt.stopPropagation(); }); - this.$box.find('.constant-input').on('input', function(evt) { + var selector = this.$box.find('.constant-input'); + selector.on('mousedown click', function(event) { event.stopPropagation(); }); + selector.on('input', function(event) { if (!self.updating) { - var target = $(evt.target); + var target = $(event.target); var data = JSON.parse(JSON.stringify(self.model.get('data'))); data.value = target.val(); self.model.set('data', data); } }); + selector.on('paste', function(event) { + var data = event.originalEvent.clipboardData.getData('text'); + if (data.startsWith('{"icestudio":')) { + // Prevent paste blocks + event.preventDefault(); + } + }); // Apply data this.apply(); @@ -630,7 +831,6 @@ joint.shapes.ice.ConstantView = joint.shapes.ice.ModelView.extend({ // Code block -// Size: 64 * x joint.shapes.ice.Code = joint.shapes.ice.Model.extend({ defaults: joint.util.deepSupplement({ @@ -638,12 +838,6 @@ joint.shapes.ice.Code = joint.shapes.ice.Model.extend({ size: { width: 384, height: 256 - }, - attrs: { - '.body': { - width: 384, - height: 256 - } } }, joint.shapes.ice.Model.prototype.defaults) }); @@ -664,11 +858,11 @@ joint.shapes.ice.CodeView = joint.shapes.ice.ModelView.extend({ \ +
    \
    \ ' )()); @@ -685,7 +879,7 @@ joint.shapes.ice.CodeView = joint.shapes.ice.ModelView.extend({ var selector = this.$box.find('#' + editorLabel); // Prevent paper from handling pointerdown. - selector.on('mousedown click', function(evt) { evt.stopPropagation(); }); + selector.on('mousedown click', function(event) { event.stopPropagation(); }); this.deltas = []; this.counter = 0; @@ -705,15 +899,15 @@ joint.shapes.ice.CodeView = joint.shapes.ice.ModelView.extend({ } // Update deltas self.deltas = self.deltas.concat([delta]); - // Launch timer to + // Launch timer self.timer = setTimeout(function() { - var data = JSON.parse(JSON.stringify(self.model.get('data'))); - // Set data - data.code = self.editor.session.getValue(); - data.deltas = self.deltas; - self.model.set('data', data); + var deltas = JSON.parse(JSON.stringify(self.deltas)); + // Set deltas + self.model.set('deltas', deltas); // Reset deltas self.deltas = []; + // Set data.code + self.model.attributes.data.code = self.editor.session.getValue(); }, undoGroupingInterval); // Reset counter self.counter = Date.now(); @@ -722,33 +916,56 @@ joint.shapes.ice.CodeView = joint.shapes.ice.ModelView.extend({ this.editor.on('focus', function() { $(document).trigger('disableSelected'); }); - $('#' + blockLabel).resize(function() { - self.editor.resize(); + this.editor.on('paste', function(e) { + if (e.text.startsWith('{"icestudio":')) { + // Prevent paste blocks + e.text = ''; + } }); + this.setupResizer(); + // Apply data - this.apply(); + this.apply({ ini: true }); }, applyValue: function(opt) { this.updating = true; + var dontselect = false; var data = this.model.get('data'); - if (data.deltas && opt) { - var changes = [{ - group: 'doc', - deltas: data.deltas - }]; - if (opt.undo) { - this.editor.session.undoChanges(changes, dontselect); - } - else { - this.editor.session.redoChanges(changes, dontselect); - } + var deltas = this.model.get('deltas'); + + opt = opt || {}; + + switch (opt.attribute) { + case 'deltas': + if (deltas) { + var changes = [{ + group: 'doc', + deltas: deltas + }]; + if (opt.undo) { + this.editor.session.undoChanges(changes, dontselect); + } + else { + this.editor.session.redoChanges(changes, dontselect); + } + } + break; + case 'data': + + break; + default: + break; } - else { + if (opt.ini) { this.editor.session.setValue(data.code); } + else { + // Set data.code + this.model.attributes.data.code = this.editor.session.getValue(); + } setTimeout(function(self) { self.updating = false; }, 10, this); @@ -765,25 +982,51 @@ joint.shapes.ice.CodeView = joint.shapes.ice.ModelView.extend({ }, updateBox: function() { - var port, wireWidth; + var i, port; var bbox = this.model.getBBox(); + var data = this.model.get('data'); var state = this.model.get('state'); + var rules = this.model.get('rules'); var leftPorts = this.model.get('leftPorts'); var rightPorts = this.model.get('rightPorts'); - // Render ports width - this.$('.port-wire').css('stroke-width', 2 * state.zoom); - for (var i in leftPorts) { + // Set font size + if (this.editor) { + this.editor.setFontSize(aceFontSize * state.zoom); + this.editor.resize(); + } + // Set ports width + var width = WIRE_WIDTH * state.zoom; + this.$('.port-wire').css('stroke-width', width); + // Set buses + for (i in leftPorts) { port = leftPorts[i]; - wireWidth = (port.size > 1) ? 8 : 2; - this.$('#port-wire-' + port.id).css('stroke-width', wireWidth * state.zoom); + if (port.size > 1) { + this.$('#port-wire-' + port.id).css('stroke-width', width * 3); + } } - for (var o in rightPorts) { - port = rightPorts[o]; - wireWidth = (port.size > 1) ? 8 : 2; - this.$('#port-wire-' + port.id).css('stroke-width', wireWidth * state.zoom); + for (i in rightPorts) { + port = rightPorts[i]; + if (port.size > 1) { + this.$('#port-wire-' + port.id).css('stroke-width', width * 3); + } + } + // Render rules + if (data && data.ports && data.ports.in) { + for (i in data.ports.in) { + port = data.ports.in[i]; + if (rules && port.default && port.default.apply) { + this.$('#port-default-' + port.name).css('display', 'inline'); + this.$('#port-default-wire-' + port.name).css('stroke-width', width); + this.$('#port-default-rect-' + port.name).css('stroke-width', state.zoom); + } + else { + this.$('#port-default-' + port.name).css('display', 'none'); + } + } } + this.$box.find('.code-editor').css('margin', 8 * state.zoom); this.$box.css({ width: bbox.width * state.zoom, height: bbox.height * state.zoom, left: bbox.x * state.zoom + state.pan.x, @@ -795,27 +1038,17 @@ joint.shapes.ice.CodeView = joint.shapes.ice.ModelView.extend({ // Info block -joint.shapes.ice.Info = joint.shapes.basic.Rect.extend({ +joint.shapes.ice.Info = joint.shapes.ice.Model.extend({ defaults: joint.util.deepSupplement({ type: 'ice.Info', size: { width: 400, height: 256 - }, - attrs: { - '.body': { - width: 400, - height: 256 - }, - rect: { - stroke: 'none', - 'fill-opacity': 0 - } } - }, joint.shapes.basic.Rect.prototype.defaults) + }, joint.shapes.ice.Model.prototype.defaults) }); -joint.shapes.ice.InfoView = joint.dia.ElementView.extend({ +joint.shapes.ice.InfoView = joint.shapes.ice.ModelView.extend({ initialize: function() { _.bindAll(this, 'updateBox'); @@ -831,10 +1064,10 @@ joint.shapes.ice.InfoView = joint.dia.ElementView.extend({ \ +
    \
    \ ' )()); @@ -848,7 +1081,7 @@ joint.shapes.ice.InfoView = joint.dia.ElementView.extend({ var selector = this.$box.find('#' + editorLabel); // Prevent paper from handling pointerdown. - selector.on('mousedown click', function(evt) { evt.stopPropagation(); }); + selector.on('mousedown click', function(event) { event.stopPropagation(); }); this.deltas = []; this.counter = 0; @@ -868,16 +1101,15 @@ joint.shapes.ice.InfoView = joint.dia.ElementView.extend({ } // Update deltas self.deltas = self.deltas.concat([delta]); - // Launch timer to + // Launch timer self.timer = setTimeout(function() { - // Set data - var data = { - info: self.editor.session.getValue(), - deltas: self.deltas - }; - self.model.set('data', data); + var deltas = JSON.parse(JSON.stringify(self.deltas)); + // Set deltas + self.model.set('deltas', deltas); // Reset deltas self.deltas = []; + // Set data.code + self.model.attributes.data.info = self.editor.session.getValue(); }, undoGroupingInterval); // Reset counter self.counter = Date.now(); @@ -886,33 +1118,56 @@ joint.shapes.ice.InfoView = joint.dia.ElementView.extend({ this.editor.on('focus', function() { $(document).trigger('disableSelected'); }); - $('#' + blockLabel).resize(function() { - self.editor.resize(); + this.editor.on('paste', function(e) { + if (e.text.startsWith('{"icestudio":')) { + // Prevent paste blocks + e.text = ''; + } }); + this.setupResizer(); + // Apply data - this.apply(); + this.apply({ ini: true }); }, applyValue: function(opt) { this.updating = true; + var dontselect = false; var data = this.model.get('data'); - if (data.deltas && opt) { - var changes = [{ - group: 'doc', - deltas: data.deltas - }]; - if (opt.undo) { - this.editor.session.undoChanges(changes, dontselect); - } - else { - this.editor.session.redoChanges(changes, dontselect); - } + var deltas = this.model.get('deltas'); + + opt = opt || {}; + + switch (opt.attribute) { + case 'deltas': + if (deltas) { + var changes = [{ + group: 'doc', + deltas: deltas + }]; + if (opt.undo) { + this.editor.session.undoChanges(changes, dontselect); + } + else { + this.editor.session.redoChanges(changes, dontselect); + } + } + break; + case 'data': + + break; + default: + break; } - else { + if (opt.ini) { this.editor.session.setValue(data.info); } + else { + // Set data.code + this.model.attributes.data.info = this.editor.session.getValue(); + } setTimeout(function(self) { self.updating = false; }, 10, this); @@ -938,19 +1193,22 @@ joint.shapes.ice.InfoView = joint.dia.ElementView.extend({ var bbox = this.model.getBBox(); var state = this.model.get('state'); + // Set font size + if (this.editor) { + this.editor.setFontSize(aceFontSize * state.zoom); + this.editor.resize(); + } + + this.$box.find('.info-editor').css('margin', 8 * state.zoom); this.$box.css({ width: bbox.width * state.zoom, height: bbox.height * state.zoom, left: bbox.x * state.zoom + state.pan.x, top: bbox.y * state.zoom + state.pan.y }); }, - remove: function() { + removeBox: function(/*event*/) { // Remove delta to allow Session Value restore delete this.model.attributes.data.delta; - joint.dia.LinkView.prototype.remove.apply(this, arguments); - }, - - removeBox: function(/*evt*/) { this.$box.remove(); } }); @@ -961,7 +1219,7 @@ joint.shapes.ice.InfoView = joint.dia.ElementView.extend({ joint.shapes.ice.Wire = joint.dia.Link.extend({ markup: [ - '', + '', '', '', '', @@ -972,9 +1230,16 @@ joint.shapes.ice.Wire = joint.dia.Link.extend({ '' ].join(''), + labelMarkup: [ + '' + ].join(''), + bifurcationMarkup: [ '', - '', + '', '' ].join(''), @@ -984,6 +1249,26 @@ joint.shapes.ice.Wire = joint.dia.Link.extend({ '' ].join(''), + toolMarkup: [ + '', + '', + '', + '', + 'Remove link.', + '', + '' + ].join(''), + + vertexMarkup: [ + '', + '', + '', + '', + 'Remove vertex.', + '', + '' + ].join(''), + defaults: joint.util.deepSupplement({ type: 'ice.Wire', @@ -995,8 +1280,9 @@ joint.shapes.ice.Wire = joint.dia.Link.extend({ text: { text: '', 'font-weight': 'bold', - 'font-size': '150%', - 'y': '12px' + 'font-size': '13px', + 'text-anchor': 'middle', + 'y': '4px' } } } @@ -1004,10 +1290,9 @@ joint.shapes.ice.Wire = joint.dia.Link.extend({ attrs: { '.connection': { - 'stroke-width': 2, - stroke: '#888' - }, - '.marker-vertex': { r: 8 } + 'stroke-width': WIRE_WIDTH, + stroke: '#777' + } }, router: { name: 'ice' }, @@ -1024,27 +1309,30 @@ joint.shapes.ice.WireView = joint.dia.LinkView.extend({ var self = this; setTimeout(function() { - var portName = self.model.get('source').port; - var rightPorts = self.sourceView.model.get('rightPorts'); - - // Initialize wire properties - var port; - for (var o in rightPorts) { - port = rightPorts[o]; - if (portName === port.id) { - self.model.attributes.size = port.size; // For wire size connection validation - self.$('.connection').css('stroke-width', (port.size > 1) ? 8 : 2); - self.model.label(0, {attrs: { text: { text: (port.size > 1) ? '' + port.size + '' : '' } } }); - self.model.bifurcationMarkup = self.model.bifurcationMarkup.replace(/<%= r %>/g, (port.size > 1) ? 8 : 4); - self.update(); - break; + var size = self.model.get('size'); + + if (!size) { // New wire + var i, port, portName = self.model.get('source').port; + var rightPorts = self.sourceView.model.get('rightPorts'); + // Initialize wire properties + for (i in rightPorts) { + port = rightPorts[i]; + if (portName === port.id) { + size = port.size; + // For wire size connection validation + self.model.attributes.size = size; + break; + } } } + + self.updateWireProperties(size); + self.updateBifurcations(); }, 0); }, apply: function() { - this.render(); + // No operation required }, render: function() { @@ -1067,6 +1355,61 @@ joint.shapes.ice.WireView = joint.dia.LinkView.extend({ return this; }, + renderLabels: function() { + if (!this._V.labels) { + return this; + } + + this._labelCache = {}; + var $labels = $(this._V.labels.node).empty(); + + var labels = this.model.get('labels') || []; + if (!labels.length) { + return this; + } + + var labelTemplate = joint.util.template(this.model.get('labelMarkup') || this.model.labelMarkup); + // This is a prepared instance of a vectorized SVGDOM node for the label element resulting from + // compilation of the labelTemplate. The purpose is that all labels will just `clone()` this + // node to create a duplicate. + var labelNodeInstance = V(labelTemplate()); + + _.each(labels, function(label, idx) { + + var labelNode = labelNodeInstance.clone().node; + V(labelNode).attr('label-idx', idx); + this._labelCache[idx] = V(labelNode); + + var $text = $(labelNode).find('text'); + var textAttributes = _.extend({ 'text-anchor': 'middle', 'font-size': 13 }, joint.util.getByPath(label, 'attrs/text', '/')); + + $text.attr(_.omit(textAttributes, 'text')); + + if (label.attrs.text.text) { + $(labelNode).removeClass('hidden'); + } + + if (!_.isUndefined(textAttributes.text)) { + V($text[0]).text(textAttributes.text + '', { annotations: textAttributes.annotations }); + } + $labels.append(labelNode); + + }, this); + + return this; + }, + + updateWireProperties: function(size) { + if (size > 1) { + this.$('.connection').css('stroke-width', WIRE_WIDTH * 3); + this.model.label(0, {attrs: { text: { text: size } } }); + this.model.bifurcationMarkup = this.model.bifurcationMarkup.replace(/<%= r %>/g, WIRE_WIDTH * 4); + } + else { + this.model.bifurcationMarkup = this.model.bifurcationMarkup.replace(/<%= r %>/g, WIRE_WIDTH * 2); + } + }, + updateConnection: function(opt) { opt = opt || {}; diff --git a/app/scripts/services/blocks.service.js b/app/scripts/services/blocks.js similarity index 64% rename from app/scripts/services/blocks.service.js rename to app/scripts/services/blocks.js index f24fb33a0..276ce8a85 100644 --- a/app/scripts/services/blocks.service.js +++ b/app/scripts/services/blocks.js @@ -2,8 +2,8 @@ angular.module('icestudio') .service('blocks', function(joint, - boards, utils, + common, gettextCatalog) { var gridsize = 8; @@ -22,8 +22,10 @@ angular.module('icestudio') function newBasic(type, addCellCallback) { switch(type) { case 'basic.input': + newBasicInput(addCellCallback); + break; case 'basic.output': - newBasicIO(type, addCellCallback); + newBasicOutput(addCellCallback); break; case 'basic.constant': newBasicConstant(addCellCallback); @@ -39,26 +41,79 @@ angular.module('icestudio') } } - function newBasicIO(type, addCellCallback) { - var config; - if (type === 'basic.input') { - config = { type: type, _default: 'in', x: 4 }; - } - else { // 'basic.output' - config = { type: type, _default: 'out', x: 95 }; - } + function newBasicInput(addCellCallback) { + var blockInstance = { + id: null, + data: {}, + type: 'basic.input', + position: { x: 4 * gridsize, y: 4 * gridsize } + }; + utils.inputcheckbox2prompt([ + gettextCatalog.getString('Enter the input blocks'), + gettextCatalog.getString('FPGA pin'), + gettextCatalog.getString('Show clock') + ], [ + 'in', + true, + false + ], + function(evt, values) { + var labels = values[0].replace(/ /g, '').split(','); + var virtual = !values[1]; + var clock = values[2]; + // Validate values + var portInfo, portInfos = []; + for (var l in labels) { + if (labels[l]) { + portInfo = utils.parsePortLabel(labels[l]); + if (portInfo) { + evt.cancel = false; + portInfos.push(portInfo); + } + else { + evt.cancel = true; + alertify.warning(gettextCatalog.getString('Wrong block name {{name}}', { name: labels[l] })); + return; + } + } + else { + evt.cancel = true; + //return; + } + } + // Create blocks + for (var p in portInfos) { + portInfo = portInfos[p]; + var pins = getPins(portInfo); + blockInstance.data = { + name: portInfo.name, + range: portInfo.rangestr, + pins: pins, + virtual: virtual, + clock: clock + }; + if (addCellCallback) { + addCellCallback(loadBasic(blockInstance)); + } + // Next block position + blockInstance.position.y += (virtual ? 10 : (6 + 4 * pins.length)) * gridsize; + } + }); + } + + function newBasicOutput(addCellCallback) { var blockInstance = { id: null, data: {}, - type: config.type, - position: { x: config.x * gridsize, y: 4 * gridsize } + type: 'basic.output', + position: { x: 95 * gridsize, y: 4 * gridsize } }; utils.inputcheckboxprompt([ - gettextCatalog.getString('Enter the ports'), + gettextCatalog.getString('Enter the output blocks'), gettextCatalog.getString('FPGA pin') ], [ - config._default, - false + 'out', + true ], function(evt, values) { var labels = values[0].replace(/ /g, '').split(','); @@ -74,7 +129,7 @@ angular.module('icestudio') } else { evt.cancel = true; - alertify.notify(gettextCatalog.getString('Wrong port name {{name}}', { name: labels[l] }), 'warning', 3); + alertify.warning(gettextCatalog.getString('Wrong block name {{name}}', { name: labels[l] })); return; } } @@ -143,7 +198,7 @@ angular.module('icestudio') } else { evt.cancel = true; - alertify.notify(gettextCatalog.getString('Wrong parameter name {{name}}', { name: labels[l] }), 'warning', 3); + alertify.warning(gettextCatalog.getString('Wrong block name {{name}}', { name: labels[l] })); return; } } @@ -177,7 +232,8 @@ angular.module('icestudio') ports: { in: [], out: [] } }, type: 'basic.code', - position: { x: 31 * gridsize, y: 24 * gridsize } + position: { x: 40 * gridsize, y: 16 * gridsize }, + size: { width: 192, height: 128 } }; var defaultValues = [ 'a , b', @@ -230,7 +286,7 @@ angular.module('icestudio') } else { evt.cancel = true; - alertify.notify(gettextCatalog.getString('Wrong port name {{name}}', { name: inPorts[i] }), 'warning', 3); + alertify.warning(gettextCatalog.getString('Wrong port name {{name}}', { name: inPorts[i] })); return; } } @@ -245,7 +301,7 @@ angular.module('icestudio') } else { evt.cancel = true; - alertify.notify(gettextCatalog.getString('Wrong port name {{name}}', { name: outPorts[o] }), 'warning', 3); + alertify.warning(gettextCatalog.getString('Wrong port name {{name}}', { name: outPorts[o] })); return; } } @@ -260,7 +316,7 @@ angular.module('icestudio') } else { evt.cancel = true; - alertify.notify(gettextCatalog.getString('Wrong parameter name {{name}}', { name: params[p] }), 'warning', 3); + alertify.warning(gettextCatalog.getString('Wrong parameter name {{name}}', { name: params[p] })); return; } } @@ -311,7 +367,7 @@ angular.module('icestudio') } else { evt.cancel = true; - alertify.notify(gettextCatalog.getString('Duplicated block attributes'), 'warning', 3); + alertify.warning(gettextCatalog.getString('Duplicated block attributes')); } }); } @@ -321,7 +377,8 @@ angular.module('icestudio') id: null, data: { info: '' }, type: 'basic.info', - position: { x: 4 * gridsize, y: 30 * gridsize } + position: { x: 40 * gridsize, y: 36 * gridsize }, + size: { width: 192, height: 128 } }; if (addCellCallback) { addCellCallback(loadBasicInfo(blockInstance)); @@ -332,7 +389,7 @@ angular.module('icestudio') var blockInstance = { id: null, type: type, - position: { x: 6 * gridsize, y: 16 * gridsize } + position: { x: 10 * gridsize, y: 16 * gridsize } }; if (block && block.design && @@ -344,7 +401,7 @@ angular.module('icestudio') } } else { - alertify.notify(gettextCatalog.getString('Wrong block format: {{type}}', { type: type }), 'error', 30); + alertify.error(gettextCatalog.getString('Wrong block format: {{type}}', { type: type }), 30); } } @@ -372,9 +429,9 @@ angular.module('icestudio') var data = instance.data; var rightPorts = [{ id: 'out', + name: '', label: '', - size: data.pins ? data.pins.length : (data.size || 1), - gridUnits: 8 + size: data.pins ? data.pins.length : (data.size || 1) }]; var cell = new joint.shapes.ice.Input({ @@ -384,7 +441,7 @@ angular.module('icestudio') position: instance.position, disabled: disabled, rightPorts: rightPorts, - choices: boards.getPinoutHTML() + choices: common.pinoutInputHTML }); return cell; } @@ -393,9 +450,9 @@ angular.module('icestudio') var data = instance.data; var leftPorts = [{ id: 'in', + name: '', label: '', - size: data.pins ? data.pins.length : (data.size || 1), - gridUnits: 8 + size: data.pins ? data.pins.length : (data.size || 1) }]; var cell = new joint.shapes.ice.Output({ id: instance.id, @@ -404,7 +461,7 @@ angular.module('icestudio') position: instance.position, disabled: disabled, leftPorts: leftPorts, - choices: boards.getPinoutHTML() + choices: common.pinoutOutputHTML }); return cell; } @@ -412,8 +469,8 @@ angular.module('icestudio') function loadBasicConstant(instance, disabled) { var bottomPorts = [{ id: 'constant-out', - label: '', - gridUnits: 8 + name: '', + label: '' }]; var cell = new joint.shapes.ice.Constant({ id: instance.id, @@ -434,11 +491,14 @@ angular.module('icestudio') for (var i in instance.data.ports.in) { port = instance.data.ports.in[i]; + if (!port.range) { + port.default = utils.hasInputRule(port.name); + } leftPorts.push({ id: port.name, + name: port.name, label: port.name + (port.range || ''), - size: port.size || 1, - gridUnits: 32 + size: port.size || 1 }); } @@ -446,9 +506,9 @@ angular.module('icestudio') port = instance.data.ports.out[o]; rightPorts.push({ id: port.name, + name: port.name, label: port.name + (port.range || ''), - size: port.size || 1, - gridUnits: 32 + size: port.size || 1 }); } @@ -456,8 +516,8 @@ angular.module('icestudio') port = instance.data.params[p]; topPorts.push({ id: port.name, - label: port.name, - gridUnits: 48 + name: port.name, + label: port.name }); } @@ -466,11 +526,13 @@ angular.module('icestudio') blockType: instance.type, data: instance.data, position: instance.position, + size: instance.size, disabled: disabled, leftPorts: leftPorts, rightPorts: rightPorts, topPorts: topPorts }); + return cell; } @@ -480,77 +542,72 @@ angular.module('icestudio') blockType: instance.type, data: instance.data, position: instance.position, + size: instance.size, disabled: disabled }); return cell; } - function loadGeneric(instance, block) { + function loadGeneric(instance, block, disabled) { var i; var leftPorts = []; var rightPorts = []; var topPorts = []; var bottomPorts = []; - var gridsize = 8; + + instance.data = { ports: { in: [] }}; for (i in block.design.graph.blocks) { - var data; var item = block.design.graph.blocks[i]; if (item.type === 'basic.input') { - data = block.design.graph.blocks[i].data; + if (!item.data.range) { + instance.data.ports.in.push({ + name: item.id, + default: utils.hasInputRule((item.data.clock ? 'clk' : '') || item.data.name) + }); + } leftPorts.push({ id: item.id, + name: item.data.name, label: item.data.name + (item.data.range || ''), - size: data.pins ? data.pins.length : (data.size || 1) + size: item.data.pins ? item.data.pins.length : (item.data.size || 1), + clock: item.data.clock }); } else if (item.type === 'basic.output') { - data = block.design.graph.blocks[i].data; rightPorts.push({ id: item.id, + name: item.data.name, label: item.data.name + (item.data.range || ''), - size: data.pins ? data.pins.length : (data.size || 1) + size: item.data.pins ? item.data.pins.length : (item.data.size || 1) }); } else if (item.type === 'basic.constant') { if (!item.data.local) { topPorts.push({ id: item.id, + name: item.data.name, label: item.data.name }); } } } - var numPortsHeight = Math.max(leftPorts.length, rightPorts.length); - var numPortsWidth = Math.max(topPorts.length, bottomPorts.length); - - var height = 8 * gridsize; - height = Math.max(4 * gridsize * numPortsHeight, height); - var blockLabel = block.package.name; - var width = 12 * gridsize; + var size = instance.size; - width = Math.max(4 * gridsize * numPortsWidth, width); + if (!size) { + var numPortsHeight = Math.max(leftPorts.length, rightPorts.length); + var numPortsWidth = Math.max(topPorts.length, bottomPorts.length); - var gridUnitsHeight = height / gridsize; - var gridUnitsWidth = width / gridsize; - - for (i in leftPorts) { - leftPorts[i].gridUnits = gridUnitsHeight; - } - for (i in rightPorts) { - rightPorts[i].gridUnits = gridUnitsHeight; - } - for (i in topPorts) { - topPorts[i].gridUnits = gridUnitsWidth; - } - for (i in bottomPorts) { - bottomPorts[i].gridUnits = gridUnitsWidth; + size = { + width: Math.max(4 * gridsize * numPortsWidth, 12 * gridsize), + height: Math.max(4 * gridsize * numPortsHeight, 8 * gridsize) + }; } + var blockLabel = block.package.name; var blockImage = ''; if (block.package.image) { - width = 12 * gridsize; if (block.package.image.startsWith('%3Csvg')) { blockImage = block.package.image; } @@ -562,19 +619,18 @@ angular.module('icestudio') var cell = new joint.shapes.ice.Generic({ id: instance.id, blockType: instance.type, + data: instance.data, config: block.design.config, pullup: block.design.pullup, image: blockImage, label: blockLabel, - tooltip: block.package.description, + tooltip: gettextCatalog.getString(block.package.description), // TODO: update on change language position: instance.position, + size: size, + disabled: disabled, leftPorts: leftPorts, rightPorts: rightPorts, - topPorts: topPorts, - size: { - width: width, - height: height - } + topPorts: topPorts }); return cell; } @@ -618,8 +674,10 @@ angular.module('icestudio') function editBasic(type, cellView, addCellCallback) { switch(type) { case 'basic.input': + editBasicInput(cellView, addCellCallback); + break; case 'basic.output': - editBasicIO(cellView, addCellCallback); + editBasicOutput(cellView, addCellCallback); break; case 'basic.constant': editBasicConstant(cellView, addCellCallback); @@ -632,11 +690,91 @@ angular.module('icestudio') } } - function editBasicIO(cellView, addCellCallback) { + function editBasicInput(cellView, addCellCallback) { + var graph = cellView.paper.model; + var block = cellView.model.attributes; + utils.inputcheckbox2prompt([ + gettextCatalog.getString('Update the block name'), + gettextCatalog.getString('FPGA pin'), + gettextCatalog.getString('Show clock'), + ], [ + block.data.name + (block.data.range || ''), + !block.data.virtual, + block.data.clock + ], + function(evt, values) { + var oldSize, newSize, offset = 0; + var label = values[0].replace(/ /g, ''); + var virtual = !values[1]; + var clock = values[2]; + // Validate values + var portInfo = utils.parsePortLabel(label); + if (portInfo) { + evt.cancel = false; + if ((block.data.range || '') !== + (portInfo.rangestr || '')) { + var pins = getPins(portInfo); + oldSize = block.data.virtual ? 1 : (block.data.pins ? block.data.pins.length : 1); + newSize = virtual ? 1 : (pins ? pins.length : 1); + // Update block position when size changes + offset = 16 * (oldSize - newSize); + // Create new block + var blockInstance = { + id: null, + data: { + name: portInfo.name, + range: portInfo.rangestr, + pins: pins, + virtual: virtual, + clock: clock + }, + type: block.blockType, + position: { + x: block.position.x, + y: block.position.y + offset + } + }; + if (addCellCallback) { + graph.startBatch('change'); + addCellCallback(loadBasic(blockInstance)); + cellView.model.remove(); + graph.stopBatch('change'); + alertify.success(gettextCatalog.getString('Block updated')); + } + } + else if (block.data.name !== portInfo.name || + block.data.virtual !== virtual || + block.data.clock !== clock) { + var size = block.data.pins ? block.data.pins.length : 1; + oldSize = block.data.virtual ? 1 : size; + newSize = virtual ? 1 : size; + // Update block position when size changes + offset = 16 * (oldSize - newSize); + // Edit block + graph.startBatch('change'); + var data = utils.clone(block.data); + data.name = portInfo.name; + data.virtual = virtual; + data.clock = clock; + cellView.model.set('data', data, { translateBy: cellView.model.id, tx: 0, ty: -offset }); + cellView.model.translate(0, offset); + graph.stopBatch('change'); + cellView.apply(); + alertify.success(gettextCatalog.getString('Block updated')); + } + } + else { + evt.cancel = true; + alertify.warning(gettextCatalog.getString('Wrong block name {{name}}', { name: label })); + } + }); + } + + function editBasicOutput(cellView, addCellCallback) { var graph = cellView.paper.model; var block = cellView.model.attributes; utils.inputcheckboxprompt([ - gettextCatalog.getString('Update the port'), + gettextCatalog.getString('Update the block name'), gettextCatalog.getString('FPGA pin') ], [ block.data.name + (block.data.range || ''), @@ -701,7 +839,7 @@ angular.module('icestudio') } else { evt.cancel = true; - alertify.notify(gettextCatalog.getString('Wrong port name {{name}}', { name: label }), 'warning', 3); + alertify.warning(gettextCatalog.getString('Wrong block name {{name}}', { name: label })); } }); } @@ -709,25 +847,35 @@ angular.module('icestudio') function editBasicConstant(cellView) { var block = cellView.model.attributes; utils.inputcheckboxprompt([ - gettextCatalog.getString('Update the block label'), + gettextCatalog.getString('Update the block name'), gettextCatalog.getString('Local parameter') ], [ block.data.name, block.data.local ], function(evt, values) { - var name = values[0].replace(/ /g, ''); + var label = values[0].replace(/ /g, ''); var local = values[1]; - // Edit block - if (block.data.name !== name || - block.data.local !== local) { - // Edit block - var data = utils.clone(block.data); - data.name = name; - data.local = local; - cellView.model.set('data', data); - cellView.apply(); - alertify.success(gettextCatalog.getString('Block updated')); + // Validate values + var paramInfo = utils.parseParamLabel(label); + if (paramInfo) { + var name = paramInfo.name; + evt.cancel = false; + if (block.data.name !== name || + block.data.local !== local) { + // Edit block + var data = utils.clone(block.data); + data.name = name; + data.local = local; + cellView.model.set('data', data); + cellView.apply(); + alertify.success(gettextCatalog.getString('Block updated')); + } + } + else { + evt.cancel = true; + alertify.warning(gettextCatalog.getString('Wrong block name {{name}}', { name: label })); + return; } }); } @@ -736,20 +884,44 @@ angular.module('icestudio') var graph = cellView.paper.model; var block = cellView.model.attributes; var blockInstance = { - id: null, - data: block.data, + id: block.id, + data: utils.clone(block.data), type: 'basic.code', - position: block.position + position: block.position, + size: block.size }; newBasicCode(function(cell) { if (addCellCallback) { + var connectedWires = graph.getConnectedLinks(cellView.model); graph.startBatch('change'); - addCellCallback(cell); cellView.model.remove(); + addCellCallback(cell); + // Restore previous connections + for (var w in connectedWires) { + var wire = connectedWires[w]; + var source = wire.get('source'); + var target = wire.get('target'); + if ((source.id === cell.id && containsPort(source.port, cell.get('rightPorts'))) || + (target.id === cell.id && containsPort(target.port, cell.get('leftPorts')) && source.port !== 'constant-out') || + (target.id === cell.id && containsPort(target.port, cell.get('topPorts')) && source.port === 'constant-out')) { + graph.addCell(wire); + } + } graph.stopBatch('change'); alertify.success(gettextCatalog.getString('Block updated')); } }, blockInstance); } + function containsPort(port, ports) { + var found = false; + for (var i in ports) { + if (port === ports[i].name) { + found = true; + break; + } + } + return found; + } + }); diff --git a/app/scripts/services/boards.service.js b/app/scripts/services/boards.js similarity index 52% rename from app/scripts/services/boards.service.js rename to app/scripts/services/boards.js index 778e419d1..3e8ed6ff7 100644 --- a/app/scripts/services/boards.service.js +++ b/app/scripts/services/boards.js @@ -2,10 +2,11 @@ angular.module('icestudio') .service('boards', function(utils, + common, nodeFs, nodePath) { - this.pinoutHTML = ''; - this.selectedBoard = null; + const DEFAULT = 'icezum'; + this.currentBoards = loadBoards(nodePath.join('resources', 'boards')); function loadBoards(path) { @@ -17,10 +18,12 @@ angular.module('icestudio') if (!content.startsWith('_')) { var info = readJSONFile(contentPath, 'info.json'); var pinout = readJSONFile(contentPath, 'pinout.json'); + var rules = readJSONFile(contentPath, 'rules.json'); boards.push({ 'name': content, 'info': info, - 'pinout': pinout + 'pinout': pinout, + 'rules': rules }); } } @@ -45,27 +48,46 @@ angular.module('icestudio') }); this.selectBoard = function(name) { - for (var i in this.currentBoards) { - if (name === this.currentBoards[i].name) { - this.selectedBoard = this.currentBoards[i]; - this.pinoutHTML = generateHTMLOptions(this.selectedBoard.pinout); + name = name || DEFAULT; + var i; + var selectedBoard = null; + for (i in this.currentBoards) { + if (this.currentBoards[i].name === name) { + selectedBoard = this.currentBoards[i]; break; } } + if (selectedBoard === null) { + // Board not found: select default board + for (i in this.currentBoards) { + if (this.currentBoards[i].name === DEFAULT) { + selectedBoard = this.currentBoards[i]; + break; + } + } + } + common.selectedBoard = selectedBoard; + common.pinoutInputHTML = generateHTMLOptions(common.selectedBoard.pinout, 'input'); + common.pinoutOutputHTML = generateHTMLOptions(common.selectedBoard.pinout, 'output'); utils.rootScopeSafeApply(); + return common.selectedBoard.name; }; - // Set default board - this.selectBoard('icezum'); - - this.getPinoutHTML = function() { - return this.pinoutHTML; + this.boardLabel = function(name) { + for (var i in this.currentBoards) { + if (this.currentBoards[i].name === name) { + return this.currentBoards[i].info.label; + } + } + return name; }; - function generateHTMLOptions(pinout) { + function generateHTMLOptions(pinout, type) { var code = ''; for (var i in pinout) { - code += ''; + if (pinout[i].type === type || pinout[i].type === 'inout' ) { + code += ''; + } } return code; } diff --git a/app/scripts/services/common.js b/app/scripts/services/common.js new file mode 100644 index 000000000..b8f8874d6 --- /dev/null +++ b/app/scripts/services/common.js @@ -0,0 +1,19 @@ +'use strict'; + +angular.module('icestudio') + .service('common', function() { + + // Project version + this.VERSION = '1.1'; + + // All project dependencies + this.allDependencies = {}; + + // Selected board + this.selectedBoard = null; + this.pinoutInputHTML = ''; + this.pinoutOutputHTML = ''; + + // TODO: move all constants + + }); diff --git a/app/scripts/services/compiler.service.js b/app/scripts/services/compiler.js similarity index 65% rename from app/scripts/services/compiler.service.js rename to app/scripts/services/compiler.js index a6872a477..11ca86f7d 100644 --- a/app/scripts/services/compiler.service.js +++ b/app/scripts/services/compiler.js @@ -1,20 +1,21 @@ 'use strict'; angular.module('icestudio') - .service('compiler', function(nodeSha1, + .service('compiler', function(common, + nodeSha1, _package) { - this.generate = function(target, project) { + this.generate = function(target, project, opt) { var code = ''; switch(target) { case 'verilog': code += header('//'); code += '`default_nettype none\n'; - code += verilogCompiler('main', project); + code += verilogCompiler('main', project, opt); break; case 'pcf': code += header('#'); - code += pcfCompiler(project); + code += pcfCompiler(project, opt); break; case 'testbench': code += header('//'); @@ -240,9 +241,9 @@ angular.module('icestudio') // Header - var instance = ''; + var instance; if (block.type === 'basic.code') { - instance = digestId(block.id); + instance = name + '_' + digestId(block.id); } else { instance = digestId(block.type); @@ -279,26 +280,14 @@ angular.module('icestudio') var ports = []; var portsNames = []; for (w in graph.wires) { - var portName = ''; - var isConstant = false; wire = graph.wires[w]; if (block.id === wire.source.block) { - portName = wire.source.port; + connectPort(wire.source.port, portsNames, ports, block); } - else if (block.id === wire.target.block) { - portName = wire.target.port; - isConstant = wire.source.port === 'constant-out'; - } - if (portName && block.type !== 'basic.code') { - portName = digestId(portName); - } - if (portName && !isConstant && - portsNames.indexOf(portName) === -1) { - portsNames.push(portName); - var port = ''; - port += ' .' + portName; - port += '(w' + w + ')'; - ports.push(port); + if (block.id === wire.target.block) { + if (wire.source.port !== 'constant-out') { + connectPort(wire.target.port, portsNames, ports, block); + } } } @@ -309,6 +298,22 @@ angular.module('icestudio') } } } + + function connectPort(portName, portsNames, ports, block) { + if (portName) { + if (block.type !== 'basic.code') { + portName = digestId(portName); + } + if (portsNames.indexOf(portName) === -1) { + portsNames.push(portName); + var port = ''; + port += ' .' + portName; + port += '(w' + w + ')'; + ports.push(port); + } + } + } + return instances; } @@ -321,25 +326,177 @@ angular.module('icestudio') return null; } - function verilogCompiler(name, project) { - var data; - var code = ''; + this.getInitPorts = getInitPorts; + function getInitPorts(project) { + // Find not connected input wire ports to initialize + + var i, j; + var initPorts = []; + var blocks = project.design.graph.blocks; + + // Find all not connected input ports: + // - Code blocks + // - Generic blocks + for (i in blocks) { + var block = blocks[i]; + if (block) { + if (block.type === 'basic.code' || !block.type.startsWith('basic.')) { + // Code block or Generic block + for (j in block.data.ports.in) { + var inPort = block.data.ports.in[j]; + if (inPort.default && inPort.default.apply) { + initPorts.push({ + block: block.id, + port: inPort.name, + name: inPort.default.port, + pin: inPort.default.pin + }); + } + } + } + } + } + + return initPorts; + } + + this.getInitPins = getInitPins; + function getInitPins(project) { + // Find not used output pins to initialize + + var i; + var initPins = []; + var usedPins = []; + var blocks = project.design.graph.blocks; + + // Find all set output pins + for (i in blocks) { + var block = blocks[i]; + if (block.type === 'basic.output') { + for (var p in block.data.pins) { + usedPins.push(block.data.virtual ? '' : block.data.pins[p].value); + } + } + } + + // Filter pins defined in rules + var allInitPins = common.selectedBoard.rules.output; + for (i in allInitPins) { + if (usedPins.indexOf(allInitPins[i].pin) === -1) { + initPins.push(allInitPins[i]); + } + } + + return initPins; + } + + function verilogCompiler(name, project, opt) { + var i, data, block, code = ''; + opt = opt || {}; if (project && project.design && project.design.graph) { - var graph = project.design.graph; + var blocks = project.design.graph.blocks; var dependencies = project.dependencies; // Main module if (name) { + + // Initialize input ports + + if (name === 'main' && opt.boardRules) { + + var initPorts = opt.initPorts || getInitPorts(project); + for (i in initPorts) { + var initPort = initPorts[i]; + + // Find existing input block with the initPort value + var found = false; + var source = { + block: initPort.name, + port: 'out' + }; + for (i in blocks) { + block = blocks[i]; + if (block.type === 'basic.input' && + !block.data.range && + !block.data.virtual && + initPort.pin === block.data.pins[0].value) { + found = true; + source.block = block.id; + break; + } + } + + if (!found) { + // Add imaginary input block with the initPort value + project.design.graph.blocks.push({ + id: initPort.name, + type: 'basic.input', + data: { + name: initPort.name, + pins: [ + { + index: '0', + value: initPort.pin + } + ], + virtual: false + } + }); + } + + // Add imaginary wire between the input block and the initPort + project.design.graph.wires.push({ + source: { + block: source.block, + port: source.port + }, + target: { + block: initPort.block, + port: initPort.port + } + }); + } + } + + var params = getParams(project); + var ports = getPorts(project); + var content = getContent(name, project); + + // Initialize output pins + + if (name === 'main' && opt.boardRules) { + + // Initialize output pins + + var initPins = opt.initPins || getInitPins(project); + var n = initPins.length; + + if (n > 0) { + // Declare m port + ports.out.push({ + name: 'vinit', + range: '[0:' + (n-1) + ']' + }); + // Generate port value + var value = n.toString() + '\'b'; + for (i in initPins) { + value += initPins[i].bit; + } + // Assign m port + content += '\nassign vinit = ' + value + ';'; + } + } + data = { name: name, - params: getParams(project), - ports: getPorts(project), - content: getContent(name, project) + params: params, + ports: ports, + content: content }; code += module(data); } @@ -352,15 +509,15 @@ angular.module('icestudio') // Code modules - for (var i in graph.blocks) { - var block = graph.blocks[i]; + for (i in blocks) { + block = blocks[i]; if (block) { if (block.type === 'basic.code') { data = { - name: digestId(block.id), + name: name + '_' + digestId(block.id), params: block.data.params, ports: block.data.ports, - content: block.data.code + content: block.data.code.replace(/\n+/g, '\n').replace(/\n$/g, '') }; code += module(data); } @@ -371,33 +528,89 @@ angular.module('icestudio') return code; } - function pcfCompiler(project) { - var code = ''; - var graph = project.design.graph; + function pcfCompiler(project, opt) { + var i, j, block, pin, value, code = ''; + var blocks = project.design.graph.blocks; + opt = opt || {}; - for (var i in graph.blocks) { - var block = graph.blocks[i]; + for (i in blocks) { + block = blocks[i]; if (block.type === 'basic.input' || block.type === 'basic.output') { if (block.data.pins.length > 1) { for (var p in block.data.pins) { - var pin = block.data.pins[p]; + pin = block.data.pins[p]; + value = block.data.virtual ? '' : pin.value; code += 'set_io '; code += digestId(block.id); code += '[' + pin.index + '] '; - code += block.data.virtual ? '' : pin.value; + code += value; code += '\n'; } } - else { + else if (block.data.pins.length > 0) { + pin = block.data.pins[0]; + value = block.data.virtual ? '' : pin.value; code += 'set_io '; code += digestId(block.id); code += ' '; - code += block.data.virtual ? '' : block.data.pins[0].value; + code += value; + code += '\n'; + } + } + } + + if (opt.boardRules) { + // Declare init input ports + + var used = []; + var initPorts = opt.initPorts || getInitPorts(project); + for (i in initPorts) { + var initPort = initPorts[i]; + if (used.indexOf(initPort.pin) !== -1) { + break; + } + used.push(initPort.pin); + + // Find existing input block with the initPort value + var found = false; + for (j in blocks) { + block = blocks[j]; + if (block.type === 'basic.input' && + !block.data.range && + !block.data.virtual && + initPort.pin === block.data.pins[0].value) { + found = true; + used.push(initPort.pin); + break; + } + } + + if (!found) { + code += 'set_io v'; + code += initPorts[i].name; + code += ' '; + code += initPorts[i].pin; code += '\n'; } } + + // Declare init output pins + + var initPins = opt.initPins || getInitPins(project); + if (initPins.length > 1) { + for (i in initPins) { + code += 'set_io vinit[' + i + '] '; + code += initPins[i].pin; + code += '\n'; + } + } + else if (initPins.length > 0) { + code += 'set_io vinit '; + code += initPins[0].pin; + code += '\n'; + } } return code; diff --git a/app/scripts/services/graph.service.js b/app/scripts/services/graph.js similarity index 51% rename from app/scripts/services/graph.service.js rename to app/scripts/services/graph.js index 415747842..27be97512 100644 --- a/app/scripts/services/graph.service.js +++ b/app/scripts/services/graph.js @@ -5,7 +5,9 @@ angular.module('icestudio') joint, boards, blocks, + profile, utils, + common, gettextCatalog, window) { // Variables @@ -13,36 +15,23 @@ angular.module('icestudio') var z = { index: 100 }; - var ctrlPressed = false; var graph = null; var paper = null; var selection = null; var selectionView = null; var commandManager = null; - var clipboard = []; var mousePosition = { x: 0, y: 0 }; - var dependencies = {}; this.breadcrumbs = [{ name: '', type: '' }]; var gridsize = 8; - var state = { - pan: { - x: 0, - y: 0 - }, - zoom: 1.0 - }; - const ZOOM_MAX = 2; - const ZOOM_MIN = 0.2; + var state = { pan: { x: 0, y: 0 }, zoom: 1.0 }; + const ZOOM_MAX = 2.0; + const ZOOM_MIN = 0.3; // Functions - $(document).on('keydown', function(event) { - ctrlPressed = event.keyCode === 17; - }); - this.getState = function() { // Clone state return utils.clone(state); @@ -129,7 +118,7 @@ angular.module('icestudio') height: 1000, model: graph, gridSize: gridsize, - snapLinks: { radius: 15 }, + snapLinks: { radius: 16 }, linkPinning: false, embeddingMode: false, //markAvailable: true, @@ -181,21 +170,21 @@ angular.module('icestudio') return false; } // Prevent to connect a pull-up if other blocks are connected - if ((cellViewT.model.attributes.pullup) && + if ((cellViewT.model.get('pullup')) && (cellViewS.model.id === links[i].get('source').id)) { warning(gettextCatalog.getString('Invalid Pull up connection:
    block already connected')); return false; } // Prevent to connect other blocks if a pull-up is connected - if ((linkIView.targetView.model.attributes.pullup) && + if ((linkIView.targetView.model.get('pullup')) && (cellViewS.model.id === links[i].get('source').id)) { warning(gettextCatalog.getString('Invalid block connection:
    Pull up already connected')); return false; } } // Ensure input -> pull-up connections - if (cellViewT.model.attributes.pullup) { - var ret = (cellViewS.model.attributes.blockType === 'basic.input'); + if (cellViewT.model.get('pullup')) { + var ret = (cellViewS.model.get('blockType') === 'basic.input'); if (!ret) { warning(gettextCatalog.getString('Invalid Pull up connection:
    only Input blocks allowed')); } @@ -203,9 +192,9 @@ angular.module('icestudio') } // Prevent different size connections var tsize; - var lsize = linkView.model.attributes.size; + var lsize = linkView.model.get('size'); var portId = magnetT.getAttribute('port'); - var tLeftPorts = cellViewT.model.attributes.leftPorts; + var tLeftPorts = cellViewT.model.get('leftPorts'); for (i in tLeftPorts) { var port = tLeftPorts[i]; if (portId === port.id) { @@ -224,13 +213,30 @@ angular.module('icestudio') } }); + // Command Manager + + commandManager = new joint.dia.CommandManager({ + paper: paper, + graph: graph + }); + + // Selection View + + selection = new Backbone.Collection(); + selectionView = new joint.ui.SelectionView({ + paper: paper, + graph: graph, + model: selection, + state: state + }); + paper.options.enabled = true; paper.options.warningTimer = false; function warning(message) { if (!paper.options.warningTimer) { paper.options.warningTimer = true; - alertify.notify(message, 'warning', 5); + alertify.warning(message, 5); setTimeout(function() { paper.options.warningTimer = false; }, 4000); @@ -253,50 +259,42 @@ angular.module('icestudio') /*beforeZoom: function(oldzoom, newzoom) { },*/ onZoom: function(scale) { - state.zoom = scale; - // Already rendered in pan + state.zoom = scale; // Already rendered in pan + + // Close expanded combo + if (document.activeElement.className === 'select2-search__field') { + $('select').select2('close'); + } }, /*beforePan: function(oldpan, newpan) { },*/ onPan: function(newPan) { state.pan = newPan; selectionView.options.state = state; - - var cells = graph.getCells(); - - _.each(cells, function(cell) { - if (!cell.isLink()) { - cell.attributes.state = state; - var elementView = paper.findViewByModel(cell); - // Pan blocks - elementView.updateBox(); - // Pan selection boxes - selectionView.updateBox(elementView.model); - } - }); + graph.trigger('state', state); + updateCellBoxes(); } }); - // Command Manager - - commandManager = new joint.dia.CommandManager({ - paper: paper, - graph: graph - }); - - // Selection View - - selection = new Backbone.Collection(); - selectionView = new joint.ui.SelectionView({ - paper: paper, - graph: graph, - model: selection, - state: state - }); + function updateCellBoxes() { + var cells = graph.getCells(); + _.each(cells, function(cell) { + if (!cell.isLink()) { + cell.attributes.state = state; + var elementView = paper.findViewByModel(cell); + // Pan blocks + elementView.updateBox(); + // Pan selection boxes + selectionView.updateBox(elementView.model); + } + }); + } // Events this.mousedown = false; + $(document).on('mouseup', function() { self.mousedown = false; }); + $(document).on('mousedown', function() { self.mousedown = true; }); var self = this; $('#paper').mousemove(function(event) { @@ -319,7 +317,7 @@ angular.module('icestudio') }); } // Toggle selection - if ((evt.which === 3) && (evt.ctrlKey || evt.metaKey)) { + if (evt.which === 3) { var cell = selection.get($(evt.target).data('model')); selection.reset(selection.without(cell)); selectionView.destroySelectionBox(paper.findViewByModel(cell)); @@ -327,7 +325,6 @@ angular.module('icestudio') }); paper.on('cell:pointerup', function(cellView, evt/*, x, y*/) { - self.mousedown = false; if (paper.options.enabled) { if (!cellView.model.isLink()) { if (evt.which === 3) { @@ -336,33 +333,24 @@ angular.module('icestudio') // Right button selection.add(cellView.model); selectionView.createSelectionBox(cellView); - cellView.$box.removeClass('highlight'); - } - // Update wires on obstacles - var cells = graph.getCells(); - for (var i in cells) { - var cell = cells[i]; - if (cell.isLink()) { - paper.findViewByModel(cell).update(); - } + unhighlight(cellView); } + updateWiresOnObstacles(); } } }); - paper.on('cell:pointerdown', function(/*cellView*/) { - self.mousedown = true; - /*if (paper.options.enabled) { - if (!cellView.model.isLink()) { - if (cellView.$box.css('z-index') < z.index) { - cellView.$box.css('z-index', ++z.index); - } - } - }*/ + paper.on('cell:pointerdown', function(cellView) { + if (paper.options.enabled) { + if (cellView.model.isLink()) { + // Unhighlight source block of the wire + unhighlight(paper.findViewByModel(cellView.model.get('source').id)); + } + } }); paper.on('cell:pointerdblclick', function(cellView/*, evt, x, y*/) { - var type = cellView.model.attributes.blockType; + var type = cellView.model.get('blockType'); if (type.indexOf('basic.') !== -1) { if (paper.options.enabled) { blocks.editBasic(type, cellView, function(cell) { @@ -370,25 +358,20 @@ angular.module('icestudio') }); } } - else if (dependencies[type]) { - var name = dependencies[type].package.name; - var design = dependencies[type].design; - self.breadcrumbs.push({ name: name ? name : '#', type: type }); - utils.rootScopeSafeApply(); + else if (common.allDependencies[type]) { z.index = 1; - if (self.breadcrumbs.length === 2) { - $rootScope.$broadcast('updateProject', function() { - self.loadDesign(design, true); - }); - } - else { - self.loadDesign(design, true); - } + var project = common.allDependencies[type]; + var breadcrumbsLength = self.breadcrumbs.length; + $rootScope.$broadcast('navigateProject', { + update: breadcrumbsLength === 1, + project: project + }); + self.breadcrumbs.push({ name: project.package.name || '#', type: type }); + utils.rootScopeSafeApply(); } }); paper.on('blank:pointerdown', function(evt, x, y) { - self.mousedown = true; // Disable current focus document.activeElement.blur(); @@ -405,18 +388,15 @@ angular.module('icestudio') }); paper.on('cell:pointerup blank:pointerup', function(/*cellView, evt*/) { - self.mousedown = false; self.panAndZoom.disablePan(); }); paper.on('cell:mouseover', function(cellView/*, evt*/) { if (!self.mousedown) { if (!cellView.model.isLink()) { - cellView.$box.addClass('highlight'); - if (cellView && !cellView.model.isLink()) { - if (cellView.$box.css('z-index') < z.index) { - cellView.$box.css('z-index', ++z.index); - } + highlight(cellView); + if (cellView.$box.css('z-index') < z.index) { + cellView.$box.css('z-index', ++z.index); } } } @@ -425,7 +405,7 @@ angular.module('icestudio') paper.on('cell:mouseout', function(cellView/*, evt*/) { if (!self.mousedown) { if (!cellView.model.isLink()) { - cellView.$box.removeClass('highlight'); + unhighlight(cellView); } } }); @@ -442,16 +422,91 @@ angular.module('icestudio') } }*/ }); + + graph.on('add change:source change:target', function(cell) { + if (cell.isLink() && cell.get('source').id) { + // Link connected + var target = cell.get('target'); + if (target.id) { + // Connected to a port + cell.attributes.lastTarget = target; + updatePortDefault(target, false); + } + else { + // Moving the wire connection + target = cell.get('lastTarget'); + updatePortDefault(target, true); + } + } + }); + + graph.on('remove', function(cell) { + if (cell.isLink()) { + // Link removed + var target = cell.get('target'); + if (!target.id) { + target = cell.get('lastTarget'); + } + updatePortDefault(target, true); + } + }); + + function updatePortDefault(target, value) { + if (target) { + var i, port; + var block = graph.getCell(target.id); + if (block) { + var data = block.get('data'); + if (data && data.ports && data.ports.in) { + for (i in data.ports.in) { + port = data.ports.in[i]; + if (port.name === target.port && port.default) { + port.default.apply = value; + break; + } + } + paper.findViewByModel(block.id).updateBox(); + } + } + } + } + + // Initialize state + graph.trigger('state', state); + + }; + + function updateWiresOnObstacles() { + var cells = graph.getCells(); + for (var i in cells) { + var cell = cells[i]; + if (cell.isLink()) { + paper.findViewByModel(cell).update(); + } + } + } + + this.setBoardRules = function(value) { + var cells = graph.getCells(); + profile.set('boardRules', value); + + _.each(cells, function(cell) { + if (!cell.isLink()) { + cell.attributes.rules = value; + var cellView = paper.findViewByModel(cell); + cellView.updateBox(); + } + }); }; this.undo = function() { disableSelected(); - commandManager.undo(state); + commandManager.undo(); }; this.redo = function() { disableSelected(); - commandManager.redo(state); + commandManager.redo(); }; this.clearAll = function() { @@ -476,7 +531,7 @@ angular.module('icestudio') for (var i in cells) { var cellView = paper.findViewByModel(cells[i].id); cellView.options.interactive = value; - if (cells[i].attributes.type !== 'ice.Generic') { + if (cells[i].get('type') !== 'ice.Generic') { if (value) { cellView.$el.removeClass('disable-graph'); } @@ -484,8 +539,7 @@ angular.module('icestudio') cellView.$el.addClass('disable-graph'); } } - else if (cells[i].attributes.type !== 'ice.Wire') { - // TODO: also on !mousedown + else if (cells[i].get('type') !== 'ice.Wire') { if (value) { cellView.$el.find('.port-body').removeClass('disable-graph'); } @@ -524,68 +578,91 @@ angular.module('icestudio') graph.startBatch('change'); // Trigger board event var data = { - previous: boards.selectedBoard.name, + previous: common.selectedBoard.name, next: boardName }; graph.trigger('board', { data: data }); - boards.selectBoard(boardName); + boardName = boards.selectBoard(boardName); + resetBlocks(); + graph.stopBatch('change'); + return boardName; + }; + + function resetBlocks() { + var data; var cells = graph.getCells(); - // Reset choices in all I/O blocks for (var i in cells) { var cell = cells[i]; - var type = cell.attributes.blockType; - if (type === 'basic.input' || - type === 'basic.output') { + if (cell.isLink()) { + break; + } + var type = cell.get('blockType'); + if (type === 'basic.input' || type === 'basic.output') { + // Reset choices in all Input / blocks var view = paper.findViewByModel(cell.id); - cell.set('choices', boards.getPinoutHTML()); + cell.set('choices', (type === 'basic.input') ? common.pinoutInputHTML : common.pinoutOutputHTML); view.clearValues(); view.applyChoices(); } + else if (type === 'basic.code') { + // Reset rules in Code block ports + data = utils.clone(cell.get('data')); + if (data && data.ports && data.ports.in) { + for (var j in data.ports.in) { + var port = data.ports.in[j]; + port.default = utils.hasInputRule(port.name); + } + } + cell.set('data', data); + paper.findViewByModel(cell.id).updateBox(); + } + else if (type.indexOf('basic.') === -1) { + // Reset rules in Generic block ports + var block = common.allDependencies[type]; + data = { ports: { in: [] }}; + for (i in block.design.graph.blocks) { + var item = block.design.graph.blocks[i]; + if (item.type === 'basic.input') { + if (!item.data.range) { + data.ports.in.push({ + name: item.id, + default: utils.hasInputRule((item.data.clock ? 'clk' : '') || item.data.name) + }); + } + } + } + cell.set('data', data); + paper.findViewByModel(cell.id).updateBox(); + } } - graph.stopBatch('change'); - }; + } this.resetCommandStack = function() { commandManager.reset(); }; this.cutSelected = function() { - if (selection) { - clipboard = selection.clone(); + if (hasSelection()) { + utils.copyToClipboard(selection, graph); this.removeSelected(); } }; this.copySelected = function() { - if (selection) { - clipboard = selection.clone(); + if (hasSelection()) { + utils.copyToClipboard(selection, graph); } }; this.pasteSelected = function() { - if (clipboard && clipboard.length > 0) { - var offset = clipboard.models[0].attributes.position; - selectionView.cancelSelection(); - var newCells = []; - clipboard.each(function(cell) { - var newCell = cell.clone(); - newCell.translate( - Math.round(((mousePosition.x - state.pan.x) / state.zoom - offset.x) / gridsize) * gridsize, - Math.round(((mousePosition.y - state.pan.y) / state.zoom - offset.y) / gridsize) * gridsize - ); - newCells.push(newCell); - }); - graph.addCells(newCells); - // Select pasted cells - _.each(newCells, function(cell) { - if (!cell.isLink()) { - var cellView = paper.findViewByModel(cell); - selection.add(cell); - selectionView.createSelectionBox(cellView); - cellView.$box.removeClass('highlight'); - } - }); - } + var self = this; + utils.pasteFromClipboard(function(object) { + if (object.version === common.VERSION && + (document.activeElement.tagName === 'A' || + document.activeElement.tagName === 'BODY')) { + self.appendDesign(object.design, object.dependencies); + } + }); }; this.selectAll = function() { @@ -596,19 +673,86 @@ angular.module('icestudio') var cellView = paper.findViewByModel(cell); selection.add(cell); selectionView.createSelectionBox(cellView); - cellView.$box.removeClass('highlight'); + unhighlight(cellView); } }); }; - this.hasSelection = function() { - return selection.length > 0; - }; + function highlight(cellView) { + if (cellView) { + switch(cellView.model.get('type')) { + case 'ice.Input': + case 'ice.Output': + if (cellView.model.get('data').virtual) { + cellView.$box.addClass('highlight-green'); + } + else { + cellView.$box.addClass('highlight-yellow'); + } + break; + case 'ice.Constant': + cellView.$box.addClass('highlight-orange'); + break; + case 'ice.Code': + cellView.$box.addClass('highlight-blue'); + break; + case 'ice.Generic': + if (cellView.model.get('config')) { + cellView.$box.addClass('highlight-yellow'); + } + else { + cellView.$box.addClass('highlight-blue'); + } + break; + case 'ice.Info': + cellView.$box.addClass('highlight-gray'); + break; + } + } + } + + function unhighlight(cellView) { + if (cellView) { + switch(cellView.model.get('type')) { + case 'ice.Input': + case 'ice.Output': + if (cellView.model.get('data').virtual) { + cellView.$box.removeClass('highlight-green'); + } + else { + cellView.$box.removeClass('highlight-yellow'); + } + break; + case 'ice.Constant': + cellView.$box.removeClass('highlight-orange'); + break; + case 'ice.Code': + cellView.$box.removeClass('highlight-blue'); + break; + case 'ice.Generic': + if (cellView.model.get('config')) { + cellView.$box.removeClass('highlight-yellow'); + } + else { + cellView.$box.removeClass('highlight-blue'); + } + break; + case 'ice.Info': + cellView.$box.removeClass('highlight-gray'); + break; + } + } + } + + function hasSelection() { + return selection && selection.length > 0; + } this.removeSelected = function() { - if (selection) { + if (hasSelection()) { graph.removeCells(selection.models); selectionView.cancelSelection(); + updateWiresOnObstacles(); } }; @@ -617,7 +761,7 @@ angular.module('icestudio') }); function disableSelected() { - if (selection) { + if (hasSelection()) { selectionView.cancelSelection(); } } @@ -625,30 +769,77 @@ angular.module('icestudio') var stepValue = 8; this.stepLeft = function() { - step({ x: -stepValue, y: 0 }); + performStep({ x: -stepValue, y: 0 }); }; this.stepUp = function() { - step({ x: 0, y: -stepValue }); + performStep({ x: 0, y: -stepValue }); }; this.stepRight = function() { - step({ x: stepValue, y: 0 }); + performStep({ x: stepValue, y: 0 }); }; this.stepDown = function() { - step({ x: 0, y: stepValue }); + performStep({ x: 0, y: stepValue }); }; + var stepCounter = 0; + var stepTimer = null; + var stepGroupingInterval = 500; + var allowStep = true; + var allosStepInterval = 200; + + function performStep(offset) { + if (selection && allowStep) { + allowStep = false; + // Check consecutive-change interval + if (Date.now() - stepCounter < stepGroupingInterval) { + clearTimeout(stepTimer); + } + else { + graph.startBatch('change'); + } + // Move a step + step(offset); + // Launch timer + stepTimer = setTimeout(function() { + graph.stopBatch('change'); + }, stepGroupingInterval); + // Reset counter + stepCounter = Date.now(); + setTimeout(function() { + allowStep = true; + }, allosStepInterval); + } + } + function step(offset) { - if (selection) { - graph.startBatch('change'); - selection.each(function(cell) { - cell.translate(offset.x, offset.y); - selectionView.updateBox(cell); + var processedWires = {}; + // Translate blocks + selection.each(function(cell) { + cell.translate(offset.x, offset.y); + selectionView.updateBox(cell); + // Translate link vertices + var connectedWires = graph.getConnectedLinks(cell); + _.each(connectedWires, function(wire) { + + if (processedWires[wire.id]) { + return; + } + + var vertices = wire.get('vertices'); + if (vertices && vertices.length) { + var newVertices = []; + _.each(vertices, function(vertex) { + newVertices.push({ x: vertex.x + offset.x, y: vertex.y + offset.y }); + }); + wire.set('vertices', newVertices); + } + + processedWires[wire.id] = true; }); - graph.stopBatch('change'); - } + }); } this.isEmpty = function() { @@ -659,57 +850,32 @@ angular.module('icestudio') return paper.options.enabled; }; - this.setDependencies = function(_dependencies) { - dependencies = _dependencies; - }; - - this.loadDesign = function(design, disabled, callback) { + this.loadDesign = function(design, opt, callback) { if (design && design.graph && design.graph.blocks && design.graph.wires) { - var i; var self = this; - var blockInstances = design.graph.blocks; - var wires = design.graph.wires; + + opt = opt || {}; $('body').addClass('waiting'); - commandManager.stopListening(); + setTimeout(function() { - this.clearAll(); - this.setState(design.state); + self.setState(design.state); - setTimeout(function() { - var cell; + commandManager.stopListening(); - // Blocks - for (i in blockInstances) { - var blockInstance = blockInstances[i]; - if (blockInstance.type.indexOf('basic.') !== -1) { - cell = blocks.loadBasic(blockInstance, disabled); - } - else { - if (blockInstance.type in dependencies) { - cell = blocks.loadGeneric(blockInstance, dependencies[blockInstance.type]); - } - } - addCell(cell); - } + self.clearAll(); - // Wires - for (i in wires) { - var source = graph.getCell(wires[i].source.block); - var target = graph.getCell(wires[i].target.block); - cell = blocks.loadWire(wires[i], source, target); - addCell(cell); - } + var cells = graphToCells(design.graph, opt); + graph.addCells(cells); - self.appEnable(!disabled); - $('body').removeClass('waiting'); + self.appEnable(!opt.disabled); - if (!disabled) { + if (!opt.disabled) { commandManager.listen(); } @@ -717,15 +883,153 @@ angular.module('icestudio') callback(); } + $('body').removeClass('waiting'); + }, 20); return true; } }; - function addCell(cell) { + function graphToCells(_graph, opt) { + // Options: + // - new: assign a new id to all the cells + // - reset: clear I/O blocks values + // - disabled: set disabled flag to the blocks + // - offset: apply an offset to all the cells + + var cell; + var cells = []; + var blocksMap = {}; + + opt = opt || {}; + + // Blocks + _.each(_graph.blocks, function(blockInstance) { + if (blockInstance.type.indexOf('basic.') !== -1) { + if (opt.reset && + (blockInstance.type === 'basic.input' || + blockInstance.type === 'basic.output')) { + var pins = blockInstance.data.pins; + for (var i in pins) { + pins[i].name = ''; + pins[i].value = 0; + } + } + cell = blocks.loadBasic(blockInstance, opt.disabled); + } + else { + if (blockInstance.type in common.allDependencies) { + cell = blocks.loadGeneric(blockInstance, common.allDependencies[blockInstance.type], opt.disabled); + } + } + blocksMap[cell.id] = cell; + if (opt.new) { + var oldId = cell.id; + cell = cell.clone(); + blocksMap[oldId] = cell; + } + if (opt.offset) { + cell.translate(opt.offset.x, opt.offset.y); + } + updateCellAttributes(cell); + cells.push(cell); + }); + + // Wires + _.each(_graph.wires, function(wireInstance) { + var source = blocksMap[wireInstance.source.block]; + var target = blocksMap[wireInstance.target.block]; + if (opt.offset) { + var newVertices = []; + var vertices = wireInstance.vertices; + if (vertices && vertices.length) { + _.each(vertices, function(vertex) { + newVertices.push({ + x: vertex.x + opt.offset.x, + y: vertex.y + opt.offset.y + }); + }); + } + wireInstance.vertices = newVertices; + } + cell = blocks.loadWire(wireInstance, source, target); + if (opt.new) { + cell = cell.clone(); + } + updateCellAttributes(cell); + cells.push(cell); + }); + + return cells; + } + + this.appendDesign = function(design, dependencies) { + if (design && + dependencies && + design.graph && + design.graph.blocks && + design.graph.wires) { + + selectionView.cancelSelection(); + + // Merge dependencies + for (var type in dependencies) { + if (!(type in common.allDependencies)) { + common.allDependencies[type] = dependencies[type]; + } + } + + // Append graph cells: blocks and wires + // - assign new UUIDs to the cells + // - add the graph in the mouse position + var origin = graphOrigin(design.graph); + var opt = { + new: true, + disabled: false, + reset: design.board !== common.selectedBoard.name, + offset: { + x: Math.round(((mousePosition.x - state.pan.x) / state.zoom - origin.x) / gridsize) * gridsize, + y: Math.round(((mousePosition.y - state.pan.y) / state.zoom - origin.y) / gridsize) * gridsize, + } + }; + var cells = graphToCells(design.graph, opt); + graph.addCells(cells); + + // Select pasted elements + _.each(cells, function(cell) { + if (!cell.isLink()) { + var cellView = paper.findViewByModel(cell); + selection.add(cell); + selectionView.createSelectionBox(cellView); + unhighlight(cellView); + } + }); + } + }; + + function graphOrigin(graph) { + var origin = { x: Infinity, y: Infinity }; + _.each(graph.blocks, function(block) { + var position = block.position; + if (position.x < origin.x) { + origin.x = position.x; + } + if (position.y < origin.y) { + origin.y = position.y; + } + }); + return origin; + } + + function updateCellAttributes(cell) { cell.attributes.state = state; + cell.attributes.rules = profile.get('boardRules'); //cell.attributes.zindex = z.index; + } + + function addCell(cell) { + updateCellAttributes(cell); graph.addCell(cell); if (!cell.isLink()) { var cellView = paper.findViewByModel(cell); diff --git a/app/scripts/services/profile.service.js b/app/scripts/services/profile.js similarity index 50% rename from app/scripts/services/profile.service.js rename to app/scripts/services/profile.js index bd04bf74a..03fc01b0f 100644 --- a/app/scripts/services/profile.service.js +++ b/app/scripts/services/profile.js @@ -6,29 +6,47 @@ angular.module('icestudio') this.data = { 'language': '', - 'remoterHostname': '', - 'collection': '' + 'remoteHostname': '', + 'collection': '', + 'board': '', + 'boardRules': true }; this.load = function(callback) { var self = this; utils.readFile(utils.PROFILE_PATH, function(data) { if (data) { - self.data = data; + self.data = { + 'language': data.language || '', + 'remoteHostname': data.remoteHostname || '', + 'collection': data.collection || '', + 'board': data.board || '', + 'boardRules': data.remoteHostname || true + }; } if (callback) { callback(); } - // console.log('Profile loaded'); }); }; + this.set = function(key, value) { + if (this.data.hasOwnProperty(key)) { + this.data[key] = value; + this.save(); + } + }; + + this.get = function(key) { + return this.data[key]; + }; + this.save = function() { if (!nodeFs.existsSync(utils.ICESTUDIO_DIR)) { nodeFs.mkdirSync(utils.ICESTUDIO_DIR); } utils.saveFile(utils.PROFILE_PATH, this.data, function() { - console.log('Profile saved'); + // Success }, true); }; diff --git a/app/scripts/services/project.service.js b/app/scripts/services/project.js similarity index 73% rename from app/scripts/services/project.service.js rename to app/scripts/services/project.js index fe234a8dc..c6755c693 100644 --- a/app/scripts/services/project.service.js +++ b/app/scripts/services/project.js @@ -5,7 +5,9 @@ angular.module('icestudio') graph, boards, compiler, + profile, utils, + common, gettextCatalog, nodeFs, nodePath) { @@ -14,14 +16,11 @@ angular.module('icestudio') this.path = ''; // Used in Save / Save as this.changed = false; - const VERSION = '1.1'; - var project = _default(); - var allDependencies = {}; function _default() { return { - version: VERSION, + version: common.VERSION, package: { name: '', version: '', @@ -69,10 +68,6 @@ angular.module('icestudio') } }; - this.getAllDependencies = function() { - return allDependencies; - }; - this.new = function(name) { this.path = ''; project = _default(); @@ -97,38 +92,58 @@ angular.module('icestudio') }; this.load = function(name, data) { - if (data.version !== VERSION) { - alertify.notify(gettextCatalog.getString('Old project format {{version}}', { version: data.version }), 'warning', 5); + var self = this; + if (data.version !== common.VERSION) { + alertify.warning(gettextCatalog.getString('Old project format {{version}}', { version: data.version }), 5); } - project = _safeLoad(data); - allDependencies = project.dependencies; - graph.setDependencies(allDependencies); - var ret = graph.loadDesign(project.design, false, function() { - graph.resetCommandStack(); - alertify.success(gettextCatalog.getString('Project {{name}} loaded', { name: utils.bold(name) })); - }); - - if (ret) { - boards.selectBoard(project.design.board); - this.updateTitle(name); + project = _safeLoad(data, name); + if (project.design.board !== common.selectedBoard.name) { + var projectBoard = boards.boardLabel(project.design.board); + alertify.confirm( + gettextCatalog.getString('This project is designed for the {{name}} board.', { name: utils.bold(projectBoard) }) + '
    ' + + gettextCatalog.getString('Do you want to convert it?'), + function() { + project.design.board = common.selectedBoard.name; + _load(true); + }, + function() { + _load(); + }); } else { - alertify.notify(gettextCatalog.getString('Wrong project format: {{name}}', { name: utils.bold(name) }), 'error', 30); + _load(); + } + + function _load(reset) { + common.allDependencies = project.dependencies; + var opt = { reset: reset || false, disabled: false }; + var ret = graph.loadDesign(project.design, opt, function() { + graph.resetCommandStack(); + alertify.success(gettextCatalog.getString('Project {{name}} loaded', { name: utils.bold(name) })); + }); + + if (ret) { + profile.set('board', boards.selectBoard(project.design.board)); + self.updateTitle(name); + } + else { + alertify.error(gettextCatalog.getString('Wrong project format: {{name}}', { name: utils.bold(name) }), 30); + } } }; - function _safeLoad(data) { + function _safeLoad(data, name) { // Backwards compatibility var project = {}; switch(data.version) { - case VERSION: + case common.VERSION: project = data; break; case '1.0': project = convert10To11(data); break; default: - project = convertTo10(data); + project = convertTo10(data, name); project = convert10To11(project); break; } @@ -188,13 +203,13 @@ angular.module('icestudio') } } - function convertTo10(data) { + function convertTo10(data, name) { var project = { version: '1.0', package: { - name: '', + name: name || '', version: '', - description: '', + description: name || '', author: '', image: '' }, @@ -262,8 +277,8 @@ angular.module('icestudio') project.design.graph = data.graph; project.design.state = data.state; // Safe load all dependencies recursively - for (var j in data.deps) { - project.design.deps[j] = convertTo10(data.deps[j]); + for (var key in data.deps) { + project.design.deps[key] = convertTo10(data.deps[key], key); } return project; @@ -276,7 +291,7 @@ angular.module('icestudio') sortGraph(); this.update(); - utils.saveFile(filepath, project, function() { + utils.saveFile(filepath, pruneProject(project), function() { alertify.success(gettextCatalog.getString('Project {{name}} saved', { name: utils.bold(name) })); }, true); }; @@ -304,10 +319,11 @@ angular.module('icestudio') this.addAsBlock = function(filepath) { var self = this; utils.readFile(filepath, function(data) { - if (data.version !== VERSION) { - alertify.notify(gettextCatalog.getString('Old project format {{version}}', { version: data.version }), 'warning', 5); + if (data.version !== common.VERSION) { + alertify.warning(gettextCatalog.getString('Old project format {{version}}', { version: data.version }), 5); } - var block = _safeLoad(data); + var name = utils.basename(filepath); + var block = _safeLoad(data, name); if (block) { var path = utils.dirname(filepath); // 1. Parse and find included files @@ -389,10 +405,10 @@ angular.module('icestudio') function doCopySync(orig, dest, filename) { var success = utils.copySync(orig, dest); if (success) { - alertify.notify(gettextCatalog.getString('File {{file}} imported', { file: utils.bold(filename) }), 'message', 5); + alertify.message(gettextCatalog.getString('File {{file}} imported', { file: utils.bold(filename) }), 5); } else { - alertify.notify(gettextCatalog.getString('Original file {{file}} does not exist', { file: utils.bold(filename) }), 'error', 30); + alertify.error(gettextCatalog.getString('Original file {{file}} does not exist', { file: utils.bold(filename) }), 30); } return success; } @@ -404,45 +420,47 @@ angular.module('icestudio') }); }; - this.update = function(callback, updateDependencies) { - var graphData = graph.toJSON(); + function pruneProject (project) { + var _project = utils.clone(project); + + _prune(_project); + for (var d in _project.dependencies) { + _prune(_project.dependencies[d]); + } - var blocks = []; - var wires = []; - - for (var c = 0; c < graphData.cells.length; c++) { - var cell = graphData.cells[c]; - - if (cell.type === 'ice.Generic' || - cell.type === 'ice.Input' || - cell.type === 'ice.Output' || - cell.type === 'ice.Code' || - cell.type === 'ice.Info' || - cell.type === 'ice.Constant') { - var block = {}; - block.id = cell.id; - block.type = cell.blockType; - block.data = cell.data; - block.position = cell.position; - if (cell.type === 'ice.Code' || - cell.type === 'ice.Info') { - delete block.data.deltas; + function _prune(_project) { + for (var i in _project.design.graph.blocks) { + var block = _project.design.graph.blocks[i]; + switch (block.type) { + case 'basic.input': + case 'basic.output': + case 'basic.constant': + case 'basic.info': + break; + case 'basic.code': + for (var j in block.data.ports.in) { + delete block.data.ports.in[j].default; + } + break; + default: + // Generic block + delete block.data; + break; } - blocks.push(block); - } - else if (cell.type === 'ice.Wire') { - var wire = {}; - wire.source = { block: cell.source.id, port: cell.source.port }; - wire.target = { block: cell.target.id, port: cell.target.port }; - wire.vertices = cell.vertices; - wire.size = (cell.size > 1) ? cell.size : undefined; - wires.push(wire); } } + return _project; + } + + this.update = function(opt, callback) { + var graphData = graph.toJSON(); + var p = utils.cellsToProject(graphData.cells, opt); + + project.design.board = p.design.board; + project.design.graph = p.design.graph; + project.dependencies = p.dependencies; var state = graph.getState(); - project.design.board = boards.selectedBoard.name; - project.design.graph = { blocks: blocks, wires: wires }; project.design.state = { pan: { x: parseFloat(state.pan.x.toFixed(4)), @@ -451,49 +469,24 @@ angular.module('icestudio') zoom: parseFloat(state.zoom.toFixed(4)) }; - // Update dependencies - if (updateDependencies !== false) { - project.dependencies = {}; - var types = findSubDependencies(project); - for (var i in types) { - project.dependencies[types[i]] = allDependencies[types[i]]; - } - } - if (callback) { callback(); } }; - function findSubDependencies(dependency) { - var subDependencies = []; - if (dependency) { - var blocks = dependency.design.graph.blocks; - for (var i in blocks) { - var type = blocks[i].type; - if (type.indexOf('basic.') === -1) { - subDependencies.push(type); - var newSubDependencies = findSubDependencies(allDependencies[type]); - subDependencies = subDependencies.concat(newSubDependencies); - } - } - return _.unique(subDependencies); - } - return subDependencies; - } - this.updateTitle = function(name) { if (name) { this.name = name; graph.resetBreadcrumbs(name); } - var title = (this.changed ? '●' : '') + this.name + ' ─ Icestudio'; + var title = (this.changed ? '*' : '') + this.name + ' ─ Icestudio'; utils.updateWindowTitle(title); }; this.export = function(target, filepath, message) { this.update(); - var data = compiler.generate(target, project); + var opt = { boardRules: profile.get('boardRules') }; + var data = compiler.generate(target, project, opt); utils.saveFile(filepath, data, function() { alertify.success(message); }, false); @@ -520,9 +513,8 @@ angular.module('icestudio') block = _safeLoad(block); block = pruneBlock(block); var type = utils.dependencyID(block); - mergeDependencies(type, block); + utils.mergeDependencies(type, block); graph.createBlock(type, block); - graph.setDependencies(allDependencies); } } }; @@ -547,23 +539,6 @@ angular.module('icestudio') return block; } - function mergeDependencies(type, block) { - if (type in allDependencies) { - return; // If the block is already in dependencies - } - // Merge the block dependencies - var deps = block.dependencies; - for (var i in deps) { - var depType = utils.dependencyID(deps[i]); - if (!(depType in allDependencies)) { - allDependencies[depType] = deps[i]; - } - } - // Add the block as a dependency - delete block.dependencies; - allDependencies[type] = block; - } - this.removeSelected = function() { graph.removeSelected(); }; diff --git a/app/scripts/services/resources.js b/app/scripts/services/resources.js new file mode 100644 index 000000000..fbdf161c5 --- /dev/null +++ b/app/scripts/services/resources.js @@ -0,0 +1,86 @@ +'use strict'; + +angular.module('icestudio') + .service('resources', function(utils, + nodePath) { + + const DEFAULT = ''; + + this.collections = []; + this.selectedCollection = null; + + this.loadCollections = function() { + this.collections = []; + // Add Default collection + var defaultPath = nodePath.join('resources', 'collection'); + var defaultData = { + 'name': DEFAULT, + 'path': nodePath.resolve(defaultPath), + 'children': utils.getFilesRecursive(defaultPath) + }; + var defaultCollection = getCollection(defaultData); + this.collections.push(defaultCollection); + // Add installed collections + var data = utils.getFilesRecursive(utils.COLLECTIONS_DIR); + for (var i in data) { + var collection = getCollection(data[i]); + if (collection) { + this.collections.push(collection); + } + } + }; + + function getCollection(data) { + var collection = { + name: data.name, + path: data.path, + content: { + blocks: [], + examples: [], + package: {} + } + }; + for (var i in data.children) { + var child = data.children[i]; + switch (child.name) { + case ('blocks'): + if (child.children) { + collection.content.blocks = child.children; + } + break; + case ('examples'): + if (child.children) { + collection.content.examples = child.children; + } + break; + case ('package'): + if (!child.children) { + // TODO: use package data + //collection.content.package = require(child.path); + } + break; + } + } + return collection; + } + + this.loadCollections(); + + this.selectCollection = function(name) { + name = name || DEFAULT; + var selectedCollection = null; + for (var i in this.collections) { + if (this.collections[i].name === name) { + selectedCollection = this.collections[i]; + break; + } + } + if (selectedCollection === null) { + // Collection not found: select default collection + selectedCollection = this.collections[0]; + } + this.selectedCollection = selectedCollection; + return selectedCollection.name; + }; + + }); diff --git a/app/scripts/services/resources.service.js b/app/scripts/services/resources.service.js deleted file mode 100644 index 0b5d98ec1..000000000 --- a/app/scripts/services/resources.service.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -angular.module('icestudio') - .service('resources', function(utils, - nodePath) { - - const DEFAULT = ''; - - this.selectedCollection = null; - this.currentCollections = []; - this.currentExamples = []; - - this.loadCollections = function() { - var defaultPath = nodePath.join('resources', 'blocks'); - var collections = [{ - 'name': DEFAULT, - 'path': nodePath.resolve(defaultPath), - 'children': utils.getFilesRecursive(defaultPath, '.ice') - }]; - this.currentCollections = collections.concat(utils.getFilesRecursive(utils.COLLECTIONS_DIR, '.ice')); - }; - - this.loadExamples = function() { - this.currentExamples = utils.getFilesRecursive(nodePath.join('resources', 'examples'), '.ice'); - }; - - this.loadCollections(); - this.loadExamples(); - - this.selectCollection = function(name) { - name = name || DEFAULT; - var selectedCollection = null; - for (var i in this.currentCollections) { - if (name === this.currentCollections[i].name) { - selectedCollection = this.currentCollections[i]; - break; - } - } - if (selectedCollection === null) { - // Collection not found: select default collection - selectedCollection = this.currentCollections[0]; - } - this.selectedCollection = selectedCollection; - return selectedCollection.name; - }; - - }); diff --git a/app/scripts/services/shortcuts.js b/app/scripts/services/shortcuts.js new file mode 100644 index 000000000..08ac8e53e --- /dev/null +++ b/app/scripts/services/shortcuts.js @@ -0,0 +1,169 @@ +'use strict'; + +angular.module('icestudio') + .filter('shortcut', function(shortcuts) { + return function(action) { + return shortcuts.label(action); + }; + }) + .service('shortcuts', function(utils) { + + this.method = function(action, method) { + // Configure shortcut method + if (action in shortcuts) { + shortcuts[action]['method'] = method; + } + }; + + this.execute = function(event, opt) { + // Execute shortcut method + // Options: + // - opt.prompt: allow shortcut when a prompt is shown + // - opt.disable: allow shortcut when the graph is disabled + + var action = ''; + var method = null; + var system = utils.DARWIN ? 'mac' : 'linux'; + var ret = { preventDefault: false }; + for (action in shortcuts) { + var options = shortcuts[action].opt || {}; + var command = shortcuts[action][system]; + if (event.keyCode === command.key && + event.ctrlKey === (command.ctrl || false) && + event.metaKey === (command.meta || false) && + event.shiftKey === (command.shift || false) && + (!opt.prompt || (options.prompt || false)) && + (!opt.disabled || (options.disabled || false))) { + + method = shortcuts[action].method; + ret.preventDefault = options.preventDefault || false; + break; + } + } + if (method) { + method(); + } + return ret; + }; + + this.label = function(action) { + // Return shortcut label + var label = ''; + if (action in shortcuts) { + if (utils.DARWIN) { + label = shortcuts[action].mac.label; + } + else { + label = shortcuts[action].linux.label; + } + } + return label; + }; + + var shortcuts = { + newProject: { + linux: { label: 'Ctrl+N', ctrl: true, key: 78 }, + mac: { label: '⌘+N', meta: true, key: 78 } + }, + openProject: { + linux: { label: 'Ctrl+O', ctrl: true, key: 79 }, + mac: { label: '⌘+O', meta: true, key: 79 } + }, + saveProject: { + linux: { label: 'Ctrl+S', ctrl: true, key: 83 }, + mac: { label: '⌘+S', meta: true, key: 83 } + }, + saveProjectAs: { + linux: { label: 'Ctrl+Shift+S', ctrl: true, shift: true, key: 83 }, + mac: { label: 'Shift+⌘+S', meta: true, shift: true, key: 83 } + }, + quit: { + linux: { label: 'Ctrl+Q', ctrl: true, key: 81 }, + mac: { label: '⌘+Q', meta: true, key: 81 } + }, + undoGraph: { + linux: { label: 'Ctrl+Z', ctrl: true, key: 90 }, + mac: { label: '⌘+Z', meta: true, key: 90 }, + opt: { preventDefault: true } + }, + redoGraph: { + linux: { label: 'Ctrl+Y', ctrl: true, key: 89 }, + mac: { label: '⌘+Y', meta: true, key: 89 }, + opt: { preventDefault: true } + }, + redoGraph2: { + linux: { label: 'Ctrl+Shift+Z', ctrl: true, shift: true, key: 90 }, + mac: { label: 'Shift+⌘+Z', meta: true, shift: true, key: 90 }, + opt: { preventDefault: true } + }, + cutSelected: { + linux: { label: 'Ctrl+X', ctrl: true, key: 88 }, + mac: { label: '⌘+X', meta: true, key: 88 } + }, + copySelected: { + linux: { label: 'Ctrl+C', ctrl: true, key: 67 }, + mac: { label: '⌘+C', meta: true, key: 67 } + }, + pasteSelected: { + linux: { label: 'Ctrl+V', ctrl: true, key: 86 }, + mac: { label: '⌘+V', meta: true, key: 86 } + }, + selectAll: { + linux: { label: 'Ctrl+A', ctrl: true, key: 65 }, + mac: { label: '⌘+A', meta: true, key: 65 } + }, + resetView: { + linux: { label: 'Ctrl+0', ctrl: true, key: 48 }, + mac: { label: '⌘+0', meta: true, key: 48 }, + opt: { disabled: true } + }, + fitContent: { + linux: { label: 'Ctrl+1', ctrl: true, key: 49 }, + mac: { label: '⌘+1', meta: true, key: 49 }, + opt: { disabled: true } + }, + verifyCode: { + linux: { label: 'Ctrl+R', ctrl: true, key: 82 }, + mac: { label: '⌘+R', meta: true, key: 82 } + }, + buildCode: { + linux: { label: 'Ctrl+B', ctrl: true, key: 66 }, + mac: { label: '⌘+B', meta: true, key: 66 } + }, + uploadCode: { + linux: { label: 'Ctrl+U', ctrl: true, key: 85 }, + mac: { label: '⌘+U', meta: true, key: 85 } + }, + stepUp: { + linux: { label: 'Arrow up', key: 38 }, + mac: { label: 'Arrow up', key: 38 } + }, + stepDown: { + linux: { label: 'Arrow down', key: 40 }, + mac: { label: 'Arrow down', key: 40 } + }, + stepLeft: { + linux: { label: 'Arrow left', key: 37 }, + mac: { label: 'Arrow left', key: 37 } + }, + stepRight: { + linux: { label: 'Arrow right', key: 39 }, + mac: { label: 'Arrow right', key: 39 } + }, + removeSelected: { + linux: { label: 'Supr', key: 46 }, + mac: { label: 'Fn+Delete', key: 46 }, + }, + breadcrumbsBack: { + linux: { label: 'Back', key: 8 }, + mac: { label: 'Delete', key: 8 }, + opt: { disabled: true } + }, + takeSnapshot: { + linux: { label: 'Ctrl+P', ctrl: true, key: 80 }, + mac: { label: '⌘+P', meta: true, key: 80 }, + opt: { prompt: true, disabled: true, preventDefault: true } + } + }; + + }); diff --git a/app/scripts/services/tools.service.js b/app/scripts/services/tools.js similarity index 67% rename from app/scripts/services/tools.service.js rename to app/scripts/services/tools.js index ffece9ce5..5e2dd4e95 100644 --- a/app/scripts/services/tools.service.js +++ b/app/scripts/services/tools.js @@ -2,49 +2,45 @@ angular.module('icestudio') .service('tools', function(project, - boards, compiler, profile, resources, utils, + common, gettextCatalog, gettext, + nodeGettext, nodeFs, nodeFse, - nodeOs, nodePath, - nodeProcess, nodeChildProcess, nodeSSHexec, nodeRSync, - nodeUnzip) { + nodeAdmZip, + _package) { var currentAlert = null; var taskRunning = false; var toolchain = { apio: '-', installed: false, disabled: false }; this.toolchain = toolchain; - const buildPath = '_build'; // Check if the toolchain is installed checkToolchain(); - // Update toolchain information - updateToolchainInfo(); - - // Remove _build directory on start - nodeFse.removeSync(buildPath); + // Remove build directory on start + nodeFse.removeSync(utils.BUILD_DIR); this.verifyCode = function() { this.apio(['verify']); }; this.buildCode = function() { - this.apio(['build', '--board', boards.selectedBoard.name]); + this.apio(['build', '-b', common.selectedBoard.name]); }; this.uploadCode = function() { - this.apio(['upload', '--board', boards.selectedBoard.name]); + this.apio(['upload', '-b', common.selectedBoard.name]); }; this.apio = function(commands) { @@ -65,9 +61,8 @@ angular.module('icestudio') /// Start uploading ... gettext('start_upload'); var message = 'start_' + commands[0]; - currentAlert = alertify.notify(gettextCatalog.getString(message), 'message', 100000); + currentAlert = alertify.message(gettextCatalog.getString(message), 100000); $('body').addClass('waiting'); - nodeProcess.chdir(buildPath); check = this.syncResources(code); try { if (check) { @@ -92,52 +87,65 @@ angular.module('icestudio') } catch(e) { } - finally { - nodeProcess.chdir('..'); - } } else { - alertify.notify(gettextCatalog.getString('Toolchain not installed. Please, install the toolchain'), 'error', 30); + alertify.error(gettextCatalog.getString('Toolchain not installed. Please, install the toolchain'), 30); + taskRunning = false; } } + else { + taskRunning = false; + } }; function checkToolchain(callback) { var apio = utils.getApioExecutable(); toolchain.disabled = utils.toolchainDisabled; - nodeChildProcess.exec([ - 'cd', utils.SAMPLE_DIR, (process.platform === 'win32' ? '&' : ';'), - apio, 'clean'].join(' '), function(error/*, stdout, stderr*/) { - if (!toolchain.disabled) { - toolchain.installed = !error; + if (!toolchain.disabled) { + nodeChildProcess.exec([apio, '--version'].join(' '), function(error, stdout/*, stderr*/) { + if (error) { + toolchain.apio = ''; + toolchain.installed = false; if (callback) { - callback(toolchain.installed); + callback(); + } + } + else { + toolchain.apio = stdout.match(/apio,\sversion\s(.+)/i)[1]; + toolchain.installed = toolchain.apio >= _package.apio.min && + toolchain.apio < _package.apio.max; + if (toolchain.installed) { + nodeChildProcess.exec([apio, 'clean', '-p', utils.SAMPLE_DIR].join(' '), function(error/*, stdout, stderr*/) { + toolchain.installed = !error; + if (callback) { + callback(); + } + }); + } + else { + if (callback) { + callback(); + } } } }); - } - - function updateToolchainInfo() { - var apio = utils.getApioExecutable(); - nodeChildProcess.exec([apio, '--version'].join(' '), function(error, stdout/*, stderr*/) { - if (error) { - toolchain.apio = '-'; - } - else { - toolchain.apio = stdout.match(/apio,\sversion\s(.+)/i)[1]; - } - }); + } } this.generateCode = function() { - if (!nodeFs.existsSync(buildPath)) { - nodeFs.mkdirSync(buildPath); + if (!nodeFs.existsSync(utils.BUILD_DIR)) { + nodeFs.mkdirSync(utils.BUILD_DIR); } project.update(); - var verilog = compiler.generate('verilog', project.get()); - var pcf = compiler.generate('pcf', project.get()); - nodeFs.writeFileSync(nodePath.join(buildPath, 'main.v'), verilog, 'utf8'); - nodeFs.writeFileSync(nodePath.join(buildPath, 'main.pcf'), pcf, 'utf8'); + var opt = { boardRules: profile.get('boardRules') }; + if (opt.boardRules) { + opt.initPorts = compiler.getInitPorts(project.get()); + opt.initPins = compiler.getInitPins(project.get()); + } + var verilog = compiler.generate('verilog', project.get(), opt); + var pcf = compiler.generate('pcf', project.get(), opt); + nodeFs.writeFileSync(nodePath.join(utils.BUILD_DIR, 'main.v'), verilog, 'utf8'); + nodeFs.writeFileSync(nodePath.join(utils.BUILD_DIR, 'main.pcf'), pcf, 'utf8'); return verilog; }; @@ -163,13 +171,13 @@ angular.module('icestudio') var match; while (match = pattern.exec(code)) { var file = match[1]; - var destPath = nodePath.join('.', file); + var destPath = nodePath.join(utils.BUILD_DIR, file); var origPath = nodePath.join(utils.dirname(project.path), file); // Copy included file var copySuccess = utils.copySync(origPath, destPath); if (!copySuccess) { - alertify.notify(gettextCatalog.getString('File {{file}} does not exist', { file: file }), 'error', 30); + alertify.error(gettextCatalog.getString('File {{file}} does not exist', { file: file }), 30); ret = false; break; } @@ -179,13 +187,13 @@ angular.module('icestudio') }; function execute(commands, label, currentAlert, callback) { - var remoteHostname = profile.data.remoteHostname; + var remoteHostname = profile.get('remoteHostname'); if (remoteHostname) { currentAlert.setContent(gettextCatalog.getString('Synchronize remote files ...')); nodeRSync({ - src: nodeProcess.cwd() + '/', - dest: remoteHostname + ':' + buildPath + '/', + src: utils.BUILD_DIR + '/', + dest: remoteHostname + ':.build/', ssh: true, recursive: true, delete: true, @@ -194,7 +202,7 @@ angular.module('icestudio') }, function (error, stdout, stderr/*, cmd*/) { if (!error) { currentAlert.setContent(gettextCatalog.getString('Execute remote {{label}} ...', { label: label })); - nodeSSHexec('cd ' + buildPath + '; ' + (['apio'].concat(commands)).join(' '), remoteHostname, + nodeSSHexec((['apio'].concat(commands).concat(['-p', '.build'])).join(' '), remoteHostname, function (error, stdout, stderr) { processExecute(label, callback, error, stdout, stderr); }); @@ -207,9 +215,8 @@ angular.module('icestudio') else { var apio = utils.getApioExecutable(); toolchain.disabled = utils.toolchainDisabled; - nodeChildProcess.exec(([apio].concat(commands)).join(' '), { maxBuffer: 5000 * 1024 }, + nodeChildProcess.exec(([apio].concat(commands).concat(['-p', utils.coverPath(utils.BUILD_DIR)])).join(' '), { maxBuffer: 5000 * 1024 }, function(error, stdout, stderr) { - // console.log(error, stdout, stderr); processExecute(label, callback, error, stdout, stderr); }); } @@ -224,19 +231,19 @@ angular.module('icestudio') if (stdout) { if (stdout.indexOf('[upload] Error') !== -1 || stdout.indexOf('Error: board not detected') !== -1) { - alertify.notify(gettextCatalog.getString('Board {{name}} not detected', { name: utils.bold(boards.selectedBoard.info.label) }), 'error', 30); + alertify.error(gettextCatalog.getString('Board {{name}} not detected', { name: utils.bold(common.selectedBoard.info.label) }), 30); } else if (stdout.indexOf('Error: unkown board') !== -1) { - alertify.notify(gettextCatalog.getString('Unknown board'), 'error', 30); + alertify.error(gettextCatalog.getString('Unknown board'), 30); } else if (stdout.indexOf('set_io: too few arguments') !== -1) { - alertify.notify(gettextCatalog.getString('FPGA I/O ports not defined'), 'error', 30); + alertify.error(gettextCatalog.getString('FPGA I/O ports not defined'), 30); } else if (stdout.indexOf('error: unknown pin') !== -1) { - alertify.notify(gettextCatalog.getString('FPGA I/O ports not defined'), 'error', 30); + alertify.error(gettextCatalog.getString('FPGA I/O ports not defined'), 30); } else if (stdout.indexOf('error: duplicate pin constraints') !== -1) { - alertify.notify(gettextCatalog.getString('Duplicated FPGA I/O ports'), 'error', 30); + alertify.error(gettextCatalog.getString('Duplicated FPGA I/O ports'), 30); } else { var stdoutError = stdout.split('\n').filter(function (line) { @@ -248,23 +255,23 @@ angular.module('icestudio') line.indexOf('already declared') !== -1); }); if (stdoutError.length > 0) { - alertify.notify(stdoutError[0], 'error', 30); + alertify.error(stdoutError[0], 30); } else { - alertify.notify(stdout, 'error', 30); + alertify.error(stdout, 30); } } } else if (stderr) { if (stderr.indexOf('Could not resolve hostname') !== -1 || stderr.indexOf('Connection refused') !== -1) { - alertify.notify(gettextCatalog.getString('Wrong remote hostname {{name}}', { name: profile.data.remoteHostname }), 'error', 30); + alertify.error(gettextCatalog.getString('Wrong remote hostname {{name}}', { name: profile.get('remoteHostname') }), 30); } else if (stderr.indexOf('No route to host') !== -1) { - alertify.notify(gettextCatalog.getString('Remote host {{name}} not connected', { name: profile.data.remoteHostname }), 'error', 30); + alertify.error(gettextCatalog.getString('Remote host {{name}} not connected', { name: profile.get('remoteHostname') }), 30); } else { - alertify.notify(stderr, 'error', 30); + alertify.error(stderr, 30); } } } @@ -298,7 +305,7 @@ angular.module('icestudio') fpgaResources += (match && match.length > 0) ? match[0] + '\n' : ''; } if (fpgaResources) { - alertify.notify('
    ' + fpgaResources + '
    ', 'message', 5); + alertify.message('
    ' + fpgaResources + '
    ', 5); } } } @@ -307,8 +314,8 @@ angular.module('icestudio') } this.installToolchain = function() { + utils.removeToolchain(); if (utils.checkDefaultToolchain()) { - utils.removeToolchain(); installDefaultToolchain(); } else { @@ -343,6 +350,7 @@ angular.module('icestudio') alertify.confirm(gettextCatalog.getString('The toolchain will be removed. Do you want to continue?'), function() { utils.removeToolchain(); + toolchain.apio = ''; toolchain.installed = false; alertify.success(gettextCatalog.getString('Toolchain removed')); }); @@ -504,7 +512,7 @@ angular.module('icestudio') } function apioInstallDrivers(callback) { - if (nodeOs.platform().indexOf('win32') > -1) { + if (utils.WIN32) { updateProgress('apio install drivers', 80); utils.apioInstall('drivers', callback); } @@ -519,11 +527,10 @@ angular.module('icestudio') } function installationCompleted(callback) { - checkToolchain(function(installed) { - if (installed) { + checkToolchain(function() { + if (toolchain.installed) { updateProgress(gettextCatalog.getString('Installation completed'), 100); alertify.success(gettextCatalog.getString('Toolchain installed')); - updateToolchainInfo(); } else { errorProgress(gettextCatalog.getString('Toolchain not installed')); @@ -568,16 +575,101 @@ angular.module('icestudio') // Collections management - this.addCollection = function(filepath) { - var name = utils.basename(filepath); - nodeFs.createReadStream(filepath) - .pipe(nodeUnzip.Extract({ path: utils.COLLECTIONS_DIR })) - .on('close', function() { + this.addCollections = function(filepath) { + alertify.message(gettextCatalog.getString('Load {{name}} ...', { name: utils.bold(utils.basename(filepath) + '.zip') })); + + var collections = {}; + var zip = nodeAdmZip(filepath); + var zipEntries = zip.getEntries(); + + // Validate collections + zipEntries.forEach(function(zipEntry) { + var name = zipEntry.entryName.match(/^([^\/]+)\/$/); + if (name) { + collections[name[1]] = { + name: name[1], blocks: [], examples: [], locale: [], package: '' + }; + } + name = zipEntry.entryName.match(/^([^\/]+)\/blocks\/.*\.ice$/); + if (name) { + collections[name[1]].blocks.push(zipEntry.entryName); + } + name = zipEntry.entryName.match(/^([^\/]+)\/examples\/.*\.ice$/); + if (name) { + collections[name[1]].examples.push(zipEntry.entryName); + } + name = zipEntry.entryName.match(/^([^\/]+)\/locale\/.*\.po$/); + if (name) { + collections[name[1]].locale.push(zipEntry.entryName); + } + name = zipEntry.entryName.match(/^([^\/]+)\/package\.json$/); + if (name) { + collections[name[1]].package = zipEntry.entryName; + } + }); + async.eachSeries(collections, function(collection, next) { + setTimeout(function() { + if (collection.package && (collection.blocks || collection.examples)) { + var destPath = nodePath.join(utils.COLLECTIONS_DIR, collection.name); + if (nodeFs.existsSync(destPath)) { + alertify.confirm( + gettextCatalog.getString('The collection {{name}} already exists.', { name: utils.bold(collection.name) }) + '
    ' + + gettextCatalog.getString('Do you want to replace it?'), + function() { + utils.deleteFolderRecursive(destPath); + installCollection(collection, zip); + alertify.success(gettextCatalog.getString('Collection {{name}} replaced', { name: utils.bold(collection.name) })); + next(); + }, + function() { + alertify.warning(gettextCatalog.getString('Collection {{name}} not replaced', { name: utils.bold(collection.name) })); + next(); + }); + } + else { + installCollection(collection, zip); + alertify.success(gettextCatalog.getString('Collection {{name}} added', { name: utils.bold(collection.name) })); + next(); + } + } + else { + alertify.warning(gettextCatalog.getString('Invalid collection {{name}}', { name: utils.bold(collection.name) })); + } + }, 0); + }, function() { resources.loadCollections(); - alertify.success(gettextCatalog.getString('Collection file {{name}} added', { name: utils.bold(name) })); }); }; + function installCollection(collection, zip) { + for (var b in collection.blocks) { + safeExtract(collection.blocks[b], zip); + } + for (var e in collection.examples) { + safeExtract(collection.examples[e], zip); + } + for (var l in collection.locale) { + safeExtract(collection.locale[l], zip); + // Generate locale JSON files + var compiler = new nodeGettext.Compiler({ format: 'json' }); + var sourcePath = nodePath.join(utils.COLLECTIONS_DIR, collection.locale[l]); + var targetPath = nodePath.join(utils.COLLECTIONS_DIR, collection.locale[l].replace(/\.po$/, '.json')); + var content = nodeFs.readFileSync(sourcePath).toString(); + var json = compiler.convertPo([content]); + nodeFs.writeFileSync(targetPath, json); + // Add string to gettext + gettextCatalog.loadRemote(targetPath); + } + safeExtract(collection.package, zip); + } + + function safeExtract(entry, zip) { + try { + zip.extractEntryTo(entry, utils.COLLECTIONS_DIR); + } + catch(e) {} + } + this.removeCollection = function(collection) { utils.deleteFolderRecursive(collection.path); resources.loadCollections(); diff --git a/app/scripts/services/utils.service.js b/app/scripts/services/utils.js similarity index 71% rename from app/scripts/services/utils.service.js rename to app/scripts/services/utils.js index e08240df3..5eb98ab2e 100644 --- a/app/scripts/services/utils.service.js +++ b/app/scripts/services/utils.js @@ -1,14 +1,13 @@ - 'use strict'; angular.module('icestudio') .service('utils', function($rootScope, gettextCatalog, + common, _package, window, nodeFs, nodeFse, - nodeOs, nodePath, nodeChildProcess, nodeTarball, @@ -17,68 +16,69 @@ angular.module('icestudio') nodeOnline, nodeGlob, nodeSha1, + nodeCP, SVGO) { const WIN32 = Boolean(process.platform.indexOf('win32') > -1); + this.WIN32 = WIN32; const DARWIN = Boolean(process.platform.indexOf('darwin') > -1); + this.DARWIN = DARWIN; - const CACHE = '_cache'; - - const VENV = 'virtualenv-15.0.1'; - const VENV_DIR = nodePath.join(CACHE, VENV); - const VENV_TARGZ = nodePath.join('resources', 'virtualenv', VENV + '.tar.gz'); - + const LOCALE_DIR = nodePath.join('resources', 'locale'); const SAMPLE_DIR = nodePath.join('resources', 'sample'); this.SAMPLE_DIR = SAMPLE_DIR; - const LOCALE_DIR = nodePath.join('resources', 'locale'); + const BASE_DIR = process.env.HOME || process.env.USERPROFILE; + const ICESTUDIO_DIR = safeDir(nodePath.join(BASE_DIR, '.icestudio')); + this.ICESTUDIO_DIR = ICESTUDIO_DIR; + const COLLECTIONS_DIR = nodePath.join(ICESTUDIO_DIR, 'collections'); + this.COLLECTIONS_DIR = COLLECTIONS_DIR; + const APIO_HOME_DIR = nodePath.join(ICESTUDIO_DIR, 'apio'); + const PROFILE_PATH = nodePath.join(ICESTUDIO_DIR, 'profile.json'); + this.PROFILE_PATH = PROFILE_PATH; + const CACHE_DIR = nodePath.join(ICESTUDIO_DIR, '.cache'); + const BUILD_DIR = nodePath.join(ICESTUDIO_DIR, '.build'); + this.BUILD_DIR = BUILD_DIR; + + const VENV = 'virtualenv-15.0.1'; + const VENV_DIR = nodePath.join(CACHE_DIR, VENV); + const VENV_TARGZ = nodePath.join('resources', 'virtualenv', VENV + '.tar.gz'); const APP_DIR = nodePath.dirname(process.execPath); const TOOLCHAIN_DIR = nodePath.join(APP_DIR, 'toolchain'); this.TOOLCHAIN_DIR = TOOLCHAIN_DIR; const DEFAULT_APIO = 'default-apio'; - const DEFAULT_APIO_DIR = nodePath.join(CACHE, DEFAULT_APIO); + const DEFAULT_APIO_DIR = nodePath.join(CACHE_DIR, DEFAULT_APIO); const DEFAULT_APIO_TARGZ = nodePath.join(TOOLCHAIN_DIR, DEFAULT_APIO + '.tar.gz'); const DEFAULT_APIO_PACKAGES = 'default-apio-packages'; const DEFAULT_APIO_PACKAGES_TARGZ = nodePath.join(TOOLCHAIN_DIR, DEFAULT_APIO_PACKAGES + '.tar.gz'); - const BASE_DIR = process.env.HOME || process.env.USERPROFILE; - const ICESTUDIO_DIR = nodePath.join(BASE_DIR, '.icestudio'); - this.ICESTUDIO_DIR = ICESTUDIO_DIR; - const COLLECTIONS_DIR = nodePath.join(ICESTUDIO_DIR, 'collections'); - this.COLLECTIONS_DIR = COLLECTIONS_DIR; - const APIO_HOME_DIR = nodePath.join(ICESTUDIO_DIR, 'apio'); - const PROFILE_PATH = nodePath.join(ICESTUDIO_DIR, 'profile.json'); - this.PROFILE_PATH = PROFILE_PATH; - - const ENV_DIR = _getEnvDir(nodePath.join(ICESTUDIO_DIR, 'venv')); + const ENV_DIR = nodePath.join(ICESTUDIO_DIR, 'venv'); const ENV_BIN_DIR = nodePath.join(ENV_DIR, WIN32 ? 'Scripts' : 'bin'); const ENV_PIP = nodePath.join(ENV_BIN_DIR, 'pip'); const ENV_APIO = nodePath.join(ENV_BIN_DIR, WIN32 ? 'apio.exe' : 'apio'); - const APIO_CMD = (WIN32 ? 'set' : 'export') + ' APIO_HOME_DIR=' + APIO_HOME_DIR + (WIN32 ? '& ' : '; ') + ENV_APIO; + const APIO_CMD = (WIN32 ? 'set' : 'export') + ' APIO_HOME_DIR=' + APIO_HOME_DIR + (WIN32 ? '& ' : '; ') + coverPath(ENV_APIO); const SYSTEM_APIO = '/usr/bin/apio'; - function _getEnvDir(defaultEnvDir) { + function safeDir(_dir) { if (WIN32) { // Put the env directory to the root of the current local disk when // default path contains non-ASCII characters. Virtualenv will fail to - for (var i in defaultEnvDir) { - var char = defaultEnvDir[i]; - if (char.charCodeAt(0) > 127) { - var defaultEnvDirFormat = nodeOs.parse(defaultEnvDir); - return nodeOs.format({ - root: defaultEnvDirFormat.root, - dir: defaultEnvDirFormat.root, - base: '.icestudiovenv', - name: '.icestudiovenv', + for (var i in _dir) { + if (_dir[i].charCodeAt(0) > 127) { + const _dirFormat = nodePath.parse(_dir); + return nodePath.format({ + root: _dirFormat.root, + dir: _dirFormat.root, + base: '.icestudio', + name: '.icestudio', }); } } } - - return defaultEnvDir; + return _dir; } var _pythonExecutableCached = null; @@ -129,7 +129,7 @@ angular.module('icestudio') }; this.extractVirtualEnv = function(callback) { - this.extractTargz(VENV_TARGZ, CACHE, callback); + this.extractTargz(VENV_TARGZ, CACHE_DIR, callback); }; function disableClick(e) { @@ -178,7 +178,9 @@ angular.module('icestudio') if (!nodeFs.existsSync(ENV_DIR)) { nodeFs.mkdirSync(ENV_DIR); this.executeCommand( - [this.getPythonExecutable(), nodePath.join(VENV_DIR, 'virtualenv.py'), ENV_DIR], callback); + [this.getPythonExecutable(), + coverPath(nodePath.join(VENV_DIR, 'virtualenv.py')), + coverPath(ENV_DIR)], callback); } else { callback(); @@ -203,7 +205,8 @@ angular.module('icestudio') var self = this; nodeGlob(nodePath.join(DEFAULT_APIO_DIR, '*.*'), {}, function (error, files) { if (!error) { - self.executeCommand([ENV_PIP, 'install', '-U', '--no-deps'].concat(files), callback); + files = files.map(function(item) { return coverPath(item); }); + self.executeCommand([coverPath(ENV_PIP), 'install', '-U', '--no-deps'].concat(files), callback); } }); }; @@ -227,7 +230,7 @@ angular.module('icestudio') }; this.installOnlineApio = function(callback) { - this.executeCommand([ENV_PIP, 'install', '-U', 'apio">=' + _package.apio.min + ',<' + _package.apio.max + '"'], callback); + this.executeCommand([coverPath(ENV_PIP), 'install', '-U', 'apio">=' + _package.apio.min + ',<' + _package.apio.max + '"'], callback); }; this.apioInstall = function(_package, callback) { @@ -241,10 +244,10 @@ angular.module('icestudio') if (nodeFs.existsSync(candidateApio)) { if (!this.toolchainDisabled) { // Show message only on start - alertify.notify('Using system wide apio', 'message', 5); + alertify.message('Using system wide apio', 5); } this.toolchainDisabled = true; - return candidateApio; + return coverPath(candidateApio); } this.toolchainDisabled = false; return APIO_CMD; @@ -252,6 +255,7 @@ angular.module('icestudio') this.removeToolchain = function() { deleteFolderRecursive(ENV_DIR); + deleteFolderRecursive(CACHE_DIR); deleteFolderRecursive(APIO_HOME_DIR); }; @@ -368,29 +372,29 @@ angular.module('icestudio') this.getFilesRecursive = getFilesRecursive; - function getFilesRecursive(folder, extension) { + function getFilesRecursive(folder) { var fileTree = []; + var validator = /.*\.(ice|json)$/; + if (nodeFs.existsSync(folder)) { var fileContents = nodeFs.readdirSync(folder); var stats; - fileContents.forEach(function (fileName) { - var filePath = nodePath.join(folder, fileName); - stats = nodeFs.lstatSync(filePath); + fileContents.forEach(function (name) { + var path = nodePath.join(folder, name); + stats = nodeFs.lstatSync(path); if (stats.isDirectory()) { fileTree.push({ - name: fileName, - path: filePath, - children: getFilesRecursive(filePath, extension) + name: name, + path: path, + children: getFilesRecursive(path, validator) + }); + } else if (validator.test(name)) { + fileTree.push({ + name: basename(name), + path: path }); - } else { - if (fileName.endsWith(extension)) { - fileTree.push({ - name: basename(fileName), - path: filePath - }); - } } }); } @@ -449,7 +453,7 @@ angular.module('icestudio') alertify.warning(gettextCatalog.getString('Drivers disabled')); } setTimeout(function() { - alertify.notify(gettextCatalog.getString('Unplug and reconnect the board'), 'message', 5); + alertify.message(gettextCatalog.getString('Unplug and reconnect the board'), 5); }, 1000); } }); @@ -484,14 +488,14 @@ angular.module('icestudio') if (error) { if ((stderr.indexOf('brew: command not found') !== -1) || (stderr.indexOf('brew: No such file or directory') !== -1)) { - alertify.notify(gettextCatalog.getString('Homebrew is required'), 'error', 30); + alertify.error(gettextCatalog.getString('Homebrew is required'), 30); // TODO: open web browser with Homebrew website on click } else if (stderr.indexOf('Error: Failed to download') !== -1) { - alertify.notify(gettextCatalog.getString('Internet connection required'), 'error', 30); + alertify.error(gettextCatalog.getString('Internet connection required'), 30); } else { - alertify.notify(stderr, 'error', 30); + alertify.error(stderr, 30); } } else { @@ -522,14 +526,14 @@ angular.module('icestudio') function enableWindowsDrivers() { alertify.confirm(gettextCatalog.getString('

    FTDI driver installation instructions

    1. Connect the FPGA board
    2. Replace the (Interface 0) driver of the board by libusbK
    3. Unplug and reconnect the board
    '), function() { beginLazyProcess(); - nodeChildProcess.exec([APIO_CMD, 'drivers', '--enable'].join(' '), function(error, stdout, stderr) { + nodeSudo.exec([APIO_CMD, 'drivers', '--enable'].join(' '), {name: 'Icestudio'}, function(error, stdout, stderr) { // console.log(error, stdout, stderr); endLazyProcess(); if (stderr) { - alertify.notify(gettextCatalog.getString('Toolchain not installed. Please, install the toolchain'), 'error', 30); + alertify.error(gettextCatalog.getString('Toolchain not installed. Please, install the toolchain'), 30); } if (!error) { - alertify.notify(gettextCatalog.getString('Unplug and reconnect the board'), 'message', 5); + alertify.message(gettextCatalog.getString('Unplug and reconnect the board'), 5); } }); }); @@ -542,7 +546,7 @@ angular.module('icestudio') // console.log(error, stdout, stderr); endLazyProcess(); if (stderr) { - alertify.notify(gettextCatalog.getString('Toolchain not installed. Please, install the toolchain'), 'error', 30); + alertify.error(gettextCatalog.getString('Toolchain not installed. Please, install the toolchain'), 30); } }); }); @@ -558,7 +562,7 @@ angular.module('icestudio') angular.element('#menu').removeClass('disable-menu'); } - this.setLocale = function(locale) { + this.setLocale = function(locale, collections) { // Update current locale format locale = splitLocale(locale); // Load supported languages @@ -566,7 +570,17 @@ angular.module('icestudio') // Set the best matching language var bestLang = bestLocale(locale, supported); gettextCatalog.setCurrentLanguage(bestLang); + // Application strings gettextCatalog.loadRemote(nodePath.join(LOCALE_DIR, bestLang, bestLang + '.json')); + // Collections strings + for (var c in collections) { + var collection = collections[c]; + var filepath = nodePath.join(collection.path, 'locale', bestLang, bestLang + '.json'); + if (nodeFs.existsSync(filepath)) { + gettextCatalog.loadRemote(filepath); + } + } + // COLLECTIONS_DIR return bestLang; }; @@ -652,17 +666,45 @@ angular.module('icestudio') content.push('

    ' + messages[0] + '

    '); content.push(' '); content.push('
    '); - content.push('
    '); + content.push('
    '); content.push(''); // Restore values $('#label').val(values[0]); - $('#local').prop('checked', values[1]); + $('#check').prop('checked', values[1]); alertify.confirm(content.join('\n')) .set('onok', function(evt) { var values = []; values.push($('#label').val()); - values.push($('#local').prop('checked')); + values.push($('#check').prop('checked')); + if (callback) { + callback(evt, values); + } + }) + .set('oncancel', function(/*evt*/) { + }); + }; + + this.inputcheckbox2prompt = function(messages, values, callback) { + var content = []; + content.push('
    '); + content.push('

    ' + messages[0] + '

    '); + content.push(' '); + content.push('
    '); + content.push('
    '); + content.push('
    '); + content.push('
    '); + // Restore values + $('#label').val(values[0]); + $('#check1').prop('checked', values[1]); + $('#check2').prop('checked', values[2]); + + alertify.confirm(content.join('\n')) + .set('onok', function(evt) { + var values = []; + values.push($('#label').val()); + values.push($('#check1').prop('checked')); + values.push($('#check2').prop('checked')); if (callback) { callback(evt, values); } @@ -810,7 +852,7 @@ angular.module('icestudio') } } catch (e) { - alertify.notify(gettextCatalog.getString('Error: {{error}}', { error: e.toString() }), 'error', 30); + alertify.error(gettextCatalog.getString('Error: {{error}}', { error: e.toString() }), 30); ret = false; } return ret; @@ -882,7 +924,7 @@ angular.module('icestudio') this.parsePortLabel = function(data) { // e.g: name[x:y] var match, ret = {}; - var pattern = /([A-Za-z_]+[A-Za-z_0-9]*){0,1}(\[([0-9]+):([0-9]+)\]){0,1}/g; + var pattern = /([A-Za-z_]+[A-Za-z_0-9]*)?(\[([0-9]+):([0-9]+)\])?/g; match = pattern.exec(data); if (match && (match[0] === match.input)) { ret.name = match[1] ? match[1] : ''; @@ -903,7 +945,7 @@ angular.module('icestudio') this.parseParamLabel = function(data) { // e.g: name var match, ret = {}; - var pattern = /([A-Za-z_]+[A-Za-z_0-9]*){0,1}/g; + var pattern = /([A-Za-z_]+[A-Za-z_0-9]*)?/g; match = pattern.exec(data); if (match && (match[0] === match.input)) { ret.name = match[1] ? match[1] : ''; @@ -923,14 +965,14 @@ angular.module('icestudio') } }; - this.newWindow = function(filepath) { + this.newWindow = function(filepath, local) { var execPath = process.execPath; - var command = [ '"' + execPath + '"' ]; + var command = [ coverPath(execPath) ]; if (execPath.endsWith('nw') || execPath.endsWith('nw.exe') || execPath.endsWith('nwjs Helper')) { - command.push('"' + nodePath.dirname(process.mainModule.filename) + '"'); + command.push(coverPath(nodePath.dirname(process.mainModule.filename))); } if (filepath) { - command.push('"' + filepath + '"'); + command.push(coverPath(filepath)); } /*var win = window.get(); var position = { @@ -938,6 +980,9 @@ angular.module('icestudio') y: win.y + 30 }; command.push(position.x + 'x' + position.y);*/ + if (local) { + command.push('local'); + } nodeChildProcess.exec(command.join(' '), [], function(error/*, stdout/*, stderr*/) { if (error) { throw error; @@ -945,4 +990,174 @@ angular.module('icestudio') }); }; + this.coverPath = coverPath; + function coverPath(filepath) { + return '"' + filepath + '"'; + } + + this.mergeDependencies = function(type, block) { + if (type in common.allDependencies) { + return; // If the block is already in dependencies + } + // Merge the block dependencies + var deps = block.dependencies; + for (var i in deps) { + var depType = this.dependencyID(deps[i]); + if (!(depType in common.allDependencies)) { + common.allDependencies[depType] = deps[i]; + } + } + // Add the block as a dependency + delete block.dependencies; + common.allDependencies[type] = block; + }; + + this.copyToClipboard = function(selection, graph) { + var cells = selectionToCells(selection, graph); + var clipboard = { + icestudio: this.cellsToProject(cells, graph) + }; + // Send the clipboard object the global clipboard as a string + nodeCP.copy(JSON.stringify(clipboard), function() { + // Success + }); + }; + + this.pasteFromClipboard = function(callback) { + nodeCP.paste(function(a, text) { + try { + // Parse the global clipboard + var clipboard = JSON.parse(text); + if (callback && clipboard && clipboard.icestudio) { + callback(clipboard.icestudio); + } + } + catch (e) { } + }); + }; + + function selectionToCells(selection, graph) { + var cells = []; + var blocksMap = {}; + selection.each(function(block) { + // Add block + cells.push(block.attributes); + // Map blocks + blocksMap[block.id] = block; + // Add connected wires + var processedWires = {}; + var connectedWires = graph.getConnectedLinks(block); + _.each(connectedWires, function(wire) { + + if (processedWires[wire.id]) { + return; + } + + var source = blocksMap[wire.get('source').id]; + var target = blocksMap[wire.get('target').id]; + + if (source && target) { + cells.push(wire.attributes); + processedWires[wire.id] = true; + } + }); + }); + return cells; + } + + this.cellsToProject = function(cells, opt) { + // Convert a list of cells into the following sections of a project: + // - design.graph + // - dependencies + + var blocks = []; + var wires = []; + var p = { + version: common.VERSION, + design: {}, + dependencies: {} + }; + + opt = opt || {}; + + for (var c = 0; c < cells.length; c++) { + var cell = cells[c]; + + if (cell.type === 'ice.Generic' || + cell.type === 'ice.Input' || + cell.type === 'ice.Output' || + cell.type === 'ice.Code' || + cell.type === 'ice.Info' || + cell.type === 'ice.Constant') { + var block = {}; + block.id = cell.id; + block.type = cell.blockType; + block.data = cell.data; + block.position = cell.position; + if (cell.type === 'ice.Generic' || + cell.type === 'ice.Code' || + cell.type === 'ice.Info') { + block.size = cell.size; + } + blocks.push(block); + } + else if (cell.type === 'ice.Wire') { + var wire = {}; + wire.source = { block: cell.source.id, port: cell.source.port }; + wire.target = { block: cell.target.id, port: cell.target.port }; + wire.vertices = cell.vertices; + wire.size = (cell.size > 1) ? cell.size : undefined; + wires.push(wire); + } + } + + p.design.board = common.selectedBoard.name; + p.design.graph = { blocks: blocks, wires: wires }; + + // Update dependencies + if (opt.deps !== false) { + var types = this.findSubDependencies(p, common.allDependencies); + for (var t in types) { + p.dependencies[types[t]] = common.allDependencies[types[t]]; + } + } + + return p; + }; + + this.findSubDependencies = function(dependency) { + var subDependencies = []; + if (dependency) { + var blocks = dependency.design.graph.blocks; + for (var i in blocks) { + var type = blocks[i].type; + if (type.indexOf('basic.') === -1) { + subDependencies.push(type); + var newSubDependencies = this.findSubDependencies(common.allDependencies[type]); + subDependencies = subDependencies.concat(newSubDependencies); + } + } + return _.unique(subDependencies); + } + return subDependencies; + }; + + this.hasInputRule = function(port) { + var _default; + var rules = common.selectedBoard.rules; + if (rules) { + var allInitPorts = rules.input; + if (allInitPorts) { + for (var i in allInitPorts) { + if (port === allInitPorts[i].port){ + _default = allInitPorts[i]; + _default.apply = true; + break; + } + } + } + } + return _.clone(_default); + }; + }); diff --git a/app/styles/design.css b/app/styles/design.css index 0751fe757..004b23cac 100644 --- a/app/styles/design.css +++ b/app/styles/design.css @@ -42,28 +42,44 @@ right: 15px; } -#read-only { - font-family: Courier New; +#banner { + position: relative; +} + +#info { + position: absolute; + top: -10px; + left: 15px; font-size: 15px; - color: #EB2222; + color: #656565; background-color: white; border-radius: 5px; cursor: default; + z-index: 1501; +} + +#read-only { position: absolute; - right: 30px; + top: -10px; + right: 15px; + font-size: 14px; + color: #f05c5c; + background-color: white; + border-radius: 5px; + cursor: default; z-index: 1501; } #back-button { - font-family: Courier New; - font-size: 15px; + position: absolute; + top: 20px; + right: 15px; + font-size: 14px; + color: #63afcf; background-color: white; border-radius: 5px; cursor: pointer; text-decoration: none; - position: absolute; - top: 100px; - right: 30px; z-index: 1501; } @@ -75,19 +91,27 @@ position: absolute; background: #C0DFEB; border-radius: 5px; - border: 2px solid #888; + border: 1px solid #777; pointer-events: none; -webkit-user-select: none; user-select: none; z-index: 0; } +.generic-block .clock { + position: absolute; + top: 3px; + left: -1px; + font-size: 18px; + color: #777; +} + .generic-block .tooltiptext { visibility: hidden; width: 120px; color: #333; background-color: white; - border: 1px solid #888; + border: 1px solid #777; text-align: center; border-radius: 5px; padding: 5px 5px; @@ -106,7 +130,7 @@ margin-left: -6px; border-width: 6px; border-style: solid; - border-color: #888 transparent transparent transparent; + border-color: #777 transparent transparent transparent; } .generic-block .tooltip-large { @@ -118,14 +142,18 @@ background: #fafacd; } -.generic-block img { +.generic-block .img-container { position: absolute; margin: auto; - top: 0; - left: 0; - right: 0; - bottom: 0; - width: 80%; + top: 8px; + left: 8px; + right: 8px; + bottom: 8px; +} + +.generic-block img { + width: 100%; + height: 100%; } .generic-block label { @@ -133,7 +161,7 @@ margin-top: 20px; text-align: center; font-size: 14px; - color: #444; + color: #333; text-overflow: ellipsis; overflow: hidden; } @@ -142,19 +170,29 @@ position: absolute; background: #E2FBC9; border-radius: 5px; - border: 2px solid #888; + border: 1px solid #777; pointer-events: none; -webkit-user-select: none; user-select: none; z-index: 0; } +.virtual-port p { + position: absolute; + top: 0; + right: 5px; + font-size: 13px; + color: #555; +} + .virtual-port label { display: block; - margin-top: 20px; + margin-top: 22px; text-align: center; - font-size: 0.9em; - color: #444; + font-size: 14px; + font-weight: normal; + height: 18px; + color: #222; text-overflow: ellipsis; overflow: hidden; } @@ -163,20 +201,30 @@ position: absolute; background: #FBFBC9; border-radius: 5px; - border: 2px solid #888; + border: 1px solid #777; pointer-events: none; -webkit-user-select: none; user-select: none; z-index: 0; } +.fpga-port p { + position: absolute; + top: 0; + right: 5px; + font-size: 13px; + color: #555; +} + .fpga-port label { display: block; - margin-top: 4px; - margin-bottom: 5px; + margin-top: 5px; + margin-bottom: 7px; text-align: center; - font-size: 13px; - color: #444; + font-size: 14px; + font-weight: normal; + height: 18px; + color: #222; text-overflow: ellipsis; overflow: hidden; } @@ -190,26 +238,49 @@ .fpga-port div .select2 { position: relative; - width: 82px; + width: 84px; left: 5px; - margin-bottom: 4px; + margin-bottom: 6px; pointer-events: auto; } -.select2-selection__rendered { +.select2-selection { font-size: 13px; + height: 26px !important; +} + +.select2-selection__rendered { + line-height: 24px !important; +} + +.select2-selection__clear { + color: #777; +} + +.select2-container--default .select2-selection--single { + outline: none; + border: 1px solid #aaa; +} + +.select2-dropdown { +} + +.select2-dropdown .select2-search__field { + outline: none; + border-radius: 3px; + border: 1px solid #777; } .bigdrop { - width: 92px !important; font-size: 13px; + width: 92px !important; } .constant-block { position: absolute; background: #FBF0C9; border-radius: 5px; - border: 2px solid #888; + border: 1px solid #777; pointer-events: none; -webkit-user-select: none; user-select: none; @@ -220,16 +291,19 @@ position: absolute; top: 0; right: 5px; - font-size: 1.5em; - color: #444; + font-size: 12px; + color: #555; } .constant-block label { display: block; - margin-top: 8px; + margin-top: 5px; + margin-bottom: 7px; text-align: center; - font-size: 13px; - color: #444; + font-size: 14px; + font-weight: normal; + height: 18px; + color: #222; text-overflow: ellipsis; overflow: hidden; } @@ -238,17 +312,24 @@ position: absolute; text-align: center; left: 5px; - bottom: 5px; - width: 82px; + margin-bottom: 6px; + width: 84px; + height: 26px; font-size: 13px; + border-radius: 4px; + border: 1px solid #aaa; pointer-events: auto; } +.constant-block input:focus { + outline: none; +} + .code-block { position: absolute; background: #C0DFEB; border-radius: 5px; - border: 2px solid #888; + border: 1px solid #777; pointer-events: none; -webkit-user-select: none; user-select: none; @@ -257,13 +338,10 @@ .code-block .code-editor { position: absolute; - margin: auto; - top: 0; - left: 0; - right: 0; - bottom: 0; - width: 95%; - height: 93%; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; border-radius: 5px; border: 1px solid #BBB; pointer-events: auto; @@ -273,7 +351,7 @@ position: absolute; background: #DDD; border-radius: 5px; - border: 2px solid #888; + border: 1px solid #777; pointer-events: none; -webkit-user-select: none; user-select: none; @@ -282,24 +360,40 @@ .info-block .info-editor { position: absolute; - margin: auto; - top: 0; - left: 0; - right: 0; - bottom: 0; - width: 95%; - height: 93%; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; border-radius: 5px; border: 1px solid #BBB; pointer-events: auto; } .port-body:hover { - fill: yellow; } -.highlight { - box-shadow: 0 0 30px 0 rgba(200,200,200,1); +.joint-highlight-stroke.joint-theme-default { + display: none; +} + +.highlight-yellow { + box-shadow: 0 0 8px 8px rgba(248, 248, 160, 0.5); +} + +.highlight-green { + box-shadow: 0 0 8px 8px rgba(217, 250, 184, 0.5); +} + +.highlight-orange { + box-shadow: 0 0 8px 8px rgba(250, 235, 184, 0.5); +} + +.highlight-blue { + box-shadow: 0 0 8px 8px rgba(216, 235, 243, 0.5); +} + +.highlight-gray { + box-shadow: 0 0 8px 8px rgba(221, 221, 221, 0.5); } .selectionarea { @@ -333,45 +427,56 @@ /* Wires makers */ .joint-link.joint-theme-default .connection-wrap { - stroke: #000000; - stroke-width: 15; - stroke-linecap: butt; - stroke-linejoin: butt; - opacity: 0; - cursor: pointer; + stroke: #000000; + stroke-width: 15; + stroke-linecap: butt; + stroke-linejoin: butt; + opacity: 0; + cursor: pointer; } .joint-link.joint-theme-default .connection-wrap:hover { - opacity: .4; - stroke-opacity: .4; + opacity: .4; + stroke-opacity: .4; } .joint-link.joint-theme-default .connection { - stroke-linejoin: butt; + stroke-linejoin: butt; } .joint-link.joint-theme-default .link-tools .tool-remove circle { - fill: #EB2222; + fill: #EB2222; } .joint-link.joint-theme-default .link-tools .tool-remove path { - fill: #FFFFFF; + fill: #FFFFFF; } /* element inside .marker-vertex-group element */ .joint-link.joint-theme-default .marker-vertex { - fill: #64b0ce; + fill: #64b0ce; } .joint-link.joint-theme-default .marker-vertex:hover { - fill: #317d9b; - stroke: none; + fill: #317d9b; + stroke: none; } .joint-link.joint-theme-default .marker-arrowhead { - fill: #64b0ce; + fill: #64b0ce; } .joint-link.joint-theme-default .marker-arrowhead:hover { - fill: #317d9b; - stroke: none; + fill: #317d9b; + stroke: none; } /* element used to remove a vertex */ .joint-link.joint-theme-default .marker-vertex-remove { - fill: #FFFFFF; + fill: #FFFFFF; + +} +/* Resizer */ + +.resizer { + position: absolute; + pointer-events: auto; + bottom: -5px; + right: -5px; + width: 20px; + height: 20px; } diff --git a/app/styles/menu.css b/app/styles/menu.css index 429e6addf..3d6653854 100644 --- a/app/styles/menu.css +++ b/app/styles/menu.css @@ -1,10 +1,10 @@ .disable-menu { pointer-events: none; - opacity: 0.7; + opacity: 0.8; } .disable-paper { - opacity: 0.7; + opacity: 0.8; } .navbar { diff --git a/app/views/design.html b/app/views/design.html index a065467ba..a6e57a95c 100644 --- a/app/views/design.html +++ b/app/views/design.html @@ -1,6 +1,7 @@
    @@ -12,6 +13,6 @@ {{ item.name }} -
    {{ boards.selectedBoard.info.label }}
    +
    {{ common.selectedBoard.info.label }}
    diff --git a/app/views/menu.html b/app/views/menu.html index dd448c97b..7e9650f1a 100644 --- a/app/views/menu.html +++ b/app/views/menu.html @@ -26,38 +26,28 @@ {{ 'File' | translate }} @@ -88,30 +78,30 @@ {{ 'Edit' | translate }} @@ -180,17 +188,36 @@
  • {{ 'Datasheet' | translate }}
  • -
  • +
  • + {{ 'Board rules' | translate }} +
  • + + + +
  • + {{ 'Select' | translate }} +
      + -
    • - {{ 'Boards' | translate }} - -
    • -
    • {{ 'Tools' | translate }} @@ -271,15 +286,15 @@ {{ 'Collections' | translate }}
      • - + {{ 'Add' | translate }}