Merge lp:~dbarth/cordova-ubuntu/3.4-core-platform-plugins into lp:cordova-ubuntu/container

Proposed by David Barth on 2014-02-18
Status: Merged
Approved by: David Barth on 2014-02-20
Approved revision: 22
Merged at revision: 19
Proposed branch: lp:~dbarth/cordova-ubuntu/3.4-core-platform-plugins
Merge into: lp:cordova-ubuntu/container
Diff against target: 10607 lines (+9988/-9)
98 files modified
apparmor.json (+1/-1)
build/src/coreplugins.cpp (+17/-1)
build/src/plugins/org.apache.cordova.battery-status/battery.cpp (+78/-0)
build/src/plugins/org.apache.cordova.battery-status/battery.h (+62/-0)
build/src/plugins/org.apache.cordova.camera/camera.cpp (+143/-0)
build/src/plugins/org.apache.cordova.camera/camera.h (+76/-0)
build/src/plugins/org.apache.cordova.console/console.cpp (+29/-0)
build/src/plugins/org.apache.cordova.console/console.h (+43/-0)
build/src/plugins/org.apache.cordova.device-motion/accelerometer.cpp (+58/-0)
build/src/plugins/org.apache.cordova.device-motion/accelerometer.h (+55/-0)
build/src/plugins/org.apache.cordova.device-orientation/compass.cpp (+75/-0)
build/src/plugins/org.apache.cordova.device-orientation/compass.h (+58/-0)
build/src/plugins/org.apache.cordova.device/device.cpp (+64/-0)
build/src/plugins/org.apache.cordova.device/device.h (+47/-0)
build/src/plugins/org.apache.cordova.dialogs/notification.cpp (+81/-0)
build/src/plugins/org.apache.cordova.dialogs/notification.h (+63/-0)
build/src/plugins/org.apache.cordova.file-transfer/file-transfer.cpp (+247/-0)
build/src/plugins/org.apache.cordova.file-transfer/file-transfer.h (+97/-0)
build/src/plugins/org.apache.cordova.file/file.cpp (+773/-0)
build/src/plugins/org.apache.cordova.file/file.h (+73/-0)
build/src/plugins/org.apache.cordova.geolocation/geolocation.cpp (+119/-0)
build/src/plugins/org.apache.cordova.geolocation/geolocation.h (+69/-0)
build/src/plugins/org.apache.cordova.globalization/globalization.cpp (+342/-0)
build/src/plugins/org.apache.cordova.globalization/globalization.h (+93/-0)
build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.cpp (+106/-0)
build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.h (+61/-0)
build/src/plugins/org.apache.cordova.media-capture/capture.cpp (+167/-0)
build/src/plugins/org.apache.cordova.media-capture/capture.h (+84/-0)
build/src/plugins/org.apache.cordova.media/media.cpp (+128/-0)
build/src/plugins/org.apache.cordova.media/media.h (+267/-0)
build/src/plugins/org.apache.cordova.splashscreen/splashscreen.cpp (+42/-0)
build/src/plugins/org.apache.cordova.splashscreen/splashscreen.h (+52/-0)
build/src/plugins/org.apache.cordova.vibration/vibration.cpp (+38/-0)
build/src/plugins/org.apache.cordova.vibration/vibration.h (+47/-0)
config.xml (+19/-0)
debian/changelog (+12/-0)
debian/control (+6/-4)
debian/rules (+22/-1)
qml/CaptureWidget.qml (+119/-0)
qml/InAppBrowser.qml (+69/-0)
qml/MediaCaptureWidget.qml (+207/-0)
qml/notification.qml (+44/-0)
www/cordova_plugins.js (+407/-2)
www/plugins/org.apache.cordova.battery-status/www/battery.js (+101/-0)
www/plugins/org.apache.cordova.camera/www/Camera.js (+77/-0)
www/plugins/org.apache.cordova.camera/www/CameraConstants.js (+55/-0)
www/plugins/org.apache.cordova.camera/www/CameraPopoverHandle.js (+35/-0)
www/plugins/org.apache.cordova.camera/www/CameraPopoverOptions.js (+39/-0)
www/plugins/org.apache.cordova.console/www/console-via-logger.js (+189/-0)
www/plugins/org.apache.cordova.console/www/logger.js (+357/-0)
www/plugins/org.apache.cordova.device-motion/www/Acceleration.js (+31/-0)
www/plugins/org.apache.cordova.device-motion/www/accelerometer.js (+171/-0)
www/plugins/org.apache.cordova.device-orientation/www/CompassError.js (+36/-0)
www/plugins/org.apache.cordova.device-orientation/www/CompassHeading.js (+31/-0)
www/plugins/org.apache.cordova.device-orientation/www/compass.js (+105/-0)
www/plugins/org.apache.cordova.device/src/ubuntu/device.js (+36/-0)
www/plugins/org.apache.cordova.device/www/device.js (+79/-0)
www/plugins/org.apache.cordova.dialogs/www/notification.js (+112/-0)
www/plugins/org.apache.cordova.file-transfer/www/FileTransfer.js (+210/-0)
www/plugins/org.apache.cordova.file-transfer/www/FileTransferError.js (+41/-0)
www/plugins/org.apache.cordova.file/www/DirectoryEntry.js (+110/-0)
www/plugins/org.apache.cordova.file/www/DirectoryReader.js (+74/-0)
www/plugins/org.apache.cordova.file/www/Entry.js (+229/-0)
www/plugins/org.apache.cordova.file/www/File.js (+79/-0)
www/plugins/org.apache.cordova.file/www/FileEntry.js (+83/-0)
www/plugins/org.apache.cordova.file/www/FileError.js (+48/-0)
www/plugins/org.apache.cordova.file/www/FileReader.js (+389/-0)
www/plugins/org.apache.cordova.file/www/FileSystem.js (+46/-0)
www/plugins/org.apache.cordova.file/www/FileUploadOptions.js (+43/-0)
www/plugins/org.apache.cordova.file/www/FileUploadResult.js (+31/-0)
www/plugins/org.apache.cordova.file/www/FileWriter.js (+303/-0)
www/plugins/org.apache.cordova.file/www/Flags.js (+38/-0)
www/plugins/org.apache.cordova.file/www/LocalFileSystem.js (+25/-0)
www/plugins/org.apache.cordova.file/www/Metadata.js (+33/-0)
www/plugins/org.apache.cordova.file/www/ProgressEvent.js (+69/-0)
www/plugins/org.apache.cordova.file/www/requestFileSystem.js (+63/-0)
www/plugins/org.apache.cordova.file/www/resolveLocalFileSystemURI.js (+71/-0)
www/plugins/org.apache.cordova.file/www/ubuntu/DirectoryEntry.js (+28/-0)
www/plugins/org.apache.cordova.file/www/ubuntu/Entry.js (+34/-0)
www/plugins/org.apache.cordova.file/www/ubuntu/FileWriter.js (+137/-0)
www/plugins/org.apache.cordova.geolocation/www/Coordinates.js (+71/-0)
www/plugins/org.apache.cordova.geolocation/www/Position.js (+35/-0)
www/plugins/org.apache.cordova.geolocation/www/PositionError.js (+40/-0)
www/plugins/org.apache.cordova.geolocation/www/geolocation.js (+213/-0)
www/plugins/org.apache.cordova.globalization/www/GlobalizationError.js (+43/-0)
www/plugins/org.apache.cordova.globalization/www/globalization.js (+393/-0)
www/plugins/org.apache.cordova.globalization/www/ubuntu/globalization.js (+168/-0)
www/plugins/org.apache.cordova.inappbrowser/www/InAppBrowser.js (+98/-0)
www/plugins/org.apache.cordova.media-capture/www/CaptureAudioOptions.js (+34/-0)
www/plugins/org.apache.cordova.media-capture/www/CaptureError.js (+42/-0)
www/plugins/org.apache.cordova.media-capture/www/CaptureImageOptions.js (+32/-0)
www/plugins/org.apache.cordova.media-capture/www/CaptureVideoOptions.js (+34/-0)
www/plugins/org.apache.cordova.media-capture/www/MediaFile.js (+57/-0)
www/plugins/org.apache.cordova.media-capture/www/MediaFileData.js (+41/-0)
www/plugins/org.apache.cordova.media-capture/www/capture.js (+95/-0)
www/plugins/org.apache.cordova.media/www/Media.js (+197/-0)
www/plugins/org.apache.cordova.media/www/MediaError.js (+57/-0)
www/plugins/org.apache.cordova.vibration/www/vibration.js (+40/-0)
To merge this branch: bzr merge lp:~dbarth/cordova-ubuntu/3.4-core-platform-plugins
Reviewer Review Type Date Requested Status
Alexandre Abreu (community) 2014-02-18 Approve on 2014-02-20
Review via email: mp+206982@code.launchpad.net

Description of the change

Add missing core plugins

To post a comment you must log in.
19. By David Barth on 2014-02-18

sync with trunk

20. By David Barth on 2014-02-19

add missing plugin javascript files & assets

21. By David Barth on 2014-02-19

rules file update, but doesn't manage to copy the 2 directories i need

22. By David Barth on 2014-02-19

it worked\!

Alexandre Abreu (abreu-alexandre) wrote :

