rbcurse-experimental 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,188 @@
1
+ =begin
2
+ * Name: UndoManager
3
+ * Description: Manages undo of text components
4
+ * Author: rkumar (arunachalesha)
5
+
6
+ ISSUES
7
+
8
+ This is a very simple, undo facility. This could change in the near future.
9
+
10
+ Todo:
11
+ We need to handle block updates - several undo ops to be done together.
12
+
13
+
14
+ --------
15
+ * Date: 2010-03-07 19:42
16
+ * License:
17
+ Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
18
+
19
+ =end
20
+
21
+ #
22
+ #
23
+ module RubyCurses
24
+ #
25
+ # AbstractUndo has the basic workings of the undo redo facility.
26
+ # It leaves the actual undo and redo to the implementing source object. However,
27
+ # it does the work of storing edits, and passing the correct edit to the implementor
28
+ # when the source object calls for an undo or redo operation. It thus manages the edit (undo) queue.
29
+ #
30
+ class AbstractUndo
31
+ # initialize the source object which will issue undo requests
32
+ def initialize _source
33
+ source(_source) #if _source
34
+ @pointer = 0
35
+ @actions = []
36
+ $log.debug " INSIDE UNDO CONSTR "
37
+ end
38
+ def source(_source)
39
+ $log.debug " calling source= "
40
+ raise "Cannot pass a nil source" unless _source
41
+ @source = _source
42
+ # currently this is very hardcode again. we need to see this in the light of other objects
43
+ #@source.bind(:CHANGE){|eve| add_edit(eve) }
44
+ # a little roundabout but done for getting things up fast
45
+ @source.undo_handler(self)
46
+ $log.debug " I am listening to change events on #{@source.name} "
47
+ end
48
+ # this is called whenever an undoable edit has happened.
49
+ # Currently, it is linked above in the bind statement. We've attached this
50
+ # method as a listener to the source.
51
+ def add_edit event
52
+ # this debug is very specific. it should be removed later. We do not know about the object
53
+ $log.debug " UNDO GOT #{event}: #{event.type}, (#{event.text}), rej: #{@reject_update} "
54
+ return if @reject_update
55
+ if @pointer < @actions.length
56
+ $log.debug " removing some actions since #{@pointer} < #{@actions.length} "
57
+ @actions.slice!(@pointer..-1)
58
+ $log.debug " removed actions since #{@pointer} , #{@actions.length} "
59
+ end
60
+ @actions << event
61
+ @pointer = @actions.length
62
+ end
63
+ # this has to be bound in source component
64
+ # typically bind C-_ to undo()
65
+ # this method figures out the correct undo object to be sent
66
+ # to the implementor
67
+ def undo
68
+ $log.debug " got UNDO call #{@pointer}, sz:#{@actions.size} "
69
+ return if @pointer == 0
70
+ @reject_update = true
71
+ @pointer -=1 #if @pointer > 0
72
+ @source.repaint_required true
73
+ @reject_update = false
74
+ edit = @actions[@pointer]
75
+ perform_undo edit
76
+ end
77
+ # this has to be bound in source
78
+ # typically bind C-r to redo()
79
+ # this method figures out the correct redo object to be sent
80
+ # to the implementor
81
+ def redo
82
+ $log.debug "UNDO GOT REDO call #{@pointer}, #{@actions.size} "
83
+ return if @pointer >= @actions.size
84
+ @reject_update = true
85
+ edit = @actions[@pointer]
86
+ perform_redo edit
87
+ @source.repaint_required true
88
+ @pointer +=1 #if @pointer > 0
89
+ @reject_update = false
90
+ end
91
+ def perform_redo edit
92
+ raise "You must implement this for your undoable component "
93
+ end
94
+ def perform_undo edit
95
+ raise "You must implement this for your undoable component "
96
+ # to be implemented
97
+ end
98
+ #def to_s
99
+ #inspect
100
+ #end
101
+ #def inspect
102
+ ### now that textarea.to_s prints content we shouldn pass it here.
103
+ ##"#{@type.to_s}, #{@source}, ind0:#{@index0}, ind1:#{@index1}, row:#{@row}, text:#{@text}"
104
+ #"#{@type.to_s}, ind0:#{@index0}, ind1:#{@index1}, row:#{@row}, text:#{@text}"
105
+ #end
106
+ end
107
+ ## An implementation of AbstractUndo for textarea.
108
+ # Very basic.
109
+ class SimpleUndo < AbstractUndo
110
+ def initialize _source
111
+ super
112
+ end
113
+ def source(_source)
114
+ super
115
+ _source.bind(:CHANGE){|eve| add_edit(eve) }
116
+ end
117
+ def perform_undo act
118
+ row = act.row
119
+ col = act.index0
120
+ $log.debug " processing #{act} "
121
+ case act.type
122
+ when :INSERT
123
+ howmany = act.index1 - col
124
+ @source.list[row].slice!(col,howmany)
125
+ when :DELETE
126
+ $log.debug " UNDO processing DELETE #{col}, (#{act.text}) "
127
+ @source.list[row].insert(col, act.text.chomp)
128
+ when :DELETE_LINE
129
+ $log.debug " UNDO inside delete-line #{row} "
130
+ #@source.list.insert(row, act.text) # insert a blank line, since one was deleted
131
+ case act.text
132
+ when Array
133
+ index = row
134
+ act.text.each_with_index{|r,i| @source.list.insert index+i, r}
135
+ when String
136
+ @source.list.insert row, act.text
137
+ end
138
+ when :INSERT_LINE
139
+ $log.debug " UNDO inside insert-line #{row} "
140
+ case act.text
141
+ when Array
142
+ act.text.size.times { @source.list.delete_at row }
143
+ when String
144
+ @source.list.delete_at row
145
+ end
146
+ else
147
+ $log.warn "unhandled change type #{act.type} "
148
+ end
149
+ @source.repaint_required true
150
+ @reject_update = false
151
+ end
152
+ # this has to be bound in source
153
+ def perform_redo act
154
+ row = act.row
155
+ col = act.index0
156
+ $log.debug " REDO processing #{act} "
157
+ case act.type
158
+ when :INSERT
159
+ @source.list[row].insert(col, act.text)
160
+ when :DELETE
161
+ row = act.row
162
+ col = act.index0
163
+ howmany = act.index1 - col
164
+ @source.list[row].slice!(col,howmany)
165
+ when :DELETE_LINE
166
+ #$log.debug " UNDO redo got deleteline #{row} "
167
+ #@source.list.delete_at row
168
+ # changed on 2010-05-23 12:21 since was not handling mult delete
169
+ case act.text
170
+ when Array
171
+ act.text.size.times { @source.list.delete_at row }
172
+ when String
173
+ @source.list.delete_at row
174
+ end
175
+ when :INSERT_LINE
176
+ case act.text
177
+ when Array
178
+ index = row
179
+ act.text.each_with_index{|r,i| @source.list.insert index+i, r}
180
+ when String
181
+ @source.list.insert row, act.text
182
+ end
183
+ else
184
+ $log.warn "unhandled change type #{act.type} "
185
+ end
186
+ end
187
+ end
188
+ end # module
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbcurse-experimental
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rahul Kumar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rbcurse-core
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.0.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.0.4
30
+ - !ruby/object:Gem::Dependency
31
+ name: rbcurse-extras
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0.0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0.0'
46
+ description: Ruby curses/ncurses widgets, experimental and minimally tested
47
+ email: sentinel1879@gmail.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files:
51
+ - README.markdown
52
+ files:
53
+ - README.markdown
54
+ - VERSION
55
+ - examples/teststackflow.rb
56
+ - lib/rbcurse/experimental/widgets/directorylist.rb
57
+ - lib/rbcurse/experimental/widgets/directorytree.rb
58
+ - lib/rbcurse/experimental/widgets/masterdetail.rb
59
+ - lib/rbcurse/experimental/widgets/multiform.rb
60
+ - lib/rbcurse/experimental/widgets/resultsetbrowser.rb
61
+ - lib/rbcurse/experimental/widgets/resultsettextview.rb
62
+ - lib/rbcurse/experimental/widgets/rscrollform.rb
63
+ - lib/rbcurse/experimental/widgets/stackflow.rb
64
+ - lib/rbcurse/experimental/widgets/undomanager.rb
65
+ homepage: http://github.com/rkumar/rbcurse-experimental
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project: rbcurse
85
+ rubygems_version: 1.8.23
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Ruby Ncurses Toolkit experimental widgets
89
+ test_files: []