torqml 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +32 -0
- data/.yardopts +3 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +148 -0
- data/Rakefile +6 -0
- data/assets/images/capture.png +0 -0
- data/assets/images/configure.png +0 -0
- data/assets/images/edit.png +0 -0
- data/assets/images/play.png +0 -0
- data/assets/images/reload.png +0 -0
- data/assets/images/stop.png +0 -0
- data/assets/shapes/TQBox.obj +44 -0
- data/assets/shapes/TQCone.obj +169 -0
- data/assets/shapes/TQCylinder.obj +585 -0
- data/assets/shapes/TQSphere.obj +1497 -0
- data/assets/shapes/TQTorus.obj +3754 -0
- data/bin/torqml +12 -0
- data/examples/SerialLink/SerialLink.qml +35 -0
- data/examples/SerialLink/main.qml +29 -0
- data/examples/SerialLink/main_multi.qml +40 -0
- data/examples/Tutorial/MyModel.qml +34 -0
- data/examples/Tutorial/main_00_minimal.qml +10 -0
- data/examples/Tutorial/main_01_property.qml +15 -0
- data/examples/Tutorial/main_02_pose.qml +19 -0
- data/examples/Tutorial/main_03_link.qml +32 -0
- data/examples/Tutorial/main_04_importmodel.qml +7 -0
- data/examples/Tutorial/main_05_cameralight.qml +17 -0
- data/examples/Tutorial/main_06_animation.qml +18 -0
- data/examples/WheeledVehicle/WheeledVehicle.qml +62 -0
- data/examples/WheeledVehicle/data/maze2014student.dat +19 -0
- data/examples/WheeledVehicle/data/wheeledvehicle.csv +11712 -0
- data/examples/WheeledVehicle/main.qml +38 -0
- data/examples/WheeledVehicle/plugins/MazeWallGenerator/plugin.rb +68 -0
- data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeHorizWall.qml +29 -0
- data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeVertWall.qml +30 -0
- data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/MazeWallGenerator.qml +24 -0
- data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/qmldir +4 -0
- data/examples/WheeledVehicle/plugins/MazeWallGenerator/qml/TorQML/Plugins/MazeWallGenerator/wallAllocator.js +47 -0
- data/ext/TorQML/FrameGrabber/extconf.rb +45 -0
- data/ext/TorQML/FrameGrabber/framegrabber.cpp +36 -0
- data/ext/TorQML/FrameGrabber/framegrabber.pro +9 -0
- data/ext/TorQML/FrameGrabber/qmldir +2 -0
- data/lib/torqml.rb +47 -0
- data/lib/torqml/datasources.rb +12 -0
- data/lib/torqml/datasources/csvdatasource.rb +44 -0
- data/lib/torqml/datasources/datasource.rb +44 -0
- data/lib/torqml/datasources/lineardatasource.rb +47 -0
- data/lib/torqml/datasources/matrixdatasource.rb +37 -0
- data/lib/torqml/plugins.rb +44 -0
- data/lib/torqml/version.rb +6 -0
- data/plugins/DO_NOT_MODIFY_THIS_DIRECTORY +2 -0
- data/qml/TorQML/DataSources/TQCSVDataSource.qml +17 -0
- data/qml/TorQML/DataSources/TQLinearDataSource.qml +18 -0
- data/qml/TorQML/DataSources/qmldir +3 -0
- data/qml/TorQML/Shapes/TQAxis.qml +26 -0
- data/qml/TorQML/Shapes/TQBox.qml +11 -0
- data/qml/TorQML/Shapes/TQCone.qml +17 -0
- data/qml/TorQML/Shapes/TQCoordinate.qml +30 -0
- data/qml/TorQML/Shapes/TQCylinder.qml +17 -0
- data/qml/TorQML/Shapes/TQGrid.qml +36 -0
- data/qml/TorQML/Shapes/TQPrimitive.qml +33 -0
- data/qml/TorQML/Shapes/TQSphere.qml +18 -0
- data/qml/TorQML/Shapes/TQTorus.qml +18 -0
- data/qml/TorQML/Shapes/qmldir +10 -0
- data/qml/TorQML/TQModel.qml +9 -0
- data/qml/TorQML/Views/Dialogs/TQCaptureDialog.qml +197 -0
- data/qml/TorQML/Views/Dialogs/TQProgressDialog.qml +36 -0
- data/qml/TorQML/Views/Dialogs/qmldir +3 -0
- data/qml/TorQML/Views/TQBasicView.qml +148 -0
- data/qml/TorQML/Views/TQCamera.qml +11 -0
- data/qml/TorQML/Views/TQViewport.qml +41 -0
- data/qml/TorQML/Views/basicview.js +172 -0
- data/qml/TorQML/Views/mouseEventHandler.js +55 -0
- data/qml/TorQML/Views/qmldir +4 -0
- data/qml/TorQML/qmldir +2 -0
- data/torqml.gemspec +29 -0
- metadata +181 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import QtQuick 2.0
|
|
2
|
+
import QtQuick.Controls 1.1
|
|
3
|
+
import QtQuick.Window 2.1
|
|
4
|
+
import Qt3D 2.0
|
|
5
|
+
import TorQML.DataSources 0.1
|
|
6
|
+
import TorQML.Views 0.1
|
|
7
|
+
|
|
8
|
+
TQBasicView {
|
|
9
|
+
id: controller
|
|
10
|
+
|
|
11
|
+
light: Light {
|
|
12
|
+
position: "0,0,5000"
|
|
13
|
+
ambientColor: "white"
|
|
14
|
+
}
|
|
15
|
+
camera: TQCamera {
|
|
16
|
+
center: Qt.vector3d(8 * 180, 8 * 180, 0)
|
|
17
|
+
eye: Qt.vector3d(8 * 180, 8 * 180, 6000)
|
|
18
|
+
farPlane: 1000000
|
|
19
|
+
nearPlane: 5
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
msPerFrame: 5
|
|
23
|
+
|
|
24
|
+
models: WheeledVehicle {
|
|
25
|
+
id: links
|
|
26
|
+
dataSource: TQCSVDataSource {
|
|
27
|
+
source: "data/wheeledvehicle.csv"
|
|
28
|
+
onDataTriggered: {
|
|
29
|
+
links.tx = value_at(0)
|
|
30
|
+
links.ty = value_at(1)
|
|
31
|
+
links.theta = -value_at(2) // * 180 / Math.PI
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
wallSource: "data/maze2014student.dat"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// vim:set ts=4 sw=4 et:
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/ruby -Ku
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
require 'qml'
|
|
5
|
+
class MazeWallGenerator_
|
|
6
|
+
include QML::Access
|
|
7
|
+
register_to_qml under: "TorQML.Plugins.MazeWallGenerator", version: "0.1" # QML: MazeWallGenerator
|
|
8
|
+
|
|
9
|
+
property(:source) { "" }
|
|
10
|
+
|
|
11
|
+
def prepare_data
|
|
12
|
+
file = File.open(self.source, 'r')
|
|
13
|
+
mode = file.readline.to_i
|
|
14
|
+
@w = file.readline.to_i
|
|
15
|
+
@h = file.readline.to_i
|
|
16
|
+
gx = 7
|
|
17
|
+
gy = 7
|
|
18
|
+
|
|
19
|
+
if mode != 0
|
|
20
|
+
gx = file.readline.to_i
|
|
21
|
+
gy = file.readline.to_i
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@horizwall = Array.new(@h) { Array.new(@w - 1) }
|
|
25
|
+
@vertwall = Array.new(@h) { Array.new(@w - 1) }
|
|
26
|
+
|
|
27
|
+
y = @h - 1
|
|
28
|
+
x = 0
|
|
29
|
+
file.readlines.each do |line|
|
|
30
|
+
line.split(" ").each do |char|
|
|
31
|
+
if x >= @w then next end
|
|
32
|
+
c = 0
|
|
33
|
+
if char.ord >= '0'.ord && char.ord <= '9'.ord
|
|
34
|
+
c = char.ord - '0'.ord
|
|
35
|
+
elsif char.ord >= 'a'.ord && char.ord <= 'f'.ord
|
|
36
|
+
c = char.ord - 'a'.ord + 10
|
|
37
|
+
end
|
|
38
|
+
if (x != @w - 1 && (c & 0x2) == 0x2) then @vertwall[y][x] = 1 else @vertwall[y][x] = 0 end
|
|
39
|
+
if (y != 0 && (c & 0x4) == 0x4) then @horizwall[y][x] = 1 else @horizwall[y][x] = 0 end
|
|
40
|
+
x = x + 1
|
|
41
|
+
end
|
|
42
|
+
x = 0
|
|
43
|
+
y = y - 1
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def width
|
|
48
|
+
return @w
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def height
|
|
52
|
+
return @h
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def horiz_wall?(x, y)
|
|
56
|
+
return @horizwall[y][x]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def vert_wall?(x, y)
|
|
60
|
+
return @vertwall[y][x]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
alias_method :has_horiz_wall, :horiz_wall?
|
|
64
|
+
alias_method :has_vert_wall, :vert_wall?
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# vim:set ts=2 sw=2 et:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import QtQuick 2.0
|
|
2
|
+
import Qt3D 2.0
|
|
3
|
+
import Qt3D.Shapes 2.0
|
|
4
|
+
import TorQML.Shapes 0.1
|
|
5
|
+
|
|
6
|
+
Item3D {
|
|
7
|
+
TQBox {
|
|
8
|
+
xLength: 180
|
|
9
|
+
yWidth: 12
|
|
10
|
+
zDepth: 48
|
|
11
|
+
centered: true
|
|
12
|
+
color: "white"
|
|
13
|
+
}
|
|
14
|
+
TQBox {
|
|
15
|
+
xLength: 180
|
|
16
|
+
yWidth: 12
|
|
17
|
+
zDepth: 2
|
|
18
|
+
centered: true
|
|
19
|
+
color: "red"
|
|
20
|
+
transform: [
|
|
21
|
+
Translation3D { translate: "0,0,24" }
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
transform: [
|
|
25
|
+
Translation3D { translate: "0,0,25" }
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// vim:set ts=4 sw=4 et:
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import QtQuick 2.0
|
|
2
|
+
import Qt3D 2.0
|
|
3
|
+
import Qt3D.Shapes 2.0
|
|
4
|
+
import TorQML.Shapes 0.1
|
|
5
|
+
|
|
6
|
+
Item3D {
|
|
7
|
+
TQBox {
|
|
8
|
+
xLength: 180
|
|
9
|
+
yWidth: 12
|
|
10
|
+
zDepth: 48
|
|
11
|
+
centered: true
|
|
12
|
+
color: "white"
|
|
13
|
+
}
|
|
14
|
+
TQBox {
|
|
15
|
+
xLength: 180
|
|
16
|
+
yWidth: 12
|
|
17
|
+
zDepth: 2
|
|
18
|
+
centered: true
|
|
19
|
+
color: "red"
|
|
20
|
+
transform: [
|
|
21
|
+
Translation3D { translate: "0,0,24" }
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
transform: [
|
|
25
|
+
Translation3D { translate: "0,0,25" },
|
|
26
|
+
Rotation3D { angle: 90; axis: "0,0,1" }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// vim:set ts=4 sw=4 et:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import QtQuick 2.0
|
|
2
|
+
import Qt3D 2.0
|
|
3
|
+
import TorQML.Plugins.MazeWallGenerator 0.1
|
|
4
|
+
import "wallAllocator.js" as WallAllocator
|
|
5
|
+
|
|
6
|
+
Item {
|
|
7
|
+
property alias source: _generator.source
|
|
8
|
+
MazeWallGenerator_ {
|
|
9
|
+
id: _generator
|
|
10
|
+
Component.onCompleted: {
|
|
11
|
+
WallAllocator.prepare();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
Component {
|
|
15
|
+
id: _vertwall
|
|
16
|
+
MazeVertWall{}
|
|
17
|
+
}
|
|
18
|
+
Component {
|
|
19
|
+
id: _horizwall
|
|
20
|
+
MazeHorizWall{}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// vim:set ts=4 sw=4 et:
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
function allocateVertWall(){
|
|
2
|
+
var w = _generator.width();
|
|
3
|
+
var h = _generator.height();
|
|
4
|
+
for(var y = 0; y < h; y++){
|
|
5
|
+
for(var x = 0; x < w; x++){
|
|
6
|
+
if(_generator.has_vert_wall(x, y)){
|
|
7
|
+
_vertwall.createObject(parent, {'x': x * 180 + 90, 'y': y * 180});
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
for(var y = 0; y < h; y++){
|
|
12
|
+
_vertwall.createObject(parent, {'x': -90, 'y': y * 180});
|
|
13
|
+
_vertwall.createObject(parent, {'x': w * 180-90, 'y': y * 180});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function allocateHorizWall(){
|
|
18
|
+
var w = _generator.width();
|
|
19
|
+
var h = _generator.height();
|
|
20
|
+
for(var y = 0; y < h; y++){
|
|
21
|
+
for(var x = 0; x < w; x++){
|
|
22
|
+
if(_generator.has_horiz_wall(x, y)){
|
|
23
|
+
_horizwall.createObject(parent, {'x': x * 180, 'y': y * 180 - 90});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
for(var x = 0; x < w; x++){
|
|
28
|
+
_horizwall.createObject(parent, {'x': x * 180, 'y': h * 180 - 90});
|
|
29
|
+
_horizwall.createObject(parent, {'x': x * 180, 'y': -90});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function prepare(){
|
|
34
|
+
_generator.prepare_data();
|
|
35
|
+
if(_vertwall.status === Component.Ready){
|
|
36
|
+
allocateVertWall();
|
|
37
|
+
} else {
|
|
38
|
+
_vertwall.statusChanged.connect(allocateVertWall);
|
|
39
|
+
}
|
|
40
|
+
if(_horizwall.status === Component.Ready){
|
|
41
|
+
allocateHorizWall();
|
|
42
|
+
} else {
|
|
43
|
+
_horizwall.statusChanged.connect(allocateHorizWall);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// vim:set ts=4 sw=4 et:
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'mkmf'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
class TorQMLBuilder
|
|
5
|
+
|
|
6
|
+
def find_deps
|
|
7
|
+
@pkgconfig_bin = with_config('pkg-config') || ENV['PKGCONFIG'] || find_executable('pkg-config')
|
|
8
|
+
@qt_path = with_config('qt-dir') ? Pathname(with_config('qt-dir')).realpath : nil
|
|
9
|
+
@make_bin = ENV['MAKE'] || find_executable('make')
|
|
10
|
+
@qmake_bin = @qt_path ? @qt_path + 'bin/qmake' : find_executable('qmake')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def sh(command)
|
|
14
|
+
system(command)
|
|
15
|
+
success = $?.exitstatus == 0
|
|
16
|
+
puts "Command '#{command}' not found." if $?.exitstatus == 127
|
|
17
|
+
puts "Command '#{command}' failed." unless success
|
|
18
|
+
success
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def makefile
|
|
22
|
+
sh("#{@qmake_bin}")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def qmake
|
|
26
|
+
sh("#{@make_bin} qmake")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def build
|
|
30
|
+
sh("#{@make_bin}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def build_all
|
|
34
|
+
find_deps
|
|
35
|
+
makefile &&
|
|
36
|
+
qmake &&
|
|
37
|
+
build
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
builder = TorQMLBuilder.new
|
|
43
|
+
builder.build_all
|
|
44
|
+
|
|
45
|
+
# vim:set ts=2 sw=2 et:
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#include <QtQml/QQmlExtensionPlugin>
|
|
2
|
+
#include <QImage>
|
|
3
|
+
#include <QQuickView>
|
|
4
|
+
#include <QQuickItem>
|
|
5
|
+
#include <qdebug.h>
|
|
6
|
+
#include <qcoreapplication.h>
|
|
7
|
+
|
|
8
|
+
class FrameGrabber : public QQuickItem
|
|
9
|
+
{
|
|
10
|
+
Q_OBJECT
|
|
11
|
+
public:
|
|
12
|
+
FrameGrabber(QQuickItem* parent=0) : QQuickItem(parent)
|
|
13
|
+
{
|
|
14
|
+
}
|
|
15
|
+
Q_INVOKABLE void capture(QString const &path, int x, int y, int w, int h) const
|
|
16
|
+
{
|
|
17
|
+
QImage img = window()->grabWindow();
|
|
18
|
+
img.copy(QRect(x, y, w, h)).save(path);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
class FrameGrabberPlugin : public QQmlExtensionPlugin
|
|
23
|
+
{
|
|
24
|
+
Q_OBJECT
|
|
25
|
+
Q_PLUGIN_METADATA(IID "org.tokor.TorQML.FrameGrabber")
|
|
26
|
+
public:
|
|
27
|
+
void registerTypes(const char *uri)
|
|
28
|
+
{
|
|
29
|
+
Q_ASSERT(uri == QLatin1String("TorQML.FrameGrabber"));
|
|
30
|
+
qmlRegisterType<FrameGrabber>(uri, 0, 1, "FrameGrabber"); // QML: FrameGrabber
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
#include "framegrabber.moc"
|
|
35
|
+
|
|
36
|
+
// vim:set ts=4 sw=4 et:
|
data/lib/torqml.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'qml'
|
|
2
|
+
require 'torqml/datasources'
|
|
3
|
+
require 'torqml/plugins'
|
|
4
|
+
require 'torqml/version'
|
|
5
|
+
|
|
6
|
+
# TorQML module.
|
|
7
|
+
module TorQML
|
|
8
|
+
|
|
9
|
+
# Displays usage.
|
|
10
|
+
def usage
|
|
11
|
+
puts "torqml ver." + VERSION
|
|
12
|
+
puts "usage: torqml <main.qml>"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Main routine.
|
|
16
|
+
def run
|
|
17
|
+
if ARGV.length < 1 then usage; exit end
|
|
18
|
+
|
|
19
|
+
torqml_root_dir = Pathname.new(__dir__).parent
|
|
20
|
+
plugin_dir = Pathname.new(Plugins::default_path)
|
|
21
|
+
qml_realpath = Pathname.new(ARGV[0]).realpath
|
|
22
|
+
|
|
23
|
+
# preload ruby modules of plugins
|
|
24
|
+
Plugins::preload(plugin_dir.dirname)
|
|
25
|
+
Plugins::preload(qml_realpath.dirname + 'plugins')
|
|
26
|
+
|
|
27
|
+
# change current directory to use relative paths in both ruby and QML
|
|
28
|
+
Dir.chdir(qml_realpath.dirname) do
|
|
29
|
+
QML.run do |app|
|
|
30
|
+
# load QML/C++ components of plugins
|
|
31
|
+
Plugins::load(app, plugin_dir.dirname)
|
|
32
|
+
Plugins::load(app, qml_realpath.dirname + 'plugins')
|
|
33
|
+
|
|
34
|
+
# add QML import paths
|
|
35
|
+
app.engine.add_import_path("#{torqml_root_dir.realpath}/qml")
|
|
36
|
+
app.engine.add_import_path("#{torqml_root_dir.realpath}/ext")
|
|
37
|
+
|
|
38
|
+
app.load_path qml_realpath.basename
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
module_function :usage
|
|
44
|
+
module_function :run
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# vim:set ts=2 sw=2 et:
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module TorQML
|
|
2
|
+
# TorQML module of datasources.
|
|
3
|
+
module DataSources
|
|
4
|
+
# Version of DataSources.
|
|
5
|
+
VERSION = "0.1"
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require_relative 'datasources/csvdatasource.rb'
|
|
10
|
+
require_relative 'datasources/lineardatasource.rb'
|
|
11
|
+
|
|
12
|
+
# vim:set ts=2 sw=2 et:
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/ruby -Ku
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
require 'qml'
|
|
5
|
+
require 'csv'
|
|
6
|
+
require_relative './matrixdatasource'
|
|
7
|
+
|
|
8
|
+
module TorQML
|
|
9
|
+
module DataSources
|
|
10
|
+
# Data source class to provide CSV data.
|
|
11
|
+
class CSVDataSource_rb < MatrixDataSource_rb
|
|
12
|
+
include QML::Access
|
|
13
|
+
register_to_qml # QML: CSVDataSource_rb
|
|
14
|
+
|
|
15
|
+
# @return [String] the file path
|
|
16
|
+
property(:source) { "" }
|
|
17
|
+
# @return [String] the separator character of the CSV file
|
|
18
|
+
property(:separator) { "" }
|
|
19
|
+
|
|
20
|
+
# Prepare data to provide.
|
|
21
|
+
# The separator of CSV data can be set via `:separator` property.
|
|
22
|
+
# If not set, the method tries to detect it automatically.
|
|
23
|
+
def prepare_data
|
|
24
|
+
if self.separator.empty?
|
|
25
|
+
# detect the separator of data
|
|
26
|
+
File.open(self.source, "r") do |file|
|
|
27
|
+
row = file.readline
|
|
28
|
+
if row.match(/,/)
|
|
29
|
+
self.separator = ','
|
|
30
|
+
elsif row.match(/\t/)
|
|
31
|
+
self.separator = '\t'
|
|
32
|
+
elsif row.match(/\s/)
|
|
33
|
+
self.separator = ' '
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
@data = CSV.read(self.source, {:converters => :float, :col_sep => self.separator})
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# vim:set ts=2 sw=2 et:
|