rubyuno 0.3.0

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