rhodes 2.0.0.beta9 → 2.0.0.beta10

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.
Files changed (30) hide show
  1. data/lib/extensions/fileutils/fileutils.rb +1591 -0
  2. data/lib/extensions/rhoxml/rexml/document.rb +6 -3
  3. data/lib/extensions/rhoxml/rexml/element.rb +21 -4
  4. data/lib/extensions/rhoxml/rexml/parsers/xpathparser.rb +1 -0
  5. data/lib/framework/rho/rho.rb +72 -46
  6. data/lib/framework/rho/rhoapplication.rb +2 -13
  7. data/lib/framework/rhodes.rb +1 -1
  8. data/lib/framework/rhom/rhom_model.rb +14 -16
  9. data/lib/framework/rhom/rhom_object_factory.rb +2 -2
  10. data/lib/rhodes.rb +1 -1
  11. data/platform/android/Rhodes/res/layout/directory_list.xml +1 -1
  12. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +33 -5
  13. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Utils.java +12 -0
  14. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/Camera.java +9 -12
  15. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/FileList.java +52 -72
  16. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/ImageCapture.java +1 -5
  17. data/platform/android/build/androidcommon.rb +10 -11
  18. data/platform/iphone/Classes/GeoLocation/LocationController.m +13 -1
  19. data/platform/iphone/Classes/SimpleMainView.m +14 -2
  20. data/platform/shared/ruby/thread.c +2 -0
  21. data/platform/shared/rubyJVM/src/com/rho/net/AsyncHttp.java +1 -1
  22. data/platform/shared/rubyJVM/src/com/rho/sync/SyncEngine.java +2 -2
  23. data/platform/shared/rubyJVM/src/com/rho/sync/SyncSource.java +1 -0
  24. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/ObjectFactory.java +6 -2
  25. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyMatchData.java +1 -1
  26. data/platform/shared/sync/SyncEngine.cpp +3 -2
  27. data/platform/shared/sync/SyncSource.cpp +1 -0
  28. data/res/build-tools/db/syncdb.schema +0 -1
  29. data/rhodes.gemspec +1 -1
  30. metadata +4 -3
@@ -149,5 +149,17 @@ public class Utils {
149
149
  os.close();
150
150
  }
151
151
  }
152
+
153
+ public static String getDirName(String filePath) {
154
+ if (filePath == null)
155
+ return null;
156
+ return new File(filePath).getParent();
157
+ }
158
+
159
+ public static String getBaseName(String filePath) {
160
+ if (filePath == null)
161
+ return null;
162
+ return new File(filePath).getName();
163
+ }
152
164
 
153
165
  }
