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.
- data/lib/extensions/fileutils/fileutils.rb +1591 -0
- data/lib/extensions/rhoxml/rexml/document.rb +6 -3
- data/lib/extensions/rhoxml/rexml/element.rb +21 -4
- data/lib/extensions/rhoxml/rexml/parsers/xpathparser.rb +1 -0
- data/lib/framework/rho/rho.rb +72 -46
- data/lib/framework/rho/rhoapplication.rb +2 -13
- data/lib/framework/rhodes.rb +1 -1
- data/lib/framework/rhom/rhom_model.rb +14 -16
- data/lib/framework/rhom/rhom_object_factory.rb +2 -2
- data/lib/rhodes.rb +1 -1
- data/platform/android/Rhodes/res/layout/directory_list.xml +1 -1
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +33 -5
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Utils.java +12 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/Camera.java +9 -12
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/FileList.java +52 -72
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/ImageCapture.java +1 -5
- data/platform/android/build/androidcommon.rb +10 -11
- data/platform/iphone/Classes/GeoLocation/LocationController.m +13 -1
- data/platform/iphone/Classes/SimpleMainView.m +14 -2
- data/platform/shared/ruby/thread.c +2 -0
- data/platform/shared/rubyJVM/src/com/rho/net/AsyncHttp.java +1 -1
- data/platform/shared/rubyJVM/src/com/rho/sync/SyncEngine.java +2 -2
- data/platform/shared/rubyJVM/src/com/rho/sync/SyncSource.java +1 -0
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/ObjectFactory.java +6 -2
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyMatchData.java +1 -1
- data/platform/shared/sync/SyncEngine.cpp +3 -2
- data/platform/shared/sync/SyncSource.cpp +1 -0
- data/res/build-tools/db/syncdb.schema +0 -1
- data/rhodes.gemspec +1 -1
- 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(
|
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
|
65
|
-
|
62
|
+
private static class Picture implements Runnable {
|
66
63
|
private String url;
|
67
|
-
private Class<?>
|
64
|
+
private Class<?> klass;
|
68
65
|
|
69
|
-
public
|
66
|
+
public Picture(String u, Class<?> c) {
|
70
67
|
url = u;
|
71
|
-
|
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,
|
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
|
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
|
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.
|
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
|
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
|
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
|
-
|
85
|
-
|
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
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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.
|
29
|
-
num
|
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
|
-
|
196
|
+
srcs.each do |src|
|
198
197
|
ths << Thread.new do
|
199
|
-
|
200
|
-
cc_compile
|
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
|
-
[[
|
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
|
-
|
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,
|
360
|
+
NSString *redirect = [NSString stringWithFormat:@"%@/system/redirect_to?url=%@", homeurl, encodedUrl];
|
349
361
|
[self navigate:redirect tab:index];
|
350
362
|
}
|
351
363
|
|
@@ -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,
|
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
|
-
|
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
|
|
@@ -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
|
-
|
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
|
|