niklas-vimmate 0.8.0.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.
- data/.autotest +10 -0
- data/CHANGELOG +108 -0
- data/COPYING +20 -0
- data/README +221 -0
- data/Rakefile +97 -0
- data/TODO +21 -0
- data/bin/vimmate +95 -0
- data/config/environment.rb +33 -0
- data/controllers/file_filter_controller.rb +85 -0
- data/controllers/file_popup_menu_controller.rb +40 -0
- data/controllers/vim_controller.rb +28 -0
- data/controllers/vim_mate_controller.rb +76 -0
- data/images/file.png +0 -0
- data/images/file_green.png +0 -0
- data/images/file_orange.png +0 -0
- data/images/file_red.png +0 -0
- data/images/folder.png +0 -0
- data/images/folder_green.png +0 -0
- data/images/folder_orange.png +0 -0
- data/images/folder_red.png +0 -0
- data/images/processing.png +0 -0
- data/images/svn_added.png +0 -0
- data/images/svn_conflict.png +0 -0
- data/images/svn_deleted.png +0 -0
- data/images/svn_locked.png +0 -0
- data/images/svn_modified.png +0 -0
- data/images/svn_normal.png +0 -0
- data/images/svn_readonly.png +0 -0
- data/images/vimmate16.png +0 -0
- data/images/vimmate32.png +0 -0
- data/images/vimmate48.png +0 -0
- data/lib/active_window.rb +8 -0
- data/lib/active_window/active_column.rb +218 -0
- data/lib/active_window/active_tree_store.rb +13 -0
- data/lib/active_window/active_tree_store/columns.rb +88 -0
- data/lib/active_window/active_tree_store/extentions.rb +81 -0
- data/lib/active_window/active_tree_store/index.rb +53 -0
- data/lib/active_window/application.rb +133 -0
- data/lib/active_window/controller.rb +58 -0
- data/lib/active_window/dot_file.rb +29 -0
- data/lib/active_window/filtered_active_tree_store.rb +114 -0
- data/lib/active_window/listed_item.rb +127 -0
- data/lib/active_window/signal.rb +46 -0
- data/lib/config_window.rb +90 -0
- data/lib/file_tree_store.rb +73 -0
- data/lib/filtered_file_tree_store.rb +34 -0
- data/lib/gtk_thread_helper.rb +73 -0
- data/lib/listed_directory.rb +43 -0
- data/lib/listed_file.rb +67 -0
- data/lib/try.rb +9 -0
- data/lib/vim/buffers.rb +18 -0
- data/lib/vim/integration.rb +36 -0
- data/lib/vim/netbeans.rb +156 -0
- data/lib/vim/source.vim +18 -0
- data/lib/vim_mate/config.rb +132 -0
- data/lib/vim_mate/dummy_window.rb +14 -0
- data/lib/vim_mate/files_menu.rb +110 -0
- data/lib/vim_mate/icons.rb +156 -0
- data/lib/vim_mate/nice_singleton.rb +53 -0
- data/lib/vim_mate/plugins.rb +6 -0
- data/lib/vim_mate/plugins/inotify/init.rb +4 -0
- data/lib/vim_mate/plugins/inotify/lib/INotify.rb +206 -0
- data/lib/vim_mate/plugins/inotify/lib/directory.rb +58 -0
- data/lib/vim_mate/plugins/subversion/init.rb +7 -0
- data/lib/vim_mate/plugins/subversion/lib/file.rb +59 -0
- data/lib/vim_mate/plugins/subversion/lib/menu.rb +96 -0
- data/lib/vim_mate/plugins/subversion/lib/subversion.rb +157 -0
- data/lib/vim_mate/requirer.rb +68 -0
- data/lib/vim_mate/search_window.rb +227 -0
- data/lib/vim_mate/tags_window.rb +167 -0
- data/lib/vim_mate/terminals_window.rb +163 -0
- data/lib/vim_mate/version.rb +29 -0
- data/lib/vim_mate/vim_widget.rb +150 -0
- data/spec/active_window/active_column_spec.rb +41 -0
- data/spec/active_window/active_tree_store_spec.rb +312 -0
- data/spec/active_window/controller_spec.rb +6 -0
- data/spec/lib/file_tree_store_spec.rb +40 -0
- data/spec/lib/listed_directory_spec.rb +26 -0
- data/spec/lib/listed_file_spec.rb +53 -0
- data/spec/nice_singleton_spec.rb +23 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +10 -0
- data/views/vim_mate.glade +308 -0
- data/vimmate.gemspec +131 -0
- metadata +168 -0
data/TODO
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= TODO
|
2
|
+
List of things to do:
|
3
|
+
- Find a better way to hide the file list and use the same way to hide
|
4
|
+
the terminals. Patches for this are welcome!
|
5
|
+
- Configurable shortcut keys: allow users to change the shortcut keys
|
6
|
+
with .vimmaterc. Need to find a way to specify the modifier (shift, ctrl)
|
7
|
+
and the key. Probably something like "CONTROL_MASK SHIFT_MASK GDK_S".
|
8
|
+
- Icons are missing on move or mkdir -p
|
9
|
+
|
10
|
+
= Ideas
|
11
|
+
- New from file copy
|
12
|
+
- Opening many files at once
|
13
|
+
- Open in external viewer
|
14
|
+
|
15
|
+
= TODO from Rewrite
|
16
|
+
- re-enable SVN support
|
17
|
+
|
18
|
+
|
19
|
+
/home/niklas/ruby/VimMate/bin/../lib/file_tree_controller.rb: line 150
|
20
|
+
Gtk-CRITICAL **:gtk_tree_model_row_has_child_toggled: assertion `path != NULL' failed
|
21
|
+
|
data/bin/vimmate
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Parse the command line arguments
|
3
|
+
require 'optparse'
|
4
|
+
excludes = []
|
5
|
+
OptionParser.new do |opts|
|
6
|
+
opts.banner = "Usage: #{File.basename($0)} [options] [files or directories]"
|
7
|
+
|
8
|
+
opts.separator ""
|
9
|
+
# opts.separator "VimMate #{VimMate::VERSION}: Vim graphical add-on"
|
10
|
+
opts.separator "Copyright (C) 2006 Guillaume Benny"
|
11
|
+
opts.separator ""
|
12
|
+
opts.separator "If files or directories are omitted, the current directory is shown"
|
13
|
+
|
14
|
+
opts.on("-x",
|
15
|
+
"--exclude file1,file2,file3",
|
16
|
+
Array,
|
17
|
+
"Comma separated list of files or directory to exclude.") do |list|
|
18
|
+
excludes = list
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on_tail("-h", "--help", "Show this help screen") do |string|
|
22
|
+
puts opts
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
end.parse!
|
26
|
+
|
27
|
+
|
28
|
+
# Ignore patterns from .vimmate_ignore
|
29
|
+
local_ignore_file = File.expand_path('.vimmate_ignore')
|
30
|
+
if File.exists?(local_ignore_file)
|
31
|
+
File.open(local_ignore_file) do |f|
|
32
|
+
while line = f.gets
|
33
|
+
line.chomp!.strip!
|
34
|
+
excludes << line unless line.empty?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# We fork to give back the shell to the user, like Vim
|
40
|
+
fork do
|
41
|
+
# TODO set this in activewindow.. but how?
|
42
|
+
APP_ROOT = File.expand_path( File.join( File.dirname(__FILE__), '..' ) )
|
43
|
+
PROGRAM_NAME = 'vim_mate'
|
44
|
+
require File.join( APP_ROOT, 'config/environment' )
|
45
|
+
Thread.abort_on_exception = true
|
46
|
+
|
47
|
+
class VimMateApp < ActiveWindow::Application
|
48
|
+
def initialize(opts={})
|
49
|
+
@excludes = opts.delete(:excludes)
|
50
|
+
super
|
51
|
+
end
|
52
|
+
def file_tree
|
53
|
+
files.file_tree
|
54
|
+
end
|
55
|
+
def files
|
56
|
+
controller[:file_filter]
|
57
|
+
end
|
58
|
+
def vim
|
59
|
+
controller[:vim].vim
|
60
|
+
end
|
61
|
+
def add_path(path)
|
62
|
+
file_tree.add_path(path)
|
63
|
+
end
|
64
|
+
|
65
|
+
def post_setup
|
66
|
+
super
|
67
|
+
|
68
|
+
@excludes.each do |rule|
|
69
|
+
file_tree.exclude! rule
|
70
|
+
end unless @excludes.blank?
|
71
|
+
|
72
|
+
# If there are no files given, add the current directory to the file list.
|
73
|
+
# If files are specified on the command line, use them
|
74
|
+
if ARGV.empty?
|
75
|
+
add_path(File.expand_path('.'))
|
76
|
+
files.expand_first_row
|
77
|
+
else
|
78
|
+
ARGV.each do |file|
|
79
|
+
path = File.expand_path(file)
|
80
|
+
add_path(path)
|
81
|
+
#window.vim.open(path, :tab)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
app = VimMateApp.new(:title => 'VimMate', :main_window => 'VimMate', :excludes => excludes)
|
88
|
+
app.start
|
89
|
+
|
90
|
+
|
91
|
+
## Create the main objects
|
92
|
+
#window = VimMate::Window.new
|
93
|
+
|
94
|
+
end
|
95
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'activesupport'
|
3
|
+
|
4
|
+
|
5
|
+
#ActiveSupport::Dependencies::logger = Logger.new( File.expand_path('log/dependencies.log') )
|
6
|
+
#ActiveSupport::Dependencies::log_activity = true
|
7
|
+
ActiveSupport::Dependencies::load_paths << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
|
8
|
+
ActiveSupport::Dependencies::load_paths << File.expand_path(File.join(File.dirname(__FILE__), "../controllers"))
|
9
|
+
ActiveSupport::Dependencies::load_paths << File.expand_path(File.join(File.dirname(__FILE__), "../lib/vim_mate"))
|
10
|
+
|
11
|
+
VimMate::Requirer.require_exit('gtk2')
|
12
|
+
VimMate::Requirer.require_exit('libglade2')
|
13
|
+
|
14
|
+
|
15
|
+
#require 'vimmatelib/file_tree_view'
|
16
|
+
require_dependency 'gtk_thread_helper'
|
17
|
+
require_dependency 'plugins'
|
18
|
+
|
19
|
+
require_dependency 'active_window'
|
20
|
+
|
21
|
+
%w(
|
22
|
+
file_created file_modified file_deleted file_opened
|
23
|
+
dir_created
|
24
|
+
item_opened item_removed item_refreshed
|
25
|
+
file_opened
|
26
|
+
).each do |signal|
|
27
|
+
ActiveWindow::Signal::define signal
|
28
|
+
end
|
29
|
+
|
30
|
+
require_dependency 'vim_mate_controller'
|
31
|
+
require_dependency 'vim_controller'
|
32
|
+
require_dependency 'file_filter_controller'
|
33
|
+
require_dependency 'file_popup_menu_controller'
|
@@ -0,0 +1,85 @@
|
|
1
|
+
class FileFilterController < ActiveWindow::Controller
|
2
|
+
attr_reader :file_tree, :filtered_file_tree
|
3
|
+
|
4
|
+
def post_setup
|
5
|
+
# TODO use ActiveTreeStore derivate
|
6
|
+
@file_tree = FileTreeStore.new
|
7
|
+
@filtered_file_tree = FilteredFileTreeStore.new(file_tree)
|
8
|
+
|
9
|
+
filtered_file_tree.apply_to_tree file_tree_view
|
10
|
+
|
11
|
+
file_tree_view.selection.mode = Gtk::SELECTION_SINGLE
|
12
|
+
file_tree_view.headers_visible = VimMate::Config[:file_headers_visible]
|
13
|
+
file_tree_view.hover_selection = VimMate::Config[:file_hover_selection]
|
14
|
+
|
15
|
+
tree_scroller.set_size_request(VimMate::Config[:files_opened_width], -1)
|
16
|
+
files_filter_button.active = VimMate::Config[:files_filter_active]
|
17
|
+
files_pane.position = VimMate::Config[:files_search_separator_position]
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO find another poace to put
|
21
|
+
def selection_changed
|
22
|
+
STDERR.puts "changed selection"
|
23
|
+
if row.file_or_directory?
|
24
|
+
selected_path_label.text = File.join(row.full_path)
|
25
|
+
else
|
26
|
+
selected_path_label.text = ""
|
27
|
+
end
|
28
|
+
end
|
29
|
+
def changed
|
30
|
+
if files_filter_button.active?
|
31
|
+
filter_string = files_filter_term.text
|
32
|
+
|
33
|
+
if filtered_file_tree.filter_string.blank? && filter_string.length == 1 # begin of filtering
|
34
|
+
save_expands if VimMate::Config[:files_auto_expand_on_filter]
|
35
|
+
end
|
36
|
+
|
37
|
+
filtered_file_tree.filter = filter_string
|
38
|
+
|
39
|
+
if VimMate::Config[:files_auto_expand_on_filter]
|
40
|
+
filter_string.blank? ? restore_expands : expand_all
|
41
|
+
end
|
42
|
+
else
|
43
|
+
filtered_file_tree.clear_filter
|
44
|
+
restore_expands if VimMate::Config[:files_auto_expand_on_filter]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
alias_method :toggle, :changed
|
48
|
+
|
49
|
+
def expand_all
|
50
|
+
file_tree_view.expand_all
|
51
|
+
end
|
52
|
+
|
53
|
+
def expand_first_row
|
54
|
+
file_tree_view.collapse_all
|
55
|
+
file_tree_view.expand_row(Gtk::TreePath.new("0"), false)
|
56
|
+
end
|
57
|
+
|
58
|
+
def button_pressed(given)
|
59
|
+
event = given[:event]
|
60
|
+
if event.kind_of? Gdk::EventButton and event.button == 3
|
61
|
+
path = file_tree_view.get_path_at_pos(event.x, event.y)
|
62
|
+
file_tree_view.selection.select_path(path[0]) if path
|
63
|
+
if file_tree_view.selection.selected
|
64
|
+
file_popup.popup(nil, nil, 0, 0)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def save_expands
|
71
|
+
@expands = []
|
72
|
+
file_tree_view.map_expanded_rows { |tree_view, path| @expands << path }
|
73
|
+
@expands
|
74
|
+
end
|
75
|
+
|
76
|
+
def restore_expands
|
77
|
+
file_tree_view.collapse_all if VimMate::Config[:files_auto_expand_on_filter]
|
78
|
+
unless @expands.nil? || @expands.empty?
|
79
|
+
@expands.each do |path|
|
80
|
+
file_tree_view.expand_row(path, false)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class FilePopupMenuController < ActiveWindow::Controller
|
2
|
+
|
3
|
+
def setup
|
4
|
+
@last_path = File.expand_path '.'
|
5
|
+
end
|
6
|
+
|
7
|
+
# Open a dialog to enter a new file name to create
|
8
|
+
# TODO use path of selected file
|
9
|
+
# TODO make inline renaming (like TextMate)
|
10
|
+
def new_file(given)
|
11
|
+
dialog = Gtk::FileChooserDialog.new("New file",
|
12
|
+
window,
|
13
|
+
Gtk::FileChooser::ACTION_SAVE,
|
14
|
+
nil,
|
15
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
|
16
|
+
[Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT])
|
17
|
+
#dialog.set_icon_list(Icons.window_icons)
|
18
|
+
dialog.current_folder = if File.directory? @last_path
|
19
|
+
@last_path
|
20
|
+
else
|
21
|
+
File.dirname(@last_path)
|
22
|
+
end
|
23
|
+
if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
|
24
|
+
begin
|
25
|
+
FileUtils.touch(dialog.filename)
|
26
|
+
rescue
|
27
|
+
$stderr.puts "Cannot touch #{dialog.filename}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
dialog.destroy
|
31
|
+
end
|
32
|
+
def new_directory(given)
|
33
|
+
end
|
34
|
+
def rename_item(given)
|
35
|
+
end
|
36
|
+
def delete_item(given)
|
37
|
+
end
|
38
|
+
def refresh_item(given)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class VimController < ActiveWindow::Controller
|
2
|
+
attr_accessor :vim
|
3
|
+
|
4
|
+
def setup
|
5
|
+
@vim = VimMate::VimWidget.new
|
6
|
+
main_pane.pack2(vim.window, true, false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def open_selected_file
|
10
|
+
open_selected_file_as
|
11
|
+
end
|
12
|
+
|
13
|
+
def open_selected_file_split
|
14
|
+
open_selected_file_as :split
|
15
|
+
end
|
16
|
+
|
17
|
+
def open_selected_file_tab
|
18
|
+
open_selected_file_as :tab
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def open_selected_file_as(mode = VimMate::Config[:files_default_open_in_tabs] ? :tab : :open)
|
23
|
+
if iter = file_tree_view.selection.selected
|
24
|
+
vim.open iter[ FileTreeStore.full_path_column ], mode
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class VimMateController < ActiveWindow::Controller
|
2
|
+
|
3
|
+
attr_accessor :terminals_window, :tags_tree
|
4
|
+
|
5
|
+
def post_setup
|
6
|
+
window.set_default_size( VimMate::Config[:window_width],
|
7
|
+
VimMate::Config[:window_height])
|
8
|
+
window.set_icon_list(VimMate::Icons.window_icons)
|
9
|
+
|
10
|
+
|
11
|
+
# Double-click, Enter, Space: Signal to open the file
|
12
|
+
#file_tree.on_row_activated &method(:on_file_tree_row_activated)
|
13
|
+
|
14
|
+
#file_tree.on_right_click &method(:open_file_popup)
|
15
|
+
#file_tree.on_popup_menu &method(:open_file_popup)
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
#@tags_tree = VimMate::TagsWindow.new(@vim)
|
20
|
+
#tags_scroller.add @tags_tree.gtk_window
|
21
|
+
|
22
|
+
## Set the signals for the file menu
|
23
|
+
#menu.add_open_signal do |path, kind|
|
24
|
+
# vim.open(path, kind)
|
25
|
+
#end
|
26
|
+
#menu.add_refresh_signal do
|
27
|
+
# files.refresh
|
28
|
+
#end
|
29
|
+
end
|
30
|
+
|
31
|
+
def pressed_key(given)
|
32
|
+
return unless event = given[:event]
|
33
|
+
if event.state & Gdk::Window::ModifierType::CONTROL_MASK != 0
|
34
|
+
if event.state & Gdk::Window::ModifierType::SHIFT_MASK != 0
|
35
|
+
case event.keyval
|
36
|
+
# CTRL+SHIFT+S: Set focus to terminal (shell)
|
37
|
+
when Gdk::Keyval::GDK_S
|
38
|
+
terminals_window.focus_terminal if terminals_window
|
39
|
+
# CTRL+SHIFT+T: New terminal
|
40
|
+
when Gdk::Keyval::GDK_T
|
41
|
+
terminals_window.add_new_terminal if terminals_window
|
42
|
+
# CTRL+SHIFT+W: Close terminal
|
43
|
+
when Gdk::Keyval::GDK_W
|
44
|
+
terminals_window.delete_current_terminal if terminals_window
|
45
|
+
# CTRL+SHIFT+L: Set focus to file filter
|
46
|
+
when Gdk::Keyval::GDK_L
|
47
|
+
files_filter_term.has_focus = true
|
48
|
+
# CTRL+SHIFT+F: Set focus to file list
|
49
|
+
when Gdk::Keyval::GDK_F
|
50
|
+
file_tree_view.has_focus = true
|
51
|
+
# CTRL+SHIFT+S: Set focus to search file list
|
52
|
+
when Gdk::Keyval::GDK_E
|
53
|
+
files_window.focus_file_search if files_window
|
54
|
+
# CTRL+SHIFT+V: Set focus to Vim
|
55
|
+
when Gdk::Keyval::GDK_V
|
56
|
+
vim.focus!
|
57
|
+
end
|
58
|
+
else
|
59
|
+
#case event.keyval
|
60
|
+
## CTRL+PAGEDOWN: Next terminal
|
61
|
+
#when Gdk::Keyval::GDK_Page_Down
|
62
|
+
# terminals_window.next_terminal if terminals_window
|
63
|
+
# next true
|
64
|
+
## CTRL+PAGEDOWN: Previous terminal
|
65
|
+
#when Gdk::Keyval::GDK_Page_Up
|
66
|
+
# terminals_window.prev_terminal if terminals_window
|
67
|
+
# next true
|
68
|
+
#else
|
69
|
+
# next nil
|
70
|
+
#end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/images/file.png
ADDED
Binary file
|
Binary file
|
Binary file
|
data/images/file_red.png
ADDED
Binary file
|
data/images/folder.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module ActiveWindow
|
2
|
+
|
3
|
+
end
|
4
|
+
require_dependency 'active_window/signal'
|
5
|
+
require_dependency 'active_window/active_tree_store/columns'
|
6
|
+
require_dependency 'active_window/active_tree_store/index'
|
7
|
+
require_dependency 'active_window/active_tree_store/extentions'
|
8
|
+
require_dependency 'active_window/filtered_active_tree_store'
|
@@ -0,0 +1,218 @@
|
|
1
|
+
module ActiveWindow
|
2
|
+
|
3
|
+
=begin
|
4
|
+
|
5
|
+
ActiveColumn is used to define columns for ActiveTreeStore
|
6
|
+
|
7
|
+
=end
|
8
|
+
|
9
|
+
class ActiveColumn
|
10
|
+
attr_accessor :id, :name
|
11
|
+
extend ActiveSupport::Memoizable
|
12
|
+
|
13
|
+
ClassesToSymbols = {
|
14
|
+
TrueClass => :boolean,
|
15
|
+
FalseClass => :boolean,
|
16
|
+
String => :string,
|
17
|
+
Time => :datetime,
|
18
|
+
Date => :datetime,
|
19
|
+
Fixnum => :integer,
|
20
|
+
Bignum => :integer,
|
21
|
+
Integer => :integer,
|
22
|
+
Float => :float,
|
23
|
+
Gdk::Pixbuf => :image
|
24
|
+
}
|
25
|
+
|
26
|
+
##
|
27
|
+
## column: ActiveRecord::ConnectionAdapters::MysqlColumn
|
28
|
+
##
|
29
|
+
def self.create(id, name, klass=:string, opts={})
|
30
|
+
klass = ClassesToSymbols[klass] if klass.is_a?(Class)
|
31
|
+
subclass = case klass # ignore warning this creates
|
32
|
+
when :string; ActiveTextColumn
|
33
|
+
when :datetime; ActiveDateColumn
|
34
|
+
when :integer; ActiveIntegerColumn
|
35
|
+
when :float; ActiveFloatColumn
|
36
|
+
when :boolean; ActiveToggleColumn
|
37
|
+
when :image; ActiveImageColumn
|
38
|
+
else; self
|
39
|
+
end
|
40
|
+
return subclass.new(id, name.to_s, opts)
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(id, name, opts={})
|
44
|
+
self.id = id
|
45
|
+
self.name = name
|
46
|
+
@virtual = opts[:virtual] == true ? true : false
|
47
|
+
@visible = opts[:visible] == false ? false : true
|
48
|
+
#puts 'new column: %s %s' % [self.class, name]
|
49
|
+
end
|
50
|
+
|
51
|
+
def virtual?
|
52
|
+
@virtual
|
53
|
+
end
|
54
|
+
|
55
|
+
def hide!
|
56
|
+
@visible = false
|
57
|
+
end
|
58
|
+
|
59
|
+
def visible?
|
60
|
+
@visible
|
61
|
+
end
|
62
|
+
|
63
|
+
## return a Gtk::TreeViewColumn appropriate for showing this column
|
64
|
+
def view
|
65
|
+
raise "There is no way to show #{name} yet."
|
66
|
+
end
|
67
|
+
|
68
|
+
def renderer
|
69
|
+
raise "There is no way to render #{name} yet."
|
70
|
+
end
|
71
|
+
|
72
|
+
## return the class of the value held for this column in the model
|
73
|
+
def data_class
|
74
|
+
Object
|
75
|
+
end
|
76
|
+
|
77
|
+
## given an active record object, return the attribute
|
78
|
+
## value that corresponds to this column. the returned
|
79
|
+
## value must match the class returned in data_class.
|
80
|
+
## so, you might have to do some conversion.
|
81
|
+
def data_value(ar_object)
|
82
|
+
ar_object.send(self.name)
|
83
|
+
end
|
84
|
+
|
85
|
+
def view
|
86
|
+
r = renderer
|
87
|
+
column.pack_start(r, true)
|
88
|
+
column.add_attribute(r, attribute, self.id)
|
89
|
+
column
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
def column
|
94
|
+
@gtk_column ||= Gtk::TreeViewColumn.new(self.name)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
## ActiveTextColumn
|
100
|
+
##
|
101
|
+
## For columns with string values
|
102
|
+
##
|
103
|
+
class ActiveTextColumn < ActiveColumn
|
104
|
+
def data_class
|
105
|
+
String
|
106
|
+
end
|
107
|
+
def renderer
|
108
|
+
Gtk::CellRendererText.new
|
109
|
+
end
|
110
|
+
def attribute
|
111
|
+
:text
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class ActiveIntegerColumn < ActiveTextColumn
|
116
|
+
def data_class
|
117
|
+
Integer
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
## how to do?:
|
123
|
+
## renderer.signal_connect('toggled') do |cell, path|
|
124
|
+
## fixed_toggled(treeview.model, path)
|
125
|
+
## end
|
126
|
+
##
|
127
|
+
class ActiveToggleColumn < ActiveColumn
|
128
|
+
def data_class
|
129
|
+
TrueClass
|
130
|
+
end
|
131
|
+
def renderer
|
132
|
+
Gtk::CellRendererToggle.new
|
133
|
+
end
|
134
|
+
def attribute
|
135
|
+
:active
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
## TODO: configure the number of digits printed
|
141
|
+
##
|
142
|
+
class ActiveFloatColumn < ActiveColumn
|
143
|
+
def data_class
|
144
|
+
Float
|
145
|
+
end
|
146
|
+
def renderer
|
147
|
+
Gtk::CellRendererText.new
|
148
|
+
end
|
149
|
+
def attribute
|
150
|
+
:text
|
151
|
+
end
|
152
|
+
def view
|
153
|
+
super.set_cell_data_func(renderer) do |col, renderer, model, iter|
|
154
|
+
renderer.text = sprintf("%.2f", iter[self.id])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
def data_value(ar_object)
|
158
|
+
super(ar_object) || 0
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
## TODO: configure the date format
|
164
|
+
##
|
165
|
+
class ActiveDateColumn < ActiveColumn
|
166
|
+
def data_class
|
167
|
+
Time
|
168
|
+
end
|
169
|
+
def renderer
|
170
|
+
Gtk::CellRendererText.new
|
171
|
+
end
|
172
|
+
def attribute
|
173
|
+
:text
|
174
|
+
end
|
175
|
+
def view
|
176
|
+
super.set_cell_data_func(renderer) do |col, renderer, model, iter|
|
177
|
+
renderer.text = sprintf("%x %X", iter[self.id])
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
class ActiveImageColumn < ActiveColumn
|
184
|
+
def data_class
|
185
|
+
Gdk::Pixbuf
|
186
|
+
end
|
187
|
+
|
188
|
+
def renderer
|
189
|
+
Gtk::CellRendererPixbuf.new
|
190
|
+
end
|
191
|
+
|
192
|
+
def attribute
|
193
|
+
:pixbuf
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# pack multiple columns into one
|
198
|
+
class ActiveCompositeColumn < ActiveColumn
|
199
|
+
def initialize(name, opts={})
|
200
|
+
self.name = name
|
201
|
+
@virtual = true
|
202
|
+
@visible = true
|
203
|
+
end
|
204
|
+
def view
|
205
|
+
column
|
206
|
+
end
|
207
|
+
def add(child_column, expand=true)
|
208
|
+
raise ArgumentError, "give an ActiveColumn, not #{child_column.inspect}" unless child_column.is_a?(ActiveColumn)
|
209
|
+
child_column.hide!
|
210
|
+
rend = child_column.renderer
|
211
|
+
column.pack_start(rend, expand)
|
212
|
+
column.add_attribute(rend, child_column.attribute, child_column.id)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
end
|
218
|
+
|