rhodes 2.0.0.beta9 → 2.0.0.beta10

Sign up to get free protection for your applications and to get access to all the features.
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