@@ -35,14 +35,12 @@ public class Camera {
35
35
 
36
36
  public static final String INTENT_EXTRA_PREFIX = Rhodes.INTENT_EXTRA_PREFIX + "camera.";
37
37
 
38
- public static String BASE_CAMERA_DIR = RhodesInstance.getInstance().getRootPath() + "db/db-files";
39
-
40
38
  private static void reportFail(String name, Exception e) {
41
39
  Logger.E(TAG, "Call of \"" + name + "\" failed: " + e.getMessage());
42
40
  }
43
41
 
44
42
  private static void init() {
45
- File f = new File(BASE_CAMERA_DIR);
43
+ File f = new File(Rhodes.getBlobPath());
46
44
  if (!f.exists())
47
45
  f.mkdirs();
48
46
  }
@@ -61,28 +59,27 @@ public class Camera {
61
59
 
62
60
  };
63
61
 
64
- private static class Runner implements Runnable {
65
-
62
+ private static class Picture implements Runnable {
66
63
  private String url;
67
- private Class<?> cls;
64
+ private Class<?> klass;
68
65
 
69
- public Runner(String u, Class<?> c) {
66
+ public Picture(String u, Class<?> c) {
70
67
  url = u;
71
- cls = c;
68
+ klass = c;
72
69
  }
73
70
 
74
71
  public void run() {
75
72
  init();
76
73
  Rhodes r = RhodesInstance.getInstance();
77
- Intent intent = new Intent(r, cls);
74
+ Intent intent = new Intent(r, klass);
78
75
  intent.putExtra(INTENT_EXTRA_PREFIX + "callback", url);
79
76
  r.startActivity(intent);
80
77
  }
81
78
  };
82
-
79
+
83
80
  public static void takePicture(String url) {
84
81
  try {
85
- Runnable runnable = Capabilities.CAMERA_ENABLED ? new Runner(url, ImageCapture.class) :
82
+ Runnable runnable = Capabilities.CAMERA_ENABLED ? new Picture(url, ImageCapture.class) :
86
83
  new CameraDisabled(url);
87
84
  Rhodes.performOnUiThread(runnable, false);
88
85
  }
@@ -93,7 +90,7 @@ public class Camera {
93
90
 
94
91
  public static void choosePicture(String url) {
95
92
  try {
96
- Rhodes.performOnUiThread(new Runner(url, FileList.class), false);
93
+ Rhodes.performOnUiThread(new Picture(url, FileList.class), false);
97
94
  }
98
95
  catch (Exception e) {
99
96
  reportFail("choosePicture", e);
@@ -20,9 +20,9 @@
20
20
  */
21
21
  package com.rhomobile.rhodes.camera;
22
22
 
23
- import java.io.File;
24
23
  import java.io.IOException;
25
24
  import java.util.ArrayList;
25
+ import java.util.Iterator;
26
26
  import java.util.List;
27
27
 
28
28
  import com.rhomobile.rhodes.AndroidR;
@@ -31,11 +31,11 @@ import com.rhomobile.rhodes.Rhodes;
31
31
  import com.rhomobile.rhodes.Utils;
32
32
 
33
33
  import android.app.Activity;
34
+ import android.database.Cursor;
34
35
  import android.graphics.Bitmap;
35
36
  import android.graphics.BitmapFactory;
36
37
  import android.os.Bundle;
37
- import android.os.Environment;
38
- //import android.provider.MediaStore.Images.Media;
38
+ import android.provider.MediaStore;
39
39
  import android.view.View;
40
40
  import android.view.View.OnClickListener;
41
41
  import android.widget.AdapterView;
@@ -51,15 +51,27 @@ public class FileList extends Activity implements OnClickListener{
51
51
  private static final String TAG = "FileList";
52
52
 
53
53
  private String callbackUrl;
54
- private Button okButton;
55
- private Button cancelButton;
56
- private TextView lookIn;
57
- private List<String> items = null;
54
+ private List<String> files;
58
55
  private String selectedFile = "";
59
56
  private ImageView imagePreview;
60
- private ListView filesList;
61
57
 
62
- private static final String BASE_DIR = Environment.getExternalStorageDirectory() + "/DCIM/Camera";
58
+ private ArrayList<String> getImages() {
59
+ String[] proj = {MediaStore.Images.Media.DATA};
60
+ Cursor cursor = MediaStore.Images.Media.query(getContentResolver(),
61
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj);
62
+
63
+ ArrayList<String> files = new ArrayList<String>();
64
+
65
+ int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
66
+ if (cursor.moveToFirst()) {
67
+ do {
68
+ String path = cursor.getString(idx);
69
+ files.add(path);
70
+ } while (cursor.moveToNext());
71
+ }
72
+
73
+ return files;
74
+ }
63
75
 
64
76
  /** Called when the activity is first created. */
65
77
  @Override
@@ -74,18 +86,21 @@ public class FileList extends Activity implements OnClickListener{
74
86
 
75
87
  imagePreview = (ImageView) findViewById(AndroidR.id.preview);
76
88
 
77
- filesList = (ListView) findViewById(AndroidR.id.filesList);
78
-
79
- // TODO: implement cursor reading
80
- fill(new File(BASE_DIR).listFiles());
81
- //Cursor cursor = getContentResolver().query(Media.EXTERNAL_CONTENT_URI, null, null, null, null);
82
- //fill(cursor);
89
+ ListView filesList = (ListView) findViewById(AndroidR.id.filesList);
83
90
 
84
- okButton = (Button) findViewById(AndroidR.id.okButton);
85
- cancelButton = (Button) findViewById(AndroidR.id.cancelButton);
91
+ files = getImages();
92
+ List<String> names = new ArrayList<String>();
93
+ Iterator<String> it = files.iterator();
94
+ while (it.hasNext())
95
+ names.add(Utils.getBaseName(it.next()));
96
+ filesList.setAdapter(new ArrayAdapter<String>(this,
97
+ AndroidR.layout.file_row, names));
98
+
86
99
 
87
- lookIn = (TextView) findViewById(AndroidR.id.lookIn);
100
+ Button okButton = (Button) findViewById(AndroidR.id.okButton);
101
+ Button cancelButton = (Button) findViewById(AndroidR.id.cancelButton);
88
102
 
103
+ TextView lookIn = (TextView) findViewById(AndroidR.id.lookIn);
89
104
  lookIn.setText("Look In: Gallery");
90
105
 
91
106
  okButton.setOnClickListener(this);
@@ -95,13 +110,12 @@ public class FileList extends Activity implements OnClickListener{
95
110
 
96
111
  public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
97
112
  try {
98
- String file = items.get(position);
113
+ String file = files.get(position);
99
114
  Logger.D(TAG, "Selected file: " + file);
100
115
 
101
116
  BitmapFactory.Options options = new BitmapFactory.Options();
102
117
  options.inSampleSize = 10;
103
- String fullPath = BASE_DIR + "/" + file;
104
- Bitmap bm = BitmapFactory.decodeFile(fullPath, options);
118
+ Bitmap bm = BitmapFactory.decodeFile(file, options);
105
119
  if (bm != null)
106
120
  bm = Bitmap.createScaledBitmap(bm, 176, 144, true);
107
121
  if (bm != null) {
@@ -115,65 +129,31 @@ public class FileList extends Activity implements OnClickListener{
115
129
 
116
130
  });
117
131
  }
132
+
133
+ private void doCallback(String file) {
134
+ try {
135
+ String dst = null;
136
+ if (file != null && file.length() > 0) {
137
+ dst = Rhodes.getBlobPath() + "/" + Utils.getBaseName(file);
138
+ Utils.copy(file, dst);
139
+ }
140
+ com.rhomobile.rhodes.camera.Camera.doCallback(callbackUrl, dst == null ? "" : dst);
141
+ }
142
+ catch (IOException e) {
143
+ Logger.E(TAG, e);
144
+ }
145
+ }
118
146
 
119
147
  public void onClick(View view) {
120
148
  switch (view.getId()) {
121
149
  case AndroidR.id.okButton:
122
- try {
123
- String src = BASE_DIR + "/" + selectedFile;
124
- String dst = Camera.BASE_CAMERA_DIR + "/" + selectedFile;
125
- Utils.copy(src, dst);
126
- com.rhomobile.rhodes.camera.Camera.doCallback(callbackUrl, dst);
127
- } catch (IOException e) {
128
- Logger.E(TAG, e);
129
- }
130
- finish();
150
+ doCallback(selectedFile);
131
151
  break;
132
152
  case AndroidR.id.cancelButton:
133
- com.rhomobile.rhodes.camera.Camera.doCallback(callbackUrl, "");
134
- finish();
153
+ doCallback(null);
135
154
  break;
136
155
  }
156
+ finish();
137
157
  }
138
158
 
139
- /*
140
- private void fill(Cursor cursor) {
141
- if (!cursor.moveToFirst())
142
- return;
143
-
144
- int count = cursor.getColumnCount();
145
- for (int i = 0; i < count; ++i) {
146
- String name = cursor.getColumnName(i);
147
- Logger.D(TAG, "Name of " + i + " column: " + name);
148
- }
149
-
150
- do {
151
- String filename = cursor.getString(cursor.getColumnIndex(Media.TITLE));
152
- Logger.D(TAG, "Filename: " + filename);
153
- } while (cursor.moveToNext());
154
- }
155
- */
156
-
157
- private void fill(File[] files) {
158
- items = new ArrayList<String>();
159
- if (files != null) {
160
- for (File file : files) {
161
- if (!file.isDirectory()) {
162
-
163
- boolean skip = false;
164
-
165
- if ( file.getName().indexOf(".png") == -1 && file.getName().indexOf(".jpg") == -1 )
166
- skip = true;
167
-
168
- if ( !skip )
169
- items.add(file.getName());
170
- }
171
- }
172
- }
173
- ArrayAdapter<String> fileList = new ArrayAdapter<String>(this,
174
- AndroidR.layout.file_row, items);
175
-
176
- filesList.setAdapter(fileList);
177
- }
178
-
179
159
  }
@@ -20,7 +20,6 @@
20
20
  */
21
21
  package com.rhomobile.rhodes.camera;
22
22
 
23
- import java.io.File;
24
23
  import java.io.OutputStream;
25
24
  import java.text.SimpleDateFormat;
26
25
  import java.util.Date;
@@ -175,10 +174,7 @@ public class ImageCapture extends Activity implements SurfaceHolder.Callback, On
175
174
 
176
175
  Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
177
176
  // String filename = timeStampFormat.format(new Date());
178
- String dir = com.rhomobile.rhodes.camera.Camera.BASE_CAMERA_DIR;
179
- File fdir = new File(dir);
180
- if (!fdir.exists())
181
- fdir.mkdirs();
177
+ String dir = Rhodes.getBlobPath();
182
178
 
183
179
  OutputStream osCommon = getContentResolver().openOutputStream(uri);
184
180
  iccb = new ImageCaptureCallback(callbackUrl, osCommon, dir + "/" + filename + ".jpg");
@@ -16,17 +16,17 @@ else
16
16
  end
17
17
 
18
18
  def num_cpus
19
+ num = nil
19
20
  if RUBY_PLATFORM =~ /linux/
20
- num = `cat /proc/cpuinfo | grep processor | wc -l`
21
+ num = `cat /proc/cpuinfo | grep processor | wc -l`.gsub("\n", '')
21
22
  elsif RUBY_PLATFORM =~ /darwin/
22
- num = `sysctl -n hw.ncpu`
23
+ num = `sysctl -n hw.ncpu`.gsub("\n", '')
23
24
  elsif RUBY_PLATFORM =~ /w(in)?32/
24
25
  num = ENV['NUMBER_OF_PROCESSORS']
25
- else
26
- num '1'
27
26
  end
28
- num.gsub!("\n", '')
29
- num.to_i
27
+ num = num.to_i
28
+ num = 1 if num == 0
29
+ num
30
30
  end
31
31
 
32
32
  def get_sources(name)
@@ -185,8 +185,7 @@ def cc_build(name, objdir, additional = nil)
185
185
  jobs = num_cpus
186
186
  jobs += 1 if jobs > 1
187
187
 
188
- srcs = []
189
- jobs.times.each { |x| srcs << [] }
188
+ srcs = Array.new(jobs, [])
190
189
  sources = get_sources(name)
191
190
  sources.each do |src|
192
191
  idx = sources.index(src)%jobs
@@ -194,10 +193,10 @@ def cc_build(name, objdir, additional = nil)
194
193
  end
195
194
 
196
195
  ths = []
197
- jobs.times.each do |x|
196
+ srcs.each do |src|
198
197
  ths << Thread.new do
199
- srcs[x].each do |src|
200
- cc_compile src, objdir, additional or return 1
198
+ src.each do |f|
199
+ cc_compile f, objdir, additional or return 1
201
200
  end
202
201
  0
203
202
  end
@@ -9,6 +9,7 @@
9
9
  #import <CFNetwork/CFNetwork.h>
10
10
 
11
11
  #import <CoreLocation/CoreLocation.h>
12
+ #import "Rhodes.h"
12
13
  #import "LocationController.h"
13
14
  #import "logging/RhoLog.h"
14
15
  #include "rubyext/GeoLocation.h"
@@ -22,6 +23,17 @@ static void _TimerCallBack(CFRunLoopTimerRef timer, void* context);
22
23
  // This is a singleton class, see below
23
24
  static LocationController *sharedLC = nil;
24
25
 
26
+ @interface LocationControllerInit : NSObject {}
27
+ + (void)run;
28
+ @end
29
+
30
+ @implementation LocationControllerInit
31
+ + (void)run {
32
+ [[LocationController alloc] init]; // assignment not done here
33
+ }
34
+ @end
35
+
36
+
25
37
  @implementation LocationController
26
38
 
27
39
  @synthesize _locationManager;
@@ -154,7 +166,7 @@ static LocationController *sharedLC = nil;
154
166
  + (LocationController *)sharedInstance {
155
167
  @synchronized(self) {
156
168
  if (sharedLC == nil) {
157
- [[self alloc] init]; // assignment not done here
169
+ [Rhodes performOnUiThread:[LocationControllerInit class] wait:NO];
158
170
  }
159
171
  }
160
172
  return sharedLC;
@@ -338,14 +338,26 @@
338
338
  [webView goForward];
339
339
  }
340
340
 
341
+ - (NSString*)encodeUrl:(NSString*)url {
342
+ // This decode/encode trick allow to work properly with urls which are already encoded
343
+ // in the same manner as with those which are not. In case if 'url' is already encoded,
344
+ // encodedUrl will be exactly the same as original one whereas if original url was not
345
+ // encoded, encodedUrl will contain correct encoded version
346
+ NSString *decodedUrl = [url stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
347
+ NSString *encodedUrl = [decodedUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
348
+ return encodedUrl;
349
+ }
350
+
341
351
  - (void)navigate:(NSString *)url tab:(int)index {
342
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
352
+ NSString *encodedUrl = [self encodeUrl:url];
353
+ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:encodedUrl]];
343
354
  [webView loadRequest:request];
344
355
  }
345
356
 
346
357
  - (void)navigateRedirect:(NSString *)url tab:(int)index {
358
+ NSString *encodedUrl = [self encodeUrl:url];
347
359
  NSString* homeurl = [NSString stringWithUTF8String:rho_rhodesapp_gethomeurl()];
348
- NSString *redirect = [NSString stringWithFormat:@"%@/system/redirect_to?url=%@", homeurl, url];
360
+ NSString *redirect = [NSString stringWithFormat:@"%@/system/redirect_to?url=%@", homeurl, encodedUrl];
349
361
  [self navigate:redirect tab:index];
350
362
  }
351
363
 
@@ -2114,7 +2114,9 @@ static VALUE
2114
2114
  rb_thread_priority_set(VALUE thread, VALUE prio)
2115
2115
  {
2116
2116
  rb_thread_t *th;
2117
+ #if !USE_NATIVE_THREAD_PRIORITY
2117
2118
  int priority;
2119
+ #endif
2118
2120
  GetThreadPtr(thread, th);
2119
2121
 
2120
2122
  rb_secure(4);
@@ -147,7 +147,7 @@ public class AsyncHttp extends RhoThread
147
147
  break;
148
148
 
149
149
  case hcDownload:
150
- m_pNetResponse = m_pNetRequest.pullFile(m_strUrl, m_strBody, null, m_mapHeaders);
150
+ m_pNetResponse = m_pNetRequest.pullFile(m_strUrl, m_strFilePath, null, m_mapHeaders);
151
151
  break;
152
152
 
153
153
  case hcUpload:
@@ -475,10 +475,10 @@ public class SyncEngine implements NetRequest.IRhoSession
475
475
  {
476
476
  if ( strSources.length() > 0 )
477
477
  {
478
- /*NetResponse resp = getNet().pushData( getNet().resolveUrl("/system/loadserversources"), strSources, null);
478
+ NetResponse resp = getNet().pushData( getNet().resolveUrl("/system/loadserversources"), strSources, null);
479
479
  loadAllSources();
480
480
 
481
- DBAdapter.initAttrManager();*/
481
+ DBAdapter.initAttrManager();
482
482
  }
483
483
  }
484
484
 
@@ -454,6 +454,7 @@ class SyncSource
454
454
  {
455
455
  getSync().stopSync();
456
456
  m_nErrCode = RhoRuby.getErrorFromResponse(resp);
457
+ m_strError = resp.getCharData();
457
458
  continue;
458
459
  }
459
460
  }catch(Exception exc)
@@ -131,8 +131,12 @@ public class ObjectFactory {
131
131
  }
132
132
 
133
133
  //RHO_COMMENT
134
- public static RubyIO createResourceFile(String filename, String mode) {
135
- return new RubyFile(new InputStreamExecutor(filename, mode), RubyRuntime.FileClass );
134
+ public static RubyIO createResourceFile(String filename, String mode)
135
+ {
136
+ InputStreamExecutor ise = new InputStreamExecutor(filename, mode);
137
+ if ( ise.getInputStream() == null )
138
+ return null;
139
+ return new RubyFile( ise, RubyRuntime.FileClass );
136
140
  }
137
141
  //RHO_COMMENT
138
142