active-list 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +46 -0
- data/VERSION +1 -0
- data/lib/active-list.rb +37 -0
- data/lib/active-list/action_pack.rb +48 -0
- data/lib/active-list/columns/action_column.rb +70 -0
- data/lib/active-list/columns/data_column.rb +138 -0
- data/lib/active-list/columns/field_column.rb +29 -0
- data/lib/active-list/compass/stylesheets/_active-list.scss +7 -0
- data/lib/active-list/compass/stylesheets/active-list/_background.scss +37 -0
- data/lib/active-list/compass/stylesheets/active-list/_minimal.scss +89 -0
- data/lib/active-list/compass/stylesheets/active-list/_theme.scss +161 -0
- data/lib/active-list/definition.rb +103 -0
- data/lib/active-list/exporters.rb +71 -0
- data/lib/active-list/exporters/csv_exporter.rb +30 -0
- data/lib/active-list/exporters/excel_csv_exporter.rb +36 -0
- data/lib/active-list/exporters/open_document_spreadsheet_exporter.rb +81 -0
- data/lib/active-list/finder.rb +133 -0
- data/lib/active-list/generator.rb +88 -0
- data/lib/active-list/rails/engine.rb +11 -0
- data/lib/active-list/renderers.rb +28 -0
- data/lib/active-list/renderers/simple_renderer.rb +333 -0
- data/lib/assets/images/active-list.png +0 -0
- data/lib/assets/javascripts/active-list.jquery.js +128 -0
- data/lib/assets/stylesheets/active-list.css.scss +7 -0
- metadata +156 -0
@@ -0,0 +1,161 @@
|
|
1
|
+
// Default style for ActiveList
|
2
|
+
@import "compass/css3";
|
3
|
+
@import "compass/typography/text/replacement";
|
4
|
+
|
5
|
+
// Because Compass sprites do not seems to work well in gems
|
6
|
+
@mixin active-list-sprite($name, $size: 16px) {
|
7
|
+
background-image: image-url("active-list.png");
|
8
|
+
background-repeat: no-repeat;
|
9
|
+
height: $size;
|
10
|
+
width: $size;
|
11
|
+
$i: 0;
|
12
|
+
@each $icon in menu check columns export pages first-page previous-page previous-line next-line next-page last-page sort sort-down sort-up true false {
|
13
|
+
@if $icon == $name {
|
14
|
+
background-position: (-$i * $size) 0;
|
15
|
+
}
|
16
|
+
$i: $i + 1;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
|
21
|
+
@mixin active-list-theme($theme-color: #777777) {
|
22
|
+
$default-border-color: mix($theme-color, #FFF, 30%);
|
23
|
+
table.list {
|
24
|
+
border-collapse: collapse;
|
25
|
+
width: 100%;
|
26
|
+
border: 1px solid $default-border-color;
|
27
|
+
z-index: 2;
|
28
|
+
@include box-shadow(0 0 7px rgba(0, 0, 0, 0.15));
|
29
|
+
thead {
|
30
|
+
th {
|
31
|
+
border: 1px solid $default-border-color;
|
32
|
+
padding: 2px 3px;
|
33
|
+
@include background($theme-color linear-gradient(top, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.8)));
|
34
|
+
&[data-list-column-sort] {
|
35
|
+
.icon {
|
36
|
+
@include active-list-sprite(sort);
|
37
|
+
@include inline-block;
|
38
|
+
margin: 0 2px;
|
39
|
+
}
|
40
|
+
&.sor[data-list-column-sort="desc"] .icon {
|
41
|
+
@include active-list-sprite(sort-down); }
|
42
|
+
&.sor[data-list-column-sort="asc"] .icon {
|
43
|
+
@include active-list-sprite(sort-up); }
|
44
|
+
}
|
45
|
+
html[dir="ltr"] & { text-align: left; }
|
46
|
+
html[dir="rtl"] & { text-align: right; }
|
47
|
+
&.spe {
|
48
|
+
width: 16px;
|
49
|
+
height: 16px;
|
50
|
+
.list-menu {
|
51
|
+
position: relative;
|
52
|
+
background: none;
|
53
|
+
.list-menu-start {
|
54
|
+
padding: 2px;
|
55
|
+
width: 16px;
|
56
|
+
height: 16px;
|
57
|
+
.icon { @include active-list-sprite(menu); }
|
58
|
+
.text { display: none; }
|
59
|
+
}
|
60
|
+
&:hover {
|
61
|
+
.list-menu-start {
|
62
|
+
background-color: white;
|
63
|
+
z-index:5000;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
ul {
|
67
|
+
border: 1px solid $default-border-color;
|
68
|
+
background: #FFF;
|
69
|
+
@include box-shadow(0 0 5px rgba(0, 0, 0, 0.3));
|
70
|
+
li {
|
71
|
+
$menu-width: 290px;
|
72
|
+
width: $menu-width;
|
73
|
+
ul {
|
74
|
+
html[dir="ltr"] & { right: $menu-width; }
|
75
|
+
html[dir="rtl"] & { left: $menu-width; }
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
a, li {
|
80
|
+
display: block;
|
81
|
+
padding: 2px;
|
82
|
+
.icon {
|
83
|
+
@include inline-block;
|
84
|
+
height:16px;
|
85
|
+
width: 16px;
|
86
|
+
html[dir="ltr"] & { margin-right: 4px; }
|
87
|
+
html[dir="rtl"] & { margin-left: 4px; }
|
88
|
+
}
|
89
|
+
&.pages .icon { @include active-list-sprite(pages); }
|
90
|
+
&.export .icon { @include active-list-sprite(export); }
|
91
|
+
&.check .icon { @include active-list-sprite(check); }
|
92
|
+
&.columns .icon { @include active-list-sprite(columns); }
|
93
|
+
&.checked .icon { @include active-list-sprite(true); }
|
94
|
+
&.unchecked .icon { @include active-list-sprite(false); }
|
95
|
+
}
|
96
|
+
a:hover, li:hover {
|
97
|
+
text-decoration: none;
|
98
|
+
background: mix($theme-color, #FFF, 10%);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
tbody {
|
105
|
+
tr {
|
106
|
+
td {
|
107
|
+
padding: 2px 3px;
|
108
|
+
border-top: 1px solid mix($theme-color, #FFF, 10%);
|
109
|
+
border-bottom: none;
|
110
|
+
border-left: none;
|
111
|
+
border-right: none;
|
112
|
+
&.chk,&.act, &.dld, &.bln, &.dat, &.web { text-align:center }
|
113
|
+
&.dec, &.flt, &.int {
|
114
|
+
html[dir="ltr"] & { text-align: right; }
|
115
|
+
html[dir="rtl"] & { text-align: left; }
|
116
|
+
}
|
117
|
+
&.country { white-space: nowrap; }
|
118
|
+
&.color { color: white; text-shadow: 0 0 2px #000; width: 6ex; text-align: center; }
|
119
|
+
}
|
120
|
+
&:first-child td {
|
121
|
+
border-top: none;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
@include list-colors(#FFFFFF);
|
127
|
+
}
|
128
|
+
.extras {
|
129
|
+
z-index: 0;
|
130
|
+
@include background(transparentize(mix($theme-color, #FFF, 40%), 0.7));
|
131
|
+
.pagination {
|
132
|
+
html[dir="ltr"] & { text-align: left; }
|
133
|
+
html[dir="rtl"] & { text-align: right; }
|
134
|
+
& > * {
|
135
|
+
margin: 0 2px;
|
136
|
+
}
|
137
|
+
.first-page, .previous-page, .next-page, .last-page {
|
138
|
+
@include inline-block;
|
139
|
+
@include squish-text;
|
140
|
+
}
|
141
|
+
html[dir="rtl"] & .last-page, html[dir="ltr"] & .first-page {
|
142
|
+
@include active-list-sprite(first-page);
|
143
|
+
}
|
144
|
+
html[dir="rtl"] & .first-page, html[dir="ltr"] & .last-page {
|
145
|
+
@include active-list-sprite(last-page);
|
146
|
+
}
|
147
|
+
html[dir="rtl"] & .next-page, html[dir="ltr"] & .previous-page {
|
148
|
+
@include active-list-sprite(previous-page);
|
149
|
+
}
|
150
|
+
html[dir="rtl"] & .previous-page, html[dir="ltr"] & .next-page {
|
151
|
+
@include active-list-sprite(next-page);
|
152
|
+
}
|
153
|
+
.separator {
|
154
|
+
@include inline-block;
|
155
|
+
width: 2px;
|
156
|
+
height: 1.2em;
|
157
|
+
background: transparentize($theme-color, 0.7);
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module ActiveList
|
2
|
+
|
3
|
+
class Table
|
4
|
+
attr_reader :name, :model, :options, :id, :columns, :parameters
|
5
|
+
|
6
|
+
@@current_id = 0
|
7
|
+
|
8
|
+
def initialize(name, model = nil, options = {})
|
9
|
+
@name = name
|
10
|
+
@model = model || name.to_s.classify.constantize
|
11
|
+
@options = options
|
12
|
+
@paginate = !(@options[:pagination]==:none || @options[:paginate].is_a?(FalseClass))
|
13
|
+
@options[:renderer] ||= :simple_renderer
|
14
|
+
@options[:per_page] = 20 if @options[:per_page].to_i <= 0
|
15
|
+
@options[:page] = 1 if @options[:page].to_i <= 0
|
16
|
+
@columns = []
|
17
|
+
@current_id = 0
|
18
|
+
@id = @@current_id.to_s(36).to_sym
|
19
|
+
@@current_id += 1
|
20
|
+
@parameters = {:sort=>:to_s, :dir=>:to_s}
|
21
|
+
@parameters.merge!(:page=>:to_i, :per_page=>:to_i) if self.paginate?
|
22
|
+
end
|
23
|
+
|
24
|
+
def new_id
|
25
|
+
id = @current_id.to_s(36).to_sym
|
26
|
+
@current_id += 1
|
27
|
+
return id
|
28
|
+
end
|
29
|
+
|
30
|
+
def model_columns
|
31
|
+
@model.columns
|
32
|
+
end
|
33
|
+
|
34
|
+
def sortable_columns
|
35
|
+
@columns.select{|c| c.sortable?}
|
36
|
+
end
|
37
|
+
|
38
|
+
def exportable_columns
|
39
|
+
@columns.select{|c| c.exportable?}
|
40
|
+
end
|
41
|
+
|
42
|
+
def paginate?
|
43
|
+
@paginate
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_default_columns
|
47
|
+
for column in self.model_columns
|
48
|
+
reflections = @model.reflections.values.select{|r| r.macro == :belongs_to and r.foreign_key.to_s == column.name.to_s}
|
49
|
+
if reflections.size == 1
|
50
|
+
reflection = reflections.first
|
51
|
+
columns = reflection.class_name.constantize.columns.collect{ |c| c.name.to_s }
|
52
|
+
self.column([:label, :name, :code, :number].detect{ |l| columns.include?(l.to_s) }, :through => reflection.name, :url => true)
|
53
|
+
else
|
54
|
+
self.column(column.name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
class Column
|
64
|
+
attr_accessor :name, :options, :table
|
65
|
+
attr_reader :id
|
66
|
+
|
67
|
+
def initialize(table, name, options={})
|
68
|
+
@table = table
|
69
|
+
@name = name
|
70
|
+
@options = options
|
71
|
+
@column = @table.model.columns.detect{|c| c.name.to_s == @name.to_s }
|
72
|
+
@id = @table.new_id
|
73
|
+
end
|
74
|
+
|
75
|
+
def header_code
|
76
|
+
raise NotImplementedError.new("#{self.class.name}#header_code is not implemented.")
|
77
|
+
end
|
78
|
+
|
79
|
+
def sortable?
|
80
|
+
false
|
81
|
+
end
|
82
|
+
|
83
|
+
def exportable?
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
87
|
+
# Unique identifier of the column in the application
|
88
|
+
def unique_id
|
89
|
+
"#{@table.name}-#{@id}"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Uncommon but simple identifier for CSS class uses
|
93
|
+
def simple_id
|
94
|
+
"_#{@table.id}_#{@id}"
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
require "active-list/columns/data_column"
|
102
|
+
require "active-list/columns/action_column"
|
103
|
+
require "active-list/columns/field_column"
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
2
|
+
|
3
|
+
module ActiveList
|
4
|
+
|
5
|
+
mattr_reader :exporters
|
6
|
+
@@exporters = {}
|
7
|
+
|
8
|
+
def self.register_exporter(name, exporter)
|
9
|
+
raise ArgumentError.new("ActiveList::Exporter expected (got #{exporter.name}/#{exporter.ancestors.inspect})") unless exporter.ancestors.include? ActiveList::Exporter
|
10
|
+
@@exporters[name] = exporter.new(name)
|
11
|
+
end
|
12
|
+
|
13
|
+
class Exporter
|
14
|
+
attr_reader :name
|
15
|
+
|
16
|
+
def initialize(name)
|
17
|
+
@name = name
|
18
|
+
end
|
19
|
+
|
20
|
+
def file_extension
|
21
|
+
"txt"
|
22
|
+
end
|
23
|
+
|
24
|
+
def mime_type
|
25
|
+
Mime::TEXT
|
26
|
+
end
|
27
|
+
|
28
|
+
# Not used
|
29
|
+
# def condition
|
30
|
+
# "not request.xhr? and params[:format] == '#{name}'"
|
31
|
+
# end
|
32
|
+
|
33
|
+
def send_data_code(table)
|
34
|
+
raise NotImplementedError.new("#{self.class.name}#format_data_code is not implemented.")
|
35
|
+
end
|
36
|
+
|
37
|
+
def columns_headers(table, options={})
|
38
|
+
headers, columns = [], table.exportable_columns
|
39
|
+
for column in columns
|
40
|
+
datum = column.header_code
|
41
|
+
headers << (options[:iconv] ? "#{options[:iconv]}.iconv("+datum+".to_s)" : datum)
|
42
|
+
end
|
43
|
+
return headers
|
44
|
+
end
|
45
|
+
|
46
|
+
def columns_to_array(table, nature, options={})
|
47
|
+
columns = table.exportable_columns
|
48
|
+
|
49
|
+
array = []
|
50
|
+
record = options[:record]||'rekord'
|
51
|
+
for column in columns
|
52
|
+
if column.is_a? ActiveList::Column
|
53
|
+
if nature==:header
|
54
|
+
datum = column.header_code
|
55
|
+
else
|
56
|
+
datum = column.exporting_datum_code(record)
|
57
|
+
end
|
58
|
+
array << (options[:iconv] ? "#{options[:iconv]}.iconv("+datum+".to_s)" : datum)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
return array
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
require "active-list/exporters/open_document_spreadsheet_exporter"
|
70
|
+
require "active-list/exporters/csv_exporter"
|
71
|
+
require "active-list/exporters/excel_csv_exporter"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveList
|
2
|
+
|
3
|
+
class CsvExporter < ActiveList::Exporter
|
4
|
+
|
5
|
+
def file_extension
|
6
|
+
"csv"
|
7
|
+
end
|
8
|
+
|
9
|
+
def mime_type
|
10
|
+
Mime::CSV
|
11
|
+
end
|
12
|
+
|
13
|
+
def send_data_code(table)
|
14
|
+
record = "r"
|
15
|
+
code = table.select_data_code(:paginate => false)
|
16
|
+
code += "data = ActiveList::CSV.generate do |csv|\n"
|
17
|
+
code += " csv << [#{columns_to_array(table, :header).join(', ')}]\n"
|
18
|
+
code += " for #{record} in #{table.records_variable_name}\n"
|
19
|
+
code += " csv << [#{columns_to_array(table, :body, :record=>record).join(', ')}]\n"
|
20
|
+
code += " end\n"
|
21
|
+
code += "end\n"
|
22
|
+
code += "send_data(data, :type=>#{self.mime_type.to_s.inspect}, :disposition=>'inline', :filename=>#{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i,'_')+'.#{self.file_extension}')\n"
|
23
|
+
return code
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
ActiveList.register_exporter(:csv, ActiveList::CsvExporter)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Register XCSV format unless is already set
|
4
|
+
Mime::Type.register("text/csv", :xcsv) unless defined? Mime::XCSV
|
5
|
+
|
6
|
+
module ActiveList
|
7
|
+
|
8
|
+
class ExcelCsvExporter < ActiveList::CsvExporter
|
9
|
+
|
10
|
+
def file_extension
|
11
|
+
"csv"
|
12
|
+
end
|
13
|
+
|
14
|
+
def mime_type
|
15
|
+
Mime::XCSV
|
16
|
+
end
|
17
|
+
|
18
|
+
def send_data_code(table)
|
19
|
+
record = "r"
|
20
|
+
code = table.select_data_code(:paginate => false)
|
21
|
+
code += "ic = Iconv.new('cp1252', 'utf-8')\n"
|
22
|
+
code += "data = ActiveList::CSV.generate(:col_sep=>';') do |csv|\n"
|
23
|
+
code += " csv << [#{columns_to_array(table, :header, :iconv=>'ic').join(', ')}]\n"
|
24
|
+
code += " for #{record} in #{table.records_variable_name}\n"
|
25
|
+
code += " csv << [#{columns_to_array(table, :body, :record=>record, :iconv=>'ic').join(', ')}]\n"
|
26
|
+
code += " end\n"
|
27
|
+
code += "end\n"
|
28
|
+
code += "send_data(data, :type=>#{self.mime_type.to_s.inspect}, :disposition=>'inline', :filename=>#{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i,'_')+'.#{self.file_extension}')\n"
|
29
|
+
return code
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
ActiveList.register_exporter(:xcsv, ActiveList::ExcelCsvExporter)
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Register ODS format unless is already set
|
4
|
+
Mime::Type.register("application/vnd.oasis.opendocument.spreadsheet", :ods) unless defined? Mime::ODS
|
5
|
+
|
6
|
+
module ActiveList
|
7
|
+
|
8
|
+
class OpenDocumentSpreadsheetExporter < ActiveList::Exporter
|
9
|
+
|
10
|
+
DATE_ELEMENTS = {
|
11
|
+
"m" => "<number:month number:style=\"long\"/>",
|
12
|
+
"d" => "<number:day number:style=\"long\"/>",
|
13
|
+
"Y" => "<number:year/>"
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
def file_extension
|
18
|
+
"ods"
|
19
|
+
end
|
20
|
+
|
21
|
+
def mime_type
|
22
|
+
Mime::ODS
|
23
|
+
end
|
24
|
+
|
25
|
+
def send_data_code(table)
|
26
|
+
xml_escape = "to_s.gsub('&', '&').gsub('\\'', ''').gsub('<', '<').gsub('>', '>')"
|
27
|
+
xml_escape << ".force_encoding('US-ASCII')" if xml_escape.respond_to?(:force_encoding)
|
28
|
+
record = "r"
|
29
|
+
code = table.select_data_code(:paginate => false)
|
30
|
+
code << "name = #{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i,'_')\n"
|
31
|
+
code << "temporary_dir = ::Rails.root.join('tmp', 'active-list')\n"
|
32
|
+
code << "FileUtils.mkdir_p(temporary_dir)\n"
|
33
|
+
code << "file = temporary_dir.join(name+rand.to_s+'.#{self.file_extension}')\n"
|
34
|
+
code << "Zip::ZipOutputStream.open(file) do |zile|\n"
|
35
|
+
# MimeType in first place
|
36
|
+
code << " zile.put_next_entry('mimetype', nil, nil, Zip::ZipEntry::STORED)\n"
|
37
|
+
code << " zile << '#{self.mime_type}'\n"
|
38
|
+
|
39
|
+
# Manifest
|
40
|
+
code << " zile.put_next_entry('META-INF/manifest.xml')\n"
|
41
|
+
code << " zile << ('<?xml version=\"1.0\" encoding=\"UTF-8\"?><manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\"><manifest:file-entry manifest:media-type=\"#{self.mime_type}\" manifest:full-path=\"/\"/><manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/></manifest:manifest>')\n"
|
42
|
+
code << " zile.put_next_entry('content.xml')\n"
|
43
|
+
|
44
|
+
code << " zile << ('<?xml version=\"1.0\" encoding=\"UTF-8\"?><office:document-content xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\" xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\" xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\" xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\" xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\" xmlns:presentation=\"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0\" xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\" xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\" xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\" xmlns:math=\"http://www.w3.org/1998/Math/MathML\" xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\" xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\" xmlns:ooo=\"http://openoffice.org/2004/office\" xmlns:ooow=\"http://openoffice.org/2004/writer\" xmlns:oooc=\"http://openoffice.org/2004/calc\" xmlns:dom=\"http://www.w3.org/2001/xml-events\" xmlns:xforms=\"http://www.w3.org/2002/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:field=\"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:field:1.0\" office:version=\"1.1\"><office:scripts/>')\n"
|
45
|
+
# Styles
|
46
|
+
code << " zile << ('<office:automatic-styles>"+
|
47
|
+
"<style:style style:name=\"co1\" style:family=\"table-column\"><style:table-column-properties fo:break-before=\"auto\" style:use-optimal-column-width=\"true\"/></style:style>"+
|
48
|
+
"<style:style style:name=\"header\" style:family=\"table-cell\"><style:text-properties fo:font-weight=\"bold\" style:font-weight-asian=\"bold\" style:font-weight-complex=\"bold\"/></style:style>"+
|
49
|
+
"<number:date-style style:name=\"K4D\" number:automatic-order=\"true\"><number:text>"+::I18n.translate("date.formats.default").gsub(/\%./){|x| "</number:text>"+DATE_ELEMENTS[x[1..1]]+"<number:text>"} +"</number:text></number:date-style><style:style style:name=\"ce1\" style:family=\"table-cell\" style:data-style-name=\"K4D\"/>"+
|
50
|
+
"</office:automatic-styles>')\n"
|
51
|
+
|
52
|
+
# Tables
|
53
|
+
code << " zile << ('<office:body><office:spreadsheet><table:table table:name=\"'+#{table.model.name}.model_name.human.#{xml_escape}+'\">')\n"
|
54
|
+
code << " zile << ('<table:table-column table:number-columns-repeated=\"#{table.exportable_columns.size}\"/>')\n"
|
55
|
+
code << " zile << ('<table:table-header-rows><table:table-row>"+columns_headers(table).collect{|h| "<table:table-cell table:style-name=\"header\" office:value-type=\"string\"><text:p>'+(#{h}).#{xml_escape}+'</text:p></table:table-cell>"}.join+"</table:table-row></table:table-header-rows>')\n"
|
56
|
+
code << " for #{record} in #{table.records_variable_name}\n"
|
57
|
+
code << " zile << ('<table:table-row>"+table.exportable_columns.collect do |column|
|
58
|
+
"<table:table-cell"+(if column.numeric? or column.datatype==:decimal
|
59
|
+
" office:value-type=\"float\" office:value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
60
|
+
elsif column.datatype==:boolean
|
61
|
+
" office:value-type=\"boolean\" office:boolean-value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
62
|
+
elsif column.datatype==:date
|
63
|
+
" office:value-type=\"date\" table:style-name=\"ce1\" office:date-value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
64
|
+
else
|
65
|
+
" office:value-type=\"string\""
|
66
|
+
end)+"><text:p>'+("+column.exporting_datum_code(record, true)+").#{xml_escape}+'</text:p></table:table-cell>"
|
67
|
+
end.join+"</table:table-row>')\n"
|
68
|
+
code << " end\n"
|
69
|
+
code << " zile << ('</table:table></office:spreadsheet></office:body></office:document-content>')\n"
|
70
|
+
code << "end\n"
|
71
|
+
code << "send_file(file, :stream=>false, :type=>#{self.mime_type.to_s.inspect}, :disposition=>'inline', :filename=>name+'.#{self.file_extension}')\n"
|
72
|
+
code << "File.delete(file)\n" # Removes tmp files before they explode the disk
|
73
|
+
# raise code
|
74
|
+
return code
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
ActiveList.register_exporter(:ods, ActiveList::OpenDocumentSpreadsheetExporter)
|