source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java@ 3863

Last change on this file since 3863 was 3863, checked in by bastiK, 13 years ago

extended mappaint style dialog

  • Property svn:eol-style set to native
File size: 5.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.mapcss;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.io.InputStream;
8import java.util.ArrayList;
9import java.util.List;
10import java.util.Map.Entry;
11
12import org.openstreetmap.josm.data.osm.Node;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.gui.mappaint.Cascade;
15import org.openstreetmap.josm.gui.mappaint.Environment;
16import org.openstreetmap.josm.gui.mappaint.MultiCascade;
17import org.openstreetmap.josm.gui.mappaint.Range;
18import org.openstreetmap.josm.gui.mappaint.StyleSource;
19import org.openstreetmap.josm.gui.mappaint.mapcss.parser.MapCSSParser;
20import org.openstreetmap.josm.gui.mappaint.mapcss.parser.ParseException;
21import org.openstreetmap.josm.gui.mappaint.mapcss.parser.TokenMgrError;
22import org.openstreetmap.josm.gui.preferences.SourceEntry;
23import org.openstreetmap.josm.io.MirroredInputStream;
24import org.openstreetmap.josm.tools.LanguageInfo;
25import org.openstreetmap.josm.tools.Utils;
26
27public class MapCSSStyleSource extends StyleSource {
28
29 final public List<MapCSSRule> rules;
30
31 public MapCSSStyleSource(String url, String name, String shortdescription) {
32 super(url, name, shortdescription);
33 rules = new ArrayList<MapCSSRule>();
34 }
35
36 public MapCSSStyleSource(SourceEntry entry) {
37 super(entry);
38 rules = new ArrayList<MapCSSRule>();
39 }
40
41 @Override
42 public void loadStyleSource() {
43 rules.clear();
44 clearErrors();
45 try {
46 MapCSSParser parser = new MapCSSParser(getSourceInputStream(), "UTF-8");
47 parser.sheet(this);
48 loadMeta();
49 } catch(IOException e) {
50 System.err.println(tr("Warning: failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
51 e.printStackTrace();
52 logError(e);
53 } catch (TokenMgrError e) {
54 System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
55 e.printStackTrace();
56 logError(e);
57 } catch (ParseException e) {
58 System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
59 e.printStackTrace();
60 logError(e);
61 }
62 }
63
64 public InputStream getSourceInputStream() throws IOException {
65 MirroredInputStream in = new MirroredInputStream(url);
66 InputStream zip = in.getZipEntry("mapcss", "style");
67 if (zip != null) {
68 zipIcons = in.getFile();
69 return zip;
70 } else {
71 zipIcons = null;
72 return in;
73 }
74 }
75
76 /**
77 * load meta info from a selector "meta"
78 */
79 private void loadMeta() {
80 MultiCascade mc = new MultiCascade();
81 Node n = new Node();
82 String code = LanguageInfo.getJOSMLocaleCode();
83 n.put("lang", code);
84 // create a fake environment to read the meta data block
85 Environment env = new Environment(n, mc, "default", this);
86
87 NEXT_RULE:
88 for (MapCSSRule r : rules) {
89 for (Selector s : r.selectors) {
90 if (s.base.equals("meta")) {
91 for (Condition cnd : s.conds) {
92 if (!cnd.applies(env))
93 continue NEXT_RULE;
94 }
95 for (Instruction i : r.declaration) {
96 i.execute(env);
97 }
98 }
99 }
100 }
101 Cascade c = mc.getCascade("default");
102 String sd = c.get("title", null, String.class);
103 if (sd != null) {
104 this.shortdescription = sd;
105 }
106 }
107
108 @Override
109 public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) {
110 Environment env = new Environment(osm, mc, null, this);
111 for (MapCSSRule r : rules) {
112 for (Selector s : r.selectors) {
113 if (s.applies(env)) {
114 if (s.range.contains(scale)) {
115 mc.range = Range.cut(mc.range, s.range);
116 } else {
117 mc.range = mc.range.reduceAround(scale, s.range);
118 continue;
119 }
120
121 String sub = s.subpart;
122 if (sub == null) {
123 sub = "default";
124 }
125
126 Cascade c = mc.get(sub);
127 if (c == null) {
128 if (mc.containsKey("*")) {
129 c = mc.get("*").clone();
130 } else {
131 c = new Cascade();
132 }
133 mc.put(sub, c);
134 }
135
136 if (sub.equals("*")) { // fixme: proper subparts handling
137 for (Entry<String, Cascade> entry : mc.entrySet()) {
138 env.layer = entry.getKey();
139 for (Instruction i : r.declaration) {
140 i.execute(env);
141 }
142 }
143 } else {
144 env.layer = sub;
145 for (Instruction i : r.declaration) {
146 i.execute(env);
147 }
148 }
149 }
150 }
151 }
152 }
153
154 @Override
155 public String toString() {
156 return Utils.join("\n", rules);
157 }
158}
Note: See TracBrowser for help on using the repository browser.