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.
- 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
|
|