REBOL [ Title: "WPT viewer" Purpose: "Live Waypoints" Date: 2006-07-08 Version: 0.1.2 Author: "Piotr Gapinski" Email: {news [at] rowery! olsztyn.pl} File: %wpt.r Url: http://www.rowery.olsztyn.pl/wspolpraca/rebol/rss/ Copyright: "Olsztynska Strona Rowerowa http://www.rowery.olsztyn.pl" License: "GNU General Public License (Version II)" Library: [ level: 'intermediate platform: 'all type: [tool] domain: [web] tested-under: [ view 1.3.1 on [Linux] view 1.3.2 on [Linux WinXP] ] support: none license: 'GPL ] ] if system/version < 1.3.1 [to error! "WPT viewer requires Rebol/View 1.3.1 or greater"] if error? err: try [ ctx-wpts: context [ wpts: copy [] sort-waypoints: func [ "sortuje waypointy po nazwie - narastajaco" a [block!] b [block!]] [ (form a/name) < (form b/name) ] set 'wpts-gen-html func [ "zapis waypointow do html" file [string! file!] "nazwa pliku pod ktora zostana zapisane dane" /local ] [ lines: copy {} num: 0 foreach wpt self/wpts [ attempt [ num: minimum (num + 1) 1000 name: join "wpt" num url: make-url wpt/latitude wpt/longitude wpt/name dat: reform [
  • name {::} {} wpt/name
  • CRLF] append lines dat ] ] insert lines reform [ CRLF CRLF "Live Waypoints" CRLF CRLF CRLF CRLF CRLF CRLF

    "Waypointy" (form second split-path file)

    CRLF CRLF "plik html wygenerowany:" now CRLF CRLF CRLF ] write/direct (to-file file) lines ] not-valid-altitude: -777 ; znacznik braku wysokosci dla OZI-explorer to-meters: func [feet [number!]] [either (feet = not-valid-altitude) [feet] [feet / 3.28083931316019]] to-feet: func [meters [number!]] [either (meters = not-valid-altitude) [meters] [meters * 3.28083931316019]] wpts-load-ozi: func [ "wczytuje waypointy w formacie OZI-WPT" file "nazwa pliku do wczytania" /local dat wpt] [ if not dat: attempt [read/lines to-file file] [return none] dat: skip dat 4 foreach line dat [ attempt [ wpt: parse/all line "," repend/only wpts [ 'name trim form wpt/11 ;; wpt/2 'latitude to-decimal trim form wpt/3 'longitude to-decimal trim form wpt/4 'altitude (to-meters to-decimal trim form wpt/15) 'description wpt/2 ] ] ] sort/compare wpts :sort-waypoints ;; zablokuj zapis do formatu OZI (grozi nadpisaniem pliku WPT) disable gui-ozi-button wpts ] set 'wpts-gen-ozi func [ "zapis waypointow do pliku WPT w formacie OZI" file [string! file!] "nazwa pliku pod ktora beda zapisane dane" /local lines num name latitude longitude altitude description datetime dat] [ lines: copy {} num: 0 foreach wpt self/wpts [ attempt [ num: minimum (num + 1) 1000 name: join "wpt" num latitude: wpt/latitude longitude: wpt/longitude altitude: either empty? form wpt/altitude [not-valid-altitude] [to-feet wpt/altitude] description: trim/lines replace (copy/part reform [wpt/name] 40) "," " " dat: rejoin [ num "," ; Number - this is the location in the array (max 1000), must be unique name "," ; Name - the waypoint name, use the correct length name to suit the GPS type latitude "," ; Latitude - decimal degrees longitude "," ; Longitude - decimal degrees "," ; Date - if blank a preset date will be used "70," ; Symbol - 0 to number of symbols in GPS "1," ; Status - always set to 1 "6," ; Map Display Format "0," ; Foreground Color (RGB value) "13158342," ; Background Color (RGB value) description "," ; Description (max 40), no commas "2," ; Pointer Direction "0," ; Garmin Display Format "0," ; Proximity Distance - 0 is off any other number is valid altitude "," ; Altitude - in feet (-777 if not valid) "8.25," ; Font Size - in points "0," ; Font Style - 0 is normal, 1 is bold "17" CRLF ; Symbol Size - 17 is normal size ] append lines dat ] ] insert lines join {OziExplorer Waypoint File Version 1.1} [CRLF "WGS 84" CRLF "Reserved 2" CRLF "garmin" CRLF] write/direct (to-file file) lines ] wpts-load-grm: func [ "wczytuje waypointy w formacie garmin-protocol" file "nazwa pliku do wczytania" /local line dat wpt] [ if not dat: attempt [read/lines to-file file] [return none] foreach line dat [ attempt [ wpt: load line repend/only wpts [ ; jezeli w 4ej kolumnie nie ma liczby to traktuj ja jako opis waypointa 'name wpt/1 'latitude to-decimal trim form wpt/2 'longitude to-decimal trim form wpt/3 'altitude (any [attempt [to-decimal trim form wpt/4] ""]) 'description (either not attempt [to-decimal wpt/4] [attempt [wpt/4]] [attempt [wpt/5]]) ] ] ] sort/compare wpts :sort-waypoints wpts ] set 'wpts-load func [file [string! file!]] [ f: any [ ; decyzja w jakim formacie sa dane select [".wpt" 'wpts-load-ozi ".txt" 'wpts-load-grm] form suffix? to-file file 'wpts-load-grm ] do f file ] set 'wpts-list has [list] [ ; zwraca liste nazw waypointow list: copy [] foreach wpt wpts [append list wpt/name] return list ] ] ctx-charset: context [ standards: [ ; tabela standardow zamiany 18 polskich znakow (duze/male) win-pl [165 198 202 163 209 211 140 143 175 185 230 234 179 241 243 156 159 191] ;; "windows-1250" iso-pl [161 198 202 163 209 211 166 172 175 177 230 234 179 241 243 182 188 191] ;; "iso-8859-2" ami-pl [194 202 203 206 207 211 212 218 219 226 234 235 238 239 243 244 250 251] ;; "Amiga PL" ascii [065 067 069 076 078 079 083 090 090 097 099 101 108 110 111 115 122 122] ;; "ASCII" ] set 'to-ascii func [ "Zmienia standard polskich znaków na ascii; Zwraca string! po konwersji" str [string!] "tekst do konwersji" /from data "wymus standard wejsciowy" /local std] [ std: either all [value? 'from from] [select standards data] [select standards (either linux? ['iso-pl] ['win-pl])] iconv str std (standards/ascii) ] iconv: func [ "Konwertuje polskie znaki w tekscie; Zwraca string! po konwersji" str [string!] "tekst do konwersji" inp [block!] "tablica konwersji (wejsciowa)" out [block!] "tablica konwersji (wyjsciowa)" /local i c here] [ if same? inp out [return str] parse/all str [ any [ here: skip ( if 127 < c: first here [ any [ none? i: attempt [index? find inp to-integer c] change here to-char out/:i ] ] ) :here skip ] ] head here ] ] ctx-display: context [ def-offset: 4x1 ; odleglosc XY od gornej ramki do pierwszego elementu listy newsow def-list-separator: off def-list-desc: on pos-offset: def-offset browse-url: none list-box: none list-pane: none last-rss-num: 0 ; funkcje przesuwajace liste newsow (scroll-list) oraz scrollera (scroller-value) ; przesuniecie slidera powoduje aktualizacje pozycji listy newsow scroll-list: func [value [number!]] [ list-box/offset/y: negate value * (list-box/size/y - gui-news-list/size/y) show list-box ] scroller-value: func [distance [number!]] [ delta-y: gui-news-slider/data + (distance * 20 / pos-offset/y) if delta-y < 0 [delta-y: 0] if delta-y > 1 [delta-y: 1] scroll-list gui-news-slider/data: delta-y show gui-news-slider ] clear-display: does [ ; inicjalizuje zmienne gui; funkcja musi byc wywolana przed dostepem do list-pane i list-box ; odswiezenie gui nastepuje w funkcji display-wpts pos-offset: def-offset list-box: make-face/size 'box as-pair gui-news-list/size/x 1 gui-news-list/pane: list-box list-pane: list-box/pane: copy [] ] display-error: func [ "Wyswietla informacje o bledzie; Odswiezenie gui nastepuje w funkcji display-wpts" text [string!] "naglowek bledu" desc [string! none!] "opis bledu"] [ clear-display ;hide [gui-html-button gui-ozi-button] disable [gui-html-button gui-ozi-button] append-wpt reduce ['name text 'description desc] ] set 'disable func [ "Ukrywa obiekt lub block! obiektów GUI. W odroznieniu od HIDE dziala takze przy zamknietym okienku programu" face [object! block!]] [ foreach obj (to-block face) [ hide obj obj/show?: false ] ] set 'display-wpts func [ "Wyswietla waypointy z okreslonego pliku; Zwraca wartosc logic!" file [string! file!] "nazwa pliku z waypointami" /local wpt wpts error] [ wpts: wpts-load file either not empty? wpts [ clear-display foreach wpt wpts [append-wpt wpt] error: empty? list-pane ][ ; dane nie zostaly zaladowane error: true ] gui-info/text: to-ascii form second (split-path file) if error [display-error {Error reading wpt-list!} {please check file format!}] ; przesun scroller w polozenie wyjsciowe i przelicz pozycje suwaka gui-news-slider/data: 0 gui-news-slider/redrag (gui-news-list/size/y / list-box/size/y) show [ gui-info gui-news-slider gui-news-list ] recycle return not none? wpts ] set 'make-url func [lat lon desc] [rejoin [http://mapa.szukacz.pl/?n= lat "&e=" lon "&z=2&t=" desc]] make-header: func [ "Tworzy naglowek wiadomosci wykorzystujac VID button; Zwraca object! VID BUTTON" hdr-text [string! none!] hdr-url [url! string! none!] hdr-size [pair!] hdr-offset [pair!]] [ make get-style 'button [ size: hdr-size offset: hdr-offset text: trim/lines/head/tail hdr-text edge: make edge [size: 0x0] font: make font [align: 'left size: 13] user-data: either none? hdr-url [none] [copy hdr-url] action: make function! [] [if not none? user-data [browse/only user-data]] ] ] make-line: func [ "Tworzy linie oddzielajaca naglowek wiadomosci od jej tresci; Zwraca object! VID BOX" line-size [pair!] line-offset [pair!]] [ make get-style 'box [ size: line-size ; minimalna wysokosc 'box wynosi 3pix offset: line-offset edge: make edge [color: coal size: 1x1] ] ] make-description: func [ "Tworzy opis wiadomosci wykorzystujac VID txt; Zwraca object! VID TXT" desc-text [string! none!] desc-size [pair!] desc-offset [pair!]] [ make get-style 'txt [ size: desc-size offset: desc-offset text: trim/lines/head/tail desc-text font: make font [align: 'left color: black] ] ] append-wpt: func [ "Dodaje pozycje do listy wyswietlanych waypointow (list-box); Nie zwraca wartosci" wpt [block!] "waypoint" /local link desc btn btn-size wh] [ text: to-ascii form wpt/name link: attempt [either all [wpt/latitude wpt/longitude] [make-url wpt/latitude wpt/longitude wpt/name] [none]] desc: reform [ any [attempt [wpt/description] ""] any [attempt [wpt/latitude] ""] any [attempt [wpt/longitude] ""] any [attempt [wpt/altitude] ""] ] btn-size: as-pair (gui-news-list/size/x - pos-offset/x - 8) (16) jobs: [ ; [check this] [do that] [true] [make-header text link btn-size pos-offset] [def-list-separator] [make-line (as-pair btn-size/x 3) pos-offset] [all [def-list-desc desc]] [make-description desc btn-size pos-offset] ] foreach [check job] jobs [ if do check [ btn: do job ; jezeli tekst nie miesci sie w jednej linijce to zmien wysokosc przycisku (Y) if not zero? (wh: size-text btn) [btn/size/y: wh/y + 4] append list-pane btn list-box/size/y: list-box/size/y + btn/size/y pos-offset: as-pair (pos-offset/x) (pos-offset/y + btn/size/y) ] ] ; dodaj odstep miedzy poszczegolnymi newsami list-box/size/y: list-box/size/y + 4 pos-offset/y: pos-offset/y + 4 ] add-suffix: func [file [string! file!] suffix [string! file!] /local index] [ index: any [ attempt [index? find/last file #"."] length? file ] to-file join copy/part file index [alter form suffix "."] ] set 'look-and-feel stylize [ info-btn: info 320 middle edge [size: 0x0] font [style: 'bold size: 14 align: 'left] about-btn: btn-help [browse http://www.rowery.olsztyn.pl] news-list: box 336x280 edge [size: 1x1 color: black] news-slider: scroller 16x280 edge [size: 1x1 color: black] [scroll-list value] save-html-btn: btn "save as HTML" #"h" [wpts-gen-html (add-suffix gui-info/text %.html)] save-ozi-btn: btn "save as OZI/WPT" #"w" [wpts-gen-ozi (add-suffix gui-info/text %.wpt)] ] insert-event-func [ switch event/type [ scroll-line [scroller-value event/offset/y] ; obsluga kolka w myszce (przesuwanie listy newsow) key [ ; obslga klawiszy kursora switch event/key [ up [scroller-value -3] down [scroller-value 3] ] ] ] event ] ] linux?: equal? fourth system/version 4 if all [linux? (get-env "KDEDIR")] [ attempt [unprotect 'browse] browse: func [value [any-string!] /only] [call reform ["konqueror" rejoin [{"} value {"}]]] ] img: load 64#{ /9j/4AAQSkZJRgABAQIAAAAAAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0V FhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/2wBDAQoL Cw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAGQAfQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEA AAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6 Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZ mqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx 8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hp anN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPE xcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDt aKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAEoyKCQoyTxV SWVpG2jOKAFml3HavSprWxL4aQcelSWdnjEkg57Cr+MUAIqqi4AwKXpS9KoXl55f yIeaAFvb0Rgoh+astiWbcxyTQSWOT1NJQAUtFFACVYtLczyDI+UdahVdzADvW1aQ CGEDuaAJlUKoA6CloooAKKKKACiiigAoopCwHU0AZuqdQKz60ryI3MgEfOKbHph6 uaAM7BNSJbyueENa8dnCn8OanACjAGKAMuPTWJy5xVuOyhjHTJqzjij8KAGhQvQA UtFFACUUtJQAlFFBoAQ0UGigCvdQCWM4HNZDqUYqeCK36z763/jUfWgDPooooAKK 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 oAKKKSgAoooNACUUUUAf/9k= } main-window: center-face layout [ backdrop img effect [tile-view] key (escape) [unview quit] styles look-and-feel origin 2x2 space 2x2 across gui-info: info-btn return gui-news-list: news-list gui-news-slider: news-slider return gui-html-button: save-html-btn gui-ozi-button: save-ozi-btn pad 140 about-btn ] file: remove-each name read %. [ ;not found? [".wpt" ".grm"] lowercase form suffix? name] all [ not found? find (lowercase form name) "wpt.txt" not found? find (lowercase form name) ".wpt" ] ] if 1 <> length? file [append file request-file/title "Load wpts..." "Load"] if last file [ display-wpts last file view/title main-window "Live Waypoints" ] ][ alert rejoin [{We apologize, an unexpected error occurred (} get in disarm err 'id { error)}] ] ;halt quit