works fine for me

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'apparmor.json'
2--- apparmor.json 2014-02-06 00:00:42 +0000
3+++ apparmor.json 2014-02-19 16:53:58 +0000
4@@ -1,1 +1,1 @@
5-{"policy_groups":["networking","audio"],"policy_version":1}
6\ No newline at end of file
7+{"policy_groups":["networking","audio","camera","sensors","location","microphone","video","audio","camera","microphone"],"policy_version":1}
8\ No newline at end of file
9
10=== modified file 'build/src/coreplugins.cpp'
11--- build/src/coreplugins.cpp 2014-02-05 23:42:31 +0000
12+++ build/src/coreplugins.cpp 2014-02-19 16:53:58 +0000
13@@ -19,6 +19,22 @@
14 #include <QtCore>
15 #include "cplugin.h"
16 #include "coreplugins.h"
17+#include "plugins/org.apache.cordova.camera/camera.h"
18+#include "plugins/org.apache.cordova.console/console.h"
19+#include "plugins/org.apache.cordova.device/device.h"
20+#include "plugins/org.apache.cordova.device-motion/accelerometer.h"
21+#include "plugins/org.apache.cordova.device-orientation/compass.h"
22+#include "plugins/org.apache.cordova.file/file.h"
23+#include "plugins/org.apache.cordova.media-capture/capture.h"
24+#include "plugins/org.apache.cordova.media/media.h"
25+#include "plugins/org.apache.cordova.inappbrowser/inappbrowser.h"
26+#include "plugins/org.apache.cordova.splashscreen/splashscreen.h"
27+#include "plugins/org.apache.cordova.vibration/vibration.h"
28+#include "plugins/org.apache.cordova.geolocation/geolocation.h"
29+#include "plugins/org.apache.cordova.globalization/globalization.h"
30+#include "plugins/org.apache.cordova.battery-status/battery.h"
31+#include "plugins/org.apache.cordova.file-transfer/file-transfer.h"
32+#include "plugins/org.apache.cordova.dialogs/notification.h"
33 INSERT_HEADER_HERE
34
35 #define INIT_PLUGIN(class) \
36@@ -29,7 +45,7 @@
37 Q_DECL_EXPORT QList<QSharedPointer<CPlugin>> cordovaGetPluginInstances(Cordova *cordova) {
38 QList<QSharedPointer<CPlugin>> res;
39
40- INSERT_PLUGIN_HERE
41+ INIT_PLUGIN(Camera);INIT_PLUGIN(Console);INIT_PLUGIN(Device);INIT_PLUGIN(DeviceMotion);INIT_PLUGIN(DeviceOrientation);INIT_PLUGIN(File);INIT_PLUGIN(MediaCapture);INIT_PLUGIN(Media);INIT_PLUGIN(Inappbrowser);INIT_PLUGIN(Splashscreen);INIT_PLUGIN(Vibration);INIT_PLUGIN(Geolocation);INIT_PLUGIN(Globalization);INIT_PLUGIN(BatteryStatus);INIT_PLUGIN(FileTransfer);INIT_PLUGIN(Dialogs);INSERT_PLUGIN_HERE
42
43 return res;
44 }
45
46=== added directory 'build/src/plugins/org.apache.cordova.battery-status'
47=== added file 'build/src/plugins/org.apache.cordova.battery-status/battery.cpp'
48--- build/src/plugins/org.apache.cordova.battery-status/battery.cpp 1970-01-01 00:00:00 +0000
49+++ build/src/plugins/org.apache.cordova.battery-status/battery.cpp 2014-02-19 16:53:58 +0000
50@@ -0,0 +1,78 @@
51+/*
52+ * Licensed to the Apache Software Foundation (ASF) under one
53+ * or more contributor license agreements. See the NOTICE file
54+ * distributed with this work for additional information
55+ * regarding copyright ownership. The ASF licenses this file
56+ * to you under the Apache License, Version 2.0 (the
57+ * "License"); you may not use this file except in compliance
58+ * with the License. You may obtain a copy of the License at
59+ *
60+ * http://www.apache.org/licenses/LICENSE-2.0
61+ *
62+ * Unless required by applicable law or agreed to in writing,
63+ * software distributed under the License is distributed on an
64+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
65+ * KIND, either express or implied. See the License for the
66+ * specific language governing permissions and limitations
67+ * under the License.
68+ *
69+*/
70+
71+#include <QtCore>
72+
73+#include "battery.h"
74+
75+BatteryStatus::BatteryStatus(Cordova *cordova) : CPlugin(cordova) {
76+ _scId = 0;
77+
78+ connect(&_batteryInfo, SIGNAL(remainingCapacityChanged(int,int)), this, SLOT(remainingCapacityChanged(int,int)));
79+ connect(&_batteryInfo, SIGNAL(chargerTypeChanged(QBatteryInfo::ChargerType)), this, SLOT(chargerTypeChanged(QBatteryInfo::ChargerType)));
80+}
81+
82+void BatteryStatus::remainingCapacityChanged(int battery, int capacity) {
83+ Q_UNUSED(battery);
84+ Q_UNUSED(capacity);
85+
86+ fireEvents();
87+}
88+
89+void BatteryStatus::chargerTypeChanged(QBatteryInfo::ChargerType type) {
90+ Q_UNUSED(type);
91+
92+ fireEvents();
93+}
94+
95+void BatteryStatus::fireEvents() {
96+ int fullCount = 0;
97+ bool isPlugged = false;
98+
99+ int remaining = 0, total = 0;
100+ for (int i = 0; i < _batteryInfo.batteryCount(); i++) {
101+ isPlugged = (_batteryInfo.chargingState(i) == QBatteryInfo::Charging) || isPlugged;
102+ fullCount += _batteryInfo.chargingState(i) == QBatteryInfo::Full;
103+
104+ remaining += _batteryInfo.remainingCapacity(i);
105+ total += _batteryInfo.maximumCapacity(i);
106+ }
107+
108+ isPlugged = isPlugged || (_batteryInfo.batteryCount() == fullCount);
109+
110+ if (_scId) {
111+ QVariantMap obj;
112+ obj.insert("isPlugged", (int)isPlugged);
113+ if (total != 0)
114+ obj.insert("level", remaining * 100 / total);
115+ else
116+ obj.insert("level", 100);
117+
118+ this->callbackWithoutRemove(_scId, CordovaInternal::format(obj));
119+ }
120+}
121+
122+void BatteryStatus::start(int scId, int) {
123+ _scId = scId;
124+}
125+
126+void BatteryStatus::stop(int, int) {
127+ _scId = 0;
128+}
129
130=== added file 'build/src/plugins/org.apache.cordova.battery-status/battery.h'
131--- build/src/plugins/org.apache.cordova.battery-status/battery.h 1970-01-01 00:00:00 +0000
132+++ build/src/plugins/org.apache.cordova.battery-status/battery.h 2014-02-19 16:53:58 +0000
133@@ -0,0 +1,62 @@
134+/*
135+ * Licensed to the Apache Software Foundation (ASF) under one
136+ * or more contributor license agreements. See the NOTICE file
137+ * distributed with this work for additional information
138+ * regarding copyright ownership. The ASF licenses this file
139+ * to you under the Apache License, Version 2.0 (the
140+ * "License"); you may not use this file except in compliance
141+ * with the License. You may obtain a copy of the License at
142+ *
143+ * http://www.apache.org/licenses/LICENSE-2.0
144+ *
145+ * Unless required by applicable law or agreed to in writing,
146+ * software distributed under the License is distributed on an
147+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
148+ * KIND, either express or implied. See the License for the
149+ * specific language governing permissions and limitations
150+ * under the License.
151+ *
152+*/
153+
154+#ifndef BATTERY_H_AAAAAAAA
155+#define BATTERY_H_AAAAAAAA
156+
157+#include <QBatteryInfo>
158+
159+#include <cplugin.h>
160+
161+class BatteryStatus: public CPlugin {
162+ Q_OBJECT
163+public:
164+ explicit BatteryStatus(Cordova *cordova);
165+
166+ virtual const QString fullName() override {
167+ return BatteryStatus::fullID();
168+ }
169+
170+ virtual const QString shortName() override {
171+ return "Battery";
172+ }
173+
174+ static const QString fullID() {
175+ return "Battery";
176+ }
177+
178+public slots:
179+ void start(int scId, int ecId);
180+ void stop(int scId, int ecId);
181+
182+private slots:
183+ void remainingCapacityChanged(int battery, int capacity);
184+ void chargerTypeChanged(QBatteryInfo::ChargerType type);
185+ void onlineStatusChanged(bool isOnline);
186+
187+private:
188+ void fireEvents();
189+
190+ QBatteryInfo _batteryInfo;
191+
192+ int _scId;
193+};
194+
195+#endif
196
197=== added directory 'build/src/plugins/org.apache.cordova.camera'
198=== added file 'build/src/plugins/org.apache.cordova.camera/camera.cpp'
199--- build/src/plugins/org.apache.cordova.camera/camera.cpp 1970-01-01 00:00:00 +0000
200+++ build/src/plugins/org.apache.cordova.camera/camera.cpp 2014-02-19 16:53:58 +0000
201@@ -0,0 +1,143 @@
202+/*
203+ *
204+ * Licensed to the Apache Software Foundation (ASF) under one
205+ * or more contributor license agreements. See the NOTICE file
206+ * distributed with this work for additional information
207+ * regarding copyright ownership. The ASF licenses this file
208+ * to you under the Apache License, Version 2.0 (the
209+ * "License"); you may not use this file except in compliance
210+ * with the License. You may obtain a copy of the License at
211+ *
212+ * http://www.apache.org/licenses/LICENSE-2.0
213+ *
214+ * Unless required by applicable law or agreed to in writing,
215+ * software distributed under the License is distributed on an
216+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
217+ * KIND, either express or implied. See the License for the
218+ * specific language governing permissions and limitations
219+ * under the License.
220+ *
221+*/
222+
223+#include "camera.h"
224+#include <cordova.h>
225+
226+#include <QCameraViewfinder>
227+#include <QCameraImageCapture>
228+#include <QGraphicsObject>
229+#include <QCloseEvent>
230+#include <QQuickItem>
231+
232+const char code[] = "\
233+var component, object; \
234+function createObject() { \
235+ component = Qt.createComponent(%1); \
236+ if (component.status == Component.Ready) \
237+ finishCreation(); \
238+ else \
239+ component.statusChanged.connect(finishCreation); \
240+} \
241+function finishCreation() { \
242+ CordovaWrapper.object = component.createObject(root, \
243+ {root: root, cordova: cordova}); \
244+} \
245+createObject()";
246+
247+
248+Camera::Camera(Cordova *cordova):
249+ CPlugin(cordova),
250+ _lastScId(0),
251+ _lastEcId(0) {
252+}
253+
254+bool Camera::preprocessImage(QString &path) {
255+ bool convertToPNG = (*_options.find("encodingType")).toInt() == Camera::PNG;
256+ int quality = (*_options.find("quality")).toInt();
257+ int width = (*_options.find("targetWidth")).toInt();
258+ int height = (*_options.find("targetHeight")).toInt();
259+
260+ QImage image(path);
261+ if (width <= 0)
262+ width = image.width();
263+ if (height <= 0)
264+ height = image.height();
265+ image = image.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
266+
267+ QFile oldImage(path);
268+ QTemporaryFile newImage;
269+
270+ const char *type;
271+ if (convertToPNG) {
272+ newImage.setFileTemplate("imgXXXXXX.png");
273+ type = "png";
274+ } else {
275+ newImage.setFileTemplate("imgXXXXXX.jpg");
276+ type = "jpg";
277+ }
278+
279+ newImage.open();
280+ newImage.setAutoRemove(false);
281+ image.save(newImage.fileName(), type, quality);
282+
283+ path = newImage.fileName();
284+ oldImage.remove();
285+
286+ return true;
287+}
288+
289+void Camera::onImageSaved(QString path) {
290+ bool dataURL = _options.find("destinationType")->toInt() == Camera::DATA_URL;
291+
292+ QString cbParams;
293+ if (preprocessImage(path)) {
294+ QString absolutePath = QFileInfo(path).absoluteFilePath();
295+ if (dataURL) {
296+ QFile image(absolutePath);
297+ image.open(QIODevice::ReadOnly);
298+ QByteArray content = image.readAll().toBase64();
299+ cbParams = QString("\"%1\"").arg(content.data());
300+ image.remove();
301+ } else {
302+ cbParams = CordovaInternal::format(QUrl::fromLocalFile(absolutePath).toString());
303+ }
304+ }
305+
306+ this->callback(_lastScId, cbParams);
307+
308+ _lastEcId = _lastScId = 0;
309+}
310+
311+void Camera::takePicture(int scId, int ecId, int quality, int destinationType, int/*sourceType*/, int targetWidth, int targetHeight, int encodingType,
312+ int/*mediaType*/, bool/*allowEdit*/, bool/*correctOrientation*/, bool/*saveToPhotoAlbum*/, const QVariantMap &/*popoverOptions*/, int/*cameraDirection*/) {
313+ if (_camera.isNull()) {
314+ _camera = QSharedPointer<QCamera>(new QCamera());
315+ }
316+
317+ if (((_lastScId || _lastEcId) && (_lastScId != scId && _lastEcId != ecId)) || !_camera->isAvailable() || _camera->lockStatus() != QCamera::Unlocked) {
318+ this->cb(_lastEcId, "Device is busy");
319+ return;
320+ }
321+
322+ _options.clear();
323+ _options.insert("quality", quality);
324+ _options.insert("destinationType", destinationType);
325+ _options.insert("targetWidth", targetWidth);
326+ _options.insert("targetHeight", targetHeight);
327+ _options.insert("encodingType", encodingType);
328+
329+ _lastScId = scId;
330+ _lastEcId = ecId;
331+
332+ QString path = m_cordova->get_app_dir() + "/../qml/CaptureWidget.qml";
333+
334+ // TODO: relative url
335+ QString qml = QString(code).arg(CordovaInternal::format(path));
336+ m_cordova->execQML(qml);
337+}
338+
339+void Camera::cancel() {
340+ m_cordova->execQML("CordovaWrapper.object.destroy()");
341+ this->cb(_lastEcId, "canceled");
342+
343+ _lastEcId = _lastScId = 0;
344+}
345
346=== added file 'build/src/plugins/org.apache.cordova.camera/camera.h'
347--- build/src/plugins/org.apache.cordova.camera/camera.h 1970-01-01 00:00:00 +0000
348+++ build/src/plugins/org.apache.cordova.camera/camera.h 2014-02-19 16:53:58 +0000
349@@ -0,0 +1,76 @@
350+/*
351+ *
352+ * Licensed to the Apache Software Foundation (ASF) under one
353+ * or more contributor license agreements. See the NOTICE file
354+ * distributed with this work for additional information
355+ * regarding copyright ownership. The ASF licenses this file
356+ * to you under the Apache License, Version 2.0 (the
357+ * "License"); you may not use this file except in compliance
358+ * with the License. You may obtain a copy of the License at
359+ *
360+ * http://www.apache.org/licenses/LICENSE-2.0
361+ *
362+ * Unless required by applicable law or agreed to in writing,
363+ * software distributed under the License is distributed on an
364+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
365+ * KIND, either express or implied. See the License for the
366+ * specific language governing permissions and limitations
367+ * under the License.
368+ *
369+*/
370+
371+#ifndef CAMERA_H
372+#define CAMERA_H
373+
374+#include <cplugin.h>
375+
376+#include <QtCore>
377+#include <QQuickView>
378+#include <QCamera>
379+#include <QtMultimediaWidgets/QCameraViewfinder>
380+#include <QCameraImageCapture>
381+
382+class Camera: public CPlugin {
383+ Q_OBJECT
384+public:
385+ explicit Camera(Cordova *cordova);
386+
387+ virtual const QString fullName() override {
388+ return Camera::fullID();
389+ }
390+
391+ virtual const QString shortName() override {
392+ return "Camera";
393+ }
394+
395+ static const QString fullID() {
396+ return "Camera";
397+ }
398+
399+public slots:
400+ void takePicture(int scId, int ecId, int quality, int destinationType, int/*sourceType*/, int targetWidth, int targetHeight, int encodingType,
401+ int/*mediaType*/, bool/*allowEdit*/, bool/*correctOrientation*/, bool/*saveToPhotoAlbum*/, const QVariantMap &popoverOptions, int cameraDirection);
402+ void cancel();
403+
404+ void onImageSaved(QString path);
405+
406+private:
407+ bool preprocessImage(QString &path);
408+
409+ int _lastScId;
410+ int _lastEcId;
411+ QSharedPointer<QCamera> _camera;
412+
413+ QVariantMap _options;
414+protected:
415+ enum DestinationType {
416+ DATA_URL = 0,
417+ FILE_URI = 1
418+ };
419+ enum EncodingType {
420+ JPEG = 0,
421+ PNG = 1
422+ };
423+};
424+
425+#endif // CAMERA_H
426
427=== added directory 'build/src/plugins/org.apache.cordova.console'
428=== added file 'build/src/plugins/org.apache.cordova.console/console.cpp'
429--- build/src/plugins/org.apache.cordova.console/console.cpp 1970-01-01 00:00:00 +0000
430+++ build/src/plugins/org.apache.cordova.console/console.cpp 2014-02-19 16:53:58 +0000
431@@ -0,0 +1,29 @@
432+/*
433+ * Licensed under the Apache License, Version 2.0 (the "License");
434+ * you may not use this file except in compliance with the License.
435+ * You may obtain a copy of the License at
436+ *
437+ * http://www.apache.org/licenses/LICENSE-2.0
438+ *
439+ * Unless required by applicable law or agreed to in writing, software
440+ * distributed under the License is distributed on an "AS IS" BASIS,
441+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
442+ * See the License for the specific language governing permissions and
443+ * limitations under the License.
444+ */
445+
446+#include "console.h"
447+
448+#include <iostream>
449+
450+Console::Console(Cordova *cordova) : CPlugin(cordova) {
451+}
452+
453+void Console::logLevel(int scId, int ecId, QString level, QString message) {
454+ Q_UNUSED(scId)
455+ Q_UNUSED(ecId)
456+
457+ if (level != "LOG")
458+ std::cout << "[" << level.toStdString() << "] ";
459+ std::cout << message.toStdString() << std::endl;
460+}
461
462=== added file 'build/src/plugins/org.apache.cordova.console/console.h'
463--- build/src/plugins/org.apache.cordova.console/console.h 1970-01-01 00:00:00 +0000
464+++ build/src/plugins/org.apache.cordova.console/console.h 2014-02-19 16:53:58 +0000
465@@ -0,0 +1,43 @@
466+/*
467+ * Licensed under the Apache License, Version 2.0 (the "License");
468+ * you may not use this file except in compliance with the License.
469+ * You may obtain a copy of the License at
470+ *
471+ * http://www.apache.org/licenses/LICENSE-2.0
472+ *
473+ * Unless required by applicable law or agreed to in writing, software
474+ * distributed under the License is distributed on an "AS IS" BASIS,
475+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
476+ * See the License for the specific language governing permissions and
477+ * limitations under the License.
478+ */
479+
480+#ifndef CONSOLE_H_FDSVCXGFRS
481+#define CONSOLE_H_FDSVCXGFRS
482+
483+#include <cplugin.h>
484+
485+#include <QtCore>
486+
487+class Console : public CPlugin {
488+ Q_OBJECT
489+public:
490+ explicit Console(Cordova *cordova);
491+
492+ virtual const QString fullName() override {
493+ return Console::fullID();
494+ }
495+
496+ virtual const QString shortName() override {
497+ return "Console";
498+ }
499+
500+ static const QString fullID() {
501+ return "Console";
502+ }
503+
504+public slots:
505+ void logLevel(int scId, int ecId, QString level, QString message);
506+};
507+
508+#endif
509
510=== added directory 'build/src/plugins/org.apache.cordova.device'
511=== added directory 'build/src/plugins/org.apache.cordova.device-motion'
512=== added file 'build/src/plugins/org.apache.cordova.device-motion/accelerometer.cpp'
513--- build/src/plugins/org.apache.cordova.device-motion/accelerometer.cpp 1970-01-01 00:00:00 +0000
514+++ build/src/plugins/org.apache.cordova.device-motion/accelerometer.cpp 2014-02-19 16:53:58 +0000
515@@ -0,0 +1,58 @@
516+/*
517+ *
518+ * Licensed under the Apache License, Version 2.0 (the "License");
519+ * you may not use this file except in compliance with the License.
520+ * You may obtain a copy of the License at
521+ *
522+ * http://www.apache.org/licenses/LICENSE-2.0
523+ *
524+ * Unless required by applicable law or agreed to in writing,
525+ * software distributed under the License is distributed on an
526+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
527+ * KIND, either express or implied. See the License for the
528+ * specific language governing permissions and limitations
529+ * under the License.
530+ *
531+*/
532+
533+#include <cassert>
534+#include "accelerometer.h"
535+
536+DeviceMotion::DeviceMotion(Cordova *cordova): CPlugin(cordova), _scId(0), _ecId(0) {
537+ _accelerometerSource = QSharedPointer<QAccelerometer>(new QAccelerometer());
538+ _sensorAvaliable = _accelerometerSource->start();
539+ connect(_accelerometerSource.data(), SIGNAL(readingChanged()), SLOT(updateSensor()));
540+}
541+
542+void DeviceMotion::start(int scId, int ecId) {
543+ assert(_ecId == 0);
544+ assert(_scId == 0);
545+
546+ _ecId = ecId;
547+ _scId = scId;
548+
549+ if (!_sensorAvaliable) {
550+ this->cb(ecId);
551+ return;
552+ }
553+}
554+
555+void DeviceMotion::stop(int, int) {
556+ _scId = 0;
557+ _ecId = 0;
558+}
559+
560+void DeviceMotion::updateSensor() {
561+ QAccelerometerReading *accelerometer = _accelerometerSource->reading();
562+
563+ QVariantMap obj;
564+ obj.insert("x", accelerometer->x());
565+ obj.insert("y", accelerometer->y());
566+ obj.insert("z", accelerometer->z());
567+ // accelerometer->timestamp() is not sutiable.
568+ // Timestamps values are microseconds since _a_ fixed point(depend on backend).
569+ obj.insert("timestamp", QDateTime::currentDateTime().toMSecsSinceEpoch());
570+
571+ if (_scId)
572+ this->cb(_scId, obj);
573+}
574
575=== added file 'build/src/plugins/org.apache.cordova.device-motion/accelerometer.h'
576--- build/src/plugins/org.apache.cordova.device-motion/accelerometer.h 1970-01-01 00:00:00 +0000
577+++ build/src/plugins/org.apache.cordova.device-motion/accelerometer.h 2014-02-19 16:53:58 +0000
578@@ -0,0 +1,55 @@
579+/*
580+ *
581+ * Licensed under the Apache License, Version 2.0 (the "License");
582+ * you may not use this file except in compliance with the License.
583+ * You may obtain a copy of the License at
584+ *
585+ * http://www.apache.org/licenses/LICENSE-2.0
586+ *
587+ * Unless required by applicable law or agreed to in writing,
588+ * software distributed under the License is distributed on an
589+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
590+ * KIND, either express or implied. See the License for the
591+ * specific language governing permissions and limitations
592+ * under the License.
593+ *
594+*/
595+
596+#ifndef ACCELEROMETER_H
597+#define ACCELEROMETER_H
598+
599+#include <cplugin.h>
600+#include <QAccelerometer>
601+#include <QtCore>
602+
603+class DeviceMotion: public CPlugin {
604+ Q_OBJECT
605+public:
606+ explicit DeviceMotion(Cordova *cordova);
607+
608+ virtual const QString fullName() override {
609+ return DeviceMotion::fullID();
610+ }
611+
612+ virtual const QString shortName() override {
613+ return "Accelerometer";
614+ }
615+
616+ static const QString fullID() {
617+ return "Accelerometer";
618+ }
619+
620+public slots:
621+ void start(int scId, int ecId);
622+ void stop(int scId, int ecId);
623+
624+protected slots:
625+ void updateSensor();
626+
627+private:
628+ int _scId, _ecId;
629+ bool _sensorAvaliable;
630+ QSharedPointer<QAccelerometer> _accelerometerSource;
631+};
632+
633+#endif
634
635=== added directory 'build/src/plugins/org.apache.cordova.device-orientation'
636=== added file 'build/src/plugins/org.apache.cordova.device-orientation/compass.cpp'
637--- build/src/plugins/org.apache.cordova.device-orientation/compass.cpp 1970-01-01 00:00:00 +0000
638+++ build/src/plugins/org.apache.cordova.device-orientation/compass.cpp 2014-02-19 16:53:58 +0000
639@@ -0,0 +1,75 @@
640+/*
641+ * Licensed under the Apache License, Version 2.0 (the "License");
642+ * you may not use this file except in compliance with the License.
643+ * You may obtain a copy of the License at
644+ *
645+ * http://www.apache.org/licenses/LICENSE-2.0
646+ *
647+ * Unless required by applicable law or agreed to in writing, software
648+ * distributed under the License is distributed on an "AS IS" BASIS,
649+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
650+ * See the License for the specific language governing permissions and
651+ * limitations under the License.
652+ */
653+
654+#include "compass.h"
655+
656+DeviceOrientation::DeviceOrientation(Cordova *cordova): CPlugin(cordova), _validData(false) {
657+ _compass.connectToBackend();
658+ connect(&_compass, SIGNAL(readingChanged()), SLOT(updateSensor()));
659+ connect(&_compass, SIGNAL(sensorError(int)), SLOT(sensorError(int)));
660+}
661+
662+void DeviceOrientation::getHeading(int scId, int ecId, QVariantMap options) {
663+ Q_UNUSED(options);
664+ if (_compass.isConnectedToBackend() || !_compass.start()) {
665+ this->callback(ecId, "CompassError.COMPASS_NOT_SUPPORTED");
666+ return;
667+ }
668+
669+ _successCallbacks << scId;
670+ _errorCallbacks << ecId;
671+
672+ if (_validData) {
673+ reportResult();
674+ return;
675+ }
676+}
677+
678+void DeviceOrientation::sensorError(int error) {
679+ Q_UNUSED(error);
680+
681+ for (int ecId: _errorCallbacks) {
682+ this->callback(ecId, "CompassError.COMPASS_INTERNAL_ERR");
683+ }
684+
685+ _errorCallbacks.clear();
686+ _successCallbacks.clear();
687+ _validData = false;
688+}
689+
690+void DeviceOrientation::reportResult() {
691+ QVariantMap obj;
692+
693+ obj.insert("magneticHeading", _azymuth);
694+ obj.insert("trueHeading", _azymuth);
695+ obj.insert("headingAccuracy", _accuracy);
696+ obj.insert("timestamp", _timestamp);
697+
698+ for (int scId: _successCallbacks) {
699+ this->cb(scId, obj);
700+ }
701+
702+ _errorCallbacks.clear();
703+ _successCallbacks.clear();
704+}
705+
706+void DeviceOrientation::updateSensor(){
707+ QCompassReading *heading = _compass.reading();
708+ _azymuth = heading->azimuth();
709+ _accuracy = heading->calibrationLevel();
710+ _timestamp = QDateTime::currentDateTime().toMSecsSinceEpoch();
711+
712+ _validData = true;
713+ reportResult();
714+}
715
716=== added file 'build/src/plugins/org.apache.cordova.device-orientation/compass.h'
717--- build/src/plugins/org.apache.cordova.device-orientation/compass.h 1970-01-01 00:00:00 +0000
718+++ build/src/plugins/org.apache.cordova.device-orientation/compass.h 2014-02-19 16:53:58 +0000
719@@ -0,0 +1,58 @@
720+/*
721+ * Licensed under the Apache License, Version 2.0 (the "License");
722+ * you may not use this file except in compliance with the License.
723+ * You may obtain a copy of the License at
724+ *
725+ * http://www.apache.org/licenses/LICENSE-2.0
726+ *
727+ * Unless required by applicable law or agreed to in writing, software
728+ * distributed under the License is distributed on an "AS IS" BASIS,
729+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
730+ * See the License for the specific language governing permissions and
731+ * limitations under the License.
732+ */
733+
734+#ifndef COMPASS_H_HKFSAHKDFAS
735+#define COMPASS_H_HKFSAHKDFAS
736+
737+#include <cplugin.h>
738+#include <QCompass>
739+#include <QtCore>
740+
741+class DeviceOrientation: public CPlugin {
742+ Q_OBJECT
743+public:
744+ explicit DeviceOrientation(Cordova *cordova);
745+
746+ virtual const QString fullName() override {
747+ return DeviceOrientation::fullID();
748+ }
749+
750+ virtual const QString shortName() override {
751+ return "Compass";
752+ }
753+
754+ static const QString fullID() {
755+ return "Compass";
756+ }
757+
758+public slots:
759+ void getHeading(int scId, int ecId, QVariantMap options);
760+
761+protected slots:
762+ void updateSensor();
763+ void sensorError(int error);
764+
765+private:
766+ void reportResult();
767+ QCompass _compass;
768+ QList<int> _successCallbacks;
769+ QList<int> _errorCallbacks;
770+
771+ double _azymuth;
772+ double _accuracy;
773+ qtimestamp _timestamp;
774+ bool _validData;
775+};
776+
777+#endif
778
779=== added file 'build/src/plugins/org.apache.cordova.device/device.cpp'
780--- build/src/plugins/org.apache.cordova.device/device.cpp 1970-01-01 00:00:00 +0000
781+++ build/src/plugins/org.apache.cordova.device/device.cpp 2014-02-19 16:53:58 +0000
782@@ -0,0 +1,64 @@
783+/*
784+ * Copyright 2011 Wolfgang Koller - http://www.gofg.at/
785+ *
786+ * Licensed under the Apache License, Version 2.0 (the "License");
787+ * you may not use this file except in compliance with the License.
788+ * You may obtain a copy of the License at
789+ *
790+ * http://www.apache.org/licenses/LICENSE-2.0
791+ *
792+ * Unless required by applicable law or agreed to in writing, software
793+ * distributed under the License is distributed on an "AS IS" BASIS,
794+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
795+ * See the License for the specific language governing permissions and
796+ * limitations under the License.
797+ */
798+
799+#include <QDeviceInfo>
800+#include <QtSystemInfo>
801+
802+#include"device.h"
803+
804+#define CORDOVA "3.0.0"
805+
806+Device::Device(Cordova *cordova) : CPlugin(cordova) {
807+}
808+
809+static QString getOSName() {
810+#ifdef Q_OS_SYMBIAN
811+ QString platform = "Symbian";
812+#endif
813+#ifdef Q_OS_WIN
814+ QString platform = "Windows";
815+#endif
816+#ifdef Q_OS_WINCE
817+ QString platform = "Windows CE";
818+#endif
819+#ifdef Q_OS_LINUX
820+ QString platform = "Linux";
821+#endif
822+ return platform;
823+}
824+
825+void Device::getInfo(int scId, int ecId) {
826+ Q_UNUSED(ecId)
827+
828+ QDeviceInfo systemDeviceInfo;
829+ QDeviceInfo systemInfo;
830+
831+ QString platform = getOSName();
832+
833+ QString uuid = systemDeviceInfo.uniqueDeviceID();
834+ if (uuid.isEmpty()) {
835+ QString deviceDescription = systemInfo.imei(0) + ";" + systemInfo.manufacturer() + ";" + systemInfo.model() + ";" + systemInfo.productName() + ";" + platform;
836+ QString user = qgetenv("USER");
837+ if (user.isEmpty()) {
838+ user = qgetenv("USERNAME");
839+ if (user.isEmpty())
840+ user = QDir::homePath();
841+ }
842+ uuid = QString(QCryptographicHash::hash((deviceDescription + ";" + user).toUtf8(), QCryptographicHash::Md5).toHex());
843+ }
844+
845+ this->cb(scId, systemDeviceInfo.model(), CORDOVA, platform, uuid, systemInfo.version(QDeviceInfo::Os));
846+}
847
848=== added file 'build/src/plugins/org.apache.cordova.device/device.h'
849--- build/src/plugins/org.apache.cordova.device/device.h 1970-01-01 00:00:00 +0000
850+++ build/src/plugins/org.apache.cordova.device/device.h 2014-02-19 16:53:58 +0000
851@@ -0,0 +1,47 @@
852+/*
853+ * Copyright 2011 Wolfgang Koller - http://www.gofg.at/
854+ *
855+ * Licensed under the Apache License, Version 2.0 (the "License");
856+ * you may not use this file except in compliance with the License.
857+ * You may obtain a copy of the License at
858+ *
859+ * http://www.apache.org/licenses/LICENSE-2.0
860+ *
861+ * Unless required by applicable law or agreed to in writing, software
862+ * distributed under the License is distributed on an "AS IS" BASIS,
863+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
864+ * See the License for the specific language governing permissions and
865+ * limitations under the License.
866+ */
867+
868+#ifndef DEVICE_H_FDSAFAS
869+#define DEVICE_H_FDSAFAS
870+
871+#include <QtCore>
872+
873+#include <cplugin.h>
874+
875+class Device: public CPlugin {
876+ Q_OBJECT
877+public:
878+ explicit Device(Cordova *cordova);
879+
880+ virtual const QString fullName() override {
881+ return Device::fullID();
882+ }
883+
884+ virtual const QString shortName() override {
885+ return "Device";
886+ }
887+
888+ static const QString fullID() {
889+ return "com.cordova.Device";
890+ }
891+
892+signals:
893+
894+public slots:
895+ void getInfo(int scId, int ecId);
896+};
897+
898+#endif
899
900=== added directory 'build/src/plugins/org.apache.cordova.dialogs'
901=== added file 'build/src/plugins/org.apache.cordova.dialogs/notification.cpp'
902--- build/src/plugins/org.apache.cordova.dialogs/notification.cpp 1970-01-01 00:00:00 +0000
903+++ build/src/plugins/org.apache.cordova.dialogs/notification.cpp 2014-02-19 16:53:58 +0000
904@@ -0,0 +1,81 @@
905+/*
906+ *
907+ * Licensed under the Apache License, Version 2.0 (the "License");
908+ * you may not use this file except in compliance with the License.
909+ * You may obtain a copy of the License at
910+ *
911+ * http://www.apache.org/licenses/LICENSE-2.0
912+ *
913+ * Unless required by applicable law or agreed to in writing, software
914+ * distributed under the License is distributed on an "AS IS" BASIS,
915+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
916+ * See the License for the specific language governing permissions and
917+ * limitations under the License.
918+ */
919+
920+#include "notification.h"
921+
922+#include <QApplication>
923+
924+#include <QMediaPlayer>
925+#include <QMessageBox>
926+
927+void Dialogs::beep(int scId, int ecId, int times) {
928+ Q_UNUSED(scId)
929+ Q_UNUSED(ecId)
930+ Q_UNUSED(times)
931+ QMediaPlayer* player = new QMediaPlayer;
932+ player->setVolume(100);
933+ player->setMedia(QUrl::fromLocalFile("/usr/share/sounds/ubuntu/stereo/bell.ogg"));
934+ player->play();
935+}
936+
937+void Dialogs::alert(int scId, int ecId, const QString &message, const QString &title, const QString &buttonLabel) {
938+ QStringList list;
939+ list.append(buttonLabel);
940+
941+ confirm(scId, ecId, message, title, list);
942+}
943+
944+void Dialogs::confirm(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels) {
945+ Q_UNUSED(ecId);
946+
947+ //FIXME:
948+ assert(!_alertCallback);
949+ _alertCallback = scId;
950+
951+ QString s1, s2, s3;
952+ if (buttonLabels.size() > 0)
953+ s1 = buttonLabels[0];
954+ if (buttonLabels.size() > 1)
955+ s2 = buttonLabels[1];
956+ if (buttonLabels.size() > 2)
957+ s3 = buttonLabels[2];
958+
959+ QString path = m_cordova->get_app_dir() + "/../qml/notification.qml";
960+ //FIXME:
961+ QString qml = QString("PopupUtils.open(\"%1\", root, { root: root, cordova: cordova, title: \"%2\", text: \"%3\", promptVisible: false, button1Text: \"%4\", button2Text: \"%5\", button3Text: \"%6\" })")
962+ .arg(path).arg(title).arg(message).arg(s1).arg(s2).arg(s3);
963+ m_cordova->execQML(qml);
964+}
965+
966+void Dialogs::prompt(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels, const QString &defaultText) {
967+ Q_UNUSED(ecId)
968+
969+ assert(!_alertCallback);
970+ _alertCallback = scId;
971+
972+ QString s1, s2, s3;
973+ if (buttonLabels.size() > 0)
974+ s1 = buttonLabels[0];
975+ if (buttonLabels.size() > 1)
976+ s2 = buttonLabels[1];
977+ if (buttonLabels.size() > 2)
978+ s3 = buttonLabels[2];
979+ QString path = m_cordova->get_app_dir() + "/../qml/notification.qml";
980+ QString qml = QString("PopupUtils.open(\"%1\", root, { root: root, cordova: cordova, title: \"%2\", text: \"%3\", promptVisible: true, defaultPromptText: \"%7\", button1Text: \"%4\", button2Text: \"%5\", button3Text: \"%6\" })")
981+ .arg(path).arg(title).arg(message).arg(s1).arg(s2).arg(s3).arg(defaultText);
982+
983+ qDebug() << qml;
984+ m_cordova->execQML(qml);
985+}
986
987=== added file 'build/src/plugins/org.apache.cordova.dialogs/notification.h'
988--- build/src/plugins/org.apache.cordova.dialogs/notification.h 1970-01-01 00:00:00 +0000
989+++ build/src/plugins/org.apache.cordova.dialogs/notification.h 2014-02-19 16:53:58 +0000
990@@ -0,0 +1,63 @@
991+/*
992+ *
993+ * Licensed under the Apache License, Version 2.0 (the "License");
994+ * you may not use this file except in compliance with the License.
995+ * You may obtain a copy of the License at
996+ *
997+ * http://www.apache.org/licenses/LICENSE-2.0
998+ *
999+ * Unless required by applicable law or agreed to in writing, software
1000+ * distributed under the License is distributed on an "AS IS" BASIS,
1001+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1002+ * See the License for the specific language governing permissions and
1003+ * limitations under the License.
1004+ */
1005+
1006+#ifndef NOTIFICATION_H
1007+#define NOTIFICATION_H
1008+
1009+#include <QtQuick>
1010+#include <cplugin.h>
1011+#include <cordova.h>
1012+
1013+class Dialogs: public CPlugin {
1014+ Q_OBJECT
1015+public:
1016+ explicit Dialogs(Cordova *cordova): CPlugin(cordova), _alertCallback(0) {
1017+ }
1018+
1019+ virtual const QString fullName() override {
1020+ return Dialogs::fullID();
1021+ }
1022+
1023+ virtual const QString shortName() override {
1024+ return "Notification";
1025+ }
1026+
1027+ static const QString fullID() {
1028+ return "Notification";
1029+ }
1030+public slots:
1031+ void beep(int scId, int ecId, int times);
1032+ void alert(int scId, int ecId, const QString &message, const QString &title, const QString &buttonLabel);
1033+ void confirm(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels);
1034+ void prompt(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels, const QString &defaultText);
1035+
1036+ void notificationDialogButtonPressed(int buttonId, const QString &text) {
1037+ if (text.size()) {
1038+ QVariantMap res;
1039+ res.insert("buttonIndex", buttonId);
1040+ res.insert("input1", text);
1041+ this->cb(_alertCallback, res);
1042+ } else {
1043+ this->cb(_alertCallback, buttonId);
1044+ }
1045+ _alertCallback = 0;
1046+ }
1047+
1048+private:
1049+ QQmlComponent *_component;
1050+ int _alertCallback;
1051+};
1052+
1053+#endif
1054
1055=== added directory 'build/src/plugins/org.apache.cordova.file'
1056=== added directory 'build/src/plugins/org.apache.cordova.file-transfer'
1057=== added file 'build/src/plugins/org.apache.cordova.file-transfer/file-transfer.cpp'
1058--- build/src/plugins/org.apache.cordova.file-transfer/file-transfer.cpp 1970-01-01 00:00:00 +0000
1059+++ build/src/plugins/org.apache.cordova.file-transfer/file-transfer.cpp 2014-02-19 16:53:58 +0000
1060@@ -0,0 +1,247 @@
1061+/*
1062+ *
1063+ * Copyright 2013 Canonical Ltd.
1064+ *
1065+ * Licensed under the Apache License, Version 2.0 (the "License");
1066+ * you may not use this file except in compliance with the License.
1067+ * You may obtain a copy of the License at
1068+ *
1069+ * http://www.apache.org/licenses/LICENSE-2.0
1070+ *
1071+ * Unless required by applicable law or agreed to in writing,
1072+ * software distributed under the License is distributed on an
1073+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1074+ * KIND, either express or implied. See the License for the
1075+ * specific language governing permissions and limitations
1076+ * under the License.
1077+ *
1078+*/
1079+
1080+#include "file-transfer.h"
1081+#include <cassert>
1082+
1083+void FileTransfer::download(int scId, int ecId, const QString& url, const QString &target, bool /*trustAllHost*/, int id, const QVariantMap &/*headers*/) {
1084+ QSharedPointer<FileTransferRequest> request(new FileTransferRequest(_manager, scId, ecId, id, this));
1085+
1086+ assert(_id2request.find(id) == _id2request.end());
1087+
1088+ _id2request.insert(id, request);
1089+
1090+ request->connect(request.data(), &FileTransferRequest::done, [&]() {
1091+ auto it = _id2request.find(id);
1092+ while (it != _id2request.end() && it.key() == id) {
1093+ if (it.value().data() == request.data()) {
1094+ _id2request.erase(it);
1095+ break;
1096+ }
1097+ it++;
1098+ }
1099+ });
1100+ request->download(url, target);
1101+}
1102+
1103+void FileTransfer::upload(int scId, int ecId, const QString &filePath, const QString& url, const QString& fileKey, const QString& fileName, const QString& mimeType,
1104+ const QVariantMap & params, bool /*trustAllHosts*/, bool /*chunkedMode*/, const QVariantMap &headers, int id, const QString &httpMethod) {
1105+ QSharedPointer<FileTransferRequest> request(new FileTransferRequest(_manager, scId, ecId, id, this));
1106+
1107+ assert(_id2request.find(id) == _id2request.end());
1108+
1109+ _id2request.insert(id, request);
1110+
1111+ request->connect(request.data(), &FileTransferRequest::done, [&]() {
1112+ auto it = _id2request.find(id);
1113+ while (it != _id2request.end() && it.key() == id) {
1114+ if (it.value().data() == request.data()) {
1115+ _id2request.erase(it);
1116+ break;
1117+ }
1118+ it++;
1119+ }
1120+ });
1121+ request->upload(url, filePath, fileKey, fileName, mimeType, params, headers);
1122+}
1123+
1124+void FileTransfer::abort(int scId, int ecId, int id) {
1125+ Q_UNUSED(scId)
1126+ Q_UNUSED(ecId)
1127+
1128+ auto it = _id2request.find(id);
1129+ while (it != _id2request.end() && it.key() == id) {
1130+ (*it)->abort();
1131+ it++;
1132+ }
1133+}
1134+
1135+void FileTransferRequest::download(const QString& uri, const QString &target) {
1136+ QUrl url(uri);
1137+ QNetworkRequest request;
1138+
1139+ if (!url.isValid()) {
1140+ QVariantMap map;
1141+ map.insert("code", INVALID_URL_ERR);
1142+ map.insert("source", uri);
1143+ map.insert("target", target);
1144+ _plugin->cb(_ecId, map);
1145+ emit done();
1146+ return;
1147+ }
1148+
1149+ request.setUrl(url);
1150+ if (url.password().size() || url.userName().size()) {
1151+ QString headerData = "Basic " + (url.userName() + ":" + url.password()).toLocal8Bit().toBase64();
1152+ request.setRawHeader("Authorization", headerData.toLocal8Bit());
1153+ }
1154+ _reply = QSharedPointer<QNetworkReply>(_manager.get(request));
1155+
1156+ _reply->connect(_reply.data(), &QNetworkReply::finished, [this, target, uri]() {
1157+ if (!_scId || _reply->error() != QNetworkReply::NoError)
1158+ return;
1159+
1160+ QFile res(target);
1161+ qCritical() << target;
1162+ if (target[0] != '/' || !res.open(QIODevice::WriteOnly)) {
1163+ QVariantMap map;
1164+ map.insert("code", INVALID_URL_ERR);
1165+ map.insert("source", uri);
1166+ map.insert("target", target);
1167+ _plugin->cb(_ecId, map);
1168+ emit done();
1169+ return;
1170+ }
1171+ res.write(_reply->readAll());
1172+
1173+ QFileInfo info(target);
1174+ QVariantMap map;
1175+ map.insert("isFile", true);
1176+ map.insert("isDirectory", false);
1177+ map.insert("name", info.fileName());
1178+ map.insert("fullPath", info.absoluteFilePath());
1179+
1180+ _plugin->cb(_scId, map);
1181+
1182+ emit done();
1183+ });
1184+ _reply->connect(_reply.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
1185+ _reply->connect(_reply.data(), SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));
1186+}
1187+
1188+void FileTransferRequest::upload(const QString& _url, const QString& filePath, QString fileKey, QString fileName, QString mimeType, const QVariantMap &params, const QVariantMap &headers) {
1189+ QUrl url(_url);
1190+ QNetworkRequest request;
1191+
1192+ if (!url.isValid()) {
1193+ QVariantMap map;
1194+ map.insert("code", INVALID_URL_ERR);
1195+ map.insert("source", filePath);
1196+ map.insert("target", _url);
1197+ _plugin->cb(_ecId, map);
1198+ emit done();
1199+ return;
1200+ }
1201+
1202+ QFile file(filePath);
1203+ if (filePath[0] != '/' || !file.open(QIODevice::ReadOnly)) {
1204+ QVariantMap map;
1205+ map.insert("code", FILE_NOT_FOUND_ERR);
1206+ map.insert("source", filePath);
1207+ map.insert("target", _url);
1208+ _plugin->cb(_ecId, map);
1209+ emit done();
1210+ return;
1211+ }
1212+ QString content{file.readAll()};
1213+
1214+ request.setUrl(url);
1215+ if (url.password().size() || url.userName().size()) {
1216+ QString headerData = "Basic " + (url.userName() + ":" + url.password()).toLocal8Bit().toBase64();
1217+ request.setRawHeader("Authorization", headerData.toLocal8Bit());
1218+ }
1219+
1220+ for (const QString &key: headers.keys()) {
1221+ const QString &value = headers.find(key)->toString();
1222+ request.setRawHeader(key.toUtf8(), value.toUtf8());
1223+ }
1224+
1225+ QString boundary = QString("CORDOVA-QT-%1A").arg(qrand());
1226+ while (content.contains(boundary)) {
1227+ boundary += QString("B%1A").arg(qrand());
1228+ }
1229+
1230+ request.setHeader(QNetworkRequest::ContentTypeHeader, QString("multipart/form-data; boundary=") + boundary);
1231+
1232+ fileKey.replace("\"", "");
1233+ fileName.replace("\"", "");
1234+ mimeType.replace("\"", "");
1235+ QString part = "--" + boundary + "\r\n";
1236+
1237+ part += "Content-Disposition: form-data; name=\"" + fileKey +"\"; filename=\"" + fileName + "\"\r\n";
1238+ part += "Content-Type: " + mimeType + "\r\n\r\n";
1239+ part += content + "\r\n";
1240+
1241+ for (QString key: params.keys()) {
1242+ part += "--" + boundary + "\r\n";
1243+ part += "Content-Disposition: form-data; name=\"" + key + "\";\r\n\r\n";
1244+ part += params.find(key)->toString();
1245+ part += "\r\n";
1246+ }
1247+
1248+ part += QString("--") + boundary + "--" + "\r\n";
1249+
1250+ _reply = QSharedPointer<QNetworkReply>(_manager.post(request, QByteArray(part.toUtf8())));
1251+
1252+ _reply->connect(_reply.data(), &QNetworkReply::finished, [this, content]() {
1253+ if (_reply->error() != QNetworkReply::NoError)
1254+ return;
1255+ int status = 200;
1256+ QVariant statusCode = _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
1257+
1258+ if (statusCode.isValid()) {
1259+ status = statusCode.toInt();
1260+ }
1261+
1262+ QVariantMap map;
1263+ map.insert("responseCode", status);
1264+ map.insert("response", QString(_reply->readAll()));
1265+ map.insert("bytesSent", content.size());
1266+ _plugin->cb(_scId, map);
1267+ emit done();
1268+ });
1269+ _reply->connect(_reply.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
1270+ _reply->connect(_reply.data(), SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));
1271+}
1272+
1273+void FileTransferRequest::abort() {
1274+ QVariantMap map;
1275+ map.insert("code", ABORT_ERR);
1276+ _plugin->cb(_ecId, map);
1277+ _scId = 0;
1278+ emit done();
1279+}
1280+
1281+void FileTransferRequest::error(QNetworkReply::NetworkError code) {
1282+ Q_UNUSED(code);
1283+
1284+ int status = 404;
1285+ QVariant statusCode = _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
1286+
1287+ if (statusCode.isValid()) {
1288+ status = statusCode.toInt();
1289+ }
1290+
1291+ QVariantMap map;
1292+ map.insert("http_status", status);
1293+ map.insert("body", QString(_reply->readAll()));
1294+ map.insert("code", CONNECTION_ERR);
1295+ _plugin->cb(_ecId, map);
1296+ emit done();
1297+}
1298+
1299+void FileTransferRequest::progress(qint64 bytesReceived, qint64 bytesTotal) {
1300+ QVariantMap map;
1301+ map.insert("lengthComputable", true);
1302+ map.insert("total", bytesTotal);
1303+ map.insert("loaded", bytesReceived);
1304+
1305+ if (bytesReceived && bytesTotal && _scId)
1306+ _plugin->callbackWithoutRemove(_scId, CordovaInternal::format(map));
1307+}
1308
1309=== added file 'build/src/plugins/org.apache.cordova.file-transfer/file-transfer.h'
1310--- build/src/plugins/org.apache.cordova.file-transfer/file-transfer.h 1970-01-01 00:00:00 +0000
1311+++ build/src/plugins/org.apache.cordova.file-transfer/file-transfer.h 2014-02-19 16:53:58 +0000
1312@@ -0,0 +1,97 @@
1313+/*
1314+ *
1315+ * Copyright 2013 Canonical Ltd.
1316+ *
1317+ * Licensed under the Apache License, Version 2.0 (the "License");
1318+ * you may not use this file except in compliance with the License.
1319+ * You may obtain a copy of the License at
1320+ *
1321+ * http://www.apache.org/licenses/LICENSE-2.0
1322+ *
1323+ * Unless required by applicable law or agreed to in writing,
1324+ * software distributed under the License is distributed on an
1325+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1326+ * KIND, either express or implied. See the License for the
1327+ * specific language governing permissions and limitations
1328+ * under the License.
1329+ *
1330+*/
1331+
1332+#ifndef FILE_TRANSFER_H_SDASDASDAS
1333+#define FILE_TRANSFER_H_SDASDASDAS
1334+
1335+#include <QtCore>
1336+#include <QtNetwork>
1337+
1338+#include <cplugin.h>
1339+
1340+class FileTransferRequest: public QObject {
1341+ Q_OBJECT
1342+
1343+ QNetworkAccessManager &_manager;
1344+ int _scId, _ecId;
1345+ int _id;
1346+ QSharedPointer<QNetworkReply> _reply;
1347+
1348+ enum FileTransferError {
1349+ FILE_NOT_FOUND_ERR = 1,
1350+ INVALID_URL_ERR = 2,
1351+ CONNECTION_ERR = 3,
1352+ ABORT_ERR = 4
1353+ };
1354+
1355+public:
1356+ FileTransferRequest(QNetworkAccessManager &manager, int scId, int ecId, int id, CPlugin *plugin):
1357+ _manager(manager),
1358+ _scId(scId),
1359+ _ecId(ecId),
1360+ _id(id),
1361+ _plugin(plugin) {
1362+ }
1363+
1364+ void download(const QString& url, const QString &target);
1365+ void upload(const QString& _url, const QString& filePath, QString fileKey, QString fileName, QString mimeType, const QVariantMap &params, const QVariantMap &headers);
1366+ void abort();
1367+
1368+signals:
1369+ void done();
1370+
1371+private slots:
1372+ void progress(qint64 bytesReceived, qint64 bytesTotal);
1373+ void error(QNetworkReply::NetworkError code);
1374+private:
1375+ CPlugin *_plugin;
1376+ Q_DISABLE_COPY(FileTransferRequest);
1377+};
1378+
1379+class FileTransfer : public CPlugin {
1380+ Q_OBJECT
1381+public:
1382+ explicit FileTransfer(Cordova *cordova): CPlugin(cordova) {
1383+ }
1384+
1385+ virtual const QString fullName() override {
1386+ return FileTransfer::fullID();
1387+ }
1388+
1389+ virtual const QString shortName() override {
1390+ return "FileTransfer";
1391+ }
1392+
1393+ static const QString fullID() {
1394+ return "FileTransfer";
1395+ }
1396+
1397+public slots:
1398+ void abort(int scId, int ecId, int id);
1399+ void download(int scId, int ecId, const QString& url, const QString &target, bool /*trustAllHost*/, int id, const QVariantMap &/*headers*/);
1400+ void upload(int scId, int ecId, const QString &filePath, const QString& url, const QString& fileKey, const QString& fileName, const QString& mimeType,
1401+ const QVariantMap & params, bool /*trustAllHosts*/, bool /*chunkedMode*/, const QVariantMap &headers, int id, const QString &httpMethod);
1402+
1403+private:
1404+ QNetworkAccessManager _manager;
1405+ QMultiMap<int, QSharedPointer<FileTransferRequest> > _id2request;
1406+ int lastRequestId;
1407+};
1408+
1409+#endif
1410
1411=== added file 'build/src/plugins/org.apache.cordova.file/file.cpp'
1412--- build/src/plugins/org.apache.cordova.file/file.cpp 1970-01-01 00:00:00 +0000
1413+++ build/src/plugins/org.apache.cordova.file/file.cpp 2014-02-19 16:53:58 +0000
1414@@ -0,0 +1,773 @@
1415+/*
1416+ * Licensed under the Apache License, Version 2.0 (the "License");
1417+ * you may not use this file except in compliance with the License.
1418+ * You may obtain a copy of the License at
1419+ *
1420+ * http://www.apache.org/licenses/LICENSE-2.0
1421+ *
1422+ * Unless required by applicable law or agreed to in writing, software
1423+ * distributed under the License is distributed on an "AS IS" BASIS,
1424+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1425+ * See the License for the specific language governing permissions and
1426+ * limitations under the License.
1427+ */
1428+
1429+#include "file.h"
1430+
1431+#include <QApplication>
1432+
1433+namespace {
1434+ class FileError {
1435+ public:
1436+ static const QString kEncodingErr;
1437+ static const QString kTypeMismatchErr;
1438+ static const QString kNotFoundErr;
1439+ static const QString kSecurityErr;
1440+ static const QString kAbortErr;
1441+ static const QString kNotReadableErr;
1442+ static const QString kNoModificationAllowedErr;
1443+ static const QString kInvalidStateErr;
1444+ static const QString kSyntaxErr;
1445+ static const QString kInvalidModificationErr;
1446+ static const QString kQuotaExceededErr;
1447+ static const QString kPathExistsErr;
1448+ };
1449+
1450+ QVariantMap file2map(const QFileInfo &fileInfo) {
1451+ QVariantMap res;
1452+
1453+ res.insert("name", fileInfo.fileName());
1454+ res.insert("fullPath", fileInfo.isDir() ? QDir::cleanPath(fileInfo.absoluteFilePath()) : fileInfo.absoluteFilePath());
1455+ res.insert("isDirectory", (int)fileInfo.isDir());
1456+ res.insert("isFile", (int)fileInfo.isFile());
1457+
1458+ return res;
1459+ }
1460+ QVariantMap dir2map(const QDir &dir) {
1461+ return file2map(QFileInfo(dir.absolutePath()));
1462+ }
1463+};
1464+
1465+const QString FileError::kEncodingErr("FileError.ENCODING_ERR");
1466+const QString FileError::kTypeMismatchErr("FileError.TYPE_MISMATCH_ERR");
1467+const QString FileError::kNotFoundErr("FileError.NOT_FOUND_ERR");
1468+const QString FileError::kSecurityErr("FileError.SECURITY_ERR");
1469+const QString FileError::kAbortErr("FileError.ABORT_ERR");
1470+const QString FileError::kNotReadableErr("FileError.NOT_READABLE_ERR");
1471+const QString FileError::kNoModificationAllowedErr("FileError.NO_MODIFICATION_ALLOWED_ERR");
1472+const QString FileError::kInvalidStateErr("FileError.INVALID_STATE_ERR");
1473+const QString FileError::kSyntaxErr("FileError.SYNTAX_ERR");
1474+const QString FileError::kInvalidModificationErr("FileError.INVALID_MODIFICATION_ERR");
1475+const QString FileError::kQuotaExceededErr("FileError.QUOTA_EXCEEDED_ERR");
1476+const QString FileError::kPathExistsErr("FileError.PATH_EXISTS_ERR");
1477+
1478+File::File(Cordova *cordova) :
1479+ CPlugin(cordova),
1480+ _persistentDir(QString("%1/.local/share/%2/persistent").arg(QDir::homePath()).arg(QCoreApplication::applicationName())) {
1481+ QDir::root().mkpath(QDir(_persistentDir).absolutePath());
1482+}
1483+
1484+void File::requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size) {
1485+ QDir dir;
1486+
1487+ //FIXEME,what is quota value
1488+ if (size >= 10000){
1489+ this->callback(ecId, FileError::kQuotaExceededErr);
1490+ return;
1491+ }
1492+
1493+ if (type == 0)
1494+ dir = QDir::temp();
1495+ else
1496+ dir = QDir(_persistentDir);
1497+
1498+ if (type > 1) {
1499+ this->callback(ecId, FileError::kSyntaxErr);
1500+ return;
1501+ } else {
1502+ QVariantMap res;
1503+ res.insert("root", dir2map(dir));
1504+ if (type == 0)
1505+ res.insert("name", "temporary");
1506+ else
1507+ res.insert("name", "persistent");
1508+
1509+ this->cb(scId, res);
1510+ }
1511+}
1512+
1513+void File::resolveLocalFileSystemURI(int scId, int ecId, QString uri) {
1514+ QUrl url = QUrl::fromUserInput(uri);
1515+
1516+ if (!url.isValid() || uri[0] == '/' || uri[0] == '.') {
1517+ this->callback(ecId, FileError::kEncodingErr);
1518+ return;
1519+ }
1520+
1521+ if (url.scheme() != "file") {
1522+ this->callback(ecId, FileError::kTypeMismatchErr);
1523+ return;
1524+ }
1525+
1526+ QFileInfo fileInfo(url.path());
1527+
1528+ if (!fileInfo.exists()) {
1529+ this->callback(ecId, FileError::kNotFoundErr);
1530+ return;
1531+ }
1532+
1533+ this->cb(scId, file2map(fileInfo));
1534+}
1535+
1536+void File::getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options) {
1537+ QString path(rpath);
1538+
1539+ if (rpath[0] != '/') {
1540+ if (!parentPath.size() || !QFileInfo(parentPath).isDir())
1541+ path = _persistentDir + "/" + rpath;
1542+ else
1543+ path = parentPath + "/" + rpath;
1544+ }
1545+
1546+ //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here.
1547+ if (path.contains(":")){
1548+ this->callback(ecId, FileError::kEncodingErr);
1549+ return;
1550+ }
1551+
1552+ QUrl url = QUrl::fromUserInput(path);
1553+ if (!url.isValid()) {
1554+ this->callback(ecId, FileError::kEncodingErr);
1555+ return;
1556+ }
1557+
1558+ if (url.scheme() != "file") {
1559+ this->callback(ecId, FileError::kTypeMismatchErr);
1560+ return;
1561+ }
1562+
1563+ bool create = options.value("create").toBool();
1564+ bool exclusive = options.value("exclusive").toBool();
1565+ QFile file(path);
1566+
1567+ // if create is false and the path represents a directory, return error
1568+ QFileInfo fileInfo(url.path());
1569+ if ((!create) && fileInfo.isDir()) {
1570+ this->callback(ecId, FileError::kTypeMismatchErr);
1571+ return;
1572+ }
1573+
1574+ // if file does exist, and create is true and exclusive is true, return error
1575+ if (file.exists()) {
1576+ if (create && exclusive) {
1577+ this->callback(ecId, FileError::kPathExistsErr);
1578+ return;
1579+ }
1580+ }
1581+ else {
1582+ // if file does not exist and create is false, return error
1583+ if (!create) {
1584+ this->callback(ecId, FileError::kNotFoundErr);
1585+ return;
1586+ }
1587+
1588+ file.open(QIODevice::WriteOnly);
1589+ file.close();
1590+
1591+ // Check if creation was successfull
1592+ if (!file.exists()) {
1593+ this->callback(ecId, FileError::kNoModificationAllowedErr);
1594+ return;
1595+ }
1596+ }
1597+
1598+ this->cb(scId, file2map(QFileInfo(file)));
1599+}
1600+
1601+void File::getDirectory(int scId, int ecId, QString parentPath, QString rpath, QVariantMap options) {
1602+ QString path(rpath);
1603+ if (rpath[0] != '/') {
1604+ path = parentPath + "/" + rpath;
1605+ }
1606+
1607+ //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here.
1608+ if (path.contains(":")){
1609+ this->callback(ecId, FileError::kEncodingErr);
1610+ return;
1611+ }
1612+
1613+ QUrl url = QUrl::fromUserInput(path);
1614+ if (!url.isValid()) {
1615+ this->callback(ecId, FileError::kEncodingErr);
1616+ return;
1617+ }
1618+
1619+ if (url.scheme() != "file") {
1620+ this->callback(ecId, FileError::kTypeMismatchErr);
1621+ return;
1622+ }
1623+
1624+ bool create = options.value("create").toBool();
1625+ bool exclusive = options.value("exclusive").toBool();
1626+ QDir dir(path);
1627+
1628+ // if create is false and the path represents a file, return error
1629+ QFileInfo fileInfo(url.path());
1630+ if ((!create) && fileInfo.isFile()) {
1631+ this->callback(ecId, FileError::kTypeMismatchErr);
1632+ return;
1633+ }
1634+
1635+ // if directory does exist and create is true and exclusive is true, return error
1636+ if (dir.exists()) {
1637+ if (create && exclusive) {
1638+ this->callback(ecId, FileError::kPathExistsErr);
1639+ return;
1640+ }
1641+ }
1642+ else {
1643+ // if directory does not exist and create is false and directory does not exist, return error
1644+ if (!create) {
1645+ this->callback(ecId, FileError::kNotFoundErr);
1646+ return;
1647+ }
1648+
1649+ // if directory does not exist and create is false and directory does not exist, return error
1650+ QString folderName = dir.dirName();
1651+ dir.cdUp();
1652+ dir.mkdir(folderName);
1653+ dir.cd(folderName);
1654+
1655+ if (!dir.exists()) {
1656+ this->callback(ecId, FileError::kNoModificationAllowedErr);
1657+ return;
1658+ }
1659+ }
1660+
1661+ QVariantMap res;
1662+ res.insert("name", dir.dirName());
1663+ res.insert("fullPath", dir.absolutePath());
1664+ this->cb(scId, res);
1665+}
1666+
1667+void File::removeRecursively(int scId, int ecId, QString path) {
1668+ QDir dir(path);
1669+ if (File::rmDir(dir))
1670+ this->cb(scId);
1671+ else
1672+ this->callback(ecId, FileError::kNoModificationAllowedErr);
1673+}
1674+
1675+void File::write(int scId, int ecId, const QString &path, const QString &_data, unsigned long long position, bool binary) {
1676+ QFile file(path);
1677+
1678+ file.open(QIODevice::WriteOnly);
1679+ file.close();
1680+
1681+ if (!file.exists()) {
1682+ this->callback(ecId, FileError::kNotFoundErr);
1683+ return;
1684+ }
1685+
1686+ QFileInfo fileInfo(file);
1687+ if (!file.open(QIODevice::ReadWrite)) {
1688+ this->callback(ecId, FileError::kNoModificationAllowedErr);
1689+ return;
1690+ }
1691+
1692+ if (!binary) {
1693+ QTextStream textStream(&file);
1694+ textStream.setCodec("UTF-8");
1695+ textStream.setAutoDetectUnicode(true);
1696+
1697+ if (!textStream.seek(position)) {
1698+ file.close();
1699+ fileInfo.refresh();
1700+
1701+ this->callback(ecId, FileError::kInvalidModificationErr);
1702+ return;
1703+ }
1704+
1705+ textStream << _data;
1706+ textStream.flush();
1707+ } else {
1708+ QByteArray data(_data.toUtf8());
1709+ if (!file.seek(position)) {
1710+ file.close();
1711+ fileInfo.refresh();
1712+
1713+ this->callback(ecId, FileError::kInvalidModificationErr);
1714+ return;
1715+ }
1716+
1717+ file.write(data.data(), data.length());
1718+ }
1719+
1720+ file.flush();
1721+ file.close();
1722+ fileInfo.refresh();
1723+
1724+ this->cb(scId, fileInfo.size() - position);
1725+}
1726+
1727+void File::truncate(int scId, int ecId, const QString &path, unsigned long long size) {
1728+ QFile file(path);
1729+
1730+ if (!file.exists()) {
1731+ this->callback(ecId, FileError::kNotFoundErr);
1732+ return;
1733+ }
1734+
1735+ if (!file.resize(size)) {
1736+ this->callback(ecId, FileError::kNoModificationAllowedErr);
1737+ return;
1738+ }
1739+
1740+ this->cb(scId, size);
1741+}
1742+
1743+void File::getParent(int scId, int ecId, QString path) {
1744+ QDir dir(path);
1745+
1746+ //can't cdup more than app's root
1747+ // Try to change into upper directory
1748+ if (path != _persistentDir){
1749+ if (!dir.cdUp()) {
1750+ this->callback(ecId, FileError::kNotFoundErr);
1751+ return;
1752+ }
1753+
1754+ }
1755+ this->cb(scId, dir2map(dir));
1756+}
1757+
1758+void File::remove(int scId, int ecId, QString path) {
1759+ QFileInfo fileInfo(path);
1760+ if (!fileInfo.exists() || (path == _persistentDir)) {
1761+ this->callback(ecId, FileError::kNoModificationAllowedErr);
1762+ return;
1763+ }
1764+
1765+ if (fileInfo.isDir()) {
1766+ QDir dir(path);
1767+ if (dir.rmdir(dir.absolutePath())) {
1768+ this->cb(scId);
1769+ return;
1770+ }
1771+ } else {
1772+ QFile file(path);
1773+ if (file.remove()) {
1774+ this->cb(scId);
1775+ return;
1776+ }
1777+ }
1778+
1779+ this->callback(ecId, FileError::kInvalidModificationErr);
1780+}
1781+
1782+void File::getFileMetadata(int scId, int ecId, const QString &path) {
1783+ QFileInfo fileInfo(path);
1784+
1785+ if (!fileInfo.exists()) {
1786+ this->callback(ecId, FileError::kNotFoundErr);
1787+ } else {
1788+ QMimeType mime = _db.mimeTypeForFile(fileInfo.fileName());
1789+
1790+ QString args = QString("{name: %1, fullPath: %2, type: %3, lastModifiedDate: new Date(%4), size: %5}")
1791+ .arg(CordovaInternal::format(fileInfo.fileName())).arg(CordovaInternal::format(fileInfo.absoluteFilePath()))
1792+ .arg(CordovaInternal::format(mime.name())).arg(fileInfo.lastModified().toMSecsSinceEpoch())
1793+ .arg(fileInfo.size());
1794+
1795+ this->callback(scId, args);
1796+ }
1797+}
1798+
1799+void File::getMetadata(int scId, int ecId, const QString &path) {
1800+ QFileInfo fileInfo(path);
1801+
1802+ if (!fileInfo.exists())
1803+ this->callback(ecId, FileError::kNotFoundErr);
1804+ else
1805+ this->cb(scId, fileInfo.lastModified().toMSecsSinceEpoch());
1806+}
1807+
1808+void File::readEntries(int scId, int ecId, QString path) {
1809+ QDir dir(path);
1810+ QString entriesList;
1811+
1812+ if (!dir.exists()) {
1813+ this->callback(ecId, FileError::kNotFoundErr);
1814+ return;
1815+ }
1816+
1817+ for (const QFileInfo &fileInfo: dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
1818+ entriesList += CordovaInternal::format(file2map(fileInfo)) + ",";
1819+ }
1820+
1821+ // Remove trailing comma
1822+ if (entriesList.size() > 0)
1823+ entriesList.remove(entriesList.size()-1, 1);
1824+ entriesList = "new Array(" + entriesList + ")";
1825+
1826+ this->callback(scId, entriesList);
1827+}
1828+
1829+void File::readAsText(int scId, int ecId, const QString &path, const QString &encoding, int sliceStart, int sliceEnd) {
1830+ QFile file(path);
1831+
1832+ if (!file.exists()) {
1833+ this->callback(ecId, FileError::kNotFoundErr);
1834+ return;
1835+ }
1836+
1837+ if (!file.open(QIODevice::ReadOnly)) {
1838+ this->callback(ecId, FileError::kNotReadableErr);
1839+ return;
1840+ }
1841+
1842+ QByteArray content = file.readAll();
1843+
1844+ if (sliceEnd == -1)
1845+ sliceEnd = content.size();
1846+ if (sliceEnd < 0) {
1847+ sliceEnd++;
1848+ sliceEnd = std::max(0, content.size() + sliceEnd);
1849+ }
1850+ if (sliceEnd > content.size())
1851+ sliceEnd = content.size();
1852+
1853+ if (sliceStart < 0)
1854+ sliceStart = std::max(0, content.size() + sliceStart);
1855+ if (sliceStart > content.size())
1856+ sliceStart = content.size();
1857+
1858+ if (sliceStart > sliceEnd)
1859+ sliceEnd = sliceStart;
1860+
1861+ //FIXME: encoding
1862+ content = content.mid(sliceStart, sliceEnd - sliceStart);
1863+
1864+ this->cb(scId, content);
1865+}
1866+
1867+void File::readAsArrayBuffer(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd) {
1868+ const QString str2array("\
1869+ (function strToArray(str) { \
1870+ var res = new Uint8Array(str.length); \
1871+ for (var i = 0; i < str.length; i++) { \
1872+ res[i] = str.charCodeAt(i); \
1873+ } \
1874+ return res; \
1875+ })(\"%1\")");
1876+ QFile file(path);
1877+
1878+ if (!file.exists()) {
1879+ this->callback(ecId, FileError::kNotFoundErr);
1880+ return;
1881+ }
1882+
1883+ if (!file.open(QIODevice::ReadOnly)) {
1884+ this->callback(ecId, FileError::kNotReadableErr);
1885+ return;
1886+ }
1887+ QString res;
1888+ QByteArray content = file.readAll();
1889+
1890+ if (sliceEnd == -1)
1891+ sliceEnd = content.size();
1892+ if (sliceEnd < 0) {
1893+ sliceEnd++;
1894+ sliceEnd = std::max(0, content.size() + sliceEnd);
1895+ }
1896+ if (sliceEnd > content.size())
1897+ sliceEnd = content.size();
1898+
1899+ if (sliceStart < 0)
1900+ sliceStart = std::max(0, content.size() + sliceStart);
1901+ if (sliceStart > content.size())
1902+ sliceStart = content.size();
1903+
1904+ if (sliceStart > sliceEnd)
1905+ sliceEnd = sliceStart;
1906+
1907+ content = content.mid(sliceStart, sliceEnd - sliceStart);
1908+
1909+ res.reserve(content.length() * 6);
1910+ for (uchar c: content) {
1911+ res += "\\x";
1912+ res += QString::number(c, 16).rightJustified(2, '0').toUpper();
1913+ }
1914+
1915+ this->callback(scId, str2array.arg(res));
1916+}
1917+
1918+void File::readAsBinaryString(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd) {
1919+ QFile file(path);
1920+
1921+ if (!file.exists()) {
1922+ this->callback(ecId, FileError::kNotFoundErr);
1923+ return;
1924+ }
1925+
1926+ if (!file.open(QIODevice::ReadOnly)) {
1927+ this->callback(ecId, FileError::kNotReadableErr);
1928+ return;
1929+ }
1930+ QString res;
1931+ QByteArray content = file.readAll();
1932+
1933+ if (sliceEnd == -1)
1934+ sliceEnd = content.size();
1935+ if (sliceEnd < 0) {
1936+ sliceEnd++;
1937+ sliceEnd = std::max(0, content.size() + sliceEnd);
1938+ }
1939+ if (sliceEnd > content.size())
1940+ sliceEnd = content.size();
1941+
1942+ if (sliceStart < 0)
1943+ sliceStart = std::max(0, content.size() + sliceStart);
1944+ if (sliceStart > content.size())
1945+ sliceStart = content.size();
1946+
1947+ if (sliceStart > sliceEnd)
1948+ sliceEnd = sliceStart;
1949+
1950+ content = content.mid(sliceStart, sliceEnd - sliceStart);
1951+
1952+ res.reserve(content.length() * 6);
1953+ for (uchar c: content) {
1954+ res += "\\x";
1955+ res += QString::number(c, 16).rightJustified(2, '0').toUpper();
1956+ }
1957+ this->callback(scId, "\"" + res + "\"");
1958+}
1959+
1960+void File::readAsDataURL(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd) {
1961+ QFile file(path);
1962+ QFileInfo fileInfo(path);
1963+
1964+ if (path.startsWith("content:")){
1965+ this->callback(ecId, FileError::kNotReadableErr);
1966+ return;
1967+ }
1968+
1969+ if (!file.exists()) {
1970+ this->callback(ecId, FileError::kNotReadableErr);
1971+ return;
1972+ }
1973+ // Try to open file for reading
1974+ if (!file.open(QIODevice::ReadOnly)) {
1975+ this->callback(ecId, FileError::kNotReadableErr);
1976+ return;
1977+ }
1978+ // Read the file content
1979+ QByteArray content = file.readAll();
1980+ QString contentType(_db.mimeTypeForFile(fileInfo.fileName()).name());
1981+
1982+ if (sliceEnd == -1)
1983+ sliceEnd = content.size();
1984+ if (sliceEnd < 0) {
1985+ sliceEnd++;
1986+ sliceEnd = std::max(0, content.size() + sliceEnd);
1987+ }
1988+ if (sliceEnd > content.size())
1989+ sliceEnd = content.size();
1990+
1991+ if (sliceStart < 0)
1992+ sliceStart = std::max(0, content.size() + sliceStart);
1993+ if (sliceStart > content.size())
1994+ sliceStart = content.size();
1995+
1996+ if (sliceStart > sliceEnd)
1997+ sliceEnd = sliceStart;
1998+
1999+ content = content.mid(sliceStart, sliceEnd - sliceStart);
2000+
2001+ this->cb(scId, QString("data:%1;base64,").arg(contentType) + content.toBase64());
2002+}
2003+
2004+bool File::rmDir(QDir dir) {
2005+ if (dir == _persistentDir) {//can't remove root dir
2006+ return false;
2007+ }
2008+ bool result = true;
2009+ if (dir.exists()) {
2010+ // Iterate over entries and remove them
2011+ Q_FOREACH(const QFileInfo &fileInfo, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
2012+ if (fileInfo.isDir()) {
2013+ result = rmDir(fileInfo.absoluteFilePath());
2014+ }
2015+ else {
2016+ result = QFile::remove(fileInfo.absoluteFilePath());
2017+ }
2018+
2019+ if (!result) {
2020+ return result;
2021+ }
2022+ }
2023+
2024+ // Finally remove the current dir
2025+ return dir.rmdir(dir.absolutePath());
2026+ }
2027+ return result;
2028+}
2029+
2030+bool File::copyFile(int scId, int ecId,const QString& sourceFile, const QString& destinationParentDir, const QString& newName) {
2031+ if (!QDir(destinationParentDir).exists()){
2032+ this->callback(ecId, FileError::kNotFoundErr);
2033+ return false;
2034+ }
2035+
2036+ QFileInfo fileInfo(sourceFile);
2037+ QString fileName = ((newName.isEmpty()) ? fileInfo.fileName() : newName);
2038+ QString destinationFile(destinationParentDir + "/" + fileName);
2039+
2040+ //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here.
2041+ if (!QUrl::fromUserInput(destinationFile).isValid() || destinationFile.contains(":")){
2042+ this->callback(ecId, FileError::kEncodingErr);
2043+ return false;
2044+ }
2045+
2046+ if (QFile::copy(sourceFile, destinationFile)){
2047+ this->cb(scId, file2map(QFileInfo(destinationFile)));
2048+ return true;
2049+ } else {
2050+ this->callback(ecId, FileError::kInvalidModificationErr);
2051+ return false;
2052+ }
2053+}
2054+
2055+void File::copyDir(int scId, int ecId,const QString& sourceFolder, const QString& destinationParentDir, const QString& newName) {
2056+ QDir sourceDir(sourceFolder);
2057+ QString dirName = ((newName.isEmpty()) ? sourceDir.dirName() : newName);
2058+ QString destFolder(destinationParentDir + "/" + dirName);
2059+
2060+ if (QFileInfo(destFolder).isFile()){
2061+ this->callback(ecId, FileError::kInvalidModificationErr);
2062+ return;
2063+ }
2064+ QDir destDir(destFolder);
2065+
2066+ if ((sourceFolder == destFolder) || (sourceFolder == destinationParentDir)){
2067+ this->callback(ecId, FileError::kInvalidModificationErr);
2068+ return;
2069+ }
2070+
2071+ if (!destDir.exists()){
2072+ destDir.mkdir(destFolder);;
2073+ } else{
2074+ this->callback(ecId, FileError::kInvalidModificationErr);
2075+ return;
2076+ }
2077+
2078+ if (copyFolder(sourceFolder, destFolder)){
2079+ this->cb(scId, dir2map(destDir));
2080+ return;
2081+ } else {
2082+ this->callback(ecId, FileError::kInvalidModificationErr);
2083+ return;
2084+ }
2085+}
2086+
2087+void File::copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) {
2088+ if (QFileInfo(source).isDir())
2089+ copyDir(scId, ecId, source, destinationDir, newName);
2090+ else
2091+ copyFile(scId, ecId, source, destinationDir, newName);
2092+}
2093+
2094+void File::moveFile(int scId, int ecId,const QString& sourceFile, const QString& destinationParentDir, const QString& newName) {
2095+ QString fileName = ((newName.isEmpty()) ? QFileInfo(sourceFile).fileName() : newName);
2096+ QString destinationFile(destinationParentDir + "/" + fileName);
2097+
2098+ if (QFileInfo(sourceFile) == QFileInfo(destinationFile)) {
2099+ this->callback(ecId, FileError::kInvalidModificationErr);
2100+ return;
2101+ }
2102+
2103+ if (!QFileInfo(destinationParentDir).exists()) {
2104+ this->callback(ecId, FileError::kNotFoundErr);
2105+ return;
2106+ }
2107+
2108+ if (QFileInfo(destinationFile).exists()) {
2109+ if (!QFile::remove(QFileInfo(destinationFile).absoluteFilePath())) {
2110+ this->callback(ecId, FileError::kInvalidModificationErr);
2111+ return;
2112+ }
2113+ }
2114+
2115+ QFile::rename(sourceFile, destinationFile);
2116+ this->cb(scId, file2map(QFileInfo(destinationFile)));
2117+}
2118+
2119+void File::moveDir(int scId, int ecId,const QString& sourceDir, const QString& destinationParentDir, const QString& newName){
2120+ QString dirName = ((newName.isEmpty()) ? QDir(sourceDir).dirName() : newName);
2121+ QString destFolder(destinationParentDir + "/" + dirName);
2122+ QDir destDir(destFolder);
2123+
2124+ if (!QFileInfo(destinationParentDir).exists()){
2125+ this->callback(ecId, FileError::kNotFoundErr);
2126+ return;
2127+ }
2128+
2129+ if (QFileInfo(destFolder).isFile()){
2130+ this->callback(ecId, FileError::kInvalidModificationErr);
2131+ return;
2132+ }
2133+
2134+ if ((QFileInfo(sourceDir) == QFileInfo(destFolder)) || (QFileInfo(sourceDir) == QFileInfo(destinationParentDir))) {
2135+ this->callback(ecId, FileError::kInvalidModificationErr);
2136+ return;
2137+ }
2138+
2139+ if (destDir.exists() && !QDir(destinationParentDir).rmdir(dirName)) {
2140+ this->callback(ecId, FileError::kInvalidModificationErr);
2141+ return;
2142+ }
2143+
2144+ if (copyFolder(sourceDir, destFolder)) {
2145+ rmDir(sourceDir);
2146+ this->cb(scId, file2map(QFileInfo(destFolder)));
2147+ } else {
2148+ this->callback(ecId, FileError::kNoModificationAllowedErr);
2149+ }
2150+}
2151+
2152+void File::moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) {
2153+ if (newName.contains(":")) {
2154+ this->callback(ecId, FileError::kEncodingErr);
2155+ return;
2156+ }
2157+ if (QFileInfo(source).isDir())
2158+ moveDir(scId, ecId, source, destinationDir, newName);
2159+ else
2160+ moveFile(scId, ecId, source, destinationDir, newName);
2161+}
2162+
2163+bool File::copyFolder(const QString& sourceFolder, const QString& destFolder) {
2164+ QDir sourceDir(sourceFolder);
2165+ if (!sourceDir.exists())
2166+ return false;
2167+ QDir destDir(destFolder);
2168+ if (!destDir.exists()){
2169+ destDir.mkdir(destFolder);
2170+ }
2171+ QStringList files = sourceDir.entryList(QDir::Files);
2172+ for (int i = 0; i< files.count(); i++)
2173+ {
2174+ QString srcName = sourceFolder + "/" + files[i];
2175+ QString destName = destFolder + "/" + files[i];
2176+ QFile::copy(srcName, destName);
2177+ }
2178+ files.clear();
2179+ files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
2180+ for (int i = 0; i< files.count(); i++)
2181+ {
2182+ QString srcName = sourceFolder + "/" + files[i];
2183+ QString destName = destFolder + "/" + files[i];
2184+ copyFolder(srcName, destName);
2185+ }
2186+ return true;
2187+}
2188
2189=== added file 'build/src/plugins/org.apache.cordova.file/file.h'
2190--- build/src/plugins/org.apache.cordova.file/file.h 1970-01-01 00:00:00 +0000
2191+++ build/src/plugins/org.apache.cordova.file/file.h 2014-02-19 16:53:58 +0000
2192@@ -0,0 +1,73 @@
2193+/*
2194+ * Licensed under the Apache License, Version 2.0 (the "License");
2195+ * you may not use this file except in compliance with the License.
2196+ * You may obtain a copy of the License at
2197+ *
2198+ * http://www.apache.org/licenses/LICENSE-2.0
2199+ *
2200+ * Unless required by applicable law or agreed to in writing, software
2201+ * distributed under the License is distributed on an "AS IS" BASIS,
2202+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2203+ * See the License for the specific language governing permissions and
2204+ * limitations under the License.
2205+ */
2206+
2207+#ifndef FILEAPI_H_SDASDASDAS
2208+#define FILEAPI_H_SDASDASDAS
2209+
2210+#include <QNetworkReply>
2211+#include <QtCore>
2212+
2213+#include <cplugin.h>
2214+#include <cordova.h>
2215+
2216+class File: public CPlugin {
2217+ Q_OBJECT
2218+public:
2219+ explicit File(Cordova *cordova);
2220+
2221+ virtual const QString fullName() override {
2222+ return File::fullID();
2223+ }
2224+
2225+ virtual const QString shortName() override {
2226+ return "File";
2227+ }
2228+
2229+ static const QString fullID() {
2230+ return "File";
2231+ }
2232+
2233+public slots:
2234+ void requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size);
2235+ void resolveLocalFileSystemURI(int scId, int ecId, QString uri);
2236+ void getDirectory(int scId, int ecId, QString parentPath, QString path, QVariantMap options);
2237+ void getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options);
2238+ void readEntries(int scId, int ecId, QString path);
2239+ void getParent(int scId, int ecId, QString path);
2240+ void copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName);
2241+ void moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName);
2242+ void getFileMetadata(int scId, int ecId, const QString &path);
2243+ void getMetadata(int scId, int ecId, const QString &path);
2244+ void remove(int scId, int ecId, QString path);
2245+ void removeRecursively(int scId, int ecId, QString path);
2246+ void readAsText(int scId, int ecId, const QString &path, const QString &encoding, int sliceStart, int sliceEnd);
2247+ void write(int scId, int ecId, const QString &path, const QString &_data, unsigned long long position, bool binary);
2248+ void readAsDataURL(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd);
2249+ void readAsArrayBuffer(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd);
2250+ void readAsBinaryString(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd);
2251+ void truncate(int scId, int ecId, const QString &path, unsigned long long size);
2252+private:
2253+ void moveFile(int scId, int ecId,const QString& sourceFile, const QString& destinationParentDir, const QString& newName);
2254+ void moveDir(int scId, int ecId,const QString& sourceFolder, const QString& destFolder, const QString& newName);
2255+ bool copyFile(int scId, int ecId, const QString& sourceFile, const QString& destinationParentDir, const QString& newName);
2256+ void copyDir(int scId, int ecId, const QString& sourceFolder, const QString& destFolder, const QString& newName);
2257+ bool rmDir(QDir dir);
2258+ bool copyFolder(const QString& sourceFolder, const QString& destFolder);
2259+
2260+ QMimeDatabase _db;
2261+ const QString _persistentDir;
2262+ QNetworkAccessManager _manager;
2263+};
2264+
2265+#endif
2266
2267=== added directory 'build/src/plugins/org.apache.cordova.geolocation'
2268=== added file 'build/src/plugins/org.apache.cordova.geolocation/geolocation.cpp'
2269--- build/src/plugins/org.apache.cordova.geolocation/geolocation.cpp 1970-01-01 00:00:00 +0000
2270+++ build/src/plugins/org.apache.cordova.geolocation/geolocation.cpp 2014-02-19 16:53:58 +0000
2271@@ -0,0 +1,119 @@
2272+/*
2273+ *
2274+ * Copyright 2013 Canonical Ltd.
2275+ *
2276+ * Licensed under the Apache License, Version 2.0 (the "License");
2277+ * you may not use this file except in compliance with the License.
2278+ * You may obtain a copy of the License at
2279+ *
2280+ * http://www.apache.org/licenses/LICENSE-2.0
2281+ *
2282+ * Unless required by applicable law or agreed to in writing,
2283+ * software distributed under the License is distributed on an
2284+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
2285+ * KIND, either express or implied. See the License for the
2286+ * specific language governing permissions and limitations
2287+ * under the License.
2288+ *
2289+*/
2290+
2291+#include <QUuid>
2292+
2293+#include "geolocation.h"
2294+
2295+Geolocation::Geolocation(Cordova *cordova): CPlugin(cordova),
2296+ _geoPositionInfoSource(QGeoPositionInfoSource::createDefaultSource(this)) {
2297+ if (_geoPositionInfoSource.data() != 0) {
2298+ QObject::connect(_geoPositionInfoSource.data(), SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
2299+ QObject::connect(_geoPositionInfoSource.data(), SIGNAL(updateTimeout()), this, SLOT(updateTimeout()));
2300+ }
2301+}
2302+
2303+void Geolocation::addWatch(int scId, int ecId, const QString &id, bool enableHighAccuracy) {
2304+ Q_UNUSED(enableHighAccuracy);
2305+
2306+ assert(_id2sc.find(id) == _id2sc.end());
2307+
2308+ if (!_geoPositionInfoSource.data()) {
2309+ QVariantMap err;
2310+ err.insert("code", POSITION_UNAVAILABLE);
2311+ err.insert("message", "unavailable");
2312+
2313+ this->cb(ecId, err);
2314+ return;
2315+ }
2316+
2317+ _id2sc[id] = scId;
2318+ _id2ec[id] = ecId;
2319+}
2320+
2321+void Geolocation::clearWatch(int scId, int ecId, const QString &id) {
2322+ _id2sc.remove(id);
2323+ _id2ec.remove(id);
2324+}
2325+
2326+void Geolocation::getLocation(int scId, int ecId, bool enableHighAccuracy, qint64 maximumAge) {
2327+ Q_UNUSED(maximumAge);
2328+ Q_UNUSED(enableHighAccuracy);
2329+
2330+ if (!_geoPositionInfoSource.data()) {
2331+ QVariantMap err;
2332+ err.insert("code", POSITION_UNAVAILABLE);
2333+ err.insert("message", "unavailable");
2334+
2335+ this->cb(ecId, err);
2336+ return;
2337+ }
2338+
2339+ _geoPositionInfoSource->requestUpdate();
2340+
2341+ QString id = QString("_INTERNAL_") + QUuid::createUuid().toString();
2342+
2343+ _id2sc[id] = scId;
2344+ _id2ec[id] = ecId;
2345+ _singleUpdate.insert(id);
2346+}
2347+
2348+void Geolocation::positionUpdated(const QGeoPositionInfo &update) {
2349+ QGeoCoordinate coordinate = update.coordinate();
2350+
2351+ QVariantMap p;
2352+
2353+ p.insert("latitude", coordinate.latitude());
2354+ p.insert("longitude", coordinate.longitude());
2355+ p.insert("altitude", coordinate.altitude());
2356+
2357+ if (update.hasAttribute(QGeoPositionInfo::VerticalAccuracy))
2358+ p.insert("accuracy", update.attribute(QGeoPositionInfo::VerticalAccuracy));
2359+ if (update.hasAttribute(QGeoPositionInfo::Direction))
2360+ p.insert("heading", update.attribute(QGeoPositionInfo::Direction));
2361+ if (update.hasAttribute(QGeoPositionInfo::GroundSpeed))
2362+ p.insert("velocity", update.attribute(QGeoPositionInfo::GroundSpeed));
2363+ if (update.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
2364+ p.insert("altitudeAccuracy", update.attribute(QGeoPositionInfo::HorizontalAccuracy));
2365+ p.insert("timestamp", update.timestamp().toMSecsSinceEpoch());
2366+
2367+ for (const QString &id: _id2sc.keys()) {
2368+ int scId = _id2sc[id];
2369+ this->cb(scId, p);
2370+ if (_singleUpdate.contains(id)) {
2371+ _singleUpdate.remove(id);
2372+ _id2sc.remove(id);
2373+ _id2ec.remove(id);
2374+ }
2375+ }
2376+}
2377+
2378+void Geolocation::updateTimeout() {
2379+ QVariantMap err;
2380+ err.insert("code", TIMEOUT);
2381+ err.insert("message", "timeout");
2382+
2383+ for (int ecId: _id2ec) {
2384+ this->cb(ecId, err);
2385+ }
2386+
2387+ _id2ec.clear();
2388+ _id2sc.clear();
2389+ _singleUpdate.clear();
2390+}
2391
2392=== added file 'build/src/plugins/org.apache.cordova.geolocation/geolocation.h'
2393--- build/src/plugins/org.apache.cordova.geolocation/geolocation.h 1970-01-01 00:00:00 +0000
2394+++ build/src/plugins/org.apache.cordova.geolocation/geolocation.h 2014-02-19 16:53:58 +0000
2395@@ -0,0 +1,69 @@
2396+/*
2397+ *
2398+ * Copyright 2013 Canonical Ltd.
2399+ *
2400+ * Licensed under the Apache License, Version 2.0 (the "License");
2401+ * you may not use this file except in compliance with the License.
2402+ * You may obtain a copy of the License at
2403+ *
2404+ * http://www.apache.org/licenses/LICENSE-2.0
2405+ *
2406+ * Unless required by applicable law or agreed to in writing,
2407+ * software distributed under the License is distributed on an
2408+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
2409+ * KIND, either express or implied. See the License for the
2410+ * specific language governing permissions and limitations
2411+ * under the License.
2412+ *
2413+*/
2414+
2415+#ifndef GEOLOCATION_H_SVO2013
2416+#define GEOLOCATION_H_SVO2013
2417+
2418+#include <QGeoPositionInfoSource>
2419+#include <QGeoPositionInfo>
2420+#include <QtCore>
2421+#include <cassert>
2422+
2423+#include <cplugin.h>
2424+
2425+class Geolocation: public CPlugin {
2426+ Q_OBJECT
2427+public:
2428+ explicit Geolocation(Cordova *cordova);
2429+
2430+ virtual const QString fullName() override {
2431+ return Geolocation::fullID();
2432+ }
2433+
2434+ virtual const QString shortName() override {
2435+ return "Geolocation";
2436+ }
2437+
2438+ static const QString fullID() {
2439+ return "Geolocation";
2440+ }
2441+
2442+public slots:
2443+ void getLocation(int scId, int ecId, bool enableHighAccuracy, qint64 maximumAge);
2444+ void addWatch(int scId, int ecId, const QString &id, bool enableHighAccuracy);
2445+ void clearWatch(int scId, int ecId, const QString &id);
2446+
2447+protected slots:
2448+ void positionUpdated(const QGeoPositionInfo &update);
2449+ void updateTimeout();
2450+
2451+private:
2452+ QMap<QString, int> _id2sc;
2453+ QMap<QString, int> _id2ec;
2454+ QSet<QString> _singleUpdate;
2455+ QSharedPointer<QGeoPositionInfoSource> _geoPositionInfoSource;
2456+
2457+ enum PositionError {
2458+ PERMISSION_DENIED = 1,
2459+ POSITION_UNAVAILABLE = 2,
2460+ TIMEOUT = 3
2461+ };
2462+};
2463+
2464+#endif
2465
2466=== added directory 'build/src/plugins/org.apache.cordova.globalization'
2467=== added file 'build/src/plugins/org.apache.cordova.globalization/globalization.cpp'
2468--- build/src/plugins/org.apache.cordova.globalization/globalization.cpp 1970-01-01 00:00:00 +0000
2469+++ build/src/plugins/org.apache.cordova.globalization/globalization.cpp 2014-02-19 16:53:58 +0000
2470@@ -0,0 +1,342 @@
2471+/*
2472+ *
2473+ * Copyright 2013 Canonical Ltd.
2474+ *
2475+ * Licensed under the Apache License, Version 2.0 (the "License");
2476+ * you may not use this file except in compliance with the License.
2477+ * You may obtain a copy of the License at
2478+ *
2479+ * http://www.apache.org/licenses/LICENSE-2.0
2480+ *
2481+ * Unless required by applicable law or agreed to in writing,
2482+ * software distributed under the License is distributed on an
2483+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
2484+ * KIND, either express or implied. See the License for the
2485+ * specific language governing permissions and limitations
2486+ * under the License.
2487+ *
2488+*/
2489+
2490+#include <ctime> //TODO: switch to QTimeZone (QT 5.1)
2491+#include <unicode/decimfmt.h>
2492+#include <unicode/timezone.h>
2493+
2494+#include "globalization.h"
2495+
2496+Globalization::Globalization(Cordova *cordova):
2497+ CPlugin(cordova) {
2498+}
2499+
2500+void Globalization::getPreferredLanguage(int scId, int ecId) {
2501+ Q_UNUSED(ecId)
2502+
2503+ QLocale locale;
2504+ QString lang = QLocale::languageToString(locale.language());
2505+ QVariantMap obj;
2506+ obj.insert("value", lang);
2507+ this->cb(scId, obj);
2508+}
2509+
2510+void Globalization::getLocaleName(int scId, int ecId) {
2511+ Q_UNUSED(ecId)
2512+
2513+ QVariantMap obj;
2514+ obj.insert("value", QLocale().name());
2515+ this->cb(scId, obj);
2516+}
2517+
2518+void Globalization::getFirstDayOfWeek(int scId, int ecId) {
2519+ Q_UNUSED(ecId)
2520+
2521+ QLocale locale;
2522+
2523+ int res;
2524+ if (locale.firstDayOfWeek() == Qt::Sunday) {
2525+ res = 1;
2526+ } else {
2527+ res = (2 - Qt::Monday) + locale.firstDayOfWeek();
2528+ }
2529+
2530+ QVariantMap obj;
2531+ obj.insert("value", res);
2532+ this->cb(scId, obj);
2533+}
2534+
2535+void Globalization::isDayLightSavingsTime(int scId, int ecId, const QVariantMap &options) {
2536+ time_t time = options.find("time_t")->toLongLong() / 1000;
2537+ const tm *desc = std::localtime(&time);
2538+ if (desc->tm_isdst < 0) {
2539+ this->callback(ecId, QString("new GlobalizationError(%1, 'information is not available');").arg(Globalization::UNKNOWN_ERROR));
2540+ return;
2541+ }
2542+ this->callback(scId, QString("{dst:%1}").arg(desc->tm_isdst > 0 ? "true" : "false"));
2543+}
2544+
2545+QLocale::FormatType translateFormat(Globalization::Format formatLength) {
2546+ QLocale::FormatType format = QLocale::ShortFormat;
2547+ switch (formatLength) {
2548+ case Globalization::FORMAT_FULL:
2549+ case Globalization::FORMAT_LONG:
2550+ format = QLocale::ShortFormat; // TODO: Qt cant parse string produced with QLocale::LongFormat;
2551+ break;
2552+ case Globalization::FORMAT_MEDIUM:
2553+ format = QLocale::ShortFormat;
2554+ break;
2555+ case Globalization::FORMAT_SHORT:
2556+ format = QLocale::NarrowFormat;
2557+ break;
2558+ }
2559+ return format;
2560+}
2561+
2562+void Globalization::dateToString(int scId, int ecId, const QVariantMap &options) {
2563+ time_t time = options.find("time_t")->toLongLong() / 1000;
2564+
2565+ Globalization::Format formatLength = static_cast<Globalization::Format>(options.find("formatLength")->toInt());
2566+ Globalization::Selector selector = static_cast<Globalization::Selector>(options.find("selector")->toInt());
2567+
2568+ QLocale::FormatType format = translateFormat(formatLength);
2569+ if (time < 0) {
2570+ this->callback(ecId, QString("new GlobalizationError(%1, 'unsupported operation');").arg(Globalization::FORMATTING_ERROR));
2571+ return;
2572+ }
2573+
2574+ QLocale locale;
2575+ QString res;
2576+ QDateTime dateTime = QDateTime::fromTime_t((uint)time);
2577+ switch (selector) {
2578+ case SELECTOR_ALL:
2579+ res = locale.toString(dateTime,format);
2580+ break;
2581+ case SELECTOR_TIME:
2582+ res = locale.toString(dateTime.time(), format);
2583+ break;
2584+ case SELECTOR_DATE:
2585+ res = locale.toString(dateTime.date(), format);
2586+ break;
2587+ }
2588+ QVariantMap obj;
2589+ obj.insert("value", res);
2590+ this->cb(scId, obj);
2591+}
2592+
2593+void Globalization::stringToDate(int scId, int ecId, const QVariantMap &options) {
2594+ QString dateString = options.find("dateString")->toString();
2595+ Globalization::Format formatLength = static_cast<Globalization::Format>(options.find("formatLength")->toInt());
2596+ Globalization::Selector selector = static_cast<Globalization::Selector>(options.find("selector")->toInt());
2597+
2598+ QLocale::FormatType format = translateFormat(formatLength);
2599+ QLocale locale;
2600+ bool valid(true);
2601+ int year(0), month(0), day(0), hour(0), minute(0), second(0), millisecond(0);
2602+ switch (selector) {
2603+ case SELECTOR_ALL:
2604+ {
2605+ QDateTime dateTime = locale.toDateTime(dateString, format);
2606+ valid = dateTime.isValid();
2607+ QTime time = dateTime.time();
2608+ hour = time.hour(); minute = time.minute(); second = time.second(); millisecond = time.msec();
2609+ QDate date = dateTime.date();
2610+ year = date.year(); month = date.month(); day = date.day();
2611+ }
2612+ break;
2613+ case SELECTOR_TIME:
2614+ {
2615+ QTime time = locale.toTime(dateString, format);
2616+ valid = time.isValid();
2617+ hour = time.hour(); minute = time.minute(); second = time.second(); millisecond = time.msec();
2618+ }
2619+ break;
2620+ case SELECTOR_DATE:
2621+ {
2622+ QDate date = locale.toDate(dateString, format);
2623+ valid = date.isValid();
2624+ year = date.year(); month = date.month(); day = date.day();
2625+ }
2626+ break;
2627+ }
2628+ if ((format == QLocale::NarrowFormat || format == QLocale::ShortFormat) && year < 2000 && year > 1900) {
2629+ year += 100;
2630+ }
2631+ if (!valid) {
2632+ this->callback(ecId, QString("new GlobalizationError(%1, 'parsing error')").arg(Globalization::PARSING_ERROR));
2633+ } else {
2634+ QVariantMap obj;
2635+ obj.insert("year", year);
2636+ obj.insert("month", month - 1);
2637+ obj.insert("day", day);
2638+ obj.insert("hour", hour);
2639+ obj.insert("minute", minute);
2640+ obj.insert("second", second);
2641+ obj.insert("millisecond", millisecond);
2642+ this->cb(scId, obj);
2643+ }
2644+}
2645+
2646+void Globalization::getDateNames(int scId, int ecId, const QVariantMap &options) {
2647+ Q_UNUSED(ecId)
2648+
2649+ int type = options.find("type")->toInt();
2650+ int item = options.find("item")->toInt();
2651+
2652+ QLocale::FormatType format;
2653+ if (type == FORMAT_SHORT)
2654+ format = QLocale::ShortFormat;
2655+ else
2656+ format = QLocale::LongFormat;
2657+ QLocale locale;
2658+ QList<QString> res;
2659+ if (item == REQUEST_DAY_NAMES) {
2660+ for (int i = 1; i <= 7; i++) {
2661+ res.append(locale.dayName(i, format));
2662+ }
2663+ } else { //REQUEST_MONTH_NAMES
2664+ for (int i = 1; i <= 12; i++) {
2665+ res.append(locale.monthName(i, format));
2666+ }
2667+ }
2668+
2669+ QString result;
2670+ for (QList<QString>::iterator it = res.begin(); it != res.end(); it++) {
2671+ result += QString("'%1',").arg(*it);
2672+ }
2673+ this->callback(scId, QString("{ value: [ %1 ]}").arg(result));
2674+}
2675+
2676+template<class T>
2677+static QString format(T number, Globalization::NumberType type) {
2678+ QString res;
2679+ QLocale locale;
2680+ switch (type) {
2681+ case Globalization::DECIMAL:
2682+ res = locale.toString(number);
2683+ break;
2684+ case Globalization::PERCENT:
2685+ res = locale.toString(number) + locale.percent();
2686+ break;
2687+ case Globalization::CURRENCY:
2688+ res = locale.toCurrencyString(number);
2689+ break;
2690+ };
2691+ return res;
2692+}
2693+
2694+void Globalization::numberToString(int scId, int ecId, const QVariantMap &options) {
2695+ Q_UNUSED(ecId)
2696+
2697+ bool isInt = options.find("isInt")->toBool();
2698+ NumberType type = static_cast<NumberType>(options.find("type")->toBool());
2699+
2700+ QString res;
2701+ if (isInt) {
2702+ long long number = options.find("number")->toLongLong();
2703+ res = format(number, type);
2704+ } else {
2705+ double number = options.find("number")->toDouble();
2706+ res = format(number, type);
2707+ }
2708+ this->callback(scId, QString("{ value: '%1' }").arg(res));
2709+}
2710+
2711+void Globalization::stringToNumber(int scId, int ecId, int type, QString string) {
2712+ switch ((NumberType)type) {
2713+ case Globalization::DECIMAL:
2714+ string = string.remove(QLocale().groupSeparator());
2715+ break;
2716+ case Globalization::PERCENT:
2717+ string = string.remove(QLocale().percent()).remove(QLocale().groupSeparator());
2718+ break;
2719+ case Globalization::CURRENCY:
2720+ string = string.remove(QLocale().currencySymbol()).remove(QLocale().groupSeparator());
2721+ break;
2722+ };
2723+ bool ok;
2724+ double res = QLocale().toDouble(string, &ok);
2725+ if (ok)
2726+ this->callback(scId, QString("{ value: %1 }").arg(res));
2727+ else
2728+ this->callback(ecId, QString("new GlobalizationError(%1, 'parsing error')").arg(Globalization::PARSING_ERROR));
2729+}
2730+
2731+static QString ustr2qstr(UnicodeString &ustr) {
2732+ std::string res;
2733+ ustr.toUTF8String(res);
2734+
2735+ return QString(res.c_str());
2736+}
2737+
2738+void Globalization::getNumberPattern(int scId, int ecId, int type) {
2739+ Q_UNUSED(ecId);
2740+ UErrorCode status = U_ZERO_ERROR;
2741+ icu::DecimalFormat icu(status);
2742+
2743+ icu::UnicodeString pattern;
2744+ icu.toPattern(pattern);
2745+
2746+ QLocale locale;
2747+ QVariantMap obj;
2748+
2749+ obj.insert("pattern", ustr2qstr(pattern));
2750+
2751+ switch ((NumberType)type) {
2752+ case Globalization::DECIMAL:
2753+ obj.insert("symbol", "");
2754+ break;
2755+ case Globalization::PERCENT:
2756+ obj.insert("symbol", QString(locale.percent()));
2757+ break;
2758+ case Globalization::CURRENCY:
2759+ obj.insert("symbol", QString(locale.currencySymbol()));
2760+ break;
2761+ };
2762+
2763+ obj.insert("fraction", icu.getMaximumFractionDigits());
2764+ obj.insert("rounding", icu.getRoundingIncrement());
2765+ obj.insert("positive", QString(locale.positiveSign()));
2766+ obj.insert("negative", QString(locale.negativeSign()));
2767+ obj.insert("decimal", QString(locale.decimalPoint()));
2768+ obj.insert("grouping", QString(locale.groupSeparator()));
2769+
2770+ this->cb(scId, obj);
2771+}
2772+
2773+static bool inDayLightSavingsTime() {
2774+ time_t now;
2775+
2776+ time(&now);
2777+
2778+ const tm *desc = std::localtime(&now);
2779+
2780+ return desc->tm_isdst > 0;
2781+}
2782+
2783+void Globalization::getDatePattern(int scId, int ecId, int formatLength, int selector) {
2784+ Q_UNUSED(ecId);
2785+
2786+ QLocale locale;
2787+ QVariantMap res;
2788+ QLocale::FormatType format = translateFormat((Format)formatLength);
2789+
2790+ switch ((Selector)selector) {
2791+ case Selector::SELECTOR_TIME:
2792+ res.insert("pattern", locale.timeFormat(format));
2793+ break;
2794+ case Selector::SELECTOR_DATE:
2795+ res.insert("pattern", locale.dateFormat(format));
2796+ break;
2797+ case Selector::SELECTOR_ALL:
2798+ res.insert("pattern", locale.dateTimeFormat(format));
2799+ break;
2800+ };
2801+
2802+ UnicodeString result;
2803+ QSharedPointer<TimeZone> timezone = QSharedPointer<TimeZone>(TimeZone::createDefault());
2804+ timezone->getDisplayName(inDayLightSavingsTime(), TimeZone::SHORT, result);
2805+
2806+ res.insert("timezone", ustr2qstr(result));
2807+ res.insert("utc_offset", timezone->getRawOffset() / 1000 + timezone->getDSTSavings() / 1000);
2808+ res.insert("dst_offset", timezone->getDSTSavings() / 1000);
2809+
2810+ this->cb(scId, res);
2811+}
2812+
2813
2814=== added file 'build/src/plugins/org.apache.cordova.globalization/globalization.h'
2815--- build/src/plugins/org.apache.cordova.globalization/globalization.h 1970-01-01 00:00:00 +0000
2816+++ build/src/plugins/org.apache.cordova.globalization/globalization.h 2014-02-19 16:53:58 +0000
2817@@ -0,0 +1,93 @@
2818+/*
2819+ *
2820+ * Copyright 2013 Canonical Ltd.
2821+ *
2822+ * Licensed under the Apache License, Version 2.0 (the "License");
2823+ * you may not use this file except in compliance with the License.
2824+ * You may obtain a copy of the License at
2825+ *
2826+ * http://www.apache.org/licenses/LICENSE-2.0
2827+ *
2828+ * Unless required by applicable law or agreed to in writing,
2829+ * software distributed under the License is distributed on an
2830+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
2831+ * KIND, either express or implied. See the License for the
2832+ * specific language governing permissions and limitations
2833+ * under the License.
2834+ *
2835+*/
2836+#ifndef GLOBALIZATION_H_SVO2013
2837+#define GLOBALIZATION_H_SVO2013
2838+
2839+#include <QtCore>
2840+#include <QLocale>
2841+
2842+#include <cplugin.h>
2843+
2844+class Globalization: public CPlugin {
2845+ Q_OBJECT
2846+ enum GlobalizationError {
2847+ UNKNOWN_ERROR = 0,
2848+ FORMATTING_ERROR = 1,
2849+ PARSING_ERROR = 2,
2850+ PATTERN_ERROR = 3
2851+ };
2852+
2853+ enum Selector {
2854+ SELECTOR_DATE = 0,
2855+ SELECTOR_TIME = 1,
2856+ SELECTOR_ALL = 2
2857+ };
2858+
2859+ enum Format {
2860+ FORMAT_SHORT = 0,
2861+ FORMAT_MEDIUM = 1,
2862+ FORMAT_LONG = 2,
2863+ FORMAT_FULL = 3
2864+ };
2865+
2866+ enum {
2867+ REQUEST_DAY_NAMES = 0,
2868+ REQUEST_MONTH_NAMES = 1
2869+ };
2870+
2871+ enum NumberType {
2872+ DECIMAL,
2873+ PERCENT,
2874+ CURRENCY
2875+ };
2876+
2877+public:
2878+ explicit Globalization(Cordova *cordova);
2879+
2880+ virtual const QString fullName() override {
2881+ return Globalization::fullID();
2882+ }
2883+
2884+ virtual const QString shortName() override {
2885+ return "Globalization";
2886+ }
2887+
2888+ static const QString fullID() {
2889+ return "Globalization";
2890+ }
2891+
2892+public slots:
2893+ void getPreferredLanguage(int scId, int ecId);
2894+ void getLocaleName(int scId, int ecId);
2895+ void getFirstDayOfWeek(int scId, int ecId);
2896+ void isDayLightSavingsTime(int scId, int ecId, const QVariantMap &options);
2897+ void dateToString(int scId, int ecId, const QVariantMap &options);
2898+ void stringToDate(int scId, int ecId, const QVariantMap &options);
2899+
2900+ void getDateNames(int scId, int ecId, const QVariantMap &options);
2901+ void numberToString(int scId, int ecId, const QVariantMap &options);
2902+ void stringToNumber(int scId, int ecId, int type, QString string);
2903+ void getNumberPattern(int scId, int ecId, int type);
2904+ void getDatePattern(int scId, int ecId, int formatLength, int selector);
2905+private:
2906+ friend QLocale::FormatType translateFormat(Globalization::Format formatLength);
2907+ template<class T> friend QString format(T number, Globalization::NumberType type);
2908+};
2909+
2910+#endif
2911
2912=== added directory 'build/src/plugins/org.apache.cordova.inappbrowser'
2913=== added file 'build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.cpp'
2914--- build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.cpp 1970-01-01 00:00:00 +0000
2915+++ build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.cpp 2014-02-19 16:53:58 +0000
2916@@ -0,0 +1,106 @@
2917+/*
2918+ *
2919+ * Copyright 2013 Canonical Ltd.
2920+ *
2921+ * Licensed to the Apache Software Foundation (ASF) under one
2922+ * or more contributor license agreements. See the NOTICE file
2923+ * distributed with this work for additional information
2924+ * regarding copyright ownership. The ASF licenses this file
2925+ * to you under the Apache License, Version 2.0 (the
2926+ * "License"); you may not use this file except in compliance
2927+ * with the License. You may obtain a copy of the License at
2928+ *
2929+ * http://www.apache.org/licenses/LICENSE-2.0
2930+ *
2931+ * Unless required by applicable law or agreed to in writing,
2932+ * software distributed under the License is distributed on an
2933+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
2934+ * KIND, either express or implied. See the License for the
2935+ * specific language governing permissions and limitations
2936+ * under the License.
2937+ *
2938+*/
2939+
2940+#include <QQuickView>
2941+#include <QQuickItem>
2942+
2943+#include "inappbrowser.h"
2944+#include <cordova.h>
2945+
2946+Inappbrowser::Inappbrowser(Cordova *cordova): CPlugin(cordova), _eventCb(0) {
2947+}
2948+
2949+const char code[] = "\
2950+var component, object; \
2951+function createObject() { \
2952+ component = Qt.createComponent(%1); \
2953+ if (component.status == Component.Ready) \
2954+ finishCreation(); \
2955+ else \
2956+ component.statusChanged.connect(finishCreation); \
2957+} \
2958+function finishCreation() { \
2959+ CordovaWrapper.object = component.createObject(root, \
2960+ {root: root, cordova: cordova, url1: %2}); \
2961+} \
2962+createObject()";
2963+
2964+const char EXIT_EVENT[] = "'exit'";
2965+const char LOADSTART_EVENT[] = "'loadstart'";
2966+const char LOADSTOP_EVENT[] = "'loadstop'";
2967+const char LOADERROR_EVENT[] = "'loaderror'";
2968+
2969+void Inappbrowser::open(int cb, int, const QString &url, const QString &windowName, const QString &windowFeatures) {
2970+ assert(_eventCb == 0);
2971+
2972+ _eventCb = cb;
2973+
2974+ QString path = m_cordova->get_app_dir() + "/../qml/InAppBrowser.qml";
2975+
2976+ // TODO: relative url
2977+ QString qml = QString(code)
2978+ .arg(CordovaInternal::format(path)).arg(CordovaInternal::format(url));
2979+ m_cordova->execQML(qml);
2980+}
2981+
2982+void Inappbrowser::show(int, int) {
2983+ m_cordova->execQML("CordovaWrapper.object.visible = true");
2984+}
2985+
2986+void Inappbrowser::close(int, int) {
2987+ m_cordova->execQML("CordovaWrapper.object.destroy()");
2988+ this->callbackWithoutRemove(_eventCb, EXIT_EVENT);
2989+ _eventCb = 0;
2990+}
2991+
2992+void Inappbrowser::injectStyleFile(int cb, int, const QString&, bool) {
2993+ // TODO:
2994+ qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
2995+}
2996+
2997+void Inappbrowser::injectStyleCode(int cb, int, const QString&, bool) {
2998+ // TODO:
2999+ qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
3000+}
3001+
3002+void Inappbrowser::injectScriptFile(int cb, int, const QString&, bool) {
3003+ // TODO:
3004+ qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
3005+}
3006+
3007+void Inappbrowser::injectScriptCode(int cb, int, const QString&, bool) {
3008+ // TODO:
3009+ qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
3010+}
3011+
3012+void Inappbrowser::loadFinished(int status) {
3013+ if (status == 2) {
3014+ this->callbackWithoutRemove(_eventCb, LOADERROR_EVENT);
3015+ }
3016+ if (status == 0) {
3017+ this->callbackWithoutRemove(_eventCb, LOADSTART_EVENT);
3018+ }
3019+ if (status == 3) {
3020+ this->callbackWithoutRemove(_eventCb, LOADSTOP_EVENT);
3021+ }
3022+}
3023
3024=== added file 'build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.h'
3025--- build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.h 1970-01-01 00:00:00 +0000
3026+++ build/src/plugins/org.apache.cordova.inappbrowser/inappbrowser.h 2014-02-19 16:53:58 +0000
3027@@ -0,0 +1,61 @@
3028+/*
3029+ *
3030+ * Copyright 2013 Canonical Ltd.
3031+ *
3032+ * Licensed to the Apache Software Foundation (ASF) under one
3033+ * or more contributor license agreements. See the NOTICE file
3034+ * distributed with this work for additional information
3035+ * regarding copyright ownership. The ASF licenses this file
3036+ * to you under the Apache License, Version 2.0 (the
3037+ * "License"); you may not use this file except in compliance
3038+ * with the License. You may obtain a copy of the License at
3039+ *
3040+ * http://www.apache.org/licenses/LICENSE-2.0
3041+ *
3042+ * Unless required by applicable law or agreed to in writing,
3043+ * software distributed under the License is distributed on an
3044+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3045+ * KIND, either express or implied. See the License for the
3046+ * specific language governing permissions and limitations
3047+ * under the License.
3048+ *
3049+*/
3050+#ifndef INAPPBROWSER_H
3051+#define INAPPBROWSER_H
3052+
3053+#include <QtCore>
3054+#include <cplugin.h>
3055+
3056+class Inappbrowser: public CPlugin {
3057+ Q_OBJECT
3058+public:
3059+ Inappbrowser(Cordova *cordova);
3060+
3061+ virtual const QString fullName() override {
3062+ return Inappbrowser::fullID();
3063+ }
3064+
3065+ virtual const QString shortName() override {
3066+ return "InAppBrowser";
3067+ }
3068+
3069+ static const QString fullID() {
3070+ return "InAppBrowser";
3071+ }
3072+
3073+public slots:
3074+ void open(int cb, int, const QString &url, const QString &windowName, const QString &windowFeatures);
3075+ void show(int, int);
3076+ void close(int, int);
3077+ void injectStyleFile(int cb, int, const QString&, bool);
3078+ void injectStyleCode(int cb, int, const QString&, bool);
3079+ void injectScriptFile(int cb, int, const QString&, bool);
3080+ void injectScriptCode(int cb, int, const QString&, bool);
3081+
3082+ void loadFinished(int status);
3083+
3084+private:
3085+ int _eventCb;
3086+};
3087+
3088+#endif
3089
3090=== added directory 'build/src/plugins/org.apache.cordova.media'
3091=== added directory 'build/src/plugins/org.apache.cordova.media-capture'
3092=== added file 'build/src/plugins/org.apache.cordova.media-capture/capture.cpp'
3093--- build/src/plugins/org.apache.cordova.media-capture/capture.cpp 1970-01-01 00:00:00 +0000
3094+++ build/src/plugins/org.apache.cordova.media-capture/capture.cpp 2014-02-19 16:53:58 +0000
3095@@ -0,0 +1,167 @@
3096+/*
3097+ *
3098+ * Copyright 2013 Canonical Ltd.
3099+ *
3100+ * Licensed under the Apache License, Version 2.0 (the "License");
3101+ * you may not use this file except in compliance with the License.
3102+ * You may obtain a copy of the License at
3103+ *
3104+ * http://www.apache.org/licenses/LICENSE-2.0
3105+ *
3106+ * Unless required by applicable law or agreed to in writing,
3107+ * software distributed under the License is distributed on an
3108+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3109+ * KIND, either express or implied. See the License for the
3110+ * specific language governing permissions and limitations
3111+ * under the License.
3112+ *
3113+*/
3114+#include "capture.h"
3115+
3116+const char code[] = "\
3117+var component, object; \
3118+function createObject() { \
3119+ component = Qt.createComponent(%1); \
3120+ if (component.status == Component.Ready) \
3121+ finishCreation(); \
3122+ else \
3123+ component.statusChanged.connect(finishCreation); \
3124+} \
3125+function finishCreation() { \
3126+ CordovaWrapper.captureObject = component.createObject(root, \
3127+ {root: root, cordova: cordova, state: \"%2\"}); \
3128+} \
3129+createObject()";
3130+
3131+static QString formatFile(const QMimeDatabase &db, const QString &path) {
3132+ QFileInfo info(path);
3133+ QMimeType mime = db.mimeTypeForFile(info.fileName());
3134+
3135+ QVariantMap file;
3136+ file.insert("name", info.fileName());
3137+ file.insert("fullPath", info.absoluteFilePath());
3138+ file.insert("lastModifiedDate", info.lastModified().toMSecsSinceEpoch());
3139+ file.insert("size", info.size());
3140+ file.insert("type", mime.name());
3141+
3142+ return CordovaInternal::format(file);
3143+}
3144+
3145+MediaCapture::MediaCapture(Cordova *cordova): CPlugin(cordova), _scId(0), _ecId(0) {
3146+}
3147+
3148+void MediaCapture::captureAudio(int scId, int ecId, QVariantMap options) {
3149+ if (_scId || _ecId) {
3150+ this->callback(_ecId, QString("{code: %1}").arg(CAPTURE_APPLICATION_BUSY));
3151+ return;
3152+ }
3153+
3154+ QString path = m_cordova->get_app_dir() + "/../qml/MediaCaptureWidget.qml";
3155+
3156+ // TODO: relative url
3157+ QString qml = QString(code).arg(CordovaInternal::format(path)).arg("audio");
3158+ m_cordova->execQML(qml);
3159+
3160+ _scId = scId;
3161+ _ecId = ecId;
3162+}
3163+
3164+void MediaCapture::onAudioRecordError(QMediaRecorder::Error) {
3165+ if (!_ecId)
3166+ return;
3167+ this->callback(_ecId, QString("{code: %1}").arg(CAPTURE_INTERNAL_ERR));
3168+ _ecId = _scId = 0;
3169+
3170+ _recorder.clear();
3171+ _files.clear();
3172+
3173+ m_cordova->execQML("CordovaWrapper.captureObject.destroy()");
3174+}
3175+
3176+void MediaCapture::recordAudio() {
3177+ if (_recorder.data()) {
3178+ QUrl url = _recorder->outputLocation();
3179+
3180+ QString path = url.toString();
3181+ _recorder->stop();
3182+
3183+ _recorder.clear();
3184+
3185+ this->callback(_scId, QString("[%1]").arg(formatFile(_db, path)));
3186+ _ecId = _scId = 0;
3187+
3188+ m_cordova->execQML("CordovaWrapper.captureObject.destroy()");
3189+ } else {
3190+ _recorder = QSharedPointer<QAudioRecorder>(new QAudioRecorder);
3191+ QObject::connect(_recorder.data(), SIGNAL(error(QMediaRecorder::Error)), this, SLOT(onAudioRecordError(QMediaRecorder::Error)));
3192+
3193+ if (_options.find("mode")->toString() == "audio/amr") {
3194+ _recorder->setContainerFormat("amr");
3195+ _recorder->setOutputLocation(generateLocation("amr"));
3196+ } else {
3197+ _recorder->setContainerFormat("wav");
3198+ _recorder->setOutputLocation(generateLocation("wav"));
3199+ }
3200+ _recorder->record();
3201+ }
3202+}
3203+
3204+void MediaCapture::cancel() {
3205+ if (!_ecId)
3206+ return;
3207+
3208+ m_cordova->execQML("CordovaWrapper.captureObject.destroy()");
3209+
3210+ _recorder.clear();
3211+ this->callback(_ecId, QString("{code: %1}").arg(CAPTURE_NO_MEDIA_FILES));
3212+ _ecId = _scId = 0;
3213+
3214+ _recorder.clear();
3215+}
3216+
3217+void MediaCapture::captureVideo(int scId, int ecId, QVariantMap options) {
3218+ if (_scId || _ecId) {
3219+ this->callback(_ecId, QString("{code: %1}").arg(CAPTURE_APPLICATION_BUSY));
3220+ return;
3221+ }
3222+
3223+ QString path = m_cordova->get_app_dir() + "/../qml/MediaCaptureWidget.qml";
3224+
3225+ // TODO: relative url
3226+ QString qml = QString(code).arg(CordovaInternal::format(path)).arg("videoRecording");
3227+ m_cordova->execQML(qml);
3228+
3229+ _scId = scId;
3230+ _ecId = ecId;
3231+}
3232+
3233+void MediaCapture::onVideoRecordEnd(QString path) {
3234+ assert(path.startsWith("file:"));
3235+ path = path.mid(5);
3236+
3237+ this->callback(_scId, QString("[%1]").arg(formatFile(_db, path)));
3238+ _ecId = _scId = 0;
3239+
3240+ m_cordova->execQML("CordovaWrapper.captureObject.destroy()");
3241+}
3242+
3243+void MediaCapture::captureImage(int scId, int ecId, QVariantMap options) {
3244+ if (_scId || _ecId) {
3245+ this->callback(_ecId, QString("{code: %1}").arg(CAPTURE_APPLICATION_BUSY));
3246+ return;
3247+ }
3248+
3249+ QString path = m_cordova->get_app_dir() + "/../qml/MediaCaptureWidget.qml";
3250+
3251+ // TODO: relative url
3252+ QString qml = QString(code).arg(CordovaInternal::format(path)).arg("camera");
3253+ m_cordova->execQML(qml);
3254+
3255+ _scId = scId;
3256+ _ecId = ecId;
3257+}
3258+
3259+void MediaCapture::onImageSaved(const QString &path) {
3260+ this->callback(_scId, QString("[%1]").arg(formatFile(_db, path)));
3261+ _ecId = _scId = 0;
3262+}
3263
3264=== added file 'build/src/plugins/org.apache.cordova.media-capture/capture.h'
3265--- build/src/plugins/org.apache.cordova.media-capture/capture.h 1970-01-01 00:00:00 +0000
3266+++ build/src/plugins/org.apache.cordova.media-capture/capture.h 2014-02-19 16:53:58 +0000
3267@@ -0,0 +1,84 @@
3268+/*
3269+ *
3270+ * Copyright 2013 Canonical Ltd.
3271+ *
3272+ * Licensed under the Apache License, Version 2.0 (the "License");
3273+ * you may not use this file except in compliance with the License.
3274+ * You may obtain a copy of the License at
3275+ *
3276+ * http://www.apache.org/licenses/LICENSE-2.0
3277+ *
3278+ * Unless required by applicable law or agreed to in writing,
3279+ * software distributed under the License is distributed on an
3280+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3281+ * KIND, either express or implied. See the License for the
3282+ * specific language governing permissions and limitations
3283+ * under the License.
3284+ *
3285+*/
3286+#ifndef CAPTURE_H_ASCXZFG975
3287+#define CAPTURE_H_ASCXZFG975
3288+
3289+#include <cordova.h>
3290+#include <cplugin.h>
3291+#include <QtMultimedia>
3292+#include <QtCore>
3293+#include <QtQuick>
3294+
3295+class MediaCapture: public CPlugin {
3296+ Q_OBJECT
3297+public:
3298+ explicit MediaCapture(Cordova *cordova);
3299+
3300+ virtual const QString fullName() override {
3301+ return MediaCapture::fullID();
3302+ }
3303+
3304+ virtual const QString shortName() override {
3305+ return "Capture";
3306+ }
3307+
3308+ static const QString fullID() {
3309+ return "Capture";
3310+ }
3311+
3312+public slots:
3313+ void captureAudio(int scId, int ecId, QVariantMap options);
3314+ void captureImage(int scId, int ecId, QVariantMap options);
3315+ void captureVideo(int scId, int ecId, QVariantMap options);
3316+
3317+ void recordAudio();
3318+ void cancel();
3319+ void onVideoRecordEnd(QString path);
3320+ void onImageSaved(const QString &path);
3321+
3322+ QString generateLocation(const QString &extension) {
3323+ int i = 1;
3324+ for (;;++i) {
3325+ QString path = QString("%1/.local/share/%2/persistent/%3.%4").arg(QDir::homePath())
3326+ .arg(QCoreApplication::applicationName()).arg(i).arg(extension);
3327+
3328+ if (!QFileInfo(path).exists())
3329+ return path;
3330+ }
3331+ }
3332+private slots:
3333+ void onAudioRecordError(QMediaRecorder::Error);
3334+private:
3335+ QSharedPointer<QAudioRecorder> _recorder;
3336+
3337+ int _scId, _ecId;
3338+ QList<QString> _files;
3339+ QVariantMap _options;
3340+ QMimeDatabase _db;
3341+
3342+ enum CaptureError {
3343+ CAPTURE_INTERNAL_ERR = 0,
3344+ CAPTURE_APPLICATION_BUSY = 1,
3345+ CAPTURE_INVALID_ARGUMENT = 2,
3346+ CAPTURE_NO_MEDIA_FILES = 3,
3347+ CAPTURE_NOT_SUPPORTED = 20
3348+ };
3349+};
3350+
3351+#endif
3352
3353=== added file 'build/src/plugins/org.apache.cordova.media/media.cpp'
3354--- build/src/plugins/org.apache.cordova.media/media.cpp 1970-01-01 00:00:00 +0000
3355+++ build/src/plugins/org.apache.cordova.media/media.cpp 2014-02-19 16:53:58 +0000
3356@@ -0,0 +1,128 @@
3357+/*
3358+ *
3359+ * Licensed to the Apache Software Foundation (ASF) under one
3360+ * or more contributor license agreements. See the NOTICE file
3361+ * distributed with this work for additional information
3362+ * regarding copyright ownership. The ASF licenses this file
3363+ * to you under the Apache License, Version 2.0 (the
3364+ * "License"); you may not use this file except in compliance
3365+ * with the License. You may obtain a copy of the License at
3366+ *
3367+ * http://www.apache.org/licenses/LICENSE-2.0
3368+ *
3369+ * Unless required by applicable law or agreed to in writing,
3370+ * software distributed under the License is distributed on an
3371+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3372+ * KIND, either express or implied. See the License for the
3373+ * specific language governing permissions and limitations
3374+ * under the License.
3375+ *
3376+*/
3377+
3378+#include "media.h"
3379+
3380+void Media::create(int scId, int ecId, const QString &id, const QString &src) {
3381+ Q_UNUSED(scId);
3382+ Q_UNUSED(ecId);
3383+
3384+ if (_id2Player.find(id) != _id2Player.end()) {
3385+ _id2Player[id]->stop();
3386+ _id2Player.remove(id);
3387+ }
3388+
3389+ _id2Player[id] = QSharedPointer<Player>(new Player(id, src, this));
3390+}
3391+
3392+void Media::relase(int scId, int ecId, const QString &id) {
3393+ Q_UNUSED(scId);
3394+ Q_UNUSED(ecId);
3395+
3396+ if (_id2Player.find(id) == _id2Player.end())
3397+ return;
3398+ _id2Player.remove(id);
3399+}
3400+
3401+void Media::startPlayingAudio(int scId, int ecId, const QString &id, const QString &src, QVariantMap options) {
3402+ Q_UNUSED(scId);
3403+ Q_UNUSED(ecId);
3404+ Q_UNUSED(src);
3405+ Q_UNUSED(options);
3406+
3407+ if (_id2Player.find(id) == _id2Player.end())
3408+ return;
3409+ QSharedPointer<Player> player = _id2Player[id];
3410+ player->play();
3411+}
3412+
3413+void Media::pausePlayingAudio(int scId, int ecId, const QString &id) {
3414+ Q_UNUSED(scId);
3415+ Q_UNUSED(ecId);
3416+
3417+ if (_id2Player.find(id) == _id2Player.end())
3418+ return;
3419+ QSharedPointer<Player> player = _id2Player[id];
3420+ player->pause();
3421+}
3422+
3423+void Media::stopPlayingAudio(int scId, int ecId, const QString &id) {
3424+ Q_UNUSED(scId);
3425+ Q_UNUSED(ecId);
3426+
3427+ if (_id2Player.find(id) == _id2Player.end())
3428+ return;
3429+ QSharedPointer<Player> player = _id2Player[id];
3430+ player->stop();
3431+}
3432+
3433+void Media::startRecordingAudio(int scId, int ecId, const QString &id, const QString &src) {
3434+ Q_UNUSED(scId);
3435+ Q_UNUSED(ecId);
3436+ Q_UNUSED(src);
3437+
3438+ if (_id2Player.find(id) == _id2Player.end())
3439+ return;
3440+ QSharedPointer<Player> player = _id2Player[id];
3441+ player->startRecording();
3442+}
3443+
3444+void Media::stopRecordingAudio(int scId, int ecId, const QString &id) {
3445+ Q_UNUSED(scId);
3446+ Q_UNUSED(ecId);
3447+
3448+ if (_id2Player.find(id) == _id2Player.end())
3449+ return;
3450+ QSharedPointer<Player> player = _id2Player[id];
3451+ player->stopRecording();
3452+}
3453+
3454+void Media::getCurrentPositionAudio(int scId, int ecId, const QString &id) {
3455+ Q_UNUSED(ecId);
3456+
3457+ if (_id2Player.find(id) == _id2Player.end())
3458+ return;
3459+
3460+ QSharedPointer<Player> player = _id2Player[id];
3461+ double position = player->getPosition();
3462+ this->cb(scId, position);
3463+}
3464+
3465+void Media::seekToAudio(int scId, int ecId, const QString &id, qint64 position) {
3466+ Q_UNUSED(scId);
3467+ Q_UNUSED(ecId);
3468+
3469+ if (_id2Player.find(id) == _id2Player.end())
3470+ return;
3471+
3472+ QSharedPointer<Player> player = _id2Player[id];
3473+ player->seekTo(position);
3474+}
3475+
3476+void Media::setVolume(int scId, int ecId, const QString &id, int volume) {
3477+ Q_UNUSED(scId);
3478+ Q_UNUSED(ecId);
3479+
3480+ if (_id2Player.find(id) == _id2Player.end())
3481+ return;
3482+ QSharedPointer<Player> player = _id2Player[id];
3483+ player->setVolume(volume);
3484+}
3485
3486=== added file 'build/src/plugins/org.apache.cordova.media/media.h'
3487--- build/src/plugins/org.apache.cordova.media/media.h 1970-01-01 00:00:00 +0000
3488+++ build/src/plugins/org.apache.cordova.media/media.h 2014-02-19 16:53:58 +0000
3489@@ -0,0 +1,267 @@
3490+/*
3491+ *
3492+ * Licensed to the Apache Software Foundation (ASF) under one
3493+ * or more contributor license agreements. See the NOTICE file
3494+ * distributed with this work for additional information
3495+ * regarding copyright ownership. The ASF licenses this file
3496+ * to you under the Apache License, Version 2.0 (the
3497+ * "License"); you may not use this file except in compliance
3498+ * with the License. You may obtain a copy of the License at
3499+ *
3500+ * http://www.apache.org/licenses/LICENSE-2.0
3501+ *
3502+ * Unless required by applicable law or agreed to in writing,
3503+ * software distributed under the License is distributed on an
3504+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3505+ * KIND, either express or implied. See the License for the
3506+ * specific language governing permissions and limitations
3507+ * under the License.
3508+ *
3509+*/
3510+
3511+#ifndef MEDIA_H_789768978
3512+#define MEDIA_H_789768978
3513+
3514+#include <QtMultimedia/QMediaPlayer>
3515+#include <QtCore>
3516+#include <QAudioRecorder>
3517+#include <QtMultimedia/QAudioEncoderSettings>
3518+
3519+#include <cplugin.h>
3520+#include <cordova.h>
3521+
3522+class Player;
3523+
3524+class Media: public CPlugin {
3525+ Q_OBJECT
3526+public:
3527+ explicit Media(Cordova *cordova): CPlugin(cordova) {
3528+ }
3529+
3530+ virtual const QString fullName() override {
3531+ return Media::fullID();
3532+ }
3533+
3534+ virtual const QString shortName() override {
3535+ return "Media";
3536+ }
3537+
3538+ static const QString fullID() {
3539+ return "Media";
3540+ }
3541+
3542+ enum State {
3543+ MEDIA_NONE = 0,
3544+ MEDIA_STARTING = 1,
3545+ MEDIA_RUNNING = 2,
3546+ MEDIA_PAUSED = 3,
3547+ MEDIA_STOPPED = 4
3548+ };
3549+ enum ErrorCode {
3550+ MEDIA_ERR_NONE_ACTIVE = 0,
3551+ MEDIA_ERR_ABORTED = 1,
3552+ MEDIA_ERR_NETWORK = 2,
3553+ MEDIA_ERR_DECODE = 3,
3554+ MEDIA_ERR_NONE_SUPPORTED = 4
3555+ };
3556+
3557+ void execJS(const QString &js) {
3558+ m_cordova->execJS(js);
3559+ }
3560+public slots:
3561+ void create(int scId, int ecId, const QString &id, const QString &src);
3562+ void relase(int scId, int ecId, const QString &id);
3563+
3564+ void startRecordingAudio(int scId, int ecId, const QString &id, const QString &src);
3565+ void stopRecordingAudio(int scId, int ecId, const QString &id);
3566+
3567+ void startPlayingAudio(int scId, int ecId, const QString &id, const QString &src, QVariantMap options);
3568+ void pausePlayingAudio(int scId, int ecId, const QString &id);
3569+ void stopPlayingAudio(int scId, int ecId, const QString &id);
3570+ void getCurrentPositionAudio(int scId, int ecId, const QString &id);
3571+ void seekToAudio(int scId, int ecId, const QString &id, qint64 position);
3572+ void setVolume(int scId, int ecId, const QString &id, int volume);
3573+
3574+private:
3575+ QMap<QString, QSharedPointer<Player> > _id2Player;
3576+};
3577+
3578+class Player: public QObject {
3579+ Q_OBJECT
3580+public:
3581+ Player(const QString &id, QString src, Media *plugin):
3582+ _state(Media::MEDIA_NONE),
3583+ _src(src),
3584+ _mode(MODE_NONE),
3585+ _plugin(plugin),
3586+ _id(id),
3587+ _stateChanged(false) {
3588+ QUrl url(src, QUrl::TolerantMode);
3589+
3590+ if (url.scheme().isEmpty()) {
3591+ QAudioEncoderSettings audioSettings;
3592+
3593+ _recorder.setEncodingSettings(audioSettings);
3594+ _recorder.setOutputLocation(QFileInfo(src).absoluteFilePath());
3595+
3596+ _player.setMedia(QUrl::fromLocalFile(QFileInfo(src).absoluteFilePath()));
3597+ } else {
3598+ _player.setMedia(url);
3599+ }
3600+ QObject::connect(&_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(onMediaStatusChanged(QMediaPlayer::MediaStatus)));
3601+ QObject::connect(&_recorder, SIGNAL(error(QMediaRecorder::Error)), this, SLOT(onError(QMediaRecorder::Error)));
3602+
3603+ connect(&_timer, SIGNAL(timeout()), this, SLOT(reportPosition()));
3604+ }
3605+
3606+ void startRecording() {
3607+ if (recordMode() && _state != Media::MEDIA_RUNNING) {
3608+ _recorder.record();
3609+ setState(Media::MEDIA_RUNNING);
3610+ }
3611+ }
3612+ void stopRecording() {
3613+ if (recordMode() && _state == Media::MEDIA_RUNNING) {
3614+ _recorder.stop();
3615+ setState(Media::MEDIA_STOPPED);
3616+ }
3617+ }
3618+
3619+ void setVolume(int volume) {
3620+ _player.setVolume(volume);
3621+ }
3622+
3623+ void play() {
3624+ if (playMode() && _state != Media::MEDIA_RUNNING) {
3625+ _player.play();
3626+ setState(Media::MEDIA_RUNNING);
3627+ }
3628+ }
3629+ void pause() {
3630+ if (playMode() && _state == Media::MEDIA_RUNNING) {
3631+ _player.pause();
3632+ setState(Media::MEDIA_PAUSED);
3633+ }
3634+ }
3635+ void stop() {
3636+ if (playMode() && (_state == Media::MEDIA_RUNNING || _state == Media::MEDIA_PAUSED)) {
3637+ _player.stop();
3638+ setState(Media::MEDIA_STOPPED);
3639+ }
3640+ }
3641+ double getDuration() {
3642+ if (_mode == MODE_NONE || _player.duration() == -1)
3643+ return -1;
3644+ if (_mode != MODE_PLAY)
3645+ return -2;
3646+ return static_cast<double>(_player.duration()) / 1000.0;
3647+ }
3648+ double getPosition() {
3649+ if (_mode != MODE_PLAY)
3650+ return -1;
3651+ return static_cast<double>(_player.position()) / 1000.0;
3652+ }
3653+ bool seekTo(qint64 position) {
3654+ if (!_player.isSeekable())
3655+ return false;
3656+ _player.setPosition(position * 1000);
3657+ return true;
3658+ }
3659+private slots:
3660+ void reportPosition() {
3661+ double position = getPosition();
3662+ _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_POSITION, %2)")
3663+ .arg(_id).arg(position));
3664+ double duration = getDuration();
3665+ _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_DURATION, %2)")
3666+ .arg(_id).arg(duration));
3667+
3668+ if (_stateChanged && !(_state == Media::MEDIA_RUNNING && (duration == -1 || position == 0))) {
3669+ qCritical() << _id << "POSITION" << position << ":" << duration;
3670+ _stateChanged = false;
3671+ _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_STATE, %2)").arg(_id).arg(_state));
3672+ }
3673+ }
3674+
3675+ void onMediaStatusChanged(QMediaPlayer::MediaStatus status) {
3676+ if (status == QMediaPlayer::InvalidMedia) {
3677+ reportError(Media::MEDIA_ERR_ABORTED, "AudioPlayer Error: The current media cannot be played.");
3678+ setState(Media::MEDIA_STOPPED);
3679+ }
3680+ if (status == QMediaPlayer::EndOfMedia) {
3681+ setState(Media::MEDIA_STOPPED);
3682+ seekTo(0);
3683+ }
3684+ }
3685+ void onError(QMediaRecorder::Error) {
3686+ reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Device is not ready or not available.");
3687+ setState(Media::MEDIA_STOPPED);
3688+ }
3689+
3690+private:
3691+ void reportError(int code, const QString &descr) {
3692+ Q_UNUSED(descr);
3693+ _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_ERROR, {code: %2})")
3694+ .arg(_id).arg(code));
3695+ }
3696+
3697+ bool playMode() {
3698+ switch (_mode) {
3699+ case Player::MODE_NONE:
3700+ _mode = MODE_PLAY;
3701+ break;
3702+ case Player::MODE_PLAY:
3703+ break;
3704+ case Player::MODE_RECORD:
3705+ reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Can't play in record mode.");
3706+ return false;
3707+ break;
3708+ }
3709+ return true;
3710+ }
3711+
3712+ bool recordMode() {
3713+ switch (_mode) {
3714+ case Player::MODE_NONE:
3715+ if (_recorder.outputLocation().isEmpty()) {
3716+ reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: unsupported output location.");
3717+ return false;
3718+ }
3719+ _mode = MODE_RECORD;
3720+ break;
3721+ case Player::MODE_PLAY:
3722+ reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Can't play in play mode.");
3723+ return false;
3724+ break;
3725+ case Player::MODE_RECORD:
3726+ break;
3727+ }
3728+ return true;
3729+ }
3730+
3731+ void setState(Media::State state) {
3732+ _state = state;
3733+ _stateChanged = true;
3734+ _timer.start(250);
3735+ }
3736+
3737+ QMediaPlayer _player;
3738+
3739+ QAudioRecorder _recorder;
3740+ QTimer _timer;
3741+
3742+ Media::State _state;
3743+ QString _src;
3744+ enum Mode {
3745+ MODE_NONE,
3746+ MODE_PLAY,
3747+ MODE_RECORD
3748+ };
3749+ Mode _mode;
3750+ Media *_plugin;
3751+ QString _id;
3752+
3753+ bool _stateChanged;
3754+};
3755+
3756+#endif
3757
3758=== added directory 'build/src/plugins/org.apache.cordova.splashscreen'
3759=== added file 'build/src/plugins/org.apache.cordova.splashscreen/splashscreen.cpp'
3760--- build/src/plugins/org.apache.cordova.splashscreen/splashscreen.cpp 1970-01-01 00:00:00 +0000
3761+++ build/src/plugins/org.apache.cordova.splashscreen/splashscreen.cpp 2014-02-19 16:53:58 +0000
3762@@ -0,0 +1,42 @@
3763+/*
3764+ *
3765+ * Copyright 2013 Canonical Ltd.
3766+ *
3767+ * Licensed to the Apache Software Foundation (ASF) under one
3768+ * or more contributor license agreements. See the NOTICE file
3769+ * distributed with this work for additional information
3770+ * regarding copyright ownership. The ASF licenses this file
3771+ * to you under the Apache License, Version 2.0 (the
3772+ * "License"); you may not use this file except in compliance
3773+ * with the License. You may obtain a copy of the License at
3774+ *
3775+ * http://www.apache.org/licenses/LICENSE-2.0
3776+ *
3777+ * Unless required by applicable law or agreed to in writing,
3778+ * software distributed under the License is distributed on an
3779+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3780+ * KIND, either express or implied. See the License for the
3781+ * specific language governing permissions and limitations
3782+ * under the License.
3783+ *
3784+*/
3785+
3786+#include <QQuickItem>
3787+
3788+#include "splashscreen.h"
3789+#include <cordova.h>
3790+
3791+#define SPLASHSCREEN_STATE_NAME "splashscreen"
3792+
3793+Splashscreen::Splashscreen(Cordova *cordova): CPlugin(cordova) {
3794+}
3795+
3796+void Splashscreen::show(int, int) {
3797+ m_cordova->rootObject()->setProperty("splashscreenPath", m_cordova->getSplashscreenPath());
3798+
3799+ m_cordova->pushViewState(SPLASHSCREEN_STATE_NAME);
3800+}
3801+
3802+void Splashscreen::hide(int, int) {
3803+ m_cordova->popViewState(SPLASHSCREEN_STATE_NAME);
3804+}
3805
3806=== added file 'build/src/plugins/org.apache.cordova.splashscreen/splashscreen.h'
3807--- build/src/plugins/org.apache.cordova.splashscreen/splashscreen.h 1970-01-01 00:00:00 +0000
3808+++ build/src/plugins/org.apache.cordova.splashscreen/splashscreen.h 2014-02-19 16:53:58 +0000
3809@@ -0,0 +1,52 @@
3810+/*
3811+ *
3812+ * Copyright 2013 Canonical Ltd.
3813+ *
3814+ * Licensed to the Apache Software Foundation (ASF) under one
3815+ * or more contributor license agreements. See the NOTICE file
3816+ * distributed with this work for additional information
3817+ * regarding copyright ownership. The ASF licenses this file
3818+ * to you under the Apache License, Version 2.0 (the
3819+ * "License"); you may not use this file except in compliance
3820+ * with the License. You may obtain a copy of the License at
3821+ *
3822+ * http://www.apache.org/licenses/LICENSE-2.0
3823+ *
3824+ * Unless required by applicable law or agreed to in writing,
3825+ * software distributed under the License is distributed on an
3826+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3827+ * KIND, either express or implied. See the License for the
3828+ * specific language governing permissions and limitations
3829+ * under the License.
3830+ *
3831+*/
3832+
3833+#ifndef SPLASHSCREEN_H
3834+#define SPLASHSCREEN_H
3835+
3836+#include <QtCore>
3837+#include <cplugin.h>
3838+
3839+class Splashscreen: public CPlugin {
3840+ Q_OBJECT
3841+public:
3842+ explicit Splashscreen(Cordova *cordova);
3843+
3844+ virtual const QString fullName() override {
3845+ return Splashscreen::fullID();
3846+ }
3847+
3848+ virtual const QString shortName() override {
3849+ return "SplashScreen";
3850+ }
3851+
3852+ static const QString fullID() {
3853+ return "SplashScreen";
3854+ }
3855+
3856+public slots:
3857+ void show(int, int);
3858+ void hide(int, int);
3859+};
3860+
3861+#endif // SPLASHSCREEN_H
3862
3863=== added directory 'build/src/plugins/org.apache.cordova.vibration'
3864=== added file 'build/src/plugins/org.apache.cordova.vibration/vibration.cpp'
3865--- build/src/plugins/org.apache.cordova.vibration/vibration.cpp 1970-01-01 00:00:00 +0000
3866+++ build/src/plugins/org.apache.cordova.vibration/vibration.cpp 2014-02-19 16:53:58 +0000
3867@@ -0,0 +1,38 @@
3868+/*
3869+ *
3870+ * Copyright 2013 Canonical Ltd.
3871+ *
3872+ * Licensed under the Apache License, Version 2.0 (the "License");
3873+ * you may not use this file except in compliance with the License.
3874+ * You may obtain a copy of the License at
3875+ *
3876+ * http://www.apache.org/licenses/LICENSE-2.0
3877+ *
3878+ * Unless required by applicable law or agreed to in writing,
3879+ * software distributed under the License is distributed on an
3880+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3881+ * KIND, either express or implied. See the License for the
3882+ * specific language governing permissions and limitations
3883+ * under the License.
3884+ *
3885+*/
3886+
3887+#include <QFeedbackHapticsEffect>
3888+#include "vibration.h"
3889+
3890+void Vibration::vibrate(int, int, int mills) {
3891+ QFeedbackHapticsEffect *vibrate = new QFeedbackHapticsEffect;
3892+ vibrate->setIntensity(1.0);
3893+ vibrate->setDuration(mills);
3894+
3895+ connect(vibrate, &QFeedbackHapticsEffect::stateChanged, [&]() {
3896+ QFeedbackEffect *effect = qobject_cast<QFeedbackEffect *>(sender());
3897+ if (!effect)
3898+ return;
3899+ if (effect->state() == QFeedbackEffect::Stopped)
3900+ effect->deleteLater();
3901+ });
3902+
3903+ vibrate->start();
3904+}
3905+
3906
3907=== added file 'build/src/plugins/org.apache.cordova.vibration/vibration.h'
3908--- build/src/plugins/org.apache.cordova.vibration/vibration.h 1970-01-01 00:00:00 +0000
3909+++ build/src/plugins/org.apache.cordova.vibration/vibration.h 2014-02-19 16:53:58 +0000
3910@@ -0,0 +1,47 @@
3911+/*
3912+ *
3913+ * Copyright 2013 Canonical Ltd.
3914+ *
3915+ * Licensed under the Apache License, Version 2.0 (the "License");
3916+ * you may not use this file except in compliance with the License.
3917+ * You may obtain a copy of the License at
3918+ *
3919+ * http://www.apache.org/licenses/LICENSE-2.0
3920+ *
3921+ * Unless required by applicable law or agreed to in writing,
3922+ * software distributed under the License is distributed on an
3923+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3924+ * KIND, either express or implied. See the License for the
3925+ * specific language governing permissions and limitations
3926+ * under the License.
3927+ *
3928+*/
3929+
3930+#ifndef _VIBRATION_H_SFAFKNVX3456
3931+#define _VIBRATION_H_SFAFKNVX3456
3932+
3933+#include <QtQuick>
3934+#include <cplugin.h>
3935+
3936+class Vibration: public CPlugin {
3937+ Q_OBJECT
3938+public:
3939+ explicit Vibration(Cordova *cordova): CPlugin(cordova) {
3940+ }
3941+
3942+ virtual const QString fullName() override {
3943+ return Vibration::fullID();
3944+ }
3945+
3946+ virtual const QString shortName() override {
3947+ return "Vibration";
3948+ }
3949+
3950+ static const QString fullID() {
3951+ return "Vibration";
3952+ }
3953+public slots:
3954+ void vibrate(int, int, int mills);
3955+};
3956+
3957+#endif
3958
3959=== modified file 'config.xml'
3960--- config.xml 2014-02-05 23:42:31 +0000
3961+++ config.xml 2014-02-19 16:53:58 +0000
3962@@ -1,5 +1,24 @@
3963 <?xml version='1.0' encoding='utf-8'?>
3964 <widget id="io.cordova.hellocordova" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
3965+ <preference name="loglevel" value="DEBUG" />
3966+ <feature name="Camera">
3967+ <param policy_group="camera" policy_version="1" />
3968+ </feature>
3969+ <feature name="DeviceOrientation">
3970+ <param policy_group="sensors" policy_version="1" />
3971+ </feature>
3972+ <feature name="Geolocation">
3973+ <param policy_group="location" policy_version="1" />
3974+ </feature>
3975+ <feature name="Media">
3976+ <param policy_group="microphone" policy_version="1" />
3977+ <param policy_group="video" policy_version="1" />
3978+ </feature>
3979+ <feature name="Capture">
3980+ <param policy_group="audio" policy_version="1" />
3981+ <param policy_group="camera" policy_version="1" />
3982+ <param policy_group="microphone" policy_version="1" />
3983+ </feature>
3984 <name>HelloCordova</name>
3985 <description>
3986 A sample Apache Cordova application that responds to the deviceready event.
3987
3988=== modified file 'debian/changelog'
3989--- debian/changelog 2014-02-18 10:03:39 +0000
3990+++ debian/changelog 2014-02-19 16:53:58 +0000
3991@@ -1,3 +1,9 @@
3992+cordova-ubuntu-3.4 (3.4~pre3.r17ubuntu2) trusty; urgency=low
3993+
3994+ * Test build with additional plugins
3995+
3996+ -- David Barth <david.barth@canonical.com> Wed, 19 Feb 2014 17:48:58 +0100
3997+
3998 cordova-ubuntu-3.4 (3.4~pre3.r17) trusty; urgency=medium
3999
4000 [ Alexandre Abreu ]
4001@@ -11,6 +17,12 @@
4002
4003 -- Daniel Holbach <daniel.holbach@ubuntu.com> Fri, 14 Feb 2014 10:21:43 +0100
4004
4005+cordova-ubuntu-3.4 (3.4~pre3ubuntu1) UNRELEASED; urgency=low
4006+
4007+ * Add the full set of platform plugins
4008+
4009+ -- David Barth <david.barth@canonical.com> Fri, 14 Feb 2014 16:17:05 +0100
4010+
4011 cordova-ubuntu-3.4 (3.4~pre3) trusty; urgency=low
4012
4013 * Trusty build
4014
4015=== modified file 'debian/control'
4016--- debian/control 2014-02-17 16:24:58 +0000
4017+++ debian/control 2014-02-19 16:53:58 +0000
4018@@ -28,8 +28,10 @@
4019 Architecture: any
4020 Depends: ${misc:Depends},
4021 ${shlibs:Depends},
4022-Description: Ubuntu HTML5 Framework for building mobile web apps - development files
4023- This package contains files that are needed to build applications.
4024+Description: Cordova Framework for building mobile web apps - development files
4025+ Cordova is a free and open source framework that allows you to create mobile
4026+ apps using standardized web APIs for the platforms you care about.
4027 .
4028- They are not meant to be used locally, but are embedded in the resulting
4029- click packages.
4030+ This package contains library files that are needed to build applications.
4031+ The libraries are not meant to be installed on the system, but should be
4032+ embedded in a click package.
4033
4034=== modified file 'debian/rules'
4035--- debian/rules 2014-02-17 16:24:58 +0000
4036+++ debian/rules 2014-02-19 16:53:58 +0000
4037@@ -1,12 +1,33 @@
4038 #!/usr/bin/make -f
4039 # -*- makefile -*-
4040
4041+# to update the source tree:
4042+# create a temporary directory to construct the runtime with the cordova CLI tool
4043+# cordova create runtime
4044+# cd runtime
4045+# cordova platform add ubuntu
4046+# cordova plugin add org.apache.cordova.camera
4047+# cordova plugin add <other plugins>
4048+# ...
4049+# cordova prepare
4050+# then copy back files from the platforms/ubuntu directory
4051+
4052 DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
4053+INSTALL_PREFIX="/usr/share/ubuntu-html5-platform-3.4/${DEB_HOST_MULTIARCH}"
4054+PACKAGE_NAME=ubuntu-html5-platform-3.4-dev
4055
4056 override_dh_auto_configure:
4057- cd build; cmake -DCMAKE_INSTALL_PREFIX=/usr/share/ubuntu-html5-platform-3.4/${DEB_HOST_MULTIARCH} \
4058+ cd build; cmake -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \
4059 -DCMAKE_VERBOSE_MAKEFILE=ON \
4060 -DCMAKE_BUILD_TYPE=RelWithDebInfo
4061
4062+override_dh_install:
4063+ dh_install
4064+ cp -R www debian/${PACKAGE_NAME}/${INSTALL_PREFIX}/; \
4065+ cp -R qml debian/${PACKAGE_NAME}/${INSTALL_PREFIX}/; \
4066+ rm -f debian/${PACKAGE_NAME}/${INSTALL_PREFIX}/cordova-ubuntu
4067+
4068+override_dh_strip:
4069+
4070 %:
4071 dh $@ --sourcedirectory=build --fail-missing
4072
4073=== added directory 'qml'
4074=== added file 'qml/CaptureWidget.qml'
4075--- qml/CaptureWidget.qml 1970-01-01 00:00:00 +0000
4076+++ qml/CaptureWidget.qml 2014-02-19 16:53:58 +0000
4077@@ -0,0 +1,119 @@
4078+/*
4079+ *
4080+ * Copyright 2013 Canonical Ltd.
4081+ *
4082+ * Licensed to the Apache Software Foundation (ASF) under one
4083+ * or more contributor license agreements. See the NOTICE file
4084+ * distributed with this work for additional information
4085+ * regarding copyright ownership. The ASF licenses this file
4086+ * to you under the Apache License, Version 2.0 (the
4087+ * "License"); you may not use this file except in compliance
4088+ * with the License. You may obtain a copy of the License at
4089+ *
4090+ * http://www.apache.org/licenses/LICENSE-2.0
4091+ *
4092+ * Unless required by applicable law or agreed to in writing,
4093+ * software distributed under the License is distributed on an
4094+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
4095+ * KIND, either express or implied. See the License for the
4096+ * specific language governing permissions and limitations
4097+ * under the License.
4098+ *
4099+*/
4100+import QtQuick 2.0
4101+import QtMultimedia 5.0
4102+
4103+Rectangle {
4104+ property string shootImagePath: "shoot.png"
4105+ function isSuffix(str, suffix) {
4106+ return String(str).substr(String(str).length - suffix.length) == suffix
4107+ }
4108+
4109+ id: ui
4110+ color: "#252423"
4111+ anchors.fill: parent
4112+
4113+ Camera {
4114+ objectName: "camera"
4115+ id: camera
4116+ onError: {
4117+ console.log(errorString);
4118+ }
4119+ videoRecorder.audioBitRate: 128000
4120+ videoRecorder.mediaContainer: "mp4"
4121+ imageCapture {
4122+ onImageSaved: {
4123+ root.exec("Camera", "onImageSaved", [path]);
4124+ ui.destroy();
4125+ }
4126+ }
4127+ }
4128+ VideoOutput {
4129+ id: output
4130+ source: camera
4131+ width: parent.width
4132+ height: parent.height
4133+ }
4134+
4135+ Item {
4136+ anchors.bottom: parent.bottom
4137+ width: parent.width
4138+ height: shootButton.height
4139+ BorderImage {
4140+ id: leftBackground
4141+ anchors.left: parent.left
4142+ anchors.top: parent.top
4143+ anchors.bottom: parent.bottom
4144+ anchors.right: middle.left
4145+ anchors.topMargin: units.dp(2)
4146+ anchors.bottomMargin: units.dp(2)
4147+ source: "toolbar-left.png"
4148+ Image {
4149+ anchors.verticalCenter: parent.verticalCenter
4150+ anchors.left: parent.left
4151+ anchors.leftMargin: parent.iconSpacing
4152+ source: "back.png"
4153+ width: units.gu(6)
4154+ height: units.gu(5)
4155+ MouseArea {
4156+ anchors.fill: parent
4157+ onClicked: {
4158+ root.exec("Camera", "cancel");
4159+ }
4160+ }
4161+ }
4162+ }
4163+ BorderImage {
4164+ id: middle
4165+ anchors.top: parent.top
4166+ anchors.bottom: parent.bottom
4167+ anchors.horizontalCenter: parent.horizontalCenter
4168+ height: shootButton.height + units.gu(1)
4169+ width: shootButton.width
4170+ source: "toolbar-middle.png"
4171+ Image {
4172+ id: shootButton
4173+ width: units.gu(8)
4174+ height: width
4175+ anchors.horizontalCenter: parent.horizontalCenter
4176+ source: shootImagePath
4177+ MouseArea {
4178+ anchors.fill: parent
4179+ onClicked: {
4180+ camera.imageCapture.capture();
4181+ }
4182+ }
4183+ }
4184+ }
4185+ BorderImage {
4186+ id: rightBackground
4187+ anchors.right: parent.right
4188+ anchors.top: parent.top
4189+ anchors.bottom: parent.bottom
4190+ anchors.left: middle.right
4191+ anchors.topMargin: units.dp(2)
4192+ anchors.bottomMargin: units.dp(2)
4193+ source: "toolbar-right.png"
4194+ }
4195+ }
4196+}
4197
4198=== added file 'qml/InAppBrowser.qml'
4199--- qml/InAppBrowser.qml 1970-01-01 00:00:00 +0000
4200+++ qml/InAppBrowser.qml 2014-02-19 16:53:58 +0000
4201@@ -0,0 +1,69 @@
4202+/*
4203+ *
4204+ * Copyright 2013 Canonical Ltd.
4205+ *
4206+ * Licensed to the Apache Software Foundation (ASF) under one
4207+ * or more contributor license agreements. See the NOTICE file
4208+ * distributed with this work for additional information
4209+ * regarding copyright ownership. The ASF licenses this file
4210+ * to you under the Apache License, Version 2.0 (the
4211+ * "License"); you may not use this file except in compliance
4212+ * with the License. You may obtain a copy of the License at
4213+ *
4214+ * http://www.apache.org/licenses/LICENSE-2.0
4215+ *
4216+ * Unless required by applicable law or agreed to in writing,
4217+ * software distributed under the License is distributed on an
4218+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
4219+ * KIND, either express or implied. See the License for the
4220+ * specific language governing permissions and limitations
4221+ * under the License.
4222+ *
4223+*/
4224+import QtQuick 2.0
4225+import QtWebKit 3.0
4226+import Ubuntu.Components.Popups 0.1
4227+import Ubuntu.Components 0.1
4228+
4229+Rectangle {
4230+ anchors.fill: parent
4231+ id: inappbrowser
4232+ property string url1
4233+ Rectangle {
4234+ border.color: "black"
4235+ width: parent.width
4236+ height: urlEntry.height
4237+ color: "gray"
4238+ TextInput {
4239+ id: urlEntry
4240+ width: parent.width - closeButton.width
4241+ text: url1
4242+ activeFocusOnPress: false
4243+ }
4244+ Image {
4245+ id: closeButton
4246+ width: height
4247+ x: parent.width - width
4248+ height: parent.height
4249+ source: "close.png"
4250+ MouseArea {
4251+ anchors.fill: parent
4252+ onClicked: {
4253+ root.exec("InAppBrowser", "close", [0, 0])
4254+ }
4255+ }
4256+ }
4257+ }
4258+
4259+ WebView {
4260+ width: parent.width
4261+ y: urlEntry.height
4262+ height: parent.height - y
4263+ url: url1
4264+ onLoadingChanged: {
4265+ if (loadRequest.status) {
4266+ root.exec("InAppBrowser", "loadFinished", [loadRequest.status])
4267+ }
4268+ }
4269+ }
4270+}
4271
4272=== added file 'qml/MediaCaptureWidget.qml'
4273--- qml/MediaCaptureWidget.qml 1970-01-01 00:00:00 +0000
4274+++ qml/MediaCaptureWidget.qml 2014-02-19 16:53:58 +0000
4275@@ -0,0 +1,207 @@
4276+/*
4277+ *
4278+ * Copyright 2013 Canonical Ltd.
4279+ *
4280+ * Licensed to the Apache Software Foundation (ASF) under one
4281+ * or more contributor license agreements. See the NOTICE file
4282+ * distributed with this work for additional information
4283+ * regarding copyright ownership. The ASF licenses this file
4284+ * to you under the Apache License, Version 2.0 (the
4285+ * "License"); you may not use this file except in compliance
4286+ * with the License. You may obtain a copy of the License at
4287+ *
4288+ * http://www.apache.org/licenses/LICENSE-2.0
4289+ *
4290+ * Unless required by applicable law or agreed to in writing,
4291+ * software distributed under the License is distributed on an
4292+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
4293+ * KIND, either express or implied. See the License for the
4294+ * specific language governing permissions and limitations
4295+ * under the License.
4296+ *
4297+*/
4298+import QtQuick 2.0
4299+import QtMultimedia 5.0
4300+
4301+Rectangle {
4302+ property string recordOffImagePath: "record_off.png"
4303+ property string recordOnImagePath: "record_on.png"
4304+ property string shootImagePath: "shoot.png"
4305+ function isSuffix(str, suffix) {
4306+ return String(str).substr(String(str).length - suffix.length) == suffix
4307+ }
4308+
4309+ id: ui
4310+ color: "#252423"
4311+ anchors.fill: parent
4312+ state: "off"
4313+
4314+ Camera {
4315+ objectName: "camera"
4316+ id: camera
4317+ cameraState: Camera.UnloadedState
4318+ onError: {
4319+ console.log(errorString);
4320+ shootButton.source = recordOffImagePath
4321+ }
4322+ imageCapture {
4323+ onImageSaved: {
4324+ root.exec("Capture", "onImageSaved", [path]);
4325+ ui.destroy();
4326+ }
4327+ }
4328+ videoRecorder {
4329+ audioBitRate: 128000
4330+ mediaContainer: "mp4"
4331+ outputLocation: ui.parent.plugin('Capture').generateLocation("mp4")
4332+ onRecorderStateChanged: {
4333+ if (videoRecorder.recorderState === CameraRecorder.StoppedState) {
4334+ ui.parent.exec("Capture", "onVideoRecordEnd", [camera.videoRecorder.actualLocation]);
4335+ shootButton.source = recordOffImagePath
4336+ }
4337+ }
4338+ }
4339+ }
4340+ Image {
4341+ id: microphoneImage
4342+ source: "microphone.png"
4343+ smooth: true
4344+ visible: false
4345+ width: parent.width
4346+ height: parent.height
4347+ }
4348+ VideoOutput {
4349+ id: output
4350+ focus : visible
4351+ source: camera
4352+ width: parent.width
4353+ height: parent.height
4354+ }
4355+
4356+ Item {
4357+ anchors.bottom: parent.bottom
4358+ width: parent.width
4359+ height: shootButton.height
4360+ BorderImage {
4361+ id: leftBackground
4362+ anchors.left: parent.left
4363+ anchors.top: parent.top
4364+ anchors.bottom: parent.bottom
4365+ anchors.right: middle.left
4366+ anchors.topMargin: units.dp(2)
4367+ anchors.bottomMargin: units.dp(2)
4368+ source: "toolbar-left.png"
4369+ Image {
4370+ anchors.verticalCenter: parent.verticalCenter
4371+ anchors.left: parent.left
4372+ anchors.leftMargin: parent.iconSpacing
4373+ source: "back.png"
4374+ width: units.gu(6)
4375+ height: units.gu(5)
4376+ MouseArea {
4377+ anchors.fill: parent
4378+ onClicked: {
4379+ root.exec("Capture", "cancel");
4380+ }
4381+ }
4382+ }
4383+ }
4384+ BorderImage {
4385+ id: middle
4386+ anchors.top: parent.top
4387+ anchors.bottom: parent.bottom
4388+ anchors.horizontalCenter: parent.horizontalCenter
4389+ height: shootButton.height + units.gu(1)
4390+ width: shootButton.width
4391+ source: "toolbar-middle.png"
4392+ Image {
4393+ id: shootButton
4394+ width: units.gu(8)
4395+ height: width
4396+ anchors.horizontalCenter: parent.horizontalCenter
4397+ source: shootImagePath
4398+ MouseArea {
4399+ anchors.fill: parent
4400+ onClicked: {
4401+ if (ui.state === "camera") {
4402+ camera.imageCapture.captureToLocation(ui.parent.plugin('Capture').generateLocation("jpg"));
4403+ } else if (ui.state === "audio") {
4404+ ui.parent.exec("Capture", "recordAudio");
4405+ if (isSuffix(shootButton.source, recordOffImagePath)) {
4406+ shootButton.source = recordOnImagePath
4407+ } else {
4408+ shootButton.source = recordOffImagePath
4409+ }
4410+ } else if (ui.state === "videoRecording") {
4411+ if (!camera.videoRecorder.recorderState) {
4412+ shootButton.source = recordOnImagePath
4413+ camera.videoRecorder.record();
4414+ } else {
4415+ camera.videoRecorder.stop();
4416+ }
4417+ }
4418+ }
4419+ }
4420+ }
4421+ }
4422+ BorderImage {
4423+ id: rightBackground
4424+ anchors.right: parent.right
4425+ anchors.top: parent.top
4426+ anchors.bottom: parent.bottom
4427+ anchors.left: middle.right
4428+ anchors.topMargin: units.dp(2)
4429+ anchors.bottomMargin: units.dp(2)
4430+ source: "toolbar-right.png"
4431+ }
4432+ }
4433+ states: [
4434+ State {
4435+ name: "off"
4436+ StateChangeScript {
4437+ script:{
4438+ ui.visible = false;
4439+ camera.stop();
4440+ camera.unlock();
4441+ }
4442+ }
4443+ },
4444+ State {
4445+ name: "camera"
4446+ StateChangeScript {
4447+ script: {
4448+ camera.start();
4449+ microphoneImage.visible = false
4450+ output.visible = true
4451+ shootButton.source = shootImagePath
4452+ ui.visible = true
4453+ }
4454+ }
4455+ },
4456+ State {
4457+ name: "videoRecording"
4458+ StateChangeScript {
4459+ script: {
4460+ shootButton.source = recordOffImagePath
4461+ camera.start();
4462+ microphoneImage.visible = false
4463+ output.visible = true
4464+ ui.visible = true
4465+ }
4466+ }
4467+ },
4468+ State {
4469+ name: "audio"
4470+ StateChangeScript {
4471+ script:{
4472+ shootButton.source = recordOffImagePath
4473+ camera.stop();
4474+ microphoneImage.visible = true
4475+ camera.unlock();
4476+ output.visible = false
4477+ ui.visible = true
4478+ }
4479+ }
4480+ }
4481+ ]
4482+}
4483
4484=== added file 'qml/back.png'
4485Binary files qml/back.png 1970-01-01 00:00:00 +0000 and qml/back.png 2014-02-19 16:53:58 +0000 differ
4486=== added file 'qml/close.png'
4487Binary files qml/close.png 1970-01-01 00:00:00 +0000 and qml/close.png 2014-02-19 16:53:58 +0000 differ
4488=== added file 'qml/microphone.png'
4489Binary files qml/microphone.png 1970-01-01 00:00:00 +0000 and qml/microphone.png 2014-02-19 16:53:58 +0000 differ
4490=== added file 'qml/notification.qml'
4491--- qml/notification.qml 1970-01-01 00:00:00 +0000
4492+++ qml/notification.qml 2014-02-19 16:53:58 +0000
4493@@ -0,0 +1,44 @@
4494+import QtQuick 2.0
4495+import Ubuntu.Components.Popups 0.1
4496+import Ubuntu.Components 0.1
4497+
4498+Dialog {
4499+ id: dialogue
4500+ property string button1Text
4501+ property string button2Text
4502+ property string button3Text
4503+ property bool promptVisible
4504+ property string defaultPromptText
4505+ TextInput {// FIXME: swith to TextField(TextField should support visible property)
4506+ id: prompt
4507+ color: "white"
4508+ text: defaultPromptText
4509+ visible: promptVisible
4510+ focus: true
4511+ }
4512+ Button {
4513+ text: button1Text
4514+ color: "orange"
4515+ onClicked: {
4516+ root.exec("Notification", "notificationDialogButtonPressed", [1, prompt.text]);
4517+ PopupUtils.close(dialogue)
4518+ }
4519+ }
4520+ Button {
4521+ text: button2Text
4522+ visible: button2Text.length > 0
4523+ color: "orange"
4524+ onClicked: {
4525+ root.exec("Notification", "notificationDialogButtonPressed", [2, prompt.text]);
4526+ PopupUtils.close(dialogue)
4527+ }
4528+ }
4529+ Button {
4530+ text: button3Text
4531+ visible: button3Text.length > 0
4532+ onClicked: {
4533+ root.exec("Notification", "notificationDialogButtonPressed", [3, prompt.text]);
4534+ PopupUtils.close(dialogue)
4535+ }
4536+ }
4537+}
4538
4539=== added file 'qml/record_off.png'
4540Binary files qml/record_off.png 1970-01-01 00:00:00 +0000 and qml/record_off.png 2014-02-19 16:53:58 +0000 differ
4541=== added file 'qml/record_on.png'
4542Binary files qml/record_on.png 1970-01-01 00:00:00 +0000 and qml/record_on.png 2014-02-19 16:53:58 +0000 differ
4543=== added file 'qml/shoot.png'
4544Binary files qml/shoot.png 1970-01-01 00:00:00 +0000 and qml/shoot.png 2014-02-19 16:53:58 +0000 differ
4545=== added file 'qml/toolbar-left.png'
4546Binary files qml/toolbar-left.png 1970-01-01 00:00:00 +0000 and qml/toolbar-left.png 2014-02-19 16:53:58 +0000 differ
4547=== added file 'qml/toolbar-middle.png'
4548Binary files qml/toolbar-middle.png 1970-01-01 00:00:00 +0000 and qml/toolbar-middle.png 2014-02-19 16:53:58 +0000 differ
4549=== added file 'qml/toolbar-right.png'
4550Binary files qml/toolbar-right.png 1970-01-01 00:00:00 +0000 and qml/toolbar-right.png 2014-02-19 16:53:58 +0000 differ
4551=== modified file 'www/cordova_plugins.js'
4552--- www/cordova_plugins.js 2014-02-05 23:42:31 +0000
4553+++ www/cordova_plugins.js 2014-02-19 16:53:58 +0000
4554@@ -1,7 +1,412 @@
4555 cordova.define('cordova/plugin_list', function(require, exports, module) {
4556-module.exports = [];
4557+module.exports = [
4558+ {
4559+ "file": "plugins/org.apache.cordova.battery-status/www/battery.js",
4560+ "id": "org.apache.cordova.battery-status.battery",
4561+ "clobbers": [
4562+ "navigator.battery"
4563+ ]
4564+ },
4565+ {
4566+ "file": "plugins/org.apache.cordova.camera/www/CameraConstants.js",
4567+ "id": "org.apache.cordova.camera.Camera",
4568+ "clobbers": [
4569+ "Camera"
4570+ ]
4571+ },
4572+ {
4573+ "file": "plugins/org.apache.cordova.camera/www/CameraPopoverOptions.js",
4574+ "id": "org.apache.cordova.camera.CameraPopoverOptions",
4575+ "clobbers": [
4576+ "CameraPopoverOptions"
4577+ ]
4578+ },
4579+ {
4580+ "file": "plugins/org.apache.cordova.camera/www/Camera.js",
4581+ "id": "org.apache.cordova.camera.camera",
4582+ "clobbers": [
4583+ "navigator.camera"
4584+ ]
4585+ },
4586+ {
4587+ "file": "plugins/org.apache.cordova.camera/www/CameraPopoverHandle.js",
4588+ "id": "org.apache.cordova.camera.CameraPopoverHandle",
4589+ "clobbers": [
4590+ "CameraPopoverHandle"
4591+ ]
4592+ },
4593+ {
4594+ "file": "plugins/org.apache.cordova.console/www/console-via-logger.js",
4595+ "id": "org.apache.cordova.console.console",
4596+ "clobbers": [
4597+ "console"
4598+ ]
4599+ },
4600+ {
4601+ "file": "plugins/org.apache.cordova.console/www/logger.js",
4602+ "id": "org.apache.cordova.console.logger",
4603+ "clobbers": [
4604+ "cordova.logger"
4605+ ]
4606+ },
4607+ {
4608+ "file": "plugins/org.apache.cordova.device/www/device.js",
4609+ "id": "org.apache.cordova.device.device",
4610+ "clobbers": [
4611+ "device"
4612+ ]
4613+ },
4614+ {
4615+ "file": "plugins/org.apache.cordova.device/src/ubuntu/device.js",
4616+ "id": "org.apache.cordova.device.DeviceProxy",
4617+ "merges": [
4618+ "device"
4619+ ]
4620+ },
4621+ {
4622+ "file": "plugins/org.apache.cordova.device-motion/www/Acceleration.js",
4623+ "id": "org.apache.cordova.device-motion.Acceleration",
4624+ "clobbers": [
4625+ "Acceleration"
4626+ ]
4627+ },
4628+ {
4629+ "file": "plugins/org.apache.cordova.device-motion/www/accelerometer.js",
4630+ "id": "org.apache.cordova.device-motion.accelerometer",
4631+ "clobbers": [
4632+ "navigator.accelerometer"
4633+ ]
4634+ },
4635+ {
4636+ "file": "plugins/org.apache.cordova.device-orientation/www/CompassError.js",
4637+ "id": "org.apache.cordova.device-orientation.CompassError",
4638+ "clobbers": [
4639+ "CompassError"
4640+ ]
4641+ },
4642+ {
4643+ "file": "plugins/org.apache.cordova.device-orientation/www/CompassHeading.js",
4644+ "id": "org.apache.cordova.device-orientation.CompassHeading",
4645+ "clobbers": [
4646+ "CompassHeading"
4647+ ]
4648+ },
4649+ {
4650+ "file": "plugins/org.apache.cordova.device-orientation/www/compass.js",
4651+ "id": "org.apache.cordova.device-orientation.compass",
4652+ "clobbers": [
4653+ "navigator.compass"
4654+ ]
4655+ },
4656+ {
4657+ "file": "plugins/org.apache.cordova.dialogs/www/notification.js",
4658+ "id": "org.apache.cordova.dialogs.notification",
4659+ "merges": [
4660+ "navigator.notification"
4661+ ]
4662+ },
4663+ {
4664+ "file": "plugins/org.apache.cordova.file/www/DirectoryEntry.js",
4665+ "id": "org.apache.cordova.file.DirectoryEntry",
4666+ "clobbers": [
4667+ "window.DirectoryEntry"
4668+ ]
4669+ },
4670+ {
4671+ "file": "plugins/org.apache.cordova.file/www/DirectoryReader.js",
4672+ "id": "org.apache.cordova.file.DirectoryReader",
4673+ "clobbers": [
4674+ "window.DirectoryReader"
4675+ ]
4676+ },
4677+ {
4678+ "file": "plugins/org.apache.cordova.file/www/Entry.js",
4679+ "id": "org.apache.cordova.file.Entry",
4680+ "clobbers": [
4681+ "window.Entry"
4682+ ]
4683+ },
4684+ {
4685+ "file": "plugins/org.apache.cordova.file/www/File.js",
4686+ "id": "org.apache.cordova.file.File",
4687+ "clobbers": [
4688+ "window.File"
4689+ ]
4690+ },
4691+ {
4692+ "file": "plugins/org.apache.cordova.file/www/FileEntry.js",
4693+ "id": "org.apache.cordova.file.FileEntry",
4694+ "clobbers": [
4695+ "window.FileEntry"
4696+ ]
4697+ },
4698+ {
4699+ "file": "plugins/org.apache.cordova.file/www/FileError.js",
4700+ "id": "org.apache.cordova.file.FileError",
4701+ "clobbers": [
4702+ "window.FileError"
4703+ ]
4704+ },
4705+ {
4706+ "file": "plugins/org.apache.cordova.file/www/FileReader.js",
4707+ "id": "org.apache.cordova.file.FileReader",
4708+ "clobbers": [
4709+ "window.FileReader"
4710+ ]
4711+ },
4712+ {
4713+ "file": "plugins/org.apache.cordova.file/www/FileSystem.js",
4714+ "id": "org.apache.cordova.file.FileSystem",
4715+ "clobbers": [
4716+ "window.FileSystem"
4717+ ]
4718+ },
4719+ {
4720+ "file": "plugins/org.apache.cordova.file/www/FileUploadOptions.js",
4721+ "id": "org.apache.cordova.file.FileUploadOptions",
4722+ "clobbers": [
4723+ "window.FileUploadOptions"
4724+ ]
4725+ },
4726+ {
4727+ "file": "plugins/org.apache.cordova.file/www/FileUploadResult.js",
4728+ "id": "org.apache.cordova.file.FileUploadResult",
4729+ "clobbers": [
4730+ "window.FileUploadResult"
4731+ ]
4732+ },
4733+ {
4734+ "file": "plugins/org.apache.cordova.file/www/FileWriter.js",
4735+ "id": "org.apache.cordova.file.FileWriter",
4736+ "clobbers": [
4737+ "window.FileWriter"
4738+ ]
4739+ },
4740+ {
4741+ "file": "plugins/org.apache.cordova.file/www/Flags.js",
4742+ "id": "org.apache.cordova.file.Flags",
4743+ "clobbers": [
4744+ "window.Flags"
4745+ ]
4746+ },
4747+ {
4748+ "file": "plugins/org.apache.cordova.file/www/LocalFileSystem.js",
4749+ "id": "org.apache.cordova.file.LocalFileSystem",
4750+ "clobbers": [
4751+ "window.LocalFileSystem"
4752+ ],
4753+ "merges": [
4754+ "window"
4755+ ]
4756+ },
4757+ {
4758+ "file": "plugins/org.apache.cordova.file/www/Metadata.js",
4759+ "id": "org.apache.cordova.file.Metadata",
4760+ "clobbers": [
4761+ "window.Metadata"
4762+ ]
4763+ },
4764+ {
4765+ "file": "plugins/org.apache.cordova.file/www/ProgressEvent.js",
4766+ "id": "org.apache.cordova.file.ProgressEvent",
4767+ "clobbers": [
4768+ "window.ProgressEvent"
4769+ ]
4770+ },
4771+ {
4772+ "file": "plugins/org.apache.cordova.file/www/requestFileSystem.js",
4773+ "id": "org.apache.cordova.file.requestFileSystem",
4774+ "clobbers": [
4775+ "window.requestFileSystem"
4776+ ]
4777+ },
4778+ {
4779+ "file": "plugins/org.apache.cordova.file/www/resolveLocalFileSystemURI.js",
4780+ "id": "org.apache.cordova.file.resolveLocalFileSystemURI",
4781+ "merges": [
4782+ "window"
4783+ ]
4784+ },
4785+ {
4786+ "file": "plugins/org.apache.cordova.file/www/ubuntu/Entry.js",
4787+ "id": "org.apache.cordova.file.Entry1",
4788+ "merges": [
4789+ "window.Entry"
4790+ ]
4791+ },
4792+ {
4793+ "file": "plugins/org.apache.cordova.file/www/ubuntu/DirectoryEntry.js",
4794+ "id": "org.apache.cordova.file.DirectoryEntry1",
4795+ "merges": [
4796+ "window.DirectoryEntry"
4797+ ]
4798+ },
4799+ {
4800+ "file": "plugins/org.apache.cordova.file/www/ubuntu/FileWriter.js",
4801+ "id": "org.apache.cordova.file.FileWriter1",
4802+ "merges": [
4803+ "window.FileWriter"
4804+ ]
4805+ },
4806+ {
4807+ "file": "plugins/org.apache.cordova.file-transfer/www/FileTransferError.js",
4808+ "id": "org.apache.cordova.file-transfer.FileTransferError",
4809+ "clobbers": [
4810+ "window.FileTransferError"
4811+ ]
4812+ },
4813+ {
4814+ "file": "plugins/org.apache.cordova.file-transfer/www/FileTransfer.js",
4815+ "id": "org.apache.cordova.file-transfer.FileTransfer",
4816+ "clobbers": [
4817+ "window.FileTransfer"
4818+ ]
4819+ },
4820+ {
4821+ "file": "plugins/org.apache.cordova.geolocation/www/Coordinates.js",
4822+ "id": "org.apache.cordova.geolocation.Coordinates",
4823+ "clobbers": [
4824+ "Coordinates"
4825+ ]
4826+ },
4827+ {
4828+ "file": "plugins/org.apache.cordova.geolocation/www/PositionError.js",
4829+ "id": "org.apache.cordova.geolocation.PositionError",
4830+ "clobbers": [
4831+ "PositionError"
4832+ ]
4833+ },
4834+ {
4835+ "file": "plugins/org.apache.cordova.geolocation/www/Position.js",
4836+ "id": "org.apache.cordova.geolocation.Position",
4837+ "clobbers": [
4838+ "Position"
4839+ ]
4840+ },
4841+ {
4842+ "file": "plugins/org.apache.cordova.geolocation/www/geolocation.js",
4843+ "id": "org.apache.cordova.geolocation.geolocation",
4844+ "clobbers": [
4845+ "navigator.geolocation"
4846+ ]
4847+ },
4848+ {
4849+ "file": "plugins/org.apache.cordova.globalization/www/GlobalizationError.js",
4850+ "id": "org.apache.cordova.globalization.GlobalizationError",
4851+ "clobbers": [
4852+ "window.GlobalizationError"
4853+ ]
4854+ },
4855+ {
4856+ "file": "plugins/org.apache.cordova.globalization/www/globalization.js",
4857+ "id": "org.apache.cordova.globalization.globalization",
4858+ "clobbers": [
4859+ "navigator.globalization"
4860+ ]
4861+ },
4862+ {
4863+ "file": "plugins/org.apache.cordova.globalization/www/ubuntu/globalization.js",
4864+ "id": "org.apache.cordova.globalization.Globalization1",
4865+ "merges": [
4866+ "navigator.globalization"
4867+ ]
4868+ },
4869+ {
4870+ "file": "plugins/org.apache.cordova.inappbrowser/www/InAppBrowser.js",
4871+ "id": "org.apache.cordova.inappbrowser.InAppBrowser",
4872+ "clobbers": [
4873+ "window.open"
4874+ ]
4875+ },
4876+ {
4877+ "file": "plugins/org.apache.cordova.media/www/MediaError.js",
4878+ "id": "org.apache.cordova.media.MediaError",
4879+ "clobbers": [
4880+ "window.MediaError"
4881+ ]
4882+ },
4883+ {
4884+ "file": "plugins/org.apache.cordova.media/www/Media.js",
4885+ "id": "org.apache.cordova.media.Media",
4886+ "clobbers": [
4887+ "window.Media"
4888+ ]
4889+ },
4890+ {
4891+ "file": "plugins/org.apache.cordova.media-capture/www/CaptureAudioOptions.js",
4892+ "id": "org.apache.cordova.media-capture.CaptureAudioOptions",
4893+ "clobbers": [
4894+ "CaptureAudioOptions"
4895+ ]
4896+ },
4897+ {
4898+ "file": "plugins/org.apache.cordova.media-capture/www/CaptureImageOptions.js",
4899+ "id": "org.apache.cordova.media-capture.CaptureImageOptions",
4900+ "clobbers": [
4901+ "CaptureImageOptions"
4902+ ]
4903+ },
4904+ {
4905+ "file": "plugins/org.apache.cordova.media-capture/www/CaptureVideoOptions.js",
4906+ "id": "org.apache.cordova.media-capture.CaptureVideoOptions",
4907+ "clobbers": [
4908+ "CaptureVideoOptions"
4909+ ]
4910+ },
4911+ {
4912+ "file": "plugins/org.apache.cordova.media-capture/www/CaptureError.js",
4913+ "id": "org.apache.cordova.media-capture.CaptureError",
4914+ "clobbers": [
4915+ "CaptureError"
4916+ ]
4917+ },
4918+ {
4919+ "file": "plugins/org.apache.cordova.media-capture/www/MediaFileData.js",
4920+ "id": "org.apache.cordova.media-capture.MediaFileData",
4921+ "clobbers": [
4922+ "MediaFileData"
4923+ ]
4924+ },
4925+ {
4926+ "file": "plugins/org.apache.cordova.media-capture/www/MediaFile.js",
4927+ "id": "org.apache.cordova.media-capture.MediaFile",
4928+ "clobbers": [
4929+ "MediaFile"
4930+ ]
4931+ },
4932+ {
4933+ "file": "plugins/org.apache.cordova.media-capture/www/capture.js",
4934+ "id": "org.apache.cordova.media-capture.capture",
4935+ "clobbers": [
4936+ "navigator.device.capture"
4937+ ]
4938+ },
4939+ {
4940+ "file": "plugins/org.apache.cordova.vibration/www/vibration.js",
4941+ "id": "org.apache.cordova.vibration.notification",
4942+ "merges": [
4943+ "navigator.notification"
4944+ ]
4945+ }
4946+];
4947 module.exports.metadata =
4948 // TOP OF METADATA
4949-{}
4950+{
4951+ "org.apache.cordova.battery-status": "0.2.7",
4952+ "org.apache.cordova.camera": "0.2.7",
4953+ "org.apache.cordova.console": "0.2.7",
4954+ "org.apache.cordova.device": "0.2.8",
4955+ "org.apache.cordova.device-motion": "0.2.6",
4956+ "org.apache.cordova.device-orientation": "0.3.5",
4957+ "org.apache.cordova.dialogs": "0.2.6",
4958+ "org.apache.cordova.file": "1.0.0",
4959+ "org.apache.cordova.file-transfer": "0.4.1",
4960+ "org.apache.cordova.geolocation": "0.3.6",
4961+ "org.apache.cordova.globalization": "0.2.6",
4962+ "org.apache.cordova.inappbrowser": "0.3.1",
4963+ "org.apache.cordova.media": "0.2.8",
4964+ "org.apache.cordova.media-capture": "0.2.7",
4965+ "org.apache.cordova.vibration": "0.3.7"
4966+}
4967 // BOTTOM OF METADATA
4968 });
4969\ No newline at end of file
4970
4971=== added directory 'www/plugins'
4972=== added directory 'www/plugins/org.apache.cordova.battery-status'
4973=== added directory 'www/plugins/org.apache.cordova.battery-status/www'
4974=== added file 'www/plugins/org.apache.cordova.battery-status/www/battery.js'
4975--- www/plugins/org.apache.cordova.battery-status/www/battery.js 1970-01-01 00:00:00 +0000
4976+++ www/plugins/org.apache.cordova.battery-status/www/battery.js 2014-02-19 16:53:58 +0000
4977@@ -0,0 +1,101 @@
4978+cordova.define("org.apache.cordova.battery-status.battery", function(require, exports, module) { /*
4979+ *
4980+ * Licensed to the Apache Software Foundation (ASF) under one
4981+ * or more contributor license agreements. See the NOTICE file
4982+ * distributed with this work for additional information
4983+ * regarding copyright ownership. The ASF licenses this file
4984+ * to you under the Apache License, Version 2.0 (the
4985+ * "License"); you may not use this file except in compliance
4986+ * with the License. You may obtain a copy of the License at
4987+ *
4988+ * http://www.apache.org/licenses/LICENSE-2.0
4989+ *
4990+ * Unless required by applicable law or agreed to in writing,
4991+ * software distributed under the License is distributed on an
4992+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
4993+ * KIND, either express or implied. See the License for the
4994+ * specific language governing permissions and limitations
4995+ * under the License.
4996+ *
4997+*/
4998+
4999+/**
5000+ * This class contains information about the current battery status.
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches