rubyuno 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright 2011 Tsutomu Uchino
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ require 'rubyuno/rubyuno'
19
+ require 'rubyuno/uno'
20
+ require 'rubyuno/uno/connector'
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright 2011 Tsutomu Uchino
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ require 'rubyuno/rubyuno'
19
+
20
+ module Uno
21
+ @@ctx = Rubyuno.get_component_context # initialize runo internal
22
+
23
+ Rubyuno.uno_require 'com.sun.star.lang.XTypeProvider'
24
+
25
+ # Uno.msgbox(message="", title="", buttons=1, type="messbox", peer=nil) -> Integer
26
+ # Shows message dialog on top frame window or specific window.
27
+ # @message [String] message to show
28
+ # @title [String] title for the message box
29
+ # @param [String] type can be messbox, infobox, warningbox, errorbox or querybox.
30
+ # @param [Fixnum] buttons is combination of constants css.awt.MessageBoxButtons.
31
+ # @param [object] peer window peer to show the dialog.
32
+ # @return [Fixnum] depends on buttons, see buttons
33
+ def Uno.msgbox(message="", title="", buttons=1, type="messbox", peer=nil)
34
+ unless peer
35
+ ctx = Rubyuno.get_component_context
36
+ desktop = ctx.getServiceManager.createInstanceWithContext(
37
+ "com.sun.star.frame.Desktop", ctx)
38
+ doc = desktop.getCurrentComponent
39
+ peer = doc.getCurrentController.getFrame.getContainerWindow if doc
40
+ end
41
+ if peer
42
+ rectangle = Rubyuno.uno_require("com.sun.star.awt.Rectangle")
43
+ msgbox = peer.getToolkit.createMessageBox(
44
+ peer, rectangle.new, type, buttons, title, message)
45
+ n = msgbox.execute
46
+ msgbox.dispose
47
+ return n
48
+ end
49
+ end
50
+
51
+ UNO_TYPES = {}
52
+ # Keeps type information about a class which implements
53
+ # css.lang.XTypeProvider interface.
54
+ class << UNO_TYPES
55
+
56
+ def types(klass)
57
+ return find_type(klass)[0]
58
+ end
59
+
60
+ def id(klass)
61
+ return find_type(klass)[1]
62
+ end
63
+
64
+ private
65
+
66
+ def find_type(klass)
67
+ value = self[klass]
68
+ value = self[klass] = [get_uno_types(klass), Uno.uuid] unless value
69
+ return value
70
+ end
71
+
72
+ def get_uno_types(klass)
73
+ types = []
74
+ klass.ancestors.each do |m|
75
+ if m.const_defined?(:UNO_TYPE_NAME)
76
+ c = m.const_get(:UNO_TYPE_NAME)
77
+ types << Uno.get_type(c)
78
+ end
79
+ end
80
+ types.uniq!
81
+ return types
82
+ end
83
+ end
84
+
85
+ # This is base module which is used to define UNO component,
86
+ # just include this module like the following:
87
+ # class MyListener
88
+ # include Uno::UnoBase
89
+ # include ...other interfaces
90
+ # end
91
+ # The adapter needs to know its types (interfaces) are implemented by the
92
+ # component, therefore methods of this module provide it.
93
+ # If it should be class itself, implement XTypeProvider interface to
94
+ # the class.
95
+ module UnoBase
96
+ include Rubyuno::Com::Sun::Star::Lang::XTypeProvider
97
+ def getTypes
98
+ return Uno::UNO_TYPES.types self.class
99
+ end
100
+
101
+ def getImplementationId
102
+ return Uno::UNO_TYPES.id self.class
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,97 @@
1
+ # coding: utf-8
2
+ #
3
+ # Copyright 2011 Tsutomu Uchino
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ require 'rubyuno/rubyuno'
19
+
20
+ module Uno
21
+ Rubyuno.uno_require 'com.sun.star.connection.NoConnectException'
22
+ Rubyuno.uno_require 'com.sun.star.connection.ConnectionSetupException'
23
+
24
+ #
25
+ # Helps to connect to the office by RPC with UNO protocol.
26
+ #
27
+ # These environmental variables should be set before to load 'runo'
28
+ # module.
29
+ # URE_BOOTSTRAP specifies to fundamental(rc|.ini) placed under
30
+ # openoffice.org3/program directory.
31
+ # LD_LIBRARY_PATH path to URE library and program directory of the office.
32
+ #
33
+ module Connector
34
+
35
+ class NoConnectionError < StandardError
36
+ end
37
+
38
+ PIPE_NAME_PREFIX = "rubypipe_"
39
+
40
+ @@sleep_time = 2.0
41
+ @@retry = 5
42
+
43
+ attr_accessor :sleep_time, :retry
44
+
45
+ # Read Professional UNO chapter of Developer's Guide about
46
+ # UNO Remote protocol.
47
+ def self.bootstrap(office="soffice", type="socket",
48
+ host="localhost", port=2083, pipe_name=nil, nodelay=false)
49
+ url, argument = self.url_construct(type, host, port, pipe_name, nodelay)
50
+ r = self.resolver_get
51
+ c = nil
52
+ n = 0
53
+ begin
54
+ c = self.connect(url, r)
55
+ rescue Rubyuno::Com::Sun::Star::Uno::Exception => e
56
+ raise e if e.uno_instance_of?(
57
+ Rubyuno::Com::Sun::Star::Connection::ConnectionSetupException)
58
+ n += 1
59
+ (raise NoConnectionError,"") if n > @@retry
60
+ spawn(ENV, office, argument)
61
+ sleep(@@sleep_time)
62
+ retry
63
+ end
64
+ return c
65
+ end
66
+
67
+ def self.connect(url, resolver=nil)
68
+ resolver = self.resolver_get unless resolver
69
+ return resolver.resolve(url)
70
+ end
71
+
72
+ def self.url_construct(type="socket",
73
+ host="localhost", port=2083, pipe_name=nil, nodelay=false)
74
+ case type
75
+ when "socket"
76
+ part = "socket,host=#{host},port=#{port}," +
77
+ "tcpNoDelay=#{nodelay ? 1 : 0};urp;"
78
+ url = "uno:#{part}StarOffice.ComponentContext"
79
+ argument = "-accept=#{part}StarOffice.ServiceManager"
80
+ when "pipe"
81
+ pipe_name = "#{PIPE_NAME_PREFIX}#{srand * 10000}" unless pipe_name
82
+ part = "pipe,name=#{pipe_name};urp;"
83
+ url = "uno:#{part}StarOffice.ServiceManager"
84
+ argument = "-accept=#{part}StarOffice.ComponentContext"
85
+ else
86
+ raise ArgumentError, "Illegal connection type (#{type})"
87
+ end
88
+ return url, argument
89
+ end
90
+
91
+ def self.resolver_get
92
+ ctx = Rubyuno.get_component_context
93
+ return ctx.getServiceManager.createInstanceWithContext(
94
+ "com.sun.star.bridge.UnoUrlResolver", ctx)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,3 @@
1
+ module Rubyuno
2
+ VERSION = "0.3.0"
3
+ end
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rubyuno/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Daniel Vandersluis", "Tsutomu Uchino"]
6
+ gem.email = ["daniel@codexed.com", "hanya.runo@gmail.com"]
7
+ gem.description = %q{Ruby-OpenOffice UNO native bridge}
8
+ gem.summary = %q{rubyuno is a Ruby-UNO (Universal Network Object) bridge, used to interact with OpenOffice.org}
9
+ gem.homepage = "http://www.github.com/dvandersluis/rubyuno"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.extensions = ['ext/rubyuno/extconf.rb']
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "rubyuno"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Rubyuno::VERSION
17
+ end
@@ -0,0 +1,66 @@
1
+ # coding: utf-8
2
+
3
+ require 'uno.rb'
4
+
5
+ desktop = Runo.get_desktop
6
+ if desktop
7
+ # create new Spreadsheet document
8
+ doc = desktop.loadComponentFromURL('private:factory/scalc', '_blank', 0, [])
9
+ Rect, Prop, CellRangeAddress = Runo.uno_require('com.sun.star.awt.Rectangle',
10
+ 'com.sun.star.beans.PropertyValue',
11
+ 'com.sun.star.table.CellRangeAddress')
12
+ def make_prop(name, value)
13
+ prop = Prop.new
14
+ prop.Name = name
15
+ prop.Value = value
16
+ prop
17
+ end
18
+
19
+ # get sheet and cell range and set data
20
+ sheet = doc.getSheets.getByIndex(0)
21
+ cell_range = sheet.getCellRangeByPosition(0, 0, 1, 2)
22
+ cell_range.setDataArray([['X', 'Y'], [0, 5], [2, 10]])
23
+
24
+ # chart container
25
+ charts = sheet.getCharts
26
+
27
+ rect = Rect.new(1300, 1300, 7000, 5000)
28
+ chart_name = 'chart2'
29
+ if charts.hasByName(chart_name)
30
+ charts.removeByName(chart_name)
31
+ end
32
+
33
+ charts.addNewByName(chart_name, rect, [CellRangeAddress.new], false, false)
34
+ chart = charts.getByName(chart_name).getEmbeddedObject
35
+
36
+ diagram = chart.getFirstDiagram
37
+ type_manager = chart.getChartTypeManager
38
+ template = type_manager.createInstance(
39
+ 'com.sun.star.chart2.template.ScatterLineSymbol')
40
+ template.changeDiagram(diagram)
41
+ data_prov = chart.getDataProvider
42
+
43
+ coords = diagram.getCoordinateSystems
44
+ coord = coords[0]
45
+
46
+ chart_types = coord.getChartTypes
47
+ chart_type = chart_types[0]
48
+
49
+
50
+ props = Array.new
51
+ props << make_prop('CellRangeRepresentation', cell_range.AbsoluteName)
52
+
53
+ props << make_prop('DataRowSource', Runo.uno_require('com.sun.star.chart.ChartDataRowSource.COLUMNS'))
54
+ props << make_prop('FirstCellAsLabel', false)
55
+ props << make_prop('HasCategories', true)
56
+
57
+ data_source = data_prov.createDataSource(props)
58
+
59
+ args = Array.new
60
+ args << make_prop('HasCategories', true)
61
+
62
+ template.changeDiagramData(diagram, data_source, args)
63
+ end
64
+
65
+
66
+
@@ -0,0 +1,70 @@
1
+
2
+ require 'uno.rb'
3
+
4
+ ctx = Runo::Connector.bootstrap
5
+
6
+ desktop = Runo.get_desktop
7
+ p desktop
8
+ unless desktop
9
+ puts 'failed to get desktop.'
10
+ exit
11
+ end
12
+
13
+ #ctx = Runo.get_component_context
14
+ Runo.uno_require('com.sun.star.awt.XActionListener')
15
+
16
+ class ButtonListener
17
+ include Runo::Base
18
+ include Runo::Com::Sun::Star::Awt::XActionListener
19
+
20
+ # XEventListener
21
+ # must be defined for all listeners
22
+ def disposing(ev)
23
+ end
24
+
25
+ # XActionListener
26
+ # called at button pushed
27
+ def actionPerformed(ev)
28
+ dlg = ev.Source.getContext
29
+ dlg.getControl('edit').setText(Time.now.to_s)
30
+ end
31
+ end
32
+
33
+ # this runtime dialog creation is just a demonstration.
34
+ # make a dialog with dialog editor of OpenOffice.org and
35
+ # create instance of the dialog using css.awt.DialogProvider service.
36
+ def create_dialog(ctx)
37
+ awt_prefix = 'com.sun.star.awt'
38
+ smgr = ctx.getServiceManager
39
+ dlg = smgr.createInstanceWithContext("#{awt_prefix}.UnoControlDialog", ctx)
40
+ dlg_model = smgr.createInstanceWithContext("#{awt_prefix}.UnoControlDialogModel", ctx)
41
+ #mri = smgr.createInstanceWithContext('mytools.Mri', ctx)
42
+ #Runo.invoke(mri, 'inspect', [dlg])
43
+ dlg.setModel(dlg_model)
44
+ dlg_model.setPropertyValues(
45
+ ['Height', 'PositionX', 'PositionY', 'Width'],
46
+ [55, 100, 100, 80])
47
+
48
+ btn_model = dlg_model.createInstance("#{awt_prefix}.UnoControlButtonModel")
49
+ edit_model = dlg_model.createInstance("#{awt_prefix}.UnoControlEditModel")
50
+ btn_model.setPropertyValues(
51
+ ['Height', 'Label', 'PositionX', 'PositionY', 'Width'],
52
+ [20, '~Push', 5, 30, 70])
53
+ edit_model.setPropertyValues(
54
+ ['Height', 'PositionX', 'PositionY', 'Width'],
55
+ [20, 5, 5, 70])
56
+ dlg_model.insertByName('btn', btn_model)
57
+ dlg_model.insertByName('edit', edit_model)
58
+
59
+ # set button listener
60
+ dlg.getControl('btn').addActionListener(ButtonListener.new)
61
+ dlg.setVisible(true)
62
+ dlg.execute
63
+ dlg.dispose # call dispose method to destroy adapter to ensure free
64
+ end
65
+
66
+ create_dialog(ctx)
67
+
68
+
69
+
70
+
@@ -0,0 +1,123 @@
1
+ # coding: utf-8
2
+
3
+ require 'runo'
4
+
5
+ # Shows list of filter names that are installed your environment.
6
+ #
7
+ # meaning of the list:
8
+ # UIName: name shown in the file open dialog
9
+ # Name: filter name that is used in API
10
+ # Type: file type
11
+ # Import: importable?
12
+ # Export: exportable?
13
+ # FilterService: service name of filtering service
14
+ # UIComponent: dialog service
15
+ # UserData: configuration data
16
+ #
17
+ # @param [Runo::RunoProxy] component context of remote server
18
+ #
19
+ def write_filter_names(ctx)
20
+ def flag_to_s(flags)
21
+ i = (flags & 1) == 1 ? 'X' : '-'
22
+ e = (flags & 2) == 2 ? 'X' : '-'
23
+ [i, e]
24
+ end
25
+ docTypes = {'com.sun.star.text.TextDocument'=> [],
26
+ 'com.sun.star.sheet.SpreadsheetDocument'=> [],
27
+ 'com.sun.star.drawing.DrawingDocument'=> [],
28
+ 'com.sun.star.text.WebDocument'=> [],
29
+ 'com.sun.star.presentation.PresentationDocument'=> [],
30
+ 'com.sun.star.formula.FormulaProperties'=> [],
31
+ 'com.sun.star.text.GlobalDocument'=> [],
32
+ 'com.sun.star.sdb.OfficeDatabaseDocument'=> [],
33
+ 'com.sun.star.chart2.ChartDocument'=> []}
34
+ ids = {'UIName'=> 0, 'Name'=> 1, 'Type'=> 2,
35
+ 'FilterService'=> 5, 'UIComponent'=> 6}
36
+ # filter factory provides all existing filters
37
+ ff = ctx.getServiceManager.createInstanceWithContext(
38
+ 'com.sun.star.document.FilterFactory', ctx)
39
+ names = ff.getElementNames
40
+
41
+ for name in names
42
+ doc_type = ''
43
+ d = Array.new(8, '')
44
+ ps = ff.getByName(name)
45
+
46
+ for pv in ps
47
+ n = pv.Name
48
+ if n == 'DocumentService'
49
+ doc_type = pv.Value
50
+ end
51
+ pos = ids[n]
52
+ if pos === nil
53
+ if n == 'Flags'
54
+ d[3], d[4] = flag_to_s(pv.Value)
55
+ elsif n == 'UserData'
56
+ d[7] = pv.Value.join
57
+ end
58
+ else
59
+ d[pos] = pv.Value
60
+ end
61
+ end
62
+ if ! doc_type.empty?
63
+ docTypes[doc_type] << d
64
+ end
65
+ end
66
+
67
+ # create new spreadsheet document from desktop
68
+ desktop = ctx.getServiceManager\
69
+ .createInstanceWithContext('com.sun.star.frame.Desktop', ctx)
70
+ doc = desktop.loadComponentFromURL('private:factory/scalc', '_blank', 0, [])
71
+
72
+ # lock controllers and disabel the modified status changing make little bit fast
73
+ doc.disableSetModified
74
+ doc.lockControllers
75
+
76
+ sheets = doc.getSheets
77
+ n = sheets.getCount
78
+
79
+ h = ['UIName', 'Name', 'Type', 'Import', 'Export',
80
+ 'FilterService', 'UIComponent', 'UserData']
81
+
82
+ for k, v in docTypes
83
+ v.unshift(h)
84
+ sheet_name = k[k.rindex('.') + 1..-1].sub('Document', '').sub('Properties', '')
85
+ # create and insert new sheet
86
+ sheet = doc.createInstance('com.sun.star.sheet.Spreadsheet')
87
+ sheets.insertByName(sheet_name, sheet)
88
+ r = sheet.getCellRangeByPosition(0, 0, 7, v.size - 1)
89
+
90
+ # set data from array, is faster than iteration of all cells
91
+ r.setDataArray(v)
92
+ r.getColumns.OptimalWidth = true
93
+ end
94
+
95
+ # remove disuse sheets. index
96
+ for i in 0..n-1
97
+ sheets.removeByName(sheets.getByIndex(0).getName)
98
+ end
99
+
100
+ # remove lockings
101
+ doc.enableSetModified
102
+ doc.unlockControllers
103
+ print "done.\n"
104
+ end
105
+
106
+
107
+ def get_ctx(local_ctx)
108
+ if local_ctx
109
+ uno_url = 'uno:socket,host=localhost,port=2083;urp;StarOffice.ComponentContext'
110
+ local_smgr = local_ctx.getServiceManager
111
+ resolver = local_smgr\
112
+ .createInstanceWithContext('com.sun.star.bridge.UnoUrlResolver', local_ctx)
113
+ ctx = resolver.resolve(uno_url)
114
+ end
115
+ end
116
+
117
+
118
+ ctx = get_ctx(Runo.get_component_context)
119
+ if ctx
120
+ write_filter_names(ctx)
121
+ end
122
+
123
+