rhodes 2.0.0.beta3 → 2.0.0.beta4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ RHO_GLOBAL void create_navbar(rho_param *p)
10
10
  JNIEnv *env = jnienv();
11
11
  jclass cls = getJNIClass(RHODES_JAVA_CLASS_NAVBAR);
12
12
  if (!cls) return;
13
- jmethodID mid = getJNIClassStaticMethod(env, cls, "create", "(Ljava/util/Vector;)V");
13
+ jmethodID mid = getJNIClassStaticMethod(env, cls, "create", "(Ljava/util/Map;)V");
14
14
  if (!mid) return;
15
15
 
16
16
  jobject paramsObj = RhoValueConverter(env).createObject(p);
@@ -1,5 +1,6 @@
1
1
  package com.rhomobile.rhodes;
2
2
 
3
+ import java.util.Map;
3
4
  import java.util.Vector;
4
5
 
5
6
  public class NavBar {
@@ -9,21 +10,37 @@ public class NavBar {
9
10
  private static class CreateTask implements Runnable {
10
11
 
11
12
  private String title;
12
- private Vector<Object> left;
13
- private Vector<Object> right;
13
+ private Map<Object, Object> left;
14
+ private Map<Object, Object> right;
14
15
 
15
- public CreateTask(Vector<Object> p) {
16
- // TODO: implement
16
+ @SuppressWarnings("unchecked")
17
+ public CreateTask(Map<Object, Object> p) {
18
+ Object titleObj = p.get("title");
19
+ if (titleObj == null || !(titleObj instanceof String))
20
+ throw new IllegalArgumentException("'title' should be String");
21
+ title = (String)titleObj;
22
+
23
+ Object leftObj = p.get("left");
24
+ if (leftObj == null || !(leftObj instanceof Map<?,?>))
25
+ throw new IllegalArgumentException("'left' - expected Hash");
26
+ left = (Map<Object,Object>)leftObj;
27
+
28
+ Object rightObj = p.get("right");
29
+ if (rightObj != null && !(rightObj instanceof Map<?,?>))
30
+ throw new IllegalArgumentException("'right' - expected Hash");
31
+ right = (Map<Object,Object>)rightObj;
17
32
  }
18
33
 
19
34
  public void run() {
20
- // TODO: implement
35
+ Rhodes r = RhodesInstance.getInstance();
36
+ r.getMainView().setNavBar(title, left, right);
21
37
  }
22
38
  };
23
39
 
24
40
  private static class RemoveTask implements Runnable {
25
41
  public void run() {
26
- // TODO: implement
42
+ Rhodes r = RhodesInstance.getInstance();
43
+ r.getMainView().removeNavBar();
27
44
  }
28
45
  };
29
46
 
@@ -31,7 +48,7 @@ public class NavBar {
31
48
  Logger.E(TAG, "Call of \"" + name + "\" failed: " + e.getMessage());
32
49
  }
33
50
 
34
- public static void create(Vector<Object> params) {
51
+ public static void create(Map<Object, Object> params) {
35
52
  try {
36
53
  Rhodes.performOnUiThread(new CreateTask(params), false);
37
54
  }
@@ -20,6 +20,8 @@
20
20
  */
21
21
  package com.rhomobile.rhodes.mainview;
22
22
 
23
+ import java.util.Map;
24
+
23
25
  import android.view.View;
24
26
 
25
27
  public interface MainView {
@@ -41,4 +43,7 @@ public interface MainView {
41
43
  public int activeTab();
42
44
 
43
45
  public void loadData(String data, int index);
46
+
47
+ public void setNavBar(String title, Map<Object,Object> left, Map<Object,Object> right);
48
+ public void removeNavBar();
44
49
  }
@@ -39,6 +39,7 @@ import android.webkit.WebView;
39
39
  import android.widget.Button;
40
40
  import android.widget.ImageButton;
41
41
  import android.widget.LinearLayout;
42
+ import android.widget.TextView;
42
43
 
43
44
  public class SimpleMainView implements MainView {
44
45
 
@@ -108,11 +109,96 @@ public class SimpleMainView implements MainView {
108
109
 
109
110
  private LinearLayout view;
110
111
  private WebView webView;
112
+ private LinearLayout navBar = null;
111
113
 
112
114
  public View getView() {
113
115
  return view;
114
116
  }
115
117
 
118
+ private View createButton(Map<Object,Object> hash) {
119
+ Rhodes r = RhodesInstance.getInstance();
120
+
121
+ Object actionObj = hash.get("action");
122
+ if (actionObj == null || !(actionObj instanceof String))
123
+ throw new IllegalArgumentException("'action' should be String");
124
+
125
+ String action = (String)actionObj;
126
+ if (action.length() == 0)
127
+ throw new IllegalArgumentException("'action' should not be empty");
128
+
129
+ Drawable icon = null;
130
+ String label = null;
131
+ View.OnClickListener onClick = null;
132
+
133
+ if (action.equalsIgnoreCase("back")) {
134
+ icon = r.getResources().getDrawable(AndroidR.drawable.back);
135
+ onClick = new ActionBack();
136
+ }
137
+ else if (action.equalsIgnoreCase("forward")) {
138
+ icon = r.getResources().getDrawable(AndroidR.drawable.next);
139
+ onClick = new ActionForward();
140
+ }
141
+ else if (action.equalsIgnoreCase("home")) {
142
+ icon = r.getResources().getDrawable(AndroidR.drawable.home);
143
+ onClick = new ActionHome();
144
+ }
145
+ else if (action.equalsIgnoreCase("options")) {
146
+ icon = r.getResources().getDrawable(AndroidR.drawable.options);
147
+ onClick = new ActionOptions();
148
+ }
149
+ else if (action.equalsIgnoreCase("refresh")) {
150
+ icon = r.getResources().getDrawable(AndroidR.drawable.refresh);
151
+ onClick = new ActionRefresh();
152
+ }
153
+ else if (action.equalsIgnoreCase("close") || action.equalsIgnoreCase("exit")) {
154
+ icon = r.getResources().getDrawable(AndroidR.drawable.exit);
155
+ onClick = new ActionExit();
156
+ }
157
+ else if (action.equalsIgnoreCase("separator"))
158
+ return null;
159
+
160
+ Object iconObj = hash.get("icon");
161
+ if (iconObj != null) {
162
+ if (!(iconObj instanceof String))
163
+ throw new IllegalArgumentException("'icon' should be String");
164
+ String rootPath = r.getRootPath() + "/apps/";
165
+ String iconPath = rootPath + (String)iconObj;
166
+ Bitmap bitmap = BitmapFactory.decodeFile(iconPath);
167
+ if (bitmap == null)
168
+ throw new IllegalArgumentException("Can't find icon: " + iconPath);
169
+ icon = new BitmapDrawable(bitmap);
170
+ }
171
+
172
+ if (icon == null) {
173
+ Object labelObj = hash.get("label");
174
+ if (labelObj == null || !(labelObj instanceof String))
175
+ throw new IllegalArgumentException("'label' should be String");
176
+ label = (String)labelObj;
177
+ }
178
+
179
+ if (icon == null && label == null)
180
+ throw new IllegalArgumentException("One of 'icon' or 'label' should be specified");
181
+
182
+ if (onClick == null)
183
+ onClick = new ActionCustom(action);
184
+
185
+ View button;
186
+ if (icon != null) {
187
+ ImageButton btn = new ImageButton(r);
188
+ btn.setImageDrawable(icon);
189
+ button = btn;
190
+ }
191
+ else {
192
+ Button btn = new Button(r);
193
+ btn.setText(label);
194
+ button = btn;
195
+ }
196
+
197
+ button.setOnClickListener(onClick);
198
+
199
+ return button;
200
+ }
201
+
116
202
  @SuppressWarnings("unchecked")
117
203
  private void init(Vector<Object> params) {
118
204
  Rhodes r = RhodesInstance.getInstance();
@@ -133,8 +219,6 @@ public class SimpleMainView implements MainView {
133
219
  view.addView(bottom);
134
220
 
135
221
  if (params != null) {
136
- String rootPath = r.getRootPath() + "/apps/";
137
-
138
222
  LinearLayout group = null;
139
223
  // First group should have gravity LEFT
140
224
  int gravity = Gravity.LEFT;
@@ -145,88 +229,13 @@ public class SimpleMainView implements MainView {
145
229
 
146
230
  Map<Object, Object> hash = (Map<Object, Object>)param;
147
231
 
148
- Object actionObj = hash.get("action");
149
- if (actionObj == null || !(actionObj instanceof String))
150
- throw new IllegalArgumentException("'action' should be String");
151
-
152
- String action = (String)actionObj;
153
- if (action.length() == 0)
154
- throw new IllegalArgumentException("'action' should not be empty");
155
-
156
- Drawable icon = null;
157
- String label = null;
158
-
159
- View.OnClickListener onClick = null;
160
- if (action.equalsIgnoreCase("back")) {
161
- icon = r.getResources().getDrawable(AndroidR.drawable.back);
162
- onClick = new ActionBack();
163
- }
164
- else if (action.equalsIgnoreCase("forward")) {
165
- icon = r.getResources().getDrawable(AndroidR.drawable.next);
166
- onClick = new ActionForward();
167
- }
168
- else if (action.equalsIgnoreCase("home")) {
169
- icon = r.getResources().getDrawable(AndroidR.drawable.home);
170
- onClick = new ActionHome();
171
- }
172
- else if (action.equalsIgnoreCase("options")) {
173
- icon = r.getResources().getDrawable(AndroidR.drawable.options);
174
- onClick = new ActionOptions();
175
- }
176
- else if (action.equalsIgnoreCase("refresh")) {
177
- icon = r.getResources().getDrawable(AndroidR.drawable.refresh);
178
- onClick = new ActionRefresh();
179
- }
180
- else if (action.equalsIgnoreCase("close") || action.equalsIgnoreCase("exit")) {
181
- icon = r.getResources().getDrawable(AndroidR.drawable.exit);
182
- onClick = new ActionExit();
183
- }
184
- else if (action.equalsIgnoreCase("separator")) {
232
+ View button = createButton(hash);
233
+ if (button == null) {
185
234
  group = null;
186
235
  gravity = Gravity.CENTER;
187
236
  continue;
188
237
  }
189
238
 
190
- Object iconObj = hash.get("icon");
191
- if (iconObj != null) {
192
- if (!(iconObj instanceof String))
193
- throw new IllegalArgumentException("'icon' should be String");
194
- String iconPath = rootPath + (String)iconObj;
195
- Bitmap bitmap = BitmapFactory.decodeFile(iconPath);
196
- if (bitmap == null)
197
- throw new IllegalArgumentException("Can't find icon: " + iconPath);
198
- icon = new BitmapDrawable(bitmap);
199
- }
200
-
201
- if (icon == null) {
202
- Object labelObj = hash.get("label");
203
- if (labelObj == null || !(labelObj instanceof String))
204
- throw new IllegalArgumentException("'label' should be String");
205
- label = (String)labelObj;
206
- }
207
-
208
- if (icon == null && label == null)
209
- throw new IllegalArgumentException("One of 'icon' or 'label' should be specified");
210
-
211
- View button = null;
212
- if (icon != null) {
213
- ImageButton btn = new ImageButton(r);
214
- btn.setImageDrawable(icon);
215
- button = btn;
216
- }
217
- else {
218
- Button btn = new Button(r);
219
- btn.setText(label);
220
- button = btn;
221
- }
222
-
223
- if (button == null)
224
- continue;
225
-
226
- if (onClick == null)
227
- onClick = new ActionCustom(action);
228
-
229
- button.setOnClickListener(onClick);
230
239
  button.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
231
240
  if (group == null) {
232
241
  group = new LinearLayout(r);
@@ -288,4 +297,42 @@ public class SimpleMainView implements MainView {
288
297
  webView.loadData(data, "text/html", "utf-8");
289
298
  }
290
299
 
300
+ public void setNavBar(String title, Map<Object,Object> left, Map<Object,Object> right) {
301
+ removeNavBar();
302
+
303
+ Rhodes r = RhodesInstance.getInstance();
304
+
305
+ LinearLayout top = new LinearLayout(r);
306
+ top.setOrientation(LinearLayout.HORIZONTAL);
307
+ top.setBackgroundColor(Color.GRAY);
308
+ top.setGravity(Gravity.CENTER);
309
+ top.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, WRAP_CONTENT, 0));
310
+
311
+ View leftButton = createButton(left);
312
+ leftButton.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1));
313
+ top.addView(leftButton);
314
+
315
+ TextView label = new TextView(r);
316
+ label.setText(title);
317
+ label.setGravity(Gravity.CENTER);
318
+ label.setTextSize((float)30.0);
319
+ label.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 2));
320
+ top.addView(label);
321
+
322
+ if (right != null) {
323
+ View rightButton = createButton(right);
324
+ rightButton.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1));
325
+ top.addView(rightButton);
326
+ }
327
+
328
+ navBar = top;
329
+ view.addView(navBar, 0);
330
+ }
331
+
332
+ public void removeNavBar() {
333
+ if (navBar == null)
334
+ return;
335
+ view.removeViewAt(0);
336
+ navBar = null;
337
+ }
291
338
  }
@@ -218,5 +218,13 @@ public class TabbedMainView implements MainView {
218
218
  public void loadData(String data, int index) {
219
219
  getView(index).loadData(data, 0);
220
220
  }
221
+
222
+ public void setNavBar(String title, Map<Object,Object> left, Map<Object,Object> right) {
223
+ getView(activeTab()).setNavBar(title, left, right);
224
+ }
225
+
226
+ public void removeNavBar() {
227
+ getView(activeTab()).removeNavBar();
228
+ }
221
229
 
222
230
  }
@@ -253,6 +253,20 @@ void CSyncSource::doSyncClientChanges()
253
253
  m_arBlobAttrs.removeAllElements();
254
254
  }
255
255
 
256
+ static void escapeDoubleQuotes(String& str)
257
+ {
258
+ const char* szQuote = strchr(str.c_str(), '\"');
259
+ while(szQuote)
260
+ {
261
+ int nPos = szQuote - str.c_str();
262
+ str.insert(nPos, 1, '\\');
263
+ if ( nPos+2 < str.length() )
264
+ szQuote = strchr(str.c_str()+nPos+2, '\"');
265
+ else
266
+ szQuote = 0;
267
+ }
268
+ }
269
+
256
270
  //{"source_name":"SampleAdapter","client_id":1,"create":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
257
271
  //{"source_name":"SampleAdapter","client_id":1,"update":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
258
272
  //{"source_name":"SampleAdapter","client_id":1,"delete":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
@@ -315,6 +329,7 @@ void CSyncSource::makePushBody_Ver3(String& strBody, const String& strUpdateType
315
329
  if ( bFirst )
316
330
  strBody += ":{";
317
331
 
332
+ escapeDoubleQuotes(value);
318
333
  strBody += "\"" + strAttrib + "\":\"" + value + "\"";
319
334
  bFirst = false;
320
335
  }
data/rhobuild.yml CHANGED
@@ -1,19 +1,4 @@
1
1
  ---
2
- env:
3
- app: /Users/lars/Dev/code/rhomobile/gunz-rhodes2
4
- paths:
5
- android-ndk: /Users/lars/Dev/android-ndk-r3
6
- java: /Library/Java/Home/bin
7
- android: /Users/lars/Dev/android-sdk-mac_86
8
- 4.6:
9
- jde:
10
- sim: 9000
11
- mds:
12
- cabwiz:
13
- 4.2:
14
- jde:
15
- sim: 8100
16
- mds:
17
2
  excludedirs:
18
3
  bb:
19
4
  - public/js/iui
@@ -26,12 +11,27 @@ excludedirs:
26
11
  - "**/.*.swn"
27
12
  - "**/jquery*.js"
28
13
  - "**/.DS_Store"
14
+ env:
15
+ app: /Users/lars/Dev/code/rhomobile/store
16
+ paths:
17
+ android-ndk: /Users/lars/Dev/android-ndk-r3
18
+ android: /Users/lars/Dev/android-sdk-mac_86
19
+ java: /Library/Java/Home/bin
20
+ 4.6:
21
+ jde:
22
+ sim: 9000
23
+ mds:
24
+ 4.2:
25
+ jde:
26
+ sim: 8100
27
+ mds:
28
+ cabwiz:
29
29
  android:
30
30
  build:
31
- symbianpath: platform/symbian
32
- bb:
33
31
  bbsignpwd: somepasswordhere
32
+ bb:
33
+ symbianpath: platform/symbian
34
34
  bbpath: platform/bb
35
- wmpath: platform/wm
36
35
  androidpath: platform/android
36
+ wmpath: platform/wm
37
37
  iphonepath: platform/iphone
data/rhodes.gemspec CHANGED
@@ -3,7 +3,7 @@ require "lib/rhodes.rb"
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = %q{rhodes}
6
- s.version = '2.0.0.beta3'
6
+ s.version = '2.0.0.beta4'
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.authors = ["Rhomobile"]
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhodes
3
3
  version: !ruby/object:Gem::Version
4
- hash: -1848230037
5
4
  prerelease: true
6
5
  segments:
7
6
  - 2
8
7
  - 0
9
8
  - 0
10
- - beta3
11
- version: 2.0.0.beta3
9
+ - beta4
10
+ version: 2.0.0.beta4
12
11
  platform: ruby
13
12
  authors:
14
13
  - Rhomobile
@@ -23,11 +22,9 @@ dependencies:
23
22
  name: templater
24
23
  prerelease: false
25
24
  requirement: &id001 !ruby/object:Gem::Requirement
26
- none: false
27
25
  requirements:
28
26
  - - ">="
29
27
  - !ruby/object:Gem::Version
30
- hash: 11
31
28
  segments:
32
29
  - 0
33
30
  - 5
@@ -39,11 +36,9 @@ dependencies:
39
36
  name: rake
40
37
  prerelease: false
41
38
  requirement: &id002 !ruby/object:Gem::Requirement
42
- none: false
43
39
  requirements:
44
40
  - - ">="
45
41
  - !ruby/object:Gem::Version
46
- hash: 49
47
42
  segments:
48
43
  - 0
49
44
  - 8
@@ -55,11 +50,9 @@ dependencies:
55
50
  name: activesupport
56
51
  prerelease: false
57
52
  requirement: &id003 !ruby/object:Gem::Requirement
58
- none: false
59
53
  requirements:
60
54
  - - ">="
61
55
  - !ruby/object:Gem::Version
62
- hash: 9
63
56
  segments:
64
57
  - 2
65
58
  - 3
@@ -71,11 +64,9 @@ dependencies:
71
64
  name: rdoc
72
65
  prerelease: false
73
66
  requirement: &id004 !ruby/object:Gem::Requirement
74
- none: false
75
67
  requirements:
76
68
  - - ">="
77
69
  - !ruby/object:Gem::Version
78
- hash: 25
79
70
  segments:
80
71
  - 2
81
72
  - 4
@@ -87,11 +78,9 @@ dependencies:
87
78
  name: diff-lcs
88
79
  prerelease: false
89
80
  requirement: &id005 !ruby/object:Gem::Requirement
90
- none: false
91
81
  requirements:
92
82
  - - ">="
93
83
  - !ruby/object:Gem::Version
94
- hash: 23
95
84
  segments:
96
85
  - 1
97
86
  - 1
@@ -5409,27 +5398,23 @@ rdoc_options:
5409
5398
  require_paths:
5410
5399
  - lib
5411
5400
  required_ruby_version: !ruby/object:Gem::Requirement
5412
- none: false
5413
5401
  requirements:
5414
5402
  - - ">="
5415
5403
  - !ruby/object:Gem::Version
5416
- hash: 3
5417
5404
  segments:
5418
5405
  - 0
5419
5406
  version: "0"
5420
5407
  required_rubygems_version: !ruby/object:Gem::Requirement
5421
- none: false
5422
5408
  requirements:
5423
5409
  - - ">="
5424
5410
  - !ruby/object:Gem::Version
5425
- hash: 3
5426
5411
  segments:
5427
5412
  - 0
5428
5413
  version: "0"
5429
5414
  requirements: []
5430
5415
 
5431
5416
  rubyforge_project: rhodes
5432
- rubygems_version: 1.3.7
5417
+ rubygems_version: 1.3.6
5433
5418
  signing_key:
5434
5419
  specification_version: 2
5435
5420
  summary: The Rhodes framework is the easiest way to develop NATIVE apps with full device capabilities (GPS, PIM, camera, etc.) for any smartphone.