canis 0.0.4
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 +45 -0
- data/CHANGES +52 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +24 -0
- data/Rakefile +2 -0
- data/canis.gemspec +25 -0
- data/examples/alpmenu.rb +46 -0
- data/examples/app.sample +19 -0
- data/examples/appemail.rb +191 -0
- data/examples/atree.rb +105 -0
- data/examples/bline.rb +181 -0
- data/examples/common/devel.rb +319 -0
- data/examples/common/file.rb +93 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +59 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/table.txt +37 -0
- data/examples/data/tasks.csv +88 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todo.txt +16 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +506 -0
- data/examples/dirtree.rb +177 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +212 -0
- data/examples/tasks.rb +179 -0
- data/examples/term2.rb +88 -0
- data/examples/testbuttons.rb +307 -0
- data/examples/testcombo.rb +102 -0
- data/examples/testdb.rb +182 -0
- data/examples/testfields.rb +208 -0
- data/examples/testflowlayout.rb +43 -0
- data/examples/testkeypress.rb +98 -0
- data/examples/testlistbox.rb +187 -0
- data/examples/testlistbox1.rb +199 -0
- data/examples/testmessagebox.rb +144 -0
- data/examples/testprogress.rb +116 -0
- data/examples/testree.rb +107 -0
- data/examples/testsplitlayout.rb +53 -0
- data/examples/testsplitlayout1.rb +49 -0
- data/examples/teststacklayout.rb +48 -0
- data/examples/testwsshortcuts.rb +68 -0
- data/examples/testwsshortcuts2.rb +129 -0
- data/lib/canis.rb +16 -0
- data/lib/canis/core/docs/index.txt +104 -0
- data/lib/canis/core/docs/list.txt +16 -0
- data/lib/canis/core/docs/style_help.yml +34 -0
- data/lib/canis/core/docs/tabbedpane.txt +15 -0
- data/lib/canis/core/docs/table.txt +31 -0
- data/lib/canis/core/docs/textpad.txt +48 -0
- data/lib/canis/core/docs/tree.txt +23 -0
- data/lib/canis/core/include/.DS_Store +0 -0
- data/lib/canis/core/include/action.rb +83 -0
- data/lib/canis/core/include/actionmanager.rb +49 -0
- data/lib/canis/core/include/appmethods.rb +179 -0
- data/lib/canis/core/include/bordertitle.rb +49 -0
- data/lib/canis/core/include/canisparser.rb +100 -0
- data/lib/canis/core/include/colorparser.rb +437 -0
- data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
- data/lib/canis/core/include/io.rb +320 -0
- data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
- data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
- data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
- data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
- data/lib/canis/core/include/listbindings.rb +89 -0
- data/lib/canis/core/include/listeditable.rb +319 -0
- data/lib/canis/core/include/listoperations.rb +61 -0
- data/lib/canis/core/include/listselectionmodel.rb +388 -0
- data/lib/canis/core/include/multibuffer.rb +173 -0
- data/lib/canis/core/include/ractionevent.rb +73 -0
- data/lib/canis/core/include/rchangeevent.rb +27 -0
- data/lib/canis/core/include/rhistory.rb +95 -0
- data/lib/canis/core/include/rinputdataevent.rb +47 -0
- data/lib/canis/core/include/textdocument.rb +111 -0
- data/lib/canis/core/include/vieditable.rb +175 -0
- data/lib/canis/core/include/widgetmenu.rb +66 -0
- data/lib/canis/core/system/colormap.rb +165 -0
- data/lib/canis/core/system/keydefs.rb +32 -0
- data/lib/canis/core/system/ncurses.rb +237 -0
- data/lib/canis/core/system/panel.rb +129 -0
- data/lib/canis/core/system/window.rb +1081 -0
- data/lib/canis/core/util/ansiparser.rb +119 -0
- data/lib/canis/core/util/app.rb +696 -0
- data/lib/canis/core/util/basestack.rb +412 -0
- data/lib/canis/core/util/defaultcolorparser.rb +84 -0
- data/lib/canis/core/util/extras/README +5 -0
- data/lib/canis/core/util/extras/bottomline.rb +1815 -0
- data/lib/canis/core/util/extras/padreader.rb +192 -0
- data/lib/canis/core/util/focusmanager.rb +31 -0
- data/lib/canis/core/util/helpmanager.rb +160 -0
- data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
- data/lib/canis/core/util/promptmenu.rb +235 -0
- data/lib/canis/core/util/rcommandwindow.rb +933 -0
- data/lib/canis/core/util/rdialogs.rb +520 -0
- data/lib/canis/core/util/textutils.rb +74 -0
- data/lib/canis/core/util/viewer.rb +238 -0
- data/lib/canis/core/util/widgetshortcuts.rb +508 -0
- data/lib/canis/core/widgets/applicationheader.rb +103 -0
- data/lib/canis/core/widgets/box.rb +58 -0
- data/lib/canis/core/widgets/divider.rb +310 -0
- data/lib/canis/core/widgets/extras/README.md +12 -0
- data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
- data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
- data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
- data/lib/canis/core/widgets/listbox.rb +326 -0
- data/lib/canis/core/widgets/listfooter.rb +86 -0
- data/lib/canis/core/widgets/rcombo.rb +210 -0
- data/lib/canis/core/widgets/rcontainer.rb +415 -0
- data/lib/canis/core/widgets/rlink.rb +30 -0
- data/lib/canis/core/widgets/rmenu.rb +970 -0
- data/lib/canis/core/widgets/rmenulink.rb +30 -0
- data/lib/canis/core/widgets/rmessagebox.rb +400 -0
- data/lib/canis/core/widgets/rprogress.rb +118 -0
- data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
- data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
- data/lib/canis/core/widgets/rwidget.rb +3634 -0
- data/lib/canis/core/widgets/scrollbar.rb +147 -0
- data/lib/canis/core/widgets/statusline.rb +113 -0
- data/lib/canis/core/widgets/table.rb +1072 -0
- data/lib/canis/core/widgets/tabular.rb +264 -0
- data/lib/canis/core/widgets/textpad.rb +1674 -0
- data/lib/canis/core/widgets/tree.rb +690 -0
- data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
- data/lib/canis/version.rb +3 -0
- metadata +229 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
require 'canis/core/util/promptmenu'
|
|
2
|
+
module Canis
|
|
3
|
+
# this module makes it possible for a textview to maintain multiple buffers
|
|
4
|
+
# The first buffer has been placed using set_content(lines, config).
|
|
5
|
+
# After this, additional buffers mst be supplied with add_content text, config.
|
|
6
|
+
# Also, please note that after you call set_content the first time, you must call
|
|
7
|
+
# add_content so the buffer can be accessed while cycling. will try to fix this.
|
|
8
|
+
# (I don't want to touch textview, would prefer not to write a decorator).
|
|
9
|
+
|
|
10
|
+
# TODO ?? allow setting of a limit, so in some cases where we keep adding
|
|
11
|
+
# programatically, the
|
|
12
|
+
# TODO: maintain cursor and line number so user can revert to same point. this will have to be
|
|
13
|
+
# updated by buffer_next and others.
|
|
14
|
+
# Done: need to be able to set multiple file names. which are read in only when
|
|
15
|
+
# buffer is accessed. filename to be maintained and used as title.
|
|
16
|
+
# == CHANGE:
|
|
17
|
+
# allow filename to be sent, rather than array. Array was very limiting since it
|
|
18
|
+
# did not have a name to list or goto a buffer with. Also, now we can add file names that
|
|
19
|
+
# are read only if the buffer is selected.
|
|
20
|
+
module MultiBuffers
|
|
21
|
+
extend self
|
|
22
|
+
|
|
23
|
+
# add content to buffers of a textview
|
|
24
|
+
# @param [Array] text, or String (filename)
|
|
25
|
+
# @param [Hash] options, typically :content_type => :ansi or :tmux, and :title
|
|
26
|
+
def add_content text, config={}
|
|
27
|
+
unless @_buffers
|
|
28
|
+
bind_key(?\M-n, :buffer_next)
|
|
29
|
+
bind_key(?\M-p, :buffer_prev)
|
|
30
|
+
bind_key(KEY_BACKSPACE, :buffer_prev) # backspace, already hardcoded in textview !
|
|
31
|
+
bind_key(?:, :buffer_menu)
|
|
32
|
+
end
|
|
33
|
+
@_buffers ||= []
|
|
34
|
+
@_buffers_conf ||= []
|
|
35
|
+
@_buffers << text
|
|
36
|
+
if text.is_a? String
|
|
37
|
+
config[:filename] = text
|
|
38
|
+
config[:title] ||= text
|
|
39
|
+
end
|
|
40
|
+
@_buffers_conf << config
|
|
41
|
+
@_buffer_ctr ||= 0
|
|
42
|
+
$log.debug "XXX: HELP adding text #{@_buffers.size} "
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# supply an array of files to the multibuffer. These will be read
|
|
46
|
+
# as the user presses next or last etc.
|
|
47
|
+
def add_files filearray, config={}
|
|
48
|
+
filearray.each do |e| add_content(e, config.dup); end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# display next buffer
|
|
52
|
+
def buffer_next
|
|
53
|
+
buffer_update_info
|
|
54
|
+
@_buffer_ctr += 1
|
|
55
|
+
x = @_buffer_ctr
|
|
56
|
+
l = @_buffers[x]
|
|
57
|
+
if l
|
|
58
|
+
populate_buffer_from_filename x
|
|
59
|
+
else
|
|
60
|
+
@_buffer_ctr = 0
|
|
61
|
+
end
|
|
62
|
+
set_content @_buffers[@_buffer_ctr], @_buffers_conf[@_buffer_ctr]
|
|
63
|
+
buffer_update_position
|
|
64
|
+
end
|
|
65
|
+
def populate_buffer_from_filename x
|
|
66
|
+
l = @_buffers[x]
|
|
67
|
+
if l
|
|
68
|
+
if l.is_a? String
|
|
69
|
+
if File.directory? l
|
|
70
|
+
Dir.chdir(l)
|
|
71
|
+
arr = Dir.entries(".")
|
|
72
|
+
@_buffers[x] = arr
|
|
73
|
+
else
|
|
74
|
+
arr = File.open(l,"r").read.split("\n")
|
|
75
|
+
@_buffers[x] = arr
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
#
|
|
81
|
+
# display previous buffer if any
|
|
82
|
+
def buffer_prev
|
|
83
|
+
buffer_update_info
|
|
84
|
+
if @_buffer_ctr < 1
|
|
85
|
+
buffer_last
|
|
86
|
+
return
|
|
87
|
+
end
|
|
88
|
+
@_buffer_ctr -= 1 if @_buffer_ctr > 0
|
|
89
|
+
x = @_buffer_ctr
|
|
90
|
+
l = @_buffers[x]
|
|
91
|
+
if l
|
|
92
|
+
populate_buffer_from_filename x
|
|
93
|
+
l = @_buffers[x]
|
|
94
|
+
$log.debug "bp calling set_content with #{l.class} "
|
|
95
|
+
set_content l, @_buffers_conf[x]
|
|
96
|
+
buffer_update_position
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
def buffer_last
|
|
100
|
+
buffer_update_info
|
|
101
|
+
@_buffer_ctr = @_buffers.count - 1
|
|
102
|
+
x = @_buffer_ctr
|
|
103
|
+
l = @_buffers.last
|
|
104
|
+
if l
|
|
105
|
+
populate_buffer_from_filename x
|
|
106
|
+
l = @_buffers[x]
|
|
107
|
+
$log.debug " calling set_content with #{l.class} "
|
|
108
|
+
set_content l, @_buffers_conf.last
|
|
109
|
+
buffer_update_position
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
def buffer_at index
|
|
113
|
+
buffer_update_info
|
|
114
|
+
@_buffer_ctr = index
|
|
115
|
+
l = @_buffers[index]
|
|
116
|
+
if l
|
|
117
|
+
populate_buffer_from_filename index
|
|
118
|
+
l = @_buffers[index]
|
|
119
|
+
set_content l, @_buffers_conf[index]
|
|
120
|
+
buffer_update_position
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
# close window, a bit clever, we really don't know what the CLOSE_KEY is
|
|
126
|
+
def close
|
|
127
|
+
@graphic.ungetch(?q.ord)
|
|
128
|
+
end
|
|
129
|
+
# display a menu so user can do buffer management
|
|
130
|
+
# However, how can application add to these. Or disable, such as when we
|
|
131
|
+
# add buffer delete or buffer insert or edit
|
|
132
|
+
def buffer_menu
|
|
133
|
+
menu = PromptMenu.new self do
|
|
134
|
+
item :n, :buffer_next
|
|
135
|
+
item :p, :buffer_prev
|
|
136
|
+
item :b, :scroll_backward
|
|
137
|
+
item :f, :scroll_forward
|
|
138
|
+
item :l, :list_buffers
|
|
139
|
+
item :q, :close
|
|
140
|
+
submenu :m, "submenu..." do
|
|
141
|
+
item :p, :goto_last_position
|
|
142
|
+
item :r, :scroll_right
|
|
143
|
+
item :l, :scroll_left
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
menu.display_new :title => "Buffer Menu"
|
|
147
|
+
end
|
|
148
|
+
# pops up a list of buffers using titles allowing the user to select
|
|
149
|
+
# Based on selection, that buffer is displayed.
|
|
150
|
+
def list_buffers
|
|
151
|
+
arr = []
|
|
152
|
+
@_buffers_conf.each_with_index do |e, i|
|
|
153
|
+
t = e[:title] || "no title for #{i}"
|
|
154
|
+
#$log.debug " TITLE is #{e.title} , t is #{t} "
|
|
155
|
+
arr << t
|
|
156
|
+
end
|
|
157
|
+
ix = popuplist arr
|
|
158
|
+
buffer_at ix
|
|
159
|
+
end
|
|
160
|
+
def buffer_update_info
|
|
161
|
+
x = @_buffer_ctr || 0
|
|
162
|
+
@_buffers_conf[x][:current_index] = @current_index || 0
|
|
163
|
+
@_buffers_conf[x][:curpos] = @curpos || 0
|
|
164
|
+
end
|
|
165
|
+
def buffer_update_position
|
|
166
|
+
x = @_buffer_ctr || 0
|
|
167
|
+
ci = (@_buffers_conf[x][:current_index] || 0)
|
|
168
|
+
goto_line ci
|
|
169
|
+
@curpos = (@_buffers_conf[x][:curpos] || 0)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
* Name: ActionEvent
|
|
3
|
+
* Description: Event used to notify interested parties that an action has happened on component
|
|
4
|
+
Usually a button press. Nothing more.
|
|
5
|
+
* Author: jkepler (ABCD)
|
|
6
|
+
|
|
7
|
+
--------
|
|
8
|
+
* Date: 2010-09-12 18:53
|
|
9
|
+
* License:
|
|
10
|
+
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
11
|
+
|
|
12
|
+
=end
|
|
13
|
+
|
|
14
|
+
# Event created when state changed (as in ViewPort)
|
|
15
|
+
module Canis
|
|
16
|
+
# source - as always is the object whose event has been fired
|
|
17
|
+
# id - event identifier (seems redundant since we bind events often separately.
|
|
18
|
+
# event - is :PRESS
|
|
19
|
+
# action_command - command string associated with event (such as title of button that changed
|
|
20
|
+
ActionEvent = Struct.new(:source, :event, :action_command) do
|
|
21
|
+
# This should always return the most relevant text associated with this object
|
|
22
|
+
# so the user does not have to go through the source object's documentation.
|
|
23
|
+
# It should be a user-friendly string
|
|
24
|
+
# @return text associated with source (label of button)
|
|
25
|
+
def text
|
|
26
|
+
source.text
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# This is similar to text and can often be just an alias.
|
|
30
|
+
# However, i am putting this for backward compatibility with programs
|
|
31
|
+
# that received the object and called it's getvalue. It is better to use text.
|
|
32
|
+
# @return text associated with source (label of button)
|
|
33
|
+
def getvalue
|
|
34
|
+
source.getvalue
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
# a derivative of Action Event for textviews
|
|
38
|
+
# We allow a user to press ENTER on a row and use that for processing.
|
|
39
|
+
# We are basically using TextView as a list in which user can scroll around
|
|
40
|
+
# and move cursor at will.
|
|
41
|
+
class TextActionEvent < ActionEvent
|
|
42
|
+
# current_index or line number starting 0
|
|
43
|
+
attr_accessor :current_index
|
|
44
|
+
# cursor position on the line
|
|
45
|
+
attr_accessor :curpos
|
|
46
|
+
def initialize source, event, action_command, current_index, curpos
|
|
47
|
+
super source, event, action_command
|
|
48
|
+
@current_index = current_index
|
|
49
|
+
@curpos = curpos
|
|
50
|
+
end
|
|
51
|
+
# the text of the line on which the user is
|
|
52
|
+
def text
|
|
53
|
+
source.current_value.to_s
|
|
54
|
+
end
|
|
55
|
+
# the word under the cursor TODO
|
|
56
|
+
# if its a text with pipe delim, then ??
|
|
57
|
+
def word_under_cursor line=text(), pos=@curpos, delim=" "
|
|
58
|
+
line ||= text()
|
|
59
|
+
pos ||= @curpos
|
|
60
|
+
# if pressed on a space, try to go to next word to make easier 2013-03-24
|
|
61
|
+
if line[pos,1] == delim
|
|
62
|
+
while line[pos,1] == delim
|
|
63
|
+
pos += 1
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
finish = line.index(delim, pos)
|
|
67
|
+
start = line.rindex(delim,pos)
|
|
68
|
+
finish = -1 if finish.nil?
|
|
69
|
+
start = 0 if start.nil?
|
|
70
|
+
return line[start..finish]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
* Name: ChangeEvent
|
|
3
|
+
* Description: Event used to notify interested parties that state of component has changed
|
|
4
|
+
* Author: jkepler (ABCD)
|
|
5
|
+
|
|
6
|
+
--------
|
|
7
|
+
* Date: 2010-02-26 11:32
|
|
8
|
+
* License:
|
|
9
|
+
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
# Event created when state changed (as in ViewPort)
|
|
14
|
+
module Canis
|
|
15
|
+
class ChangeEvent
|
|
16
|
+
attr_accessor :source
|
|
17
|
+
def initialize source
|
|
18
|
+
@source = source
|
|
19
|
+
end
|
|
20
|
+
def to_s
|
|
21
|
+
inspect
|
|
22
|
+
end
|
|
23
|
+
def inspect
|
|
24
|
+
"ChangeEvent #{@source}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
|
2
|
+
# File: rhistory.rb
|
|
3
|
+
# Description: a module that pops up history, and then updates selected value
|
|
4
|
+
# This goes with Field.
|
|
5
|
+
# e.g.,
|
|
6
|
+
# field.extend(FieldHistory)
|
|
7
|
+
#
|
|
8
|
+
# The module name History was throwing up errors
|
|
9
|
+
# Author: jkepler http://github.com/mare-imbrium/canis/
|
|
10
|
+
# Date: 2011-11-27 - 18:10
|
|
11
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
12
|
+
# Last update: 2011-11-27 - 20:11
|
|
13
|
+
# ----------------------------------------------------------------------------- #
|
|
14
|
+
#
|
|
15
|
+
# supply history for this object, at least give an empty array
|
|
16
|
+
# widget would typically be Field,
|
|
17
|
+
# otherwise it should implement *text()* for getting and setting value
|
|
18
|
+
# and a *CHANGED* event for when user has modified a value and moved out
|
|
19
|
+
# You can externally set $history_key to any unused key, otherwise it is M-h
|
|
20
|
+
module Canis
|
|
21
|
+
extend self
|
|
22
|
+
module FieldHistory
|
|
23
|
+
def self.extended(obj)
|
|
24
|
+
|
|
25
|
+
obj.instance_exec {
|
|
26
|
+
@history ||= []
|
|
27
|
+
$history_key ||= ?\M-h
|
|
28
|
+
# ensure that the field is not overriding this in handle_key
|
|
29
|
+
bind_key($history_key) { _show_history }
|
|
30
|
+
# widget should have CHANGED event, or this will either give error, or just not work
|
|
31
|
+
# else please update history whenever you want a value to be retrieved
|
|
32
|
+
bind(:CHANGED) { @history << @text if @text && (!@history.include? @text) }
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# pass the array of history values
|
|
37
|
+
# Trying out a change where an item can also be sent in.
|
|
38
|
+
# I am lost, i want the initialization to happen once.
|
|
39
|
+
def history arr
|
|
40
|
+
return @history unless arr
|
|
41
|
+
if arr.is_a? Array
|
|
42
|
+
@history = arr
|
|
43
|
+
else
|
|
44
|
+
@history << arr unless @history.include? arr
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
def history=(x); history(x); end
|
|
48
|
+
|
|
49
|
+
# pass in some configuration for histroy such as row and column to show popup on
|
|
50
|
+
def history_config config={}
|
|
51
|
+
@_history_config = config
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# popup the hist
|
|
55
|
+
#
|
|
56
|
+
private
|
|
57
|
+
def _show_history
|
|
58
|
+
return unless @history
|
|
59
|
+
return if @history.empty?
|
|
60
|
+
list = @history
|
|
61
|
+
@_history_config ||= {}
|
|
62
|
+
#list = ["No history"] if @history.empty?
|
|
63
|
+
raise ArgumentError, "show_history got nil list" unless list
|
|
64
|
+
# calculate r and c
|
|
65
|
+
# col if fine, except for when there's a label.
|
|
66
|
+
wcol = 0 # taking care of when dialog uses history 2012-01-4
|
|
67
|
+
wcol = self.form.window.left if self.form
|
|
68
|
+
c = wcol + ( @field_col || @col) # this is also dependent on window coords, as in a status_window or messagebox
|
|
69
|
+
sz = @history.size
|
|
70
|
+
wrow = 0
|
|
71
|
+
wrow = self.form.window.top if self.form
|
|
72
|
+
crow = wrow + @row
|
|
73
|
+
# if list can be displayed above, then fit it just above
|
|
74
|
+
if crow > sz + 2
|
|
75
|
+
r = crow - sz - 2
|
|
76
|
+
else
|
|
77
|
+
# else fit it in next row
|
|
78
|
+
r = crow + 1
|
|
79
|
+
end
|
|
80
|
+
#r = @row - 10
|
|
81
|
+
#if @row < 10
|
|
82
|
+
#r = @row + 1
|
|
83
|
+
#end
|
|
84
|
+
r = @_history_config[:row] || r
|
|
85
|
+
c = @_history_config[:col] || c
|
|
86
|
+
ret = popuplist(list, :row => r, :col => c, :title => " History ")
|
|
87
|
+
if ret
|
|
88
|
+
self.text = list[ret]
|
|
89
|
+
self.set_form_col
|
|
90
|
+
end
|
|
91
|
+
@form.repaint if @form
|
|
92
|
+
@window.wrefresh if @window
|
|
93
|
+
end
|
|
94
|
+
end # mod History
|
|
95
|
+
end # mod RubyC
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
* Name: InputDataEvent
|
|
3
|
+
* Description: Event created when data modified in Field or TextEdit
|
|
4
|
+
* Author: jkepler (ABCD)
|
|
5
|
+
|
|
6
|
+
--------
|
|
7
|
+
* Date: 2008-12-24 17:27
|
|
8
|
+
* License:
|
|
9
|
+
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
10
|
+
|
|
11
|
+
NOTE: this is how we used to write code in the Java days. Anyone reading this source,
|
|
12
|
+
this is NOT how to code in rubyland. Please see this link, for how to code such as class:
|
|
13
|
+
http://blog.grayproductions.net/articles/all_about_struct
|
|
14
|
+
|
|
15
|
+
=end
|
|
16
|
+
|
|
17
|
+
# Event created when data modified in Field or TextEdit
|
|
18
|
+
# 2008-12-24 17:54
|
|
19
|
+
module Canis
|
|
20
|
+
class InputDataEvent
|
|
21
|
+
attr_accessor :index0, :index1, :source, :type, :row, :text
|
|
22
|
+
def initialize index0, index1, source, type, row, text
|
|
23
|
+
@index0 = index0
|
|
24
|
+
@index1 = index1
|
|
25
|
+
@source = source
|
|
26
|
+
@type = type
|
|
27
|
+
@row = row
|
|
28
|
+
@text = text
|
|
29
|
+
end
|
|
30
|
+
# until now to_s was returning inspect, but to make it easy for users let us return the value
|
|
31
|
+
# they most expect which is the text that was changed
|
|
32
|
+
def to_s
|
|
33
|
+
inspect
|
|
34
|
+
end
|
|
35
|
+
def inspect
|
|
36
|
+
## now that textarea.to_s prints content we shouldn pass it here.
|
|
37
|
+
#"#{@type.to_s}, #{@source}, ind0:#{@index0}, ind1:#{@index1}, row:#{@row}, text:#{@text}"
|
|
38
|
+
"#{@type.to_s}, ind0:#{@index0}, ind1:#{@index1}, row:#{@row}, text:#{@text}"
|
|
39
|
+
end
|
|
40
|
+
# this is so that earlier applications were getting source in the block, not an event. they
|
|
41
|
+
# were doing a fld.getvalue, so we must keep those apps running
|
|
42
|
+
# @since 1.2.0 added 2010-09-11 12:25
|
|
43
|
+
def getvalue
|
|
44
|
+
@source.getvalue
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
|
2
|
+
# File: textdocument.rb
|
|
3
|
+
# Description: Abstracts complex text preprocessing and rendering from TextPad
|
|
4
|
+
# Author: j kepler http://github.com/mare-imbrium/canis/
|
|
5
|
+
# Date: 2014-06-25 - 12:52
|
|
6
|
+
# License: MIT
|
|
7
|
+
# Last update: 2014-07-08 13:11
|
|
8
|
+
# ----------------------------------------------------------------------------- #
|
|
9
|
+
# textdocument.rb Copyright (C) 2012-2014 j kepler
|
|
10
|
+
|
|
11
|
+
module Canis
|
|
12
|
+
# In an attempt to keep TextPad simple, and move complexity of complex content out of it,
|
|
13
|
+
# I am trying to move specialized processing and rendering to a Document class which manages the same.
|
|
14
|
+
# I would also like to keep content, and content_type etc together. This should percolate to multibuffers
|
|
15
|
+
# to.
|
|
16
|
+
# An application may create a TextDocument object and pass it to TextPad using the +text+ method.
|
|
17
|
+
# Or an app may send in a hash, which +text+ uses to create this object.
|
|
18
|
+
class TextDocument
|
|
19
|
+
attr_accessor :content_type
|
|
20
|
+
attr_accessor :stylesheet
|
|
21
|
+
# +hash+ of options passed in constructor including content_type and stylesheet
|
|
22
|
+
attr_accessor :options
|
|
23
|
+
# +text+ is the original Array<String> which contains markup of some sort
|
|
24
|
+
# which source will retrieve. Changes happen to this (row added, deleted, changed)
|
|
25
|
+
attr_accessor :text
|
|
26
|
+
|
|
27
|
+
# returns the native or transformed format of original content. +text+ gets transformed into
|
|
28
|
+
# native text. The renderer knows how to display native_text.
|
|
29
|
+
#attr_reader :native_text
|
|
30
|
+
def native_text
|
|
31
|
+
unless @native_text
|
|
32
|
+
preprocess_text @text
|
|
33
|
+
end
|
|
34
|
+
return @native_text
|
|
35
|
+
end
|
|
36
|
+
# specify a renderer if you do not want the DefaultRenderer to be installed.
|
|
37
|
+
attr_accessor :renderer
|
|
38
|
+
attr_reader :source
|
|
39
|
+
|
|
40
|
+
def initialize hash
|
|
41
|
+
@parse_required = true
|
|
42
|
+
@options = hash
|
|
43
|
+
@content_type = hash[:content_type]
|
|
44
|
+
@stylesheet = hash[:stylesheet]
|
|
45
|
+
@text = hash[:text]
|
|
46
|
+
$log.debug " TEXTDOCUMENT created with #{@content_type} , #{@stylesheet} "
|
|
47
|
+
raise "textdoc recieves nil content_type in constructor" unless @content_type
|
|
48
|
+
end
|
|
49
|
+
# declare that transformation of entire content is required. Currently called by fire_dimension_changed event
|
|
50
|
+
# of textpad.
|
|
51
|
+
def parse_required
|
|
52
|
+
@parse_required = true
|
|
53
|
+
end
|
|
54
|
+
# set the object that is using this textdocument (typically TextPad).
|
|
55
|
+
# This allows us to bind to events such as adding or deleting a row, or modification of data.
|
|
56
|
+
def source=(sou)
|
|
57
|
+
@source = sou
|
|
58
|
+
if @renderer
|
|
59
|
+
@source.renderer = @renderer
|
|
60
|
+
end
|
|
61
|
+
@source.bind :ROW_CHANGED do | o, ix| parse_line ix ; end
|
|
62
|
+
@source.bind :DIMENSION_CHANGED do | o, _meth| parse_required() ; end
|
|
63
|
+
@source.title = self.title() if self.title()
|
|
64
|
+
end
|
|
65
|
+
# if there is a content_type specfied but nothing to handle the content
|
|
66
|
+
# then we create a default handler.
|
|
67
|
+
def create_default_content_type_handler
|
|
68
|
+
raise "source is nil in textdocument" unless @source
|
|
69
|
+
require 'canis/core/include/colorparser'
|
|
70
|
+
# cp will take the content+type from self and select actual parser
|
|
71
|
+
cp = Chunks::ColorParser.new @source
|
|
72
|
+
@content_type_handler = cp
|
|
73
|
+
end
|
|
74
|
+
# called by textpad to do any parsing or conversion on data since a textdocument by default
|
|
75
|
+
# does some transformation on the content
|
|
76
|
+
def preprocess_text data
|
|
77
|
+
parse_formatted_text data
|
|
78
|
+
end
|
|
79
|
+
# transform a given line number from original content to internal format.
|
|
80
|
+
# Called by textpad when a line changes (update)
|
|
81
|
+
def parse_line(lineno)
|
|
82
|
+
@native_text[lineno] = @content_type_handler.parse_line( @list[lineno])
|
|
83
|
+
end
|
|
84
|
+
# This is now to be called at start when text is set,
|
|
85
|
+
# and whenever there is a data modification.
|
|
86
|
+
# This updates @native_text
|
|
87
|
+
# @param [Array<String>] original content sent in by user
|
|
88
|
+
# which may contain markup
|
|
89
|
+
# @param [Hash] config containing
|
|
90
|
+
# content_type
|
|
91
|
+
# stylesheet
|
|
92
|
+
# @return [Chunklines] content in array of chunks.
|
|
93
|
+
def parse_formatted_text(formatted_text, config=nil)
|
|
94
|
+
return unless @parse_required
|
|
95
|
+
|
|
96
|
+
unless @content_type_handler
|
|
97
|
+
create_default_content_type_handler
|
|
98
|
+
end
|
|
99
|
+
@parse_required = false
|
|
100
|
+
@native_text = @content_type_handler.parse_text formatted_text
|
|
101
|
+
end
|
|
102
|
+
# returns title of document
|
|
103
|
+
def title
|
|
104
|
+
return @options[:title]
|
|
105
|
+
end
|
|
106
|
+
# set title of document (to be displayed by textpad)
|
|
107
|
+
def title=(t)
|
|
108
|
+
@options[:title] = t
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end # mod
|