##// END OF EJS Templates
Adds day numbers to HTML and PDF gantt (#3034)....
Jean-Philippe Lang -
r14256:f9425cbaf37e
parent child
Show More
@@ -1,334 +1,372
1 <% @gantt.view = self %>
1 <% @gantt.view = self %>
2 <div class="contextual">
2 <div class="contextual">
3 <% if !@query.new_record? && @query.editable_by?(User.current) %>
3 <% if !@query.new_record? && @query.editable_by?(User.current) %>
4 <%= link_to l(:button_edit), edit_query_path(@query, :gantt => 1), :class => 'icon icon-edit' %>
4 <%= link_to l(:button_edit), edit_query_path(@query, :gantt => 1), :class => 'icon icon-edit' %>
5 <%= delete_link query_path(@query, :gantt => 1) %>
5 <%= delete_link query_path(@query, :gantt => 1) %>
6 <% end %>
6 <% end %>
7 </div>
7 </div>
8
8
9 <h2><%= @query.new_record? ? l(:label_gantt) : @query.name %></h2>
9 <h2><%= @query.new_record? ? l(:label_gantt) : @query.name %></h2>
10
10
11 <%= form_tag({:controller => 'gantts', :action => 'show',
11 <%= form_tag({:controller => 'gantts', :action => 'show',
12 :project_id => @project, :month => params[:month],
12 :project_id => @project, :month => params[:month],
13 :year => params[:year], :months => params[:months]},
13 :year => params[:year], :months => params[:months]},
14 :method => :get, :id => 'query_form') do %>
14 :method => :get, :id => 'query_form') do %>
15 <%= hidden_field_tag 'set_filter', '1' %>
15 <%= hidden_field_tag 'set_filter', '1' %>
16 <%= hidden_field_tag 'gantt', '1' %>
16 <%= hidden_field_tag 'gantt', '1' %>
17 <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
17 <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
18 <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
18 <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
19 <div style="<%= @query.new_record? ? "" : "display: none;" %>">
19 <div style="<%= @query.new_record? ? "" : "display: none;" %>">
20 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
20 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
21 </div>
21 </div>
22 </fieldset>
22 </fieldset>
23 <fieldset class="collapsible collapsed">
23 <fieldset class="collapsible collapsed">
24 <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
24 <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
25 <div style="display: none;">
25 <div style="display: none;">
26 <table>
26 <table>
27 <tr>
27 <tr>
28 <td>
28 <td>
29 <fieldset>
29 <fieldset>
30 <legend><%= l(:label_related_issues) %></legend>
30 <legend><%= l(:label_related_issues) %></legend>
31 <label for="draw_relations">
31 <label for="draw_relations">
32 <%= check_box 'query', 'draw_relations', :id => 'draw_relations' %>
32 <%= check_box 'query', 'draw_relations', :id => 'draw_relations' %>
33 <% rels = [IssueRelation::TYPE_BLOCKS, IssueRelation::TYPE_PRECEDES] %>
33 <% rels = [IssueRelation::TYPE_BLOCKS, IssueRelation::TYPE_PRECEDES] %>
34 <% rels.each do |rel| %>
34 <% rels.each do |rel| %>
35 <% color = Redmine::Helpers::Gantt::DRAW_TYPES[rel][:color] %>
35 <% color = Redmine::Helpers::Gantt::DRAW_TYPES[rel][:color] %>
36 <%= content_tag(:span, '&nbsp;&nbsp;&nbsp;'.html_safe,
36 <%= content_tag(:span, '&nbsp;&nbsp;&nbsp;'.html_safe,
37 :style => "background-color: #{color}") %>
37 :style => "background-color: #{color}") %>
38 <%= l(IssueRelation::TYPES[rel][:name]) %>
38 <%= l(IssueRelation::TYPES[rel][:name]) %>
39 <% end %>
39 <% end %>
40 </label>
40 </label>
41 </fieldset>
41 </fieldset>
42 </td>
42 </td>
43 <td>
43 <td>
44 <fieldset>
44 <fieldset>
45 <legend><%= l(:label_gantt_progress_line) %></legend>
45 <legend><%= l(:label_gantt_progress_line) %></legend>
46 <label for="draw_progress_line">
46 <label for="draw_progress_line">
47 <%= check_box 'query', 'draw_progress_line', :id => 'draw_progress_line' %>
47 <%= check_box 'query', 'draw_progress_line', :id => 'draw_progress_line' %>
48 <%= l(:label_display) %>
48 <%= l(:label_display) %>
49 </label>
49 </label>
50 </fieldset>
50 </fieldset>
51 </td>
51 </td>
52 </tr>
52 </tr>
53 </table>
53 </table>
54 </div>
54 </div>
55 </fieldset>
55 </fieldset>
56
56
57 <p class="contextual">
57 <p class="contextual">
58 <%= gantt_zoom_link(@gantt, :in) %>
58 <%= gantt_zoom_link(@gantt, :in) %>
59 <%= gantt_zoom_link(@gantt, :out) %>
59 <%= gantt_zoom_link(@gantt, :out) %>
60 </p>
60 </p>
61
61
62 <p class="buttons">
62 <p class="buttons">
63 <%= text_field_tag 'months', @gantt.months, :size => 2 %>
63 <%= text_field_tag 'months', @gantt.months, :size => 2 %>
64 <%= l(:label_months_from) %>
64 <%= l(:label_months_from) %>
65 <%= select_month(@gantt.month_from, :prefix => "month", :discard_type => true) %>
65 <%= select_month(@gantt.month_from, :prefix => "month", :discard_type => true) %>
66 <%= select_year(@gantt.year_from, :prefix => "year", :discard_type => true) %>
66 <%= select_year(@gantt.year_from, :prefix => "year", :discard_type => true) %>
67 <%= hidden_field_tag 'zoom', @gantt.zoom %>
67 <%= hidden_field_tag 'zoom', @gantt.zoom %>
68
68
69 <%= link_to_function l(:button_apply), '$("#query_form").submit()',
69 <%= link_to_function l(:button_apply), '$("#query_form").submit()',
70 :class => 'icon icon-checked' %>
70 :class => 'icon icon-checked' %>
71 <%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 },
71 <%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 },
72 :class => 'icon icon-reload' %>
72 :class => 'icon icon-reload' %>
73 <% if @query.new_record? && User.current.allowed_to?(:save_queries, @project, :global => true) %>
73 <% if @query.new_record? && User.current.allowed_to?(:save_queries, @project, :global => true) %>
74 <%= link_to_function l(:button_save),
74 <%= link_to_function l(:button_save),
75 "$('#query_form').attr('action', '#{ @project ? new_project_query_path(@project) : new_query_path }').submit();",
75 "$('#query_form').attr('action', '#{ @project ? new_project_query_path(@project) : new_query_path }').submit();",
76 :class => 'icon icon-save' %>
76 :class => 'icon icon-save' %>
77 <% end %>
77 <% end %>
78 </p>
78 </p>
79 <% end %>
79 <% end %>
80
80
81 <%= error_messages_for 'query' %>
81 <%= error_messages_for 'query' %>
82 <% if @query.valid? %>
82 <% if @query.valid? %>
83 <%
83 <%
84 zoom = 1
84 zoom = 1
85 @gantt.zoom.times { zoom = zoom * 2 }
85 @gantt.zoom.times { zoom = zoom * 2 }
86
86
87 subject_width = 330
87 subject_width = 330
88 header_height = 18
88 header_height = 18
89
89
90 headers_height = header_height
90 headers_height = header_height
91 show_weeks = false
91 show_weeks = false
92 show_days = false
92 show_days = false
93 show_day_num = false
93
94
94 if @gantt.zoom > 1
95 if @gantt.zoom > 1
95 show_weeks = true
96 show_weeks = true
96 headers_height = 2 * header_height
97 headers_height = 2 * header_height
97 if @gantt.zoom > 2
98 if @gantt.zoom > 2
98 show_days = true
99 show_days = true
99 headers_height = 3 * header_height
100 headers_height = 3 * header_height
101 if @gantt.zoom > 3
102 show_day_num = true
103 headers_height = 4 * header_height
104 end
100 end
105 end
101 end
106 end
102
107
103 # Width of the entire chart
108 # Width of the entire chart
104 g_width = ((@gantt.date_to - @gantt.date_from + 1) * zoom).to_i
109 g_width = ((@gantt.date_to - @gantt.date_from + 1) * zoom).to_i
105 @gantt.render(:top => headers_height + 8,
110 @gantt.render(:top => headers_height + 8,
106 :zoom => zoom,
111 :zoom => zoom,
107 :g_width => g_width,
112 :g_width => g_width,
108 :subject_width => subject_width)
113 :subject_width => subject_width)
109 g_height = [(20 * (@gantt.number_of_rows + 6)) + 150, 206].max
114 g_height = [(20 * (@gantt.number_of_rows + 6)) + 150, 206].max
110 t_height = g_height + headers_height
115 t_height = g_height + headers_height
111 %>
116 %>
112
117
113 <% if @gantt.truncated %>
118 <% if @gantt.truncated %>
114 <p class="warning"><%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %></p>
119 <p class="warning"><%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %></p>
115 <% end %>
120 <% end %>
116
121
117 <table style="width:100%; border:0; border-collapse: collapse;">
122 <table style="width:100%; border:0; border-collapse: collapse;">
118 <tr>
123 <tr>
119 <td style="width:<%= subject_width %>px; padding:0px;">
124 <td style="width:<%= subject_width %>px; padding:0px;">
120 <%
125 <%
121 style = ""
126 style = ""
122 style += "position:relative;"
127 style += "position:relative;"
123 style += "height: #{t_height + 24}px;"
128 style += "height: #{t_height + 24}px;"
124 style += "width: #{subject_width + 1}px;"
129 style += "width: #{subject_width + 1}px;"
125 %>
130 %>
126 <%= content_tag(:div, :style => style) do %>
131 <%= content_tag(:div, :style => style) do %>
127 <%
132 <%
128 style = ""
133 style = ""
129 style += "right:-2px;"
134 style += "right:-2px;"
130 style += "width: #{subject_width}px;"
135 style += "width: #{subject_width}px;"
131 style += "height: #{headers_height}px;"
136 style += "height: #{headers_height}px;"
132 style += 'background: #eee;'
137 style += 'background: #eee;'
133 %>
138 %>
134 <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
139 <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
135 <%
140 <%
136 style = ""
141 style = ""
137 style += "right:-2px;"
142 style += "right:-2px;"
138 style += "width: #{subject_width}px;"
143 style += "width: #{subject_width}px;"
139 style += "height: #{t_height}px;"
144 style += "height: #{t_height}px;"
140 style += 'border-left: 1px solid #c0c0c0;'
145 style += 'border-left: 1px solid #c0c0c0;'
141 style += 'overflow: hidden;'
146 style += 'overflow: hidden;'
142 %>
147 %>
143 <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
148 <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
144 <%= content_tag(:div, :class => "gantt_subjects") do %>
149 <%= content_tag(:div, :class => "gantt_subjects") do %>
145 <%= @gantt.subjects.html_safe %>
150 <%= @gantt.subjects.html_safe %>
146 <% end %>
151 <% end %>
147 <% end %>
152 <% end %>
148 </td>
153 </td>
149
154
150 <td>
155 <td>
151 <div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;" id="gantt_area">
156 <div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;" id="gantt_area">
152 <%
157 <%
153 style = ""
158 style = ""
154 style += "width: #{g_width - 1}px;"
159 style += "width: #{g_width - 1}px;"
155 style += "height: #{headers_height}px;"
160 style += "height: #{headers_height}px;"
156 style += 'background: #eee;'
161 style += 'background: #eee;'
157 %>
162 %>
158 <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :class => "gantt_hdr") %>
163 <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :class => "gantt_hdr") %>
159
164
160 <% ###### Months headers ###### %>
165 <% ###### Months headers ###### %>
161 <%
166 <%
162 month_f = @gantt.date_from
167 month_f = @gantt.date_from
163 left = 0
168 left = 0
164 height = (show_weeks ? header_height : header_height + g_height)
169 height = (show_weeks ? header_height : header_height + g_height)
165 %>
170 %>
166 <% @gantt.months.times do %>
171 <% @gantt.months.times do %>
167 <%
172 <%
168 width = (((month_f >> 1) - month_f) * zoom - 1).to_i
173 width = (((month_f >> 1) - month_f) * zoom - 1).to_i
169 style = ""
174 style = ""
170 style += "left: #{left}px;"
175 style += "left: #{left}px;"
171 style += "width: #{width}px;"
176 style += "width: #{width}px;"
172 style += "height: #{height}px;"
177 style += "height: #{height}px;"
173 %>
178 %>
174 <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
179 <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
175 <%= link_to "#{month_f.year}-#{month_f.month}",
180 <%= link_to "#{month_f.year}-#{month_f.month}",
176 @gantt.params.merge(:year => month_f.year, :month => month_f.month),
181 @gantt.params.merge(:year => month_f.year, :month => month_f.month),
177 :title => "#{month_name(month_f.month)} #{month_f.year}" %>
182 :title => "#{month_name(month_f.month)} #{month_f.year}" %>
178 <% end %>
183 <% end %>
179 <%
184 <%
180 left = left + width + 1
185 left = left + width + 1
181 month_f = month_f >> 1
186 month_f = month_f >> 1
182 %>
187 %>
183 <% end %>
188 <% end %>
184
189
185 <% ###### Weeks headers ###### %>
190 <% ###### Weeks headers ###### %>
186 <% if show_weeks %>
191 <% if show_weeks %>
187 <%
192 <%
188 left = 0
193 left = 0
189 height = (show_days ? header_height - 1 : header_height - 1 + g_height)
194 height = (show_days ? header_height - 1 : header_height - 1 + g_height)
190 %>
195 %>
191 <% if @gantt.date_from.cwday == 1 %>
196 <% if @gantt.date_from.cwday == 1 %>
192 <%
197 <%
193 # @date_from is monday
198 # @date_from is monday
194 week_f = @gantt.date_from
199 week_f = @gantt.date_from
195 %>
200 %>
196 <% else %>
201 <% else %>
197 <%
202 <%
198 # find next monday after @date_from
203 # find next monday after @date_from
199 week_f = @gantt.date_from + (7 - @gantt.date_from.cwday + 1)
204 week_f = @gantt.date_from + (7 - @gantt.date_from.cwday + 1)
200 width = (7 - @gantt.date_from.cwday + 1) * zoom - 1
205 width = (7 - @gantt.date_from.cwday + 1) * zoom - 1
201 style = ""
206 style = ""
202 style += "left: #{left}px;"
207 style += "left: #{left}px;"
203 style += "top: 19px;"
208 style += "top: 19px;"
204 style += "width: #{width}px;"
209 style += "width: #{width}px;"
205 style += "height: #{height}px;"
210 style += "height: #{height}px;"
206 %>
211 %>
207 <%= content_tag(:div, '&nbsp;'.html_safe,
212 <%= content_tag(:div, '&nbsp;'.html_safe,
208 :style => style, :class => "gantt_hdr") %>
213 :style => style, :class => "gantt_hdr") %>
209 <% left = left + width + 1 %>
214 <% left = left + width + 1 %>
210 <% end %>
215 <% end %>
211 <% while week_f <= @gantt.date_to %>
216 <% while week_f <= @gantt.date_to %>
212 <%
217 <%
213 width = ((week_f + 6 <= @gantt.date_to) ?
218 width = ((week_f + 6 <= @gantt.date_to) ?
214 7 * zoom - 1 :
219 7 * zoom - 1 :
215 (@gantt.date_to - week_f + 1) * zoom - 1).to_i
220 (@gantt.date_to - week_f + 1) * zoom - 1).to_i
216 style = ""
221 style = ""
217 style += "left: #{left}px;"
222 style += "left: #{left}px;"
218 style += "top: 19px;"
223 style += "top: 19px;"
219 style += "width: #{width}px;"
224 style += "width: #{width}px;"
220 style += "height: #{height}px;"
225 style += "height: #{height}px;"
221 %>
226 %>
222 <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
227 <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
223 <%= content_tag(:small) do %>
228 <%= content_tag(:small) do %>
224 <%= week_f.cweek if width >= 16 %>
229 <%= week_f.cweek if width >= 16 %>
225 <% end %>
230 <% end %>
226 <% end %>
231 <% end %>
227 <%
232 <%
228 left = left + width + 1
233 left = left + width + 1
229 week_f = week_f + 7
234 week_f = week_f + 7
230 %>
235 %>
231 <% end %>
236 <% end %>
232 <% end %>
237 <% end %>
233
238
239 <% ###### Day numbers headers ###### %>
240 <% if show_day_num %>
241 <%
242 left = 0
243 height = g_height + header_height*2 - 1
244 wday = @gantt.date_from.cwday
245 day_num = @gantt.date_from
246 %>
247 <% (@gantt.date_to - @gantt.date_from + 1).to_i.times do %>
248 <%
249 width = zoom - 1
250 style = ""
251 style += "left:#{left}px;"
252 style += "top:37px;"
253 style += "width:#{width}px;"
254 style += "height:#{height}px;"
255 style += "font-size:0.7em;"
256 clss = "gantt_hdr"
257 clss << " nwday" if @gantt.non_working_week_days.include?(wday)
258 %>
259 <%= content_tag(:div, :style => style, :class => clss) do %>
260 <%= day_num.day %>
261 <% end %>
262 <%
263 left = left + width+1
264 day_num = day_num + 1
265 wday = wday + 1
266 wday = 1 if wday > 7
267 %>
268 <% end %>
269 <% end %>
270
234 <% ###### Days headers ####### %>
271 <% ###### Days headers ####### %>
235 <% if show_days %>
272 <% if show_days %>
236 <%
273 <%
237 left = 0
274 left = 0
238 height = g_height + header_height - 1
275 height = g_height + header_height - 1
276 top = (show_day_num ? 55 : 37)
239 wday = @gantt.date_from.cwday
277 wday = @gantt.date_from.cwday
240 %>
278 %>
241 <% (@gantt.date_to - @gantt.date_from + 1).to_i.times do %>
279 <% (@gantt.date_to - @gantt.date_from + 1).to_i.times do %>
242 <%
280 <%
243 width = zoom - 1
281 width = zoom - 1
244 style = ""
282 style = ""
245 style += "left: #{left}px;"
283 style += "left: #{left}px;"
246 style += "top:37px;"
284 style += "top: #{top}px;"
247 style += "width: #{width}px;"
285 style += "width: #{width}px;"
248 style += "height: #{height}px;"
286 style += "height: #{height}px;"
249 style += "font-size:0.7em;"
287 style += "font-size:0.7em;"
250 clss = "gantt_hdr"
288 clss = "gantt_hdr"
251 clss << " nwday" if @gantt.non_working_week_days.include?(wday)
289 clss << " nwday" if @gantt.non_working_week_days.include?(wday)
252 %>
290 %>
253 <%= content_tag(:div, :style => style, :class => clss) do %>
291 <%= content_tag(:div, :style => style, :class => clss) do %>
254 <%= day_letter(wday) %>
292 <%= day_letter(wday) %>
255 <% end %>
293 <% end %>
256 <%
294 <%
257 left = left + width + 1
295 left = left + width + 1
258 wday = wday + 1
296 wday = wday + 1
259 wday = 1 if wday > 7
297 wday = 1 if wday > 7
260 %>
298 %>
261 <% end %>
299 <% end %>
262 <% end %>
300 <% end %>
263
301
264 <%= @gantt.lines.html_safe %>
302 <%= @gantt.lines.html_safe %>
265
303
266 <% ###### Today red line (excluded from cache) ###### %>
304 <% ###### Today red line (excluded from cache) ###### %>
267 <% if Date.today >= @gantt.date_from and Date.today <= @gantt.date_to %>
305 <% if Date.today >= @gantt.date_from and Date.today <= @gantt.date_to %>
268 <%
306 <%
269 today_left = (((Date.today - @gantt.date_from + 1) * zoom).floor() - 1).to_i
307 today_left = (((Date.today - @gantt.date_from + 1) * zoom).floor() - 1).to_i
270 style = ""
308 style = ""
271 style += "position: absolute;"
309 style += "position: absolute;"
272 style += "height: #{g_height}px;"
310 style += "height: #{g_height}px;"
273 style += "top: #{headers_height + 1}px;"
311 style += "top: #{headers_height + 1}px;"
274 style += "left: #{today_left}px;"
312 style += "left: #{today_left}px;"
275 style += "width:10px;"
313 style += "width:10px;"
276 style += "border-left: 1px dashed red;"
314 style += "border-left: 1px dashed red;"
277 %>
315 %>
278 <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_line') %>
316 <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_line') %>
279 <% end %>
317 <% end %>
280 <%
318 <%
281 style = ""
319 style = ""
282 style += "position: absolute;"
320 style += "position: absolute;"
283 style += "height: #{g_height}px;"
321 style += "height: #{g_height}px;"
284 style += "top: #{headers_height + 1}px;"
322 style += "top: #{headers_height + 1}px;"
285 style += "left: 0px;"
323 style += "left: 0px;"
286 style += "width: #{g_width - 1}px;"
324 style += "width: #{g_width - 1}px;"
287 %>
325 %>
288 <%= content_tag(:div, '', :style => style, :id => "gantt_draw_area") %>
326 <%= content_tag(:div, '', :style => style, :id => "gantt_draw_area") %>
289 </div>
327 </div>
290 </td>
328 </td>
291 </tr>
329 </tr>
292 </table>
330 </table>
293
331
294 <table style="width:100%">
332 <table style="width:100%">
295 <tr>
333 <tr>
296 <td style="text-align:left;">
334 <td style="text-align:left;">
297 <%= link_to_content_update("\xc2\xab " + l(:label_previous),
335 <%= link_to_content_update("\xc2\xab " + l(:label_previous),
298 params.merge(@gantt.params_previous),
336 params.merge(@gantt.params_previous),
299 :accesskey => accesskey(:previous)) %>
337 :accesskey => accesskey(:previous)) %>
300 </td>
338 </td>
301 <td style="text-align:right;">
339 <td style="text-align:right;">
302 <%= link_to_content_update(l(:label_next) + " \xc2\xbb",
340 <%= link_to_content_update(l(:label_next) + " \xc2\xbb",
303 params.merge(@gantt.params_next),
341 params.merge(@gantt.params_next),
304 :accesskey => accesskey(:next)) %>
342 :accesskey => accesskey(:next)) %>
305 </td>
343 </td>
306 </tr>
344 </tr>
307 </table>
345 </table>
308
346
309 <% other_formats_links do |f| %>
347 <% other_formats_links do |f| %>
310 <%= f.link_to 'PDF', :url => params.merge(@gantt.params) %>
348 <%= f.link_to 'PDF', :url => params.merge(@gantt.params) %>
311 <%= f.link_to('PNG', :url => params.merge(@gantt.params)) if @gantt.respond_to?('to_image') %>
349 <%= f.link_to('PNG', :url => params.merge(@gantt.params)) if @gantt.respond_to?('to_image') %>
312 <% end %>
350 <% end %>
313 <% end # query.valid? %>
351 <% end # query.valid? %>
314
352
315 <% content_for :sidebar do %>
353 <% content_for :sidebar do %>
316 <%= render :partial => 'issues/sidebar' %>
354 <%= render :partial => 'issues/sidebar' %>
317 <% end %>
355 <% end %>
318
356
319 <% html_title(l(:label_gantt)) -%>
357 <% html_title(l(:label_gantt)) -%>
320
358
321 <% content_for :header_tags do %>
359 <% content_for :header_tags do %>
322 <%= javascript_include_tag 'raphael' %>
360 <%= javascript_include_tag 'raphael' %>
323 <%= javascript_include_tag 'gantt' %>
361 <%= javascript_include_tag 'gantt' %>
324 <% end %>
362 <% end %>
325
363
326 <%= javascript_tag do %>
364 <%= javascript_tag do %>
327 var issue_relation_type = <%= raw Redmine::Helpers::Gantt::DRAW_TYPES.to_json %>;
365 var issue_relation_type = <%= raw Redmine::Helpers::Gantt::DRAW_TYPES.to_json %>;
328 $(document).ready(drawGanttHandler);
366 $(document).ready(drawGanttHandler);
329 $(window).resize(drawGanttHandler);
367 $(window).resize(drawGanttHandler);
330 $(function() {
368 $(function() {
331 $("#draw_relations").change(drawGanttHandler);
369 $("#draw_relations").change(drawGanttHandler);
332 $("#draw_progress_line").change(drawGanttHandler);
370 $("#draw_progress_line").change(drawGanttHandler);
333 });
371 });
334 <% end %>
372 <% end %>
@@ -1,929 +1,954
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 module Helpers
19 module Helpers
20 # Simple class to handle gantt chart data
20 # Simple class to handle gantt chart data
21 class Gantt
21 class Gantt
22 class MaxLinesLimitReached < Exception
22 class MaxLinesLimitReached < Exception
23 end
23 end
24
24
25 include ERB::Util
25 include ERB::Util
26 include Redmine::I18n
26 include Redmine::I18n
27 include Redmine::Utils::DateCalculation
27 include Redmine::Utils::DateCalculation
28
28
29 # Relation types that are rendered
29 # Relation types that are rendered
30 DRAW_TYPES = {
30 DRAW_TYPES = {
31 IssueRelation::TYPE_BLOCKS => { :landscape_margin => 16, :color => '#F34F4F' },
31 IssueRelation::TYPE_BLOCKS => { :landscape_margin => 16, :color => '#F34F4F' },
32 IssueRelation::TYPE_PRECEDES => { :landscape_margin => 20, :color => '#628FEA' }
32 IssueRelation::TYPE_PRECEDES => { :landscape_margin => 20, :color => '#628FEA' }
33 }.freeze
33 }.freeze
34
34
35 # :nodoc:
35 # :nodoc:
36 # Some utility methods for the PDF export
36 # Some utility methods for the PDF export
37 class PDF
37 class PDF
38 MaxCharactorsForSubject = 45
38 MaxCharactorsForSubject = 45
39 TotalWidth = 280
39 TotalWidth = 280
40 LeftPaneWidth = 100
40 LeftPaneWidth = 100
41
41
42 def self.right_pane_width
42 def self.right_pane_width
43 TotalWidth - LeftPaneWidth
43 TotalWidth - LeftPaneWidth
44 end
44 end
45 end
45 end
46
46
47 attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months, :truncated, :max_rows
47 attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months, :truncated, :max_rows
48 attr_accessor :query
48 attr_accessor :query
49 attr_accessor :project
49 attr_accessor :project
50 attr_accessor :view
50 attr_accessor :view
51
51
52 def initialize(options={})
52 def initialize(options={})
53 options = options.dup
53 options = options.dup
54 if options[:year] && options[:year].to_i >0
54 if options[:year] && options[:year].to_i >0
55 @year_from = options[:year].to_i
55 @year_from = options[:year].to_i
56 if options[:month] && options[:month].to_i >=1 && options[:month].to_i <= 12
56 if options[:month] && options[:month].to_i >=1 && options[:month].to_i <= 12
57 @month_from = options[:month].to_i
57 @month_from = options[:month].to_i
58 else
58 else
59 @month_from = 1
59 @month_from = 1
60 end
60 end
61 else
61 else
62 @month_from ||= Date.today.month
62 @month_from ||= Date.today.month
63 @year_from ||= Date.today.year
63 @year_from ||= Date.today.year
64 end
64 end
65 zoom = (options[:zoom] || User.current.pref[:gantt_zoom]).to_i
65 zoom = (options[:zoom] || User.current.pref[:gantt_zoom]).to_i
66 @zoom = (zoom > 0 && zoom < 5) ? zoom : 2
66 @zoom = (zoom > 0 && zoom < 5) ? zoom : 2
67 months = (options[:months] || User.current.pref[:gantt_months]).to_i
67 months = (options[:months] || User.current.pref[:gantt_months]).to_i
68 @months = (months > 0 && months < 25) ? months : 6
68 @months = (months > 0 && months < 25) ? months : 6
69 # Save gantt parameters as user preference (zoom and months count)
69 # Save gantt parameters as user preference (zoom and months count)
70 if (User.current.logged? && (@zoom != User.current.pref[:gantt_zoom] ||
70 if (User.current.logged? && (@zoom != User.current.pref[:gantt_zoom] ||
71 @months != User.current.pref[:gantt_months]))
71 @months != User.current.pref[:gantt_months]))
72 User.current.pref[:gantt_zoom], User.current.pref[:gantt_months] = @zoom, @months
72 User.current.pref[:gantt_zoom], User.current.pref[:gantt_months] = @zoom, @months
73 User.current.preference.save
73 User.current.preference.save
74 end
74 end
75 @date_from = Date.civil(@year_from, @month_from, 1)
75 @date_from = Date.civil(@year_from, @month_from, 1)
76 @date_to = (@date_from >> @months) - 1
76 @date_to = (@date_from >> @months) - 1
77 @subjects = ''
77 @subjects = ''
78 @lines = ''
78 @lines = ''
79 @number_of_rows = nil
79 @number_of_rows = nil
80 @truncated = false
80 @truncated = false
81 if options.has_key?(:max_rows)
81 if options.has_key?(:max_rows)
82 @max_rows = options[:max_rows]
82 @max_rows = options[:max_rows]
83 else
83 else
84 @max_rows = Setting.gantt_items_limit.blank? ? nil : Setting.gantt_items_limit.to_i
84 @max_rows = Setting.gantt_items_limit.blank? ? nil : Setting.gantt_items_limit.to_i
85 end
85 end
86 end
86 end
87
87
88 def common_params
88 def common_params
89 { :controller => 'gantts', :action => 'show', :project_id => @project }
89 { :controller => 'gantts', :action => 'show', :project_id => @project }
90 end
90 end
91
91
92 def params
92 def params
93 common_params.merge({:zoom => zoom, :year => year_from,
93 common_params.merge({:zoom => zoom, :year => year_from,
94 :month => month_from, :months => months})
94 :month => month_from, :months => months})
95 end
95 end
96
96
97 def params_previous
97 def params_previous
98 common_params.merge({:year => (date_from << months).year,
98 common_params.merge({:year => (date_from << months).year,
99 :month => (date_from << months).month,
99 :month => (date_from << months).month,
100 :zoom => zoom, :months => months})
100 :zoom => zoom, :months => months})
101 end
101 end
102
102
103 def params_next
103 def params_next
104 common_params.merge({:year => (date_from >> months).year,
104 common_params.merge({:year => (date_from >> months).year,
105 :month => (date_from >> months).month,
105 :month => (date_from >> months).month,
106 :zoom => zoom, :months => months})
106 :zoom => zoom, :months => months})
107 end
107 end
108
108
109 # Returns the number of rows that will be rendered on the Gantt chart
109 # Returns the number of rows that will be rendered on the Gantt chart
110 def number_of_rows
110 def number_of_rows
111 return @number_of_rows if @number_of_rows
111 return @number_of_rows if @number_of_rows
112 rows = projects.inject(0) {|total, p| total += number_of_rows_on_project(p)}
112 rows = projects.inject(0) {|total, p| total += number_of_rows_on_project(p)}
113 rows > @max_rows ? @max_rows : rows
113 rows > @max_rows ? @max_rows : rows
114 end
114 end
115
115
116 # Returns the number of rows that will be used to list a project on
116 # Returns the number of rows that will be used to list a project on
117 # the Gantt chart. This will recurse for each subproject.
117 # the Gantt chart. This will recurse for each subproject.
118 def number_of_rows_on_project(project)
118 def number_of_rows_on_project(project)
119 return 0 unless projects.include?(project)
119 return 0 unless projects.include?(project)
120 count = 1
120 count = 1
121 count += project_issues(project).size
121 count += project_issues(project).size
122 count += project_versions(project).size
122 count += project_versions(project).size
123 count
123 count
124 end
124 end
125
125
126 # Renders the subjects of the Gantt chart, the left side.
126 # Renders the subjects of the Gantt chart, the left side.
127 def subjects(options={})
127 def subjects(options={})
128 render(options.merge(:only => :subjects)) unless @subjects_rendered
128 render(options.merge(:only => :subjects)) unless @subjects_rendered
129 @subjects
129 @subjects
130 end
130 end
131
131
132 # Renders the lines of the Gantt chart, the right side
132 # Renders the lines of the Gantt chart, the right side
133 def lines(options={})
133 def lines(options={})
134 render(options.merge(:only => :lines)) unless @lines_rendered
134 render(options.merge(:only => :lines)) unless @lines_rendered
135 @lines
135 @lines
136 end
136 end
137
137
138 # Returns issues that will be rendered
138 # Returns issues that will be rendered
139 def issues
139 def issues
140 @issues ||= @query.issues(
140 @issues ||= @query.issues(
141 :include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
141 :include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
142 :order => "#{Project.table_name}.lft ASC, #{Issue.table_name}.id ASC",
142 :order => "#{Project.table_name}.lft ASC, #{Issue.table_name}.id ASC",
143 :limit => @max_rows
143 :limit => @max_rows
144 )
144 )
145 end
145 end
146
146
147 # Returns a hash of the relations between the issues that are present on the gantt
147 # Returns a hash of the relations between the issues that are present on the gantt
148 # and that should be displayed, grouped by issue ids.
148 # and that should be displayed, grouped by issue ids.
149 def relations
149 def relations
150 return @relations if @relations
150 return @relations if @relations
151 if issues.any?
151 if issues.any?
152 issue_ids = issues.map(&:id)
152 issue_ids = issues.map(&:id)
153 @relations = IssueRelation.
153 @relations = IssueRelation.
154 where(:issue_from_id => issue_ids, :issue_to_id => issue_ids, :relation_type => DRAW_TYPES.keys).
154 where(:issue_from_id => issue_ids, :issue_to_id => issue_ids, :relation_type => DRAW_TYPES.keys).
155 group_by(&:issue_from_id)
155 group_by(&:issue_from_id)
156 else
156 else
157 @relations = {}
157 @relations = {}
158 end
158 end
159 end
159 end
160
160
161 # Return all the project nodes that will be displayed
161 # Return all the project nodes that will be displayed
162 def projects
162 def projects
163 return @projects if @projects
163 return @projects if @projects
164 ids = issues.collect(&:project).uniq.collect(&:id)
164 ids = issues.collect(&:project).uniq.collect(&:id)
165 if ids.any?
165 if ids.any?
166 # All issues projects and their visible ancestors
166 # All issues projects and their visible ancestors
167 @projects = Project.visible.
167 @projects = Project.visible.
168 joins("LEFT JOIN #{Project.table_name} child ON #{Project.table_name}.lft <= child.lft AND #{Project.table_name}.rgt >= child.rgt").
168 joins("LEFT JOIN #{Project.table_name} child ON #{Project.table_name}.lft <= child.lft AND #{Project.table_name}.rgt >= child.rgt").
169 where("child.id IN (?)", ids).
169 where("child.id IN (?)", ids).
170 order("#{Project.table_name}.lft ASC").
170 order("#{Project.table_name}.lft ASC").
171 uniq.
171 uniq.
172 to_a
172 to_a
173 else
173 else
174 @projects = []
174 @projects = []
175 end
175 end
176 end
176 end
177
177
178 # Returns the issues that belong to +project+
178 # Returns the issues that belong to +project+
179 def project_issues(project)
179 def project_issues(project)
180 @issues_by_project ||= issues.group_by(&:project)
180 @issues_by_project ||= issues.group_by(&:project)
181 @issues_by_project[project] || []
181 @issues_by_project[project] || []
182 end
182 end
183
183
184 # Returns the distinct versions of the issues that belong to +project+
184 # Returns the distinct versions of the issues that belong to +project+
185 def project_versions(project)
185 def project_versions(project)
186 project_issues(project).collect(&:fixed_version).compact.uniq
186 project_issues(project).collect(&:fixed_version).compact.uniq
187 end
187 end
188
188
189 # Returns the issues that belong to +project+ and are assigned to +version+
189 # Returns the issues that belong to +project+ and are assigned to +version+
190 def version_issues(project, version)
190 def version_issues(project, version)
191 project_issues(project).select {|issue| issue.fixed_version == version}
191 project_issues(project).select {|issue| issue.fixed_version == version}
192 end
192 end
193
193
194 def render(options={})
194 def render(options={})
195 options = {:top => 0, :top_increment => 20,
195 options = {:top => 0, :top_increment => 20,
196 :indent_increment => 20, :render => :subject,
196 :indent_increment => 20, :render => :subject,
197 :format => :html}.merge(options)
197 :format => :html}.merge(options)
198 indent = options[:indent] || 4
198 indent = options[:indent] || 4
199 @subjects = '' unless options[:only] == :lines
199 @subjects = '' unless options[:only] == :lines
200 @lines = '' unless options[:only] == :subjects
200 @lines = '' unless options[:only] == :subjects
201 @number_of_rows = 0
201 @number_of_rows = 0
202 begin
202 begin
203 Project.project_tree(projects) do |project, level|
203 Project.project_tree(projects) do |project, level|
204 options[:indent] = indent + level * options[:indent_increment]
204 options[:indent] = indent + level * options[:indent_increment]
205 render_project(project, options)
205 render_project(project, options)
206 end
206 end
207 rescue MaxLinesLimitReached
207 rescue MaxLinesLimitReached
208 @truncated = true
208 @truncated = true
209 end
209 end
210 @subjects_rendered = true unless options[:only] == :lines
210 @subjects_rendered = true unless options[:only] == :lines
211 @lines_rendered = true unless options[:only] == :subjects
211 @lines_rendered = true unless options[:only] == :subjects
212 render_end(options)
212 render_end(options)
213 end
213 end
214
214
215 def render_project(project, options={})
215 def render_project(project, options={})
216 render_object_row(project, options)
216 render_object_row(project, options)
217 increment_indent(options) do
217 increment_indent(options) do
218 # render issue that are not assigned to a version
218 # render issue that are not assigned to a version
219 issues = project_issues(project).select {|i| i.fixed_version.nil?}
219 issues = project_issues(project).select {|i| i.fixed_version.nil?}
220 render_issues(issues, options)
220 render_issues(issues, options)
221 # then render project versions and their issues
221 # then render project versions and their issues
222 versions = project_versions(project)
222 versions = project_versions(project)
223 self.class.sort_versions!(versions)
223 self.class.sort_versions!(versions)
224 versions.each do |version|
224 versions.each do |version|
225 render_version(project, version, options)
225 render_version(project, version, options)
226 end
226 end
227 end
227 end
228 end
228 end
229
229
230 def render_version(project, version, options={})
230 def render_version(project, version, options={})
231 render_object_row(version, options)
231 render_object_row(version, options)
232 increment_indent(options) do
232 increment_indent(options) do
233 issues = version_issues(project, version)
233 issues = version_issues(project, version)
234 render_issues(issues, options)
234 render_issues(issues, options)
235 end
235 end
236 end
236 end
237
237
238 def render_issues(issues, options={})
238 def render_issues(issues, options={})
239 self.class.sort_issues!(issues)
239 self.class.sort_issues!(issues)
240 ancestors = []
240 ancestors = []
241 issues.each do |issue|
241 issues.each do |issue|
242 while ancestors.any? && !issue.is_descendant_of?(ancestors.last)
242 while ancestors.any? && !issue.is_descendant_of?(ancestors.last)
243 ancestors.pop
243 ancestors.pop
244 decrement_indent(options)
244 decrement_indent(options)
245 end
245 end
246 render_object_row(issue, options)
246 render_object_row(issue, options)
247 unless issue.leaf?
247 unless issue.leaf?
248 ancestors << issue
248 ancestors << issue
249 increment_indent(options)
249 increment_indent(options)
250 end
250 end
251 end
251 end
252 decrement_indent(options, ancestors.size)
252 decrement_indent(options, ancestors.size)
253 end
253 end
254
254
255 def render_object_row(object, options)
255 def render_object_row(object, options)
256 class_name = object.class.name.downcase
256 class_name = object.class.name.downcase
257 send("subject_for_#{class_name}", object, options) unless options[:only] == :lines
257 send("subject_for_#{class_name}", object, options) unless options[:only] == :lines
258 send("line_for_#{class_name}", object, options) unless options[:only] == :subjects
258 send("line_for_#{class_name}", object, options) unless options[:only] == :subjects
259 options[:top] += options[:top_increment]
259 options[:top] += options[:top_increment]
260 @number_of_rows += 1
260 @number_of_rows += 1
261 if @max_rows && @number_of_rows >= @max_rows
261 if @max_rows && @number_of_rows >= @max_rows
262 raise MaxLinesLimitReached
262 raise MaxLinesLimitReached
263 end
263 end
264 end
264 end
265
265
266 def render_end(options={})
266 def render_end(options={})
267 case options[:format]
267 case options[:format]
268 when :pdf
268 when :pdf
269 options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
269 options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
270 end
270 end
271 end
271 end
272
272
273 def increment_indent(options, factor=1)
273 def increment_indent(options, factor=1)
274 options[:indent] += options[:indent_increment] * factor
274 options[:indent] += options[:indent_increment] * factor
275 if block_given?
275 if block_given?
276 yield
276 yield
277 decrement_indent(options, factor)
277 decrement_indent(options, factor)
278 end
278 end
279 end
279 end
280
280
281 def decrement_indent(options, factor=1)
281 def decrement_indent(options, factor=1)
282 increment_indent(options, -factor)
282 increment_indent(options, -factor)
283 end
283 end
284
284
285 def subject_for_project(project, options)
285 def subject_for_project(project, options)
286 subject(project.name, options, project)
286 subject(project.name, options, project)
287 end
287 end
288
288
289 def line_for_project(project, options)
289 def line_for_project(project, options)
290 # Skip projects that don't have a start_date or due date
290 # Skip projects that don't have a start_date or due date
291 if project.is_a?(Project) && project.start_date && project.due_date
291 if project.is_a?(Project) && project.start_date && project.due_date
292 label = project.name
292 label = project.name
293 line(project.start_date, project.due_date, nil, true, label, options, project)
293 line(project.start_date, project.due_date, nil, true, label, options, project)
294 end
294 end
295 end
295 end
296
296
297 def subject_for_version(version, options)
297 def subject_for_version(version, options)
298 subject(version.to_s_with_project, options, version)
298 subject(version.to_s_with_project, options, version)
299 end
299 end
300
300
301 def line_for_version(version, options)
301 def line_for_version(version, options)
302 # Skip versions that don't have a start_date
302 # Skip versions that don't have a start_date
303 if version.is_a?(Version) && version.due_date && version.start_date
303 if version.is_a?(Version) && version.due_date && version.start_date
304 label = "#{h(version)} #{h(version.completed_percent.to_f.round)}%"
304 label = "#{h(version)} #{h(version.completed_percent.to_f.round)}%"
305 label = h("#{version.project} -") + label unless @project && @project == version.project
305 label = h("#{version.project} -") + label unless @project && @project == version.project
306 line(version.start_date, version.due_date, version.completed_percent, true, label, options, version)
306 line(version.start_date, version.due_date, version.completed_percent, true, label, options, version)
307 end
307 end
308 end
308 end
309
309
310 def subject_for_issue(issue, options)
310 def subject_for_issue(issue, options)
311 subject(issue.subject, options, issue)
311 subject(issue.subject, options, issue)
312 end
312 end
313
313
314 def line_for_issue(issue, options)
314 def line_for_issue(issue, options)
315 # Skip issues that don't have a due_before (due_date or version's due_date)
315 # Skip issues that don't have a due_before (due_date or version's due_date)
316 if issue.is_a?(Issue) && issue.due_before
316 if issue.is_a?(Issue) && issue.due_before
317 label = "#{issue.status.name} #{issue.done_ratio}%"
317 label = "#{issue.status.name} #{issue.done_ratio}%"
318 markers = !issue.leaf?
318 markers = !issue.leaf?
319 line(issue.start_date, issue.due_before, issue.done_ratio, markers, label, options, issue)
319 line(issue.start_date, issue.due_before, issue.done_ratio, markers, label, options, issue)
320 end
320 end
321 end
321 end
322
322
323 def subject(label, options, object=nil)
323 def subject(label, options, object=nil)
324 send "#{options[:format]}_subject", options, label, object
324 send "#{options[:format]}_subject", options, label, object
325 end
325 end
326
326
327 def line(start_date, end_date, done_ratio, markers, label, options, object=nil)
327 def line(start_date, end_date, done_ratio, markers, label, options, object=nil)
328 options[:zoom] ||= 1
328 options[:zoom] ||= 1
329 options[:g_width] ||= (self.date_to - self.date_from + 1) * options[:zoom]
329 options[:g_width] ||= (self.date_to - self.date_from + 1) * options[:zoom]
330 coords = coordinates(start_date, end_date, done_ratio, options[:zoom])
330 coords = coordinates(start_date, end_date, done_ratio, options[:zoom])
331 send "#{options[:format]}_task", options, coords, markers, label, object
331 send "#{options[:format]}_task", options, coords, markers, label, object
332 end
332 end
333
333
334 # Generates a gantt image
334 # Generates a gantt image
335 # Only defined if RMagick is avalaible
335 # Only defined if RMagick is avalaible
336 def to_image(format='PNG')
336 def to_image(format='PNG')
337 date_to = (@date_from >> @months) - 1
337 date_to = (@date_from >> @months) - 1
338 show_weeks = @zoom > 1
338 show_weeks = @zoom > 1
339 show_days = @zoom > 2
339 show_days = @zoom > 2
340 subject_width = 400
340 subject_width = 400
341 header_height = 18
341 header_height = 18
342 # width of one day in pixels
342 # width of one day in pixels
343 zoom = @zoom * 2
343 zoom = @zoom * 2
344 g_width = (@date_to - @date_from + 1) * zoom
344 g_width = (@date_to - @date_from + 1) * zoom
345 g_height = 20 * number_of_rows + 30
345 g_height = 20 * number_of_rows + 30
346 headers_height = (show_weeks ? 2 * header_height : header_height)
346 headers_height = (show_weeks ? 2 * header_height : header_height)
347 height = g_height + headers_height
347 height = g_height + headers_height
348 imgl = Magick::ImageList.new
348 imgl = Magick::ImageList.new
349 imgl.new_image(subject_width + g_width + 1, height)
349 imgl.new_image(subject_width + g_width + 1, height)
350 gc = Magick::Draw.new
350 gc = Magick::Draw.new
351 gc.font = Redmine::Configuration['rmagick_font_path'] || ""
351 gc.font = Redmine::Configuration['rmagick_font_path'] || ""
352 # Subjects
352 # Subjects
353 gc.stroke('transparent')
353 gc.stroke('transparent')
354 subjects(:image => gc, :top => (headers_height + 20), :indent => 4, :format => :image)
354 subjects(:image => gc, :top => (headers_height + 20), :indent => 4, :format => :image)
355 # Months headers
355 # Months headers
356 month_f = @date_from
356 month_f = @date_from
357 left = subject_width
357 left = subject_width
358 @months.times do
358 @months.times do
359 width = ((month_f >> 1) - month_f) * zoom
359 width = ((month_f >> 1) - month_f) * zoom
360 gc.fill('white')
360 gc.fill('white')
361 gc.stroke('grey')
361 gc.stroke('grey')
362 gc.stroke_width(1)
362 gc.stroke_width(1)
363 gc.rectangle(left, 0, left + width, height)
363 gc.rectangle(left, 0, left + width, height)
364 gc.fill('black')
364 gc.fill('black')
365 gc.stroke('transparent')
365 gc.stroke('transparent')
366 gc.stroke_width(1)
366 gc.stroke_width(1)
367 gc.text(left.round + 8, 14, "#{month_f.year}-#{month_f.month}")
367 gc.text(left.round + 8, 14, "#{month_f.year}-#{month_f.month}")
368 left = left + width
368 left = left + width
369 month_f = month_f >> 1
369 month_f = month_f >> 1
370 end
370 end
371 # Weeks headers
371 # Weeks headers
372 if show_weeks
372 if show_weeks
373 left = subject_width
373 left = subject_width
374 height = header_height
374 height = header_height
375 if @date_from.cwday == 1
375 if @date_from.cwday == 1
376 # date_from is monday
376 # date_from is monday
377 week_f = date_from
377 week_f = date_from
378 else
378 else
379 # find next monday after date_from
379 # find next monday after date_from
380 week_f = @date_from + (7 - @date_from.cwday + 1)
380 week_f = @date_from + (7 - @date_from.cwday + 1)
381 width = (7 - @date_from.cwday + 1) * zoom
381 width = (7 - @date_from.cwday + 1) * zoom
382 gc.fill('white')
382 gc.fill('white')
383 gc.stroke('grey')
383 gc.stroke('grey')
384 gc.stroke_width(1)
384 gc.stroke_width(1)
385 gc.rectangle(left, header_height, left + width, 2 * header_height + g_height - 1)
385 gc.rectangle(left, header_height, left + width, 2 * header_height + g_height - 1)
386 left = left + width
386 left = left + width
387 end
387 end
388 while week_f <= date_to
388 while week_f <= date_to
389 width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom
389 width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom
390 gc.fill('white')
390 gc.fill('white')
391 gc.stroke('grey')
391 gc.stroke('grey')
392 gc.stroke_width(1)
392 gc.stroke_width(1)
393 gc.rectangle(left.round, header_height, left.round + width, 2 * header_height + g_height - 1)
393 gc.rectangle(left.round, header_height, left.round + width, 2 * header_height + g_height - 1)
394 gc.fill('black')
394 gc.fill('black')
395 gc.stroke('transparent')
395 gc.stroke('transparent')
396 gc.stroke_width(1)
396 gc.stroke_width(1)
397 gc.text(left.round + 2, header_height + 14, week_f.cweek.to_s)
397 gc.text(left.round + 2, header_height + 14, week_f.cweek.to_s)
398 left = left + width
398 left = left + width
399 week_f = week_f + 7
399 week_f = week_f + 7
400 end
400 end
401 end
401 end
402 # Days details (week-end in grey)
402 # Days details (week-end in grey)
403 if show_days
403 if show_days
404 left = subject_width
404 left = subject_width
405 height = g_height + header_height - 1
405 height = g_height + header_height - 1
406 wday = @date_from.cwday
406 wday = @date_from.cwday
407 (date_to - @date_from + 1).to_i.times do
407 (date_to - @date_from + 1).to_i.times do
408 width = zoom
408 width = zoom
409 gc.fill(non_working_week_days.include?(wday) ? '#eee' : 'white')
409 gc.fill(non_working_week_days.include?(wday) ? '#eee' : 'white')
410 gc.stroke('#ddd')
410 gc.stroke('#ddd')
411 gc.stroke_width(1)
411 gc.stroke_width(1)
412 gc.rectangle(left, 2 * header_height, left + width, 2 * header_height + g_height - 1)
412 gc.rectangle(left, 2 * header_height, left + width, 2 * header_height + g_height - 1)
413 left = left + width
413 left = left + width
414 wday = wday + 1
414 wday = wday + 1
415 wday = 1 if wday > 7
415 wday = 1 if wday > 7
416 end
416 end
417 end
417 end
418 # border
418 # border
419 gc.fill('transparent')
419 gc.fill('transparent')
420 gc.stroke('grey')
420 gc.stroke('grey')
421 gc.stroke_width(1)
421 gc.stroke_width(1)
422 gc.rectangle(0, 0, subject_width + g_width, headers_height)
422 gc.rectangle(0, 0, subject_width + g_width, headers_height)
423 gc.stroke('black')
423 gc.stroke('black')
424 gc.rectangle(0, 0, subject_width + g_width, g_height + headers_height - 1)
424 gc.rectangle(0, 0, subject_width + g_width, g_height + headers_height - 1)
425 # content
425 # content
426 top = headers_height + 20
426 top = headers_height + 20
427 gc.stroke('transparent')
427 gc.stroke('transparent')
428 lines(:image => gc, :top => top, :zoom => zoom,
428 lines(:image => gc, :top => top, :zoom => zoom,
429 :subject_width => subject_width, :format => :image)
429 :subject_width => subject_width, :format => :image)
430 # today red line
430 # today red line
431 if Date.today >= @date_from and Date.today <= date_to
431 if Date.today >= @date_from and Date.today <= date_to
432 gc.stroke('red')
432 gc.stroke('red')
433 x = (Date.today - @date_from + 1) * zoom + subject_width
433 x = (Date.today - @date_from + 1) * zoom + subject_width
434 gc.line(x, headers_height, x, headers_height + g_height - 1)
434 gc.line(x, headers_height, x, headers_height + g_height - 1)
435 end
435 end
436 gc.draw(imgl)
436 gc.draw(imgl)
437 imgl.format = format
437 imgl.format = format
438 imgl.to_blob
438 imgl.to_blob
439 end if Object.const_defined?(:Magick)
439 end if Object.const_defined?(:Magick)
440
440
441 def to_pdf
441 def to_pdf
442 pdf = ::Redmine::Export::PDF::ITCPDF.new(current_language)
442 pdf = ::Redmine::Export::PDF::ITCPDF.new(current_language)
443 pdf.SetTitle("#{l(:label_gantt)} #{project}")
443 pdf.SetTitle("#{l(:label_gantt)} #{project}")
444 pdf.alias_nb_pages
444 pdf.alias_nb_pages
445 pdf.footer_date = format_date(Date.today)
445 pdf.footer_date = format_date(Date.today)
446 pdf.AddPage("L")
446 pdf.AddPage("L")
447 pdf.SetFontStyle('B', 12)
447 pdf.SetFontStyle('B', 12)
448 pdf.SetX(15)
448 pdf.SetX(15)
449 pdf.RDMCell(PDF::LeftPaneWidth, 20, project.to_s)
449 pdf.RDMCell(PDF::LeftPaneWidth, 20, project.to_s)
450 pdf.Ln
450 pdf.Ln
451 pdf.SetFontStyle('B', 9)
451 pdf.SetFontStyle('B', 9)
452 subject_width = PDF::LeftPaneWidth
452 subject_width = PDF::LeftPaneWidth
453 header_height = 5
453 header_height = 5
454 headers_height = header_height
454 headers_height = header_height
455 show_weeks = false
455 show_weeks = false
456 show_days = false
456 show_days = false
457 if self.months < 7
457 if self.months < 7
458 show_weeks = true
458 show_weeks = true
459 headers_height = 2 * header_height
459 headers_height = 2 * header_height
460 if self.months < 3
460 if self.months < 3
461 show_days = true
461 show_days = true
462 headers_height = 3 * header_height
462 headers_height = 3 * header_height
463 if self.months < 2
464 show_day_num = true
465 headers_height = 4 * header_height
466 end
463 end
467 end
464 end
468 end
465 g_width = PDF.right_pane_width
469 g_width = PDF.right_pane_width
466 zoom = (g_width) / (self.date_to - self.date_from + 1)
470 zoom = (g_width) / (self.date_to - self.date_from + 1)
467 g_height = 120
471 g_height = 120
468 t_height = g_height + headers_height
472 t_height = g_height + headers_height
469 y_start = pdf.GetY
473 y_start = pdf.GetY
470 # Months headers
474 # Months headers
471 month_f = self.date_from
475 month_f = self.date_from
472 left = subject_width
476 left = subject_width
473 height = header_height
477 height = header_height
474 self.months.times do
478 self.months.times do
475 width = ((month_f >> 1) - month_f) * zoom
479 width = ((month_f >> 1) - month_f) * zoom
476 pdf.SetY(y_start)
480 pdf.SetY(y_start)
477 pdf.SetX(left)
481 pdf.SetX(left)
478 pdf.RDMCell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C")
482 pdf.RDMCell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C")
479 left = left + width
483 left = left + width
480 month_f = month_f >> 1
484 month_f = month_f >> 1
481 end
485 end
482 # Weeks headers
486 # Weeks headers
483 if show_weeks
487 if show_weeks
484 left = subject_width
488 left = subject_width
485 height = header_height
489 height = header_height
486 if self.date_from.cwday == 1
490 if self.date_from.cwday == 1
487 # self.date_from is monday
491 # self.date_from is monday
488 week_f = self.date_from
492 week_f = self.date_from
489 else
493 else
490 # find next monday after self.date_from
494 # find next monday after self.date_from
491 week_f = self.date_from + (7 - self.date_from.cwday + 1)
495 week_f = self.date_from + (7 - self.date_from.cwday + 1)
492 width = (7 - self.date_from.cwday + 1) * zoom-1
496 width = (7 - self.date_from.cwday + 1) * zoom-1
493 pdf.SetY(y_start + header_height)
497 pdf.SetY(y_start + header_height)
494 pdf.SetX(left)
498 pdf.SetX(left)
495 pdf.RDMCell(width + 1, height, "", "LTR")
499 pdf.RDMCell(width + 1, height, "", "LTR")
496 left = left + width + 1
500 left = left + width + 1
497 end
501 end
498 while week_f <= self.date_to
502 while week_f <= self.date_to
499 width = (week_f + 6 <= self.date_to) ? 7 * zoom : (self.date_to - week_f + 1) * zoom
503 width = (week_f + 6 <= self.date_to) ? 7 * zoom : (self.date_to - week_f + 1) * zoom
500 pdf.SetY(y_start + header_height)
504 pdf.SetY(y_start + header_height)
501 pdf.SetX(left)
505 pdf.SetX(left)
502 pdf.RDMCell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
506 pdf.RDMCell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
503 left = left + width
507 left = left + width
504 week_f = week_f + 7
508 week_f = week_f + 7
505 end
509 end
506 end
510 end
511 # Day numbers headers
512 if show_day_num
513 left = subject_width
514 height = header_height
515 day_num = self.date_from
516 wday = self.date_from.cwday
517 pdf.SetFontStyle('B', 7)
518 (self.date_to - self.date_from + 1).to_i.times do
519 width = zoom
520 pdf.SetY(y_start + header_height * 2)
521 pdf.SetX(left)
522 pdf.SetTextColor(non_working_week_days.include?(wday) ? 150 : 0)
523 pdf.RDMCell(width, height, day_num.day.to_s, "LTR", 0, "C")
524 left = left + width
525 day_num = day_num + 1
526 wday = wday + 1
527 wday = 1 if wday > 7
528 end
529 end
507 # Days headers
530 # Days headers
508 if show_days
531 if show_days
509 left = subject_width
532 left = subject_width
510 height = header_height
533 height = header_height
511 wday = self.date_from.cwday
534 wday = self.date_from.cwday
512 pdf.SetFontStyle('B', 7)
535 pdf.SetFontStyle('B', 7)
513 (self.date_to - self.date_from + 1).to_i.times do
536 (self.date_to - self.date_from + 1).to_i.times do
514 width = zoom
537 width = zoom
515 pdf.SetY(y_start + 2 * header_height)
538 pdf.SetY(y_start + header_height * (show_day_num ? 3 : 2))
516 pdf.SetX(left)
539 pdf.SetX(left)
540 pdf.SetTextColor(non_working_week_days.include?(wday) ? 150 : 0)
517 pdf.RDMCell(width, height, day_name(wday).first, "LTR", 0, "C")
541 pdf.RDMCell(width, height, day_name(wday).first, "LTR", 0, "C")
518 left = left + width
542 left = left + width
519 wday = wday + 1
543 wday = wday + 1
520 wday = 1 if wday > 7
544 wday = 1 if wday > 7
521 end
545 end
522 end
546 end
523 pdf.SetY(y_start)
547 pdf.SetY(y_start)
524 pdf.SetX(15)
548 pdf.SetX(15)
549 pdf.SetTextColor(0)
525 pdf.RDMCell(subject_width + g_width - 15, headers_height, "", 1)
550 pdf.RDMCell(subject_width + g_width - 15, headers_height, "", 1)
526 # Tasks
551 # Tasks
527 top = headers_height + y_start
552 top = headers_height + y_start
528 options = {
553 options = {
529 :top => top,
554 :top => top,
530 :zoom => zoom,
555 :zoom => zoom,
531 :subject_width => subject_width,
556 :subject_width => subject_width,
532 :g_width => g_width,
557 :g_width => g_width,
533 :indent => 0,
558 :indent => 0,
534 :indent_increment => 5,
559 :indent_increment => 5,
535 :top_increment => 5,
560 :top_increment => 5,
536 :format => :pdf,
561 :format => :pdf,
537 :pdf => pdf
562 :pdf => pdf
538 }
563 }
539 render(options)
564 render(options)
540 pdf.Output
565 pdf.Output
541 end
566 end
542
567
543 private
568 private
544
569
545 def coordinates(start_date, end_date, progress, zoom=nil)
570 def coordinates(start_date, end_date, progress, zoom=nil)
546 zoom ||= @zoom
571 zoom ||= @zoom
547 coords = {}
572 coords = {}
548 if start_date && end_date && start_date < self.date_to && end_date > self.date_from
573 if start_date && end_date && start_date < self.date_to && end_date > self.date_from
549 if start_date > self.date_from
574 if start_date > self.date_from
550 coords[:start] = start_date - self.date_from
575 coords[:start] = start_date - self.date_from
551 coords[:bar_start] = start_date - self.date_from
576 coords[:bar_start] = start_date - self.date_from
552 else
577 else
553 coords[:bar_start] = 0
578 coords[:bar_start] = 0
554 end
579 end
555 if end_date < self.date_to
580 if end_date < self.date_to
556 coords[:end] = end_date - self.date_from
581 coords[:end] = end_date - self.date_from
557 coords[:bar_end] = end_date - self.date_from + 1
582 coords[:bar_end] = end_date - self.date_from + 1
558 else
583 else
559 coords[:bar_end] = self.date_to - self.date_from + 1
584 coords[:bar_end] = self.date_to - self.date_from + 1
560 end
585 end
561 if progress
586 if progress
562 progress_date = calc_progress_date(start_date, end_date, progress)
587 progress_date = calc_progress_date(start_date, end_date, progress)
563 if progress_date > self.date_from && progress_date > start_date
588 if progress_date > self.date_from && progress_date > start_date
564 if progress_date < self.date_to
589 if progress_date < self.date_to
565 coords[:bar_progress_end] = progress_date - self.date_from
590 coords[:bar_progress_end] = progress_date - self.date_from
566 else
591 else
567 coords[:bar_progress_end] = self.date_to - self.date_from + 1
592 coords[:bar_progress_end] = self.date_to - self.date_from + 1
568 end
593 end
569 end
594 end
570 if progress_date < Date.today
595 if progress_date < Date.today
571 late_date = [Date.today, end_date].min
596 late_date = [Date.today, end_date].min
572 if late_date > self.date_from && late_date > start_date
597 if late_date > self.date_from && late_date > start_date
573 if late_date < self.date_to
598 if late_date < self.date_to
574 coords[:bar_late_end] = late_date - self.date_from + 1
599 coords[:bar_late_end] = late_date - self.date_from + 1
575 else
600 else
576 coords[:bar_late_end] = self.date_to - self.date_from + 1
601 coords[:bar_late_end] = self.date_to - self.date_from + 1
577 end
602 end
578 end
603 end
579 end
604 end
580 end
605 end
581 end
606 end
582 # Transforms dates into pixels witdh
607 # Transforms dates into pixels witdh
583 coords.keys.each do |key|
608 coords.keys.each do |key|
584 coords[key] = (coords[key] * zoom).floor
609 coords[key] = (coords[key] * zoom).floor
585 end
610 end
586 coords
611 coords
587 end
612 end
588
613
589 def calc_progress_date(start_date, end_date, progress)
614 def calc_progress_date(start_date, end_date, progress)
590 start_date + (end_date - start_date + 1) * (progress / 100.0)
615 start_date + (end_date - start_date + 1) * (progress / 100.0)
591 end
616 end
592
617
593 def self.sort_issues!(issues)
618 def self.sort_issues!(issues)
594 issues.sort! {|a, b| sort_issue_logic(a) <=> sort_issue_logic(b)}
619 issues.sort! {|a, b| sort_issue_logic(a) <=> sort_issue_logic(b)}
595 end
620 end
596
621
597 def self.sort_issue_logic(issue)
622 def self.sort_issue_logic(issue)
598 julian_date = Date.new()
623 julian_date = Date.new()
599 ancesters_start_date = []
624 ancesters_start_date = []
600 current_issue = issue
625 current_issue = issue
601 begin
626 begin
602 ancesters_start_date.unshift([current_issue.start_date || julian_date, current_issue.id])
627 ancesters_start_date.unshift([current_issue.start_date || julian_date, current_issue.id])
603 current_issue = current_issue.parent
628 current_issue = current_issue.parent
604 end while (current_issue)
629 end while (current_issue)
605 ancesters_start_date
630 ancesters_start_date
606 end
631 end
607
632
608 def self.sort_versions!(versions)
633 def self.sort_versions!(versions)
609 versions.sort!
634 versions.sort!
610 end
635 end
611
636
612 def pdf_new_page?(options)
637 def pdf_new_page?(options)
613 if options[:top] > 180
638 if options[:top] > 180
614 options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
639 options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
615 options[:pdf].AddPage("L")
640 options[:pdf].AddPage("L")
616 options[:top] = 15
641 options[:top] = 15
617 options[:pdf].Line(15, options[:top] - 0.1, PDF::TotalWidth, options[:top] - 0.1)
642 options[:pdf].Line(15, options[:top] - 0.1, PDF::TotalWidth, options[:top] - 0.1)
618 end
643 end
619 end
644 end
620
645
621 def html_subject_content(object)
646 def html_subject_content(object)
622 case object
647 case object
623 when Issue
648 when Issue
624 issue = object
649 issue = object
625 css_classes = ''
650 css_classes = ''
626 css_classes << ' issue-overdue' if issue.overdue?
651 css_classes << ' issue-overdue' if issue.overdue?
627 css_classes << ' issue-behind-schedule' if issue.behind_schedule?
652 css_classes << ' issue-behind-schedule' if issue.behind_schedule?
628 css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
653 css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
629 css_classes << ' issue-closed' if issue.closed?
654 css_classes << ' issue-closed' if issue.closed?
630 if issue.start_date && issue.due_before && issue.done_ratio
655 if issue.start_date && issue.due_before && issue.done_ratio
631 progress_date = calc_progress_date(issue.start_date,
656 progress_date = calc_progress_date(issue.start_date,
632 issue.due_before, issue.done_ratio)
657 issue.due_before, issue.done_ratio)
633 css_classes << ' behind-start-date' if progress_date < self.date_from
658 css_classes << ' behind-start-date' if progress_date < self.date_from
634 css_classes << ' over-end-date' if progress_date > self.date_to
659 css_classes << ' over-end-date' if progress_date > self.date_to
635 end
660 end
636 s = "".html_safe
661 s = "".html_safe
637 if issue.assigned_to.present?
662 if issue.assigned_to.present?
638 assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
663 assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
639 s << view.avatar(issue.assigned_to,
664 s << view.avatar(issue.assigned_to,
640 :class => 'gravatar icon-gravatar',
665 :class => 'gravatar icon-gravatar',
641 :size => 10,
666 :size => 10,
642 :title => assigned_string).to_s.html_safe
667 :title => assigned_string).to_s.html_safe
643 end
668 end
644 s << view.link_to_issue(issue).html_safe
669 s << view.link_to_issue(issue).html_safe
645 view.content_tag(:span, s, :class => css_classes).html_safe
670 view.content_tag(:span, s, :class => css_classes).html_safe
646 when Version
671 when Version
647 version = object
672 version = object
648 html_class = ""
673 html_class = ""
649 html_class << 'icon icon-package '
674 html_class << 'icon icon-package '
650 html_class << (version.behind_schedule? ? 'version-behind-schedule' : '') << " "
675 html_class << (version.behind_schedule? ? 'version-behind-schedule' : '') << " "
651 html_class << (version.overdue? ? 'version-overdue' : '')
676 html_class << (version.overdue? ? 'version-overdue' : '')
652 html_class << ' version-closed' unless version.open?
677 html_class << ' version-closed' unless version.open?
653 if version.start_date && version.due_date && version.completed_percent
678 if version.start_date && version.due_date && version.completed_percent
654 progress_date = calc_progress_date(version.start_date,
679 progress_date = calc_progress_date(version.start_date,
655 version.due_date, version.completed_percent)
680 version.due_date, version.completed_percent)
656 html_class << ' behind-start-date' if progress_date < self.date_from
681 html_class << ' behind-start-date' if progress_date < self.date_from
657 html_class << ' over-end-date' if progress_date > self.date_to
682 html_class << ' over-end-date' if progress_date > self.date_to
658 end
683 end
659 s = view.link_to_version(version).html_safe
684 s = view.link_to_version(version).html_safe
660 view.content_tag(:span, s, :class => html_class).html_safe
685 view.content_tag(:span, s, :class => html_class).html_safe
661 when Project
686 when Project
662 project = object
687 project = object
663 html_class = ""
688 html_class = ""
664 html_class << 'icon icon-projects '
689 html_class << 'icon icon-projects '
665 html_class << (project.overdue? ? 'project-overdue' : '')
690 html_class << (project.overdue? ? 'project-overdue' : '')
666 s = view.link_to_project(project).html_safe
691 s = view.link_to_project(project).html_safe
667 view.content_tag(:span, s, :class => html_class).html_safe
692 view.content_tag(:span, s, :class => html_class).html_safe
668 end
693 end
669 end
694 end
670
695
671 def html_subject(params, subject, object)
696 def html_subject(params, subject, object)
672 style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
697 style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
673 style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
698 style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
674 content = html_subject_content(object) || subject
699 content = html_subject_content(object) || subject
675 tag_options = {:style => style}
700 tag_options = {:style => style}
676 case object
701 case object
677 when Issue
702 when Issue
678 tag_options[:id] = "issue-#{object.id}"
703 tag_options[:id] = "issue-#{object.id}"
679 tag_options[:class] = "issue-subject"
704 tag_options[:class] = "issue-subject"
680 tag_options[:title] = object.subject
705 tag_options[:title] = object.subject
681 when Version
706 when Version
682 tag_options[:id] = "version-#{object.id}"
707 tag_options[:id] = "version-#{object.id}"
683 tag_options[:class] = "version-name"
708 tag_options[:class] = "version-name"
684 when Project
709 when Project
685 tag_options[:class] = "project-name"
710 tag_options[:class] = "project-name"
686 end
711 end
687 output = view.content_tag(:div, content, tag_options)
712 output = view.content_tag(:div, content, tag_options)
688 @subjects << output
713 @subjects << output
689 output
714 output
690 end
715 end
691
716
692 def pdf_subject(params, subject, options={})
717 def pdf_subject(params, subject, options={})
693 pdf_new_page?(params)
718 pdf_new_page?(params)
694 params[:pdf].SetY(params[:top])
719 params[:pdf].SetY(params[:top])
695 params[:pdf].SetX(15)
720 params[:pdf].SetX(15)
696 char_limit = PDF::MaxCharactorsForSubject - params[:indent]
721 char_limit = PDF::MaxCharactorsForSubject - params[:indent]
697 params[:pdf].RDMCell(params[:subject_width] - 15, 5,
722 params[:pdf].RDMCell(params[:subject_width] - 15, 5,
698 (" " * params[:indent]) +
723 (" " * params[:indent]) +
699 subject.to_s.sub(/^(.{#{char_limit}}[^\s]*\s).*$/, '\1 (...)'),
724 subject.to_s.sub(/^(.{#{char_limit}}[^\s]*\s).*$/, '\1 (...)'),
700 "LR")
725 "LR")
701 params[:pdf].SetY(params[:top])
726 params[:pdf].SetY(params[:top])
702 params[:pdf].SetX(params[:subject_width])
727 params[:pdf].SetX(params[:subject_width])
703 params[:pdf].RDMCell(params[:g_width], 5, "", "LR")
728 params[:pdf].RDMCell(params[:g_width], 5, "", "LR")
704 end
729 end
705
730
706 def image_subject(params, subject, options={})
731 def image_subject(params, subject, options={})
707 params[:image].fill('black')
732 params[:image].fill('black')
708 params[:image].stroke('transparent')
733 params[:image].stroke('transparent')
709 params[:image].stroke_width(1)
734 params[:image].stroke_width(1)
710 params[:image].text(params[:indent], params[:top] + 2, subject)
735 params[:image].text(params[:indent], params[:top] + 2, subject)
711 end
736 end
712
737
713 def issue_relations(issue)
738 def issue_relations(issue)
714 rels = {}
739 rels = {}
715 if relations[issue.id]
740 if relations[issue.id]
716 relations[issue.id].each do |relation|
741 relations[issue.id].each do |relation|
717 (rels[relation.relation_type] ||= []) << relation.issue_to_id
742 (rels[relation.relation_type] ||= []) << relation.issue_to_id
718 end
743 end
719 end
744 end
720 rels
745 rels
721 end
746 end
722
747
723 def html_task(params, coords, markers, label, object)
748 def html_task(params, coords, markers, label, object)
724 output = ''
749 output = ''
725
750
726 css = "task " + case object
751 css = "task " + case object
727 when Project
752 when Project
728 "project"
753 "project"
729 when Version
754 when Version
730 "version"
755 "version"
731 when Issue
756 when Issue
732 object.leaf? ? 'leaf' : 'parent'
757 object.leaf? ? 'leaf' : 'parent'
733 else
758 else
734 ""
759 ""
735 end
760 end
736
761
737 # Renders the task bar, with progress and late
762 # Renders the task bar, with progress and late
738 if coords[:bar_start] && coords[:bar_end]
763 if coords[:bar_start] && coords[:bar_end]
739 width = coords[:bar_end] - coords[:bar_start] - 2
764 width = coords[:bar_end] - coords[:bar_start] - 2
740 style = ""
765 style = ""
741 style << "top:#{params[:top]}px;"
766 style << "top:#{params[:top]}px;"
742 style << "left:#{coords[:bar_start]}px;"
767 style << "left:#{coords[:bar_start]}px;"
743 style << "width:#{width}px;"
768 style << "width:#{width}px;"
744 html_id = "task-todo-issue-#{object.id}" if object.is_a?(Issue)
769 html_id = "task-todo-issue-#{object.id}" if object.is_a?(Issue)
745 html_id = "task-todo-version-#{object.id}" if object.is_a?(Version)
770 html_id = "task-todo-version-#{object.id}" if object.is_a?(Version)
746 content_opt = {:style => style,
771 content_opt = {:style => style,
747 :class => "#{css} task_todo",
772 :class => "#{css} task_todo",
748 :id => html_id}
773 :id => html_id}
749 if object.is_a?(Issue)
774 if object.is_a?(Issue)
750 rels = issue_relations(object)
775 rels = issue_relations(object)
751 if rels.present?
776 if rels.present?
752 content_opt[:data] = {"rels" => rels.to_json}
777 content_opt[:data] = {"rels" => rels.to_json}
753 end
778 end
754 end
779 end
755 output << view.content_tag(:div, '&nbsp;'.html_safe, content_opt)
780 output << view.content_tag(:div, '&nbsp;'.html_safe, content_opt)
756 if coords[:bar_late_end]
781 if coords[:bar_late_end]
757 width = coords[:bar_late_end] - coords[:bar_start] - 2
782 width = coords[:bar_late_end] - coords[:bar_start] - 2
758 style = ""
783 style = ""
759 style << "top:#{params[:top]}px;"
784 style << "top:#{params[:top]}px;"
760 style << "left:#{coords[:bar_start]}px;"
785 style << "left:#{coords[:bar_start]}px;"
761 style << "width:#{width}px;"
786 style << "width:#{width}px;"
762 output << view.content_tag(:div, '&nbsp;'.html_safe,
787 output << view.content_tag(:div, '&nbsp;'.html_safe,
763 :style => style,
788 :style => style,
764 :class => "#{css} task_late")
789 :class => "#{css} task_late")
765 end
790 end
766 if coords[:bar_progress_end]
791 if coords[:bar_progress_end]
767 width = coords[:bar_progress_end] - coords[:bar_start] - 2
792 width = coords[:bar_progress_end] - coords[:bar_start] - 2
768 style = ""
793 style = ""
769 style << "top:#{params[:top]}px;"
794 style << "top:#{params[:top]}px;"
770 style << "left:#{coords[:bar_start]}px;"
795 style << "left:#{coords[:bar_start]}px;"
771 style << "width:#{width}px;"
796 style << "width:#{width}px;"
772 html_id = "task-done-issue-#{object.id}" if object.is_a?(Issue)
797 html_id = "task-done-issue-#{object.id}" if object.is_a?(Issue)
773 html_id = "task-done-version-#{object.id}" if object.is_a?(Version)
798 html_id = "task-done-version-#{object.id}" if object.is_a?(Version)
774 output << view.content_tag(:div, '&nbsp;'.html_safe,
799 output << view.content_tag(:div, '&nbsp;'.html_safe,
775 :style => style,
800 :style => style,
776 :class => "#{css} task_done",
801 :class => "#{css} task_done",
777 :id => html_id)
802 :id => html_id)
778 end
803 end
779 end
804 end
780 # Renders the markers
805 # Renders the markers
781 if markers
806 if markers
782 if coords[:start]
807 if coords[:start]
783 style = ""
808 style = ""
784 style << "top:#{params[:top]}px;"
809 style << "top:#{params[:top]}px;"
785 style << "left:#{coords[:start]}px;"
810 style << "left:#{coords[:start]}px;"
786 style << "width:15px;"
811 style << "width:15px;"
787 output << view.content_tag(:div, '&nbsp;'.html_safe,
812 output << view.content_tag(:div, '&nbsp;'.html_safe,
788 :style => style,
813 :style => style,
789 :class => "#{css} marker starting")
814 :class => "#{css} marker starting")
790 end
815 end
791 if coords[:end]
816 if coords[:end]
792 style = ""
817 style = ""
793 style << "top:#{params[:top]}px;"
818 style << "top:#{params[:top]}px;"
794 style << "left:#{coords[:end] + params[:zoom]}px;"
819 style << "left:#{coords[:end] + params[:zoom]}px;"
795 style << "width:15px;"
820 style << "width:15px;"
796 output << view.content_tag(:div, '&nbsp;'.html_safe,
821 output << view.content_tag(:div, '&nbsp;'.html_safe,
797 :style => style,
822 :style => style,
798 :class => "#{css} marker ending")
823 :class => "#{css} marker ending")
799 end
824 end
800 end
825 end
801 # Renders the label on the right
826 # Renders the label on the right
802 if label
827 if label
803 style = ""
828 style = ""
804 style << "top:#{params[:top]}px;"
829 style << "top:#{params[:top]}px;"
805 style << "left:#{(coords[:bar_end] || 0) + 8}px;"
830 style << "left:#{(coords[:bar_end] || 0) + 8}px;"
806 style << "width:15px;"
831 style << "width:15px;"
807 output << view.content_tag(:div, label,
832 output << view.content_tag(:div, label,
808 :style => style,
833 :style => style,
809 :class => "#{css} label")
834 :class => "#{css} label")
810 end
835 end
811 # Renders the tooltip
836 # Renders the tooltip
812 if object.is_a?(Issue) && coords[:bar_start] && coords[:bar_end]
837 if object.is_a?(Issue) && coords[:bar_start] && coords[:bar_end]
813 s = view.content_tag(:span,
838 s = view.content_tag(:span,
814 view.render_issue_tooltip(object).html_safe,
839 view.render_issue_tooltip(object).html_safe,
815 :class => "tip")
840 :class => "tip")
816 style = ""
841 style = ""
817 style << "position: absolute;"
842 style << "position: absolute;"
818 style << "top:#{params[:top]}px;"
843 style << "top:#{params[:top]}px;"
819 style << "left:#{coords[:bar_start]}px;"
844 style << "left:#{coords[:bar_start]}px;"
820 style << "width:#{coords[:bar_end] - coords[:bar_start]}px;"
845 style << "width:#{coords[:bar_end] - coords[:bar_start]}px;"
821 style << "height:12px;"
846 style << "height:12px;"
822 output << view.content_tag(:div, s.html_safe,
847 output << view.content_tag(:div, s.html_safe,
823 :style => style,
848 :style => style,
824 :class => "tooltip")
849 :class => "tooltip")
825 end
850 end
826 @lines << output
851 @lines << output
827 output
852 output
828 end
853 end
829
854
830 def pdf_task(params, coords, markers, label, object)
855 def pdf_task(params, coords, markers, label, object)
831 cell_height_ratio = params[:pdf].get_cell_height_ratio()
856 cell_height_ratio = params[:pdf].get_cell_height_ratio()
832 params[:pdf].set_cell_height_ratio(0.1)
857 params[:pdf].set_cell_height_ratio(0.1)
833
858
834 height = 2
859 height = 2
835 height /= 2 if markers
860 height /= 2 if markers
836 # Renders the task bar, with progress and late
861 # Renders the task bar, with progress and late
837 if coords[:bar_start] && coords[:bar_end]
862 if coords[:bar_start] && coords[:bar_end]
838 params[:pdf].SetY(params[:top] + 1.5)
863 params[:pdf].SetY(params[:top] + 1.5)
839 params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
864 params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
840 params[:pdf].SetFillColor(200, 200, 200)
865 params[:pdf].SetFillColor(200, 200, 200)
841 params[:pdf].RDMCell(coords[:bar_end] - coords[:bar_start], height, "", 0, 0, "", 1)
866 params[:pdf].RDMCell(coords[:bar_end] - coords[:bar_start], height, "", 0, 0, "", 1)
842 if coords[:bar_late_end]
867 if coords[:bar_late_end]
843 params[:pdf].SetY(params[:top] + 1.5)
868 params[:pdf].SetY(params[:top] + 1.5)
844 params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
869 params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
845 params[:pdf].SetFillColor(255, 100, 100)
870 params[:pdf].SetFillColor(255, 100, 100)
846 params[:pdf].RDMCell(coords[:bar_late_end] - coords[:bar_start], height, "", 0, 0, "", 1)
871 params[:pdf].RDMCell(coords[:bar_late_end] - coords[:bar_start], height, "", 0, 0, "", 1)
847 end
872 end
848 if coords[:bar_progress_end]
873 if coords[:bar_progress_end]
849 params[:pdf].SetY(params[:top] + 1.5)
874 params[:pdf].SetY(params[:top] + 1.5)
850 params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
875 params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
851 params[:pdf].SetFillColor(90, 200, 90)
876 params[:pdf].SetFillColor(90, 200, 90)
852 params[:pdf].RDMCell(coords[:bar_progress_end] - coords[:bar_start], height, "", 0, 0, "", 1)
877 params[:pdf].RDMCell(coords[:bar_progress_end] - coords[:bar_start], height, "", 0, 0, "", 1)
853 end
878 end
854 end
879 end
855 # Renders the markers
880 # Renders the markers
856 if markers
881 if markers
857 if coords[:start]
882 if coords[:start]
858 params[:pdf].SetY(params[:top] + 1)
883 params[:pdf].SetY(params[:top] + 1)
859 params[:pdf].SetX(params[:subject_width] + coords[:start] - 1)
884 params[:pdf].SetX(params[:subject_width] + coords[:start] - 1)
860 params[:pdf].SetFillColor(50, 50, 200)
885 params[:pdf].SetFillColor(50, 50, 200)
861 params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
886 params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
862 end
887 end
863 if coords[:end]
888 if coords[:end]
864 params[:pdf].SetY(params[:top] + 1)
889 params[:pdf].SetY(params[:top] + 1)
865 params[:pdf].SetX(params[:subject_width] + coords[:end] - 1)
890 params[:pdf].SetX(params[:subject_width] + coords[:end] - 1)
866 params[:pdf].SetFillColor(50, 50, 200)
891 params[:pdf].SetFillColor(50, 50, 200)
867 params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
892 params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
868 end
893 end
869 end
894 end
870 # Renders the label on the right
895 # Renders the label on the right
871 if label
896 if label
872 params[:pdf].SetX(params[:subject_width] + (coords[:bar_end] || 0) + 5)
897 params[:pdf].SetX(params[:subject_width] + (coords[:bar_end] || 0) + 5)
873 params[:pdf].RDMCell(30, 2, label)
898 params[:pdf].RDMCell(30, 2, label)
874 end
899 end
875
900
876 params[:pdf].set_cell_height_ratio(cell_height_ratio)
901 params[:pdf].set_cell_height_ratio(cell_height_ratio)
877 end
902 end
878
903
879 def image_task(params, coords, markers, label, object)
904 def image_task(params, coords, markers, label, object)
880 height = 6
905 height = 6
881 height /= 2 if markers
906 height /= 2 if markers
882 # Renders the task bar, with progress and late
907 # Renders the task bar, with progress and late
883 if coords[:bar_start] && coords[:bar_end]
908 if coords[:bar_start] && coords[:bar_end]
884 params[:image].fill('#aaa')
909 params[:image].fill('#aaa')
885 params[:image].rectangle(params[:subject_width] + coords[:bar_start],
910 params[:image].rectangle(params[:subject_width] + coords[:bar_start],
886 params[:top],
911 params[:top],
887 params[:subject_width] + coords[:bar_end],
912 params[:subject_width] + coords[:bar_end],
888 params[:top] - height)
913 params[:top] - height)
889 if coords[:bar_late_end]
914 if coords[:bar_late_end]
890 params[:image].fill('#f66')
915 params[:image].fill('#f66')
891 params[:image].rectangle(params[:subject_width] + coords[:bar_start],
916 params[:image].rectangle(params[:subject_width] + coords[:bar_start],
892 params[:top],
917 params[:top],
893 params[:subject_width] + coords[:bar_late_end],
918 params[:subject_width] + coords[:bar_late_end],
894 params[:top] - height)
919 params[:top] - height)
895 end
920 end
896 if coords[:bar_progress_end]
921 if coords[:bar_progress_end]
897 params[:image].fill('#00c600')
922 params[:image].fill('#00c600')
898 params[:image].rectangle(params[:subject_width] + coords[:bar_start],
923 params[:image].rectangle(params[:subject_width] + coords[:bar_start],
899 params[:top],
924 params[:top],
900 params[:subject_width] + coords[:bar_progress_end],
925 params[:subject_width] + coords[:bar_progress_end],
901 params[:top] - height)
926 params[:top] - height)
902 end
927 end
903 end
928 end
904 # Renders the markers
929 # Renders the markers
905 if markers
930 if markers
906 if coords[:start]
931 if coords[:start]
907 x = params[:subject_width] + coords[:start]
932 x = params[:subject_width] + coords[:start]
908 y = params[:top] - height / 2
933 y = params[:top] - height / 2
909 params[:image].fill('blue')
934 params[:image].fill('blue')
910 params[:image].polygon(x - 4, y, x, y - 4, x + 4, y, x, y + 4)
935 params[:image].polygon(x - 4, y, x, y - 4, x + 4, y, x, y + 4)
911 end
936 end
912 if coords[:end]
937 if coords[:end]
913 x = params[:subject_width] + coords[:end] + params[:zoom]
938 x = params[:subject_width] + coords[:end] + params[:zoom]
914 y = params[:top] - height / 2
939 y = params[:top] - height / 2
915 params[:image].fill('blue')
940 params[:image].fill('blue')
916 params[:image].polygon(x - 4, y, x, y - 4, x + 4, y, x, y + 4)
941 params[:image].polygon(x - 4, y, x, y - 4, x + 4, y, x, y + 4)
917 end
942 end
918 end
943 end
919 # Renders the label on the right
944 # Renders the label on the right
920 if label
945 if label
921 params[:image].fill('black')
946 params[:image].fill('black')
922 params[:image].text(params[:subject_width] + (coords[:bar_end] || 0) + 5,
947 params[:image].text(params[:subject_width] + (coords[:bar_end] || 0) + 5,
923 params[:top] + 1,
948 params[:top] + 1,
924 label)
949 label)
925 end
950 end
926 end
951 end
927 end
952 end
928 end
953 end
929 end
954 end
@@ -1,1245 +1,1245
1 html {overflow-y:scroll;}
1 html {overflow-y:scroll;}
2 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
2 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
3
3
4 h1, h2, h3, h4 {font-family: "Trebuchet MS", Verdana, sans-serif;padding: 2px 10px 1px 0px;margin: 0 0 10px 0;}
4 h1, h2, h3, h4 {font-family: "Trebuchet MS", Verdana, sans-serif;padding: 2px 10px 1px 0px;margin: 0 0 10px 0;}
5 #content h1, h2, h3, h4 {color: #555;}
5 #content h1, h2, h3, h4 {color: #555;}
6 h2, .wiki h1 {font-size: 20px;}
6 h2, .wiki h1 {font-size: 20px;}
7 h3, .wiki h2 {font-size: 16px;}
7 h3, .wiki h2 {font-size: 16px;}
8 h4, .wiki h3 {font-size: 13px;}
8 h4, .wiki h3 {font-size: 13px;}
9 h4 {border-bottom: 1px dotted #bbb;}
9 h4 {border-bottom: 1px dotted #bbb;}
10 pre, code {font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
10 pre, code {font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
11
11
12 /***** Layout *****/
12 /***** Layout *****/
13 #wrapper {background: white;}
13 #wrapper {background: white;}
14
14
15 #top-menu {background: #3E5B76; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
15 #top-menu {background: #3E5B76; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
16 #top-menu ul {margin: 0; padding: 0;}
16 #top-menu ul {margin: 0; padding: 0;}
17 #top-menu li {
17 #top-menu li {
18 float:left;
18 float:left;
19 list-style-type:none;
19 list-style-type:none;
20 margin: 0px 0px 0px 0px;
20 margin: 0px 0px 0px 0px;
21 padding: 0px 0px 0px 0px;
21 padding: 0px 0px 0px 0px;
22 white-space:nowrap;
22 white-space:nowrap;
23 }
23 }
24 #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
24 #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
25 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
25 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
26
26
27 #account {float:right;}
27 #account {float:right;}
28
28
29 #header {min-height:5.3em;margin:0;background-color:#628DB6;color:#f8f8f8; padding: 4px 8px 20px 6px; position:relative;}
29 #header {min-height:5.3em;margin:0;background-color:#628DB6;color:#f8f8f8; padding: 4px 8px 20px 6px; position:relative;}
30 #header a {color:#f8f8f8;}
30 #header a {color:#f8f8f8;}
31 #header h1 a.ancestor { font-size: 80%; }
31 #header h1 a.ancestor { font-size: 80%; }
32 #quick-search {float:right;}
32 #quick-search {float:right;}
33
33
34 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
34 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
35 #main-menu ul {margin: 0; padding: 0;}
35 #main-menu ul {margin: 0; padding: 0;}
36 #main-menu li {
36 #main-menu li {
37 float:left;
37 float:left;
38 list-style-type:none;
38 list-style-type:none;
39 margin: 0px 2px 0px 0px;
39 margin: 0px 2px 0px 0px;
40 padding: 0px 0px 0px 0px;
40 padding: 0px 0px 0px 0px;
41 white-space:nowrap;
41 white-space:nowrap;
42 }
42 }
43 #main-menu li a {
43 #main-menu li a {
44 display: block;
44 display: block;
45 color: #fff;
45 color: #fff;
46 text-decoration: none;
46 text-decoration: none;
47 font-weight: bold;
47 font-weight: bold;
48 margin: 0;
48 margin: 0;
49 padding: 4px 10px 4px 10px;
49 padding: 4px 10px 4px 10px;
50 }
50 }
51 #main-menu li a:hover {background:#759FCF; color:#fff;}
51 #main-menu li a:hover {background:#759FCF; color:#fff;}
52 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
52 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
53
53
54 #admin-menu ul {margin: 0; padding: 0;}
54 #admin-menu ul {margin: 0; padding: 0;}
55 #admin-menu li {margin: 0; padding: 0 0 6px 0; list-style-type:none;}
55 #admin-menu li {margin: 0; padding: 0 0 6px 0; list-style-type:none;}
56
56
57 #admin-menu a { background-position: 0% 40%; background-repeat: no-repeat; padding-left: 20px; padding-top: 2px; padding-bottom: 3px;}
57 #admin-menu a { background-position: 0% 40%; background-repeat: no-repeat; padding-left: 20px; padding-top: 2px; padding-bottom: 3px;}
58 #admin-menu a.projects { background-image: url(../images/projects.png); }
58 #admin-menu a.projects { background-image: url(../images/projects.png); }
59 #admin-menu a.users { background-image: url(../images/user.png); }
59 #admin-menu a.users { background-image: url(../images/user.png); }
60 #admin-menu a.groups { background-image: url(../images/group.png); }
60 #admin-menu a.groups { background-image: url(../images/group.png); }
61 #admin-menu a.roles { background-image: url(../images/database_key.png); }
61 #admin-menu a.roles { background-image: url(../images/database_key.png); }
62 #admin-menu a.trackers { background-image: url(../images/ticket.png); }
62 #admin-menu a.trackers { background-image: url(../images/ticket.png); }
63 #admin-menu a.issue_statuses { background-image: url(../images/ticket_edit.png); }
63 #admin-menu a.issue_statuses { background-image: url(../images/ticket_edit.png); }
64 #admin-menu a.workflows { background-image: url(../images/ticket_go.png); }
64 #admin-menu a.workflows { background-image: url(../images/ticket_go.png); }
65 #admin-menu a.custom_fields { background-image: url(../images/textfield.png); }
65 #admin-menu a.custom_fields { background-image: url(../images/textfield.png); }
66 #admin-menu a.enumerations { background-image: url(../images/text_list_bullets.png); }
66 #admin-menu a.enumerations { background-image: url(../images/text_list_bullets.png); }
67 #admin-menu a.settings { background-image: url(../images/changeset.png); }
67 #admin-menu a.settings { background-image: url(../images/changeset.png); }
68 #admin-menu a.plugins { background-image: url(../images/plugin.png); }
68 #admin-menu a.plugins { background-image: url(../images/plugin.png); }
69 #admin-menu a.info { background-image: url(../images/help.png); }
69 #admin-menu a.info { background-image: url(../images/help.png); }
70 #admin-menu a.server_authentication { background-image: url(../images/server_key.png); }
70 #admin-menu a.server_authentication { background-image: url(../images/server_key.png); }
71
71
72 #main {background-color:#EEEEEE;}
72 #main {background-color:#EEEEEE;}
73
73
74 #sidebar{ float: right; width: 22%; position: relative; z-index: 9; padding: 0; margin: 0;}
74 #sidebar{ float: right; width: 22%; position: relative; z-index: 9; padding: 0; margin: 0;}
75 * html #sidebar{ width: 22%; }
75 * html #sidebar{ width: 22%; }
76 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
76 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
77 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
77 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
78 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
78 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
79 #sidebar .contextual { margin-right: 1em; }
79 #sidebar .contextual { margin-right: 1em; }
80 #sidebar ul {margin: 0; padding: 0;}
80 #sidebar ul {margin: 0; padding: 0;}
81 #sidebar ul li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;}
81 #sidebar ul li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;}
82
82
83 #content { width: 75%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
83 #content { width: 75%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
84 * html #content{ width: 75%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
84 * html #content{ width: 75%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
85 html>body #content { min-height: 600px; }
85 html>body #content { min-height: 600px; }
86 * html body #content { height: 600px; } /* IE */
86 * html body #content { height: 600px; } /* IE */
87
87
88 #main.nosidebar #sidebar{ display: none; }
88 #main.nosidebar #sidebar{ display: none; }
89 #main.nosidebar #content{ width: auto; border-right: 0; }
89 #main.nosidebar #content{ width: auto; border-right: 0; }
90
90
91 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
91 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
92
92
93 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
93 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
94 #login-form table td {padding: 6px;}
94 #login-form table td {padding: 6px;}
95 #login-form label {font-weight: bold;}
95 #login-form label {font-weight: bold;}
96 #login-form input#username, #login-form input#password { width: 300px; }
96 #login-form input#username, #login-form input#password { width: 300px; }
97
97
98 div.modal { border-radius:5px; background:#fff; z-index:50; padding:4px;}
98 div.modal { border-radius:5px; background:#fff; z-index:50; padding:4px;}
99 div.modal h3.title {display:none;}
99 div.modal h3.title {display:none;}
100 div.modal p.buttons {text-align:right; margin-bottom:0;}
100 div.modal p.buttons {text-align:right; margin-bottom:0;}
101 div.modal .box p {margin: 0.3em 0;}
101 div.modal .box p {margin: 0.3em 0;}
102
102
103 input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; }
103 input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; }
104
104
105 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
105 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
106
106
107 /***** Links *****/
107 /***** Links *****/
108 a, a:link, a:visited{ color: #169; text-decoration: none; }
108 a, a:link, a:visited{ color: #169; text-decoration: none; }
109 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
109 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
110 a img{ border: 0; }
110 a img{ border: 0; }
111
111
112 a.issue.closed, a.issue.closed:link, a.issue.closed:visited { color: #999; text-decoration: line-through; }
112 a.issue.closed, a.issue.closed:link, a.issue.closed:visited { color: #999; text-decoration: line-through; }
113 a.project.closed, a.project.closed:link, a.project.closed:visited { color: #999; }
113 a.project.closed, a.project.closed:link, a.project.closed:visited { color: #999; }
114 a.user.locked, a.user.locked:link, a.user.locked:visited {color: #999;}
114 a.user.locked, a.user.locked:link, a.user.locked:visited {color: #999;}
115
115
116 #sidebar a.selected {line-height:1.7em; padding:1px 3px 2px 2px; margin-left:-2px; background-color:#9DB9D5; color:#fff; border-radius:2px;}
116 #sidebar a.selected {line-height:1.7em; padding:1px 3px 2px 2px; margin-left:-2px; background-color:#9DB9D5; color:#fff; border-radius:2px;}
117 #sidebar a.selected:hover {text-decoration:none;}
117 #sidebar a.selected:hover {text-decoration:none;}
118 #admin-menu a {line-height:1.7em;}
118 #admin-menu a {line-height:1.7em;}
119 #admin-menu a.selected {padding-left: 20px !important; background-position: 2px 40%;}
119 #admin-menu a.selected {padding-left: 20px !important; background-position: 2px 40%;}
120
120
121 a.collapsible {padding-left: 12px; background: url(../images/arrow_expanded.png) no-repeat -3px 40%;}
121 a.collapsible {padding-left: 12px; background: url(../images/arrow_expanded.png) no-repeat -3px 40%;}
122 a.collapsible.collapsed {background: url(../images/arrow_collapsed.png) no-repeat -5px 40%;}
122 a.collapsible.collapsed {background: url(../images/arrow_collapsed.png) no-repeat -5px 40%;}
123
123
124 a#toggle-completed-versions {color:#999;}
124 a#toggle-completed-versions {color:#999;}
125 /***** Tables *****/
125 /***** Tables *****/
126 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
126 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
127 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
127 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
128 table.list td {text-align:center; vertical-align:top; padding-right:10px;}
128 table.list td {text-align:center; vertical-align:top; padding-right:10px;}
129 table.list td.id { width: 2%; text-align: center;}
129 table.list td.id { width: 2%; text-align: center;}
130 table.list td.name, table.list td.description, table.list td.subject, table.list td.comments, table.list td.roles {text-align: left;}
130 table.list td.name, table.list td.description, table.list td.subject, table.list td.comments, table.list td.roles {text-align: left;}
131 table.list td.tick {width:15%}
131 table.list td.tick {width:15%}
132 table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
132 table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
133 table.list td.checkbox input {padding:0px;}
133 table.list td.checkbox input {padding:0px;}
134 table.list td.buttons { width: 15%; white-space:nowrap; text-align: right; }
134 table.list td.buttons { width: 15%; white-space:nowrap; text-align: right; }
135 table.list td.buttons a { padding-right: 0.6em; }
135 table.list td.buttons a { padding-right: 0.6em; }
136 table.list td.buttons img {vertical-align:middle;}
136 table.list td.buttons img {vertical-align:middle;}
137 table.list td.reorder {width:15%; white-space:nowrap; text-align:center; }
137 table.list td.reorder {width:15%; white-space:nowrap; text-align:center; }
138 table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
138 table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
139
139
140 tr.project td.name a { white-space:nowrap; }
140 tr.project td.name a { white-space:nowrap; }
141 tr.project.closed, tr.project.archived { color: #aaa; }
141 tr.project.closed, tr.project.archived { color: #aaa; }
142 tr.project.closed a, tr.project.archived a { color: #aaa; }
142 tr.project.closed a, tr.project.archived a { color: #aaa; }
143
143
144 tr.project.idnt td.name span {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
144 tr.project.idnt td.name span {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
145 tr.project.idnt-1 td.name {padding-left: 0.5em;}
145 tr.project.idnt-1 td.name {padding-left: 0.5em;}
146 tr.project.idnt-2 td.name {padding-left: 2em;}
146 tr.project.idnt-2 td.name {padding-left: 2em;}
147 tr.project.idnt-3 td.name {padding-left: 3.5em;}
147 tr.project.idnt-3 td.name {padding-left: 3.5em;}
148 tr.project.idnt-4 td.name {padding-left: 5em;}
148 tr.project.idnt-4 td.name {padding-left: 5em;}
149 tr.project.idnt-5 td.name {padding-left: 6.5em;}
149 tr.project.idnt-5 td.name {padding-left: 6.5em;}
150 tr.project.idnt-6 td.name {padding-left: 8em;}
150 tr.project.idnt-6 td.name {padding-left: 8em;}
151 tr.project.idnt-7 td.name {padding-left: 9.5em;}
151 tr.project.idnt-7 td.name {padding-left: 9.5em;}
152 tr.project.idnt-8 td.name {padding-left: 11em;}
152 tr.project.idnt-8 td.name {padding-left: 11em;}
153 tr.project.idnt-9 td.name {padding-left: 12.5em;}
153 tr.project.idnt-9 td.name {padding-left: 12.5em;}
154
154
155 tr.issue { text-align: center; white-space: nowrap; }
155 tr.issue { text-align: center; white-space: nowrap; }
156 tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text, tr.issue td.relations, tr.issue td.parent { white-space: normal; }
156 tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text, tr.issue td.relations, tr.issue td.parent { white-space: normal; }
157 tr.issue td.relations { text-align: left; }
157 tr.issue td.relations { text-align: left; }
158 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
158 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
159 tr.issue td.relations span {white-space: nowrap;}
159 tr.issue td.relations span {white-space: nowrap;}
160 table.issues td.description {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;}
160 table.issues td.description {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;}
161 table.issues td.description pre {white-space:normal;}
161 table.issues td.description pre {white-space:normal;}
162
162
163 tr.issue.idnt td.subject a {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
163 tr.issue.idnt td.subject a {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
164 tr.issue.idnt-1 td.subject {padding-left: 0.5em;}
164 tr.issue.idnt-1 td.subject {padding-left: 0.5em;}
165 tr.issue.idnt-2 td.subject {padding-left: 2em;}
165 tr.issue.idnt-2 td.subject {padding-left: 2em;}
166 tr.issue.idnt-3 td.subject {padding-left: 3.5em;}
166 tr.issue.idnt-3 td.subject {padding-left: 3.5em;}
167 tr.issue.idnt-4 td.subject {padding-left: 5em;}
167 tr.issue.idnt-4 td.subject {padding-left: 5em;}
168 tr.issue.idnt-5 td.subject {padding-left: 6.5em;}
168 tr.issue.idnt-5 td.subject {padding-left: 6.5em;}
169 tr.issue.idnt-6 td.subject {padding-left: 8em;}
169 tr.issue.idnt-6 td.subject {padding-left: 8em;}
170 tr.issue.idnt-7 td.subject {padding-left: 9.5em;}
170 tr.issue.idnt-7 td.subject {padding-left: 9.5em;}
171 tr.issue.idnt-8 td.subject {padding-left: 11em;}
171 tr.issue.idnt-8 td.subject {padding-left: 11em;}
172 tr.issue.idnt-9 td.subject {padding-left: 12.5em;}
172 tr.issue.idnt-9 td.subject {padding-left: 12.5em;}
173
173
174 table.issue-report {table-layout:fixed;}
174 table.issue-report {table-layout:fixed;}
175
175
176 tr.entry { border: 1px solid #f8f8f8; }
176 tr.entry { border: 1px solid #f8f8f8; }
177 tr.entry td { white-space: nowrap; }
177 tr.entry td { white-space: nowrap; }
178 tr.entry td.filename {width:30%; text-align:left;}
178 tr.entry td.filename {width:30%; text-align:left;}
179 tr.entry td.filename_no_report {width:70%; text-align:left;}
179 tr.entry td.filename_no_report {width:70%; text-align:left;}
180 tr.entry td.size { text-align: right; font-size: 90%; }
180 tr.entry td.size { text-align: right; font-size: 90%; }
181 tr.entry td.revision, tr.entry td.author { text-align: center; }
181 tr.entry td.revision, tr.entry td.author { text-align: center; }
182 tr.entry td.age { text-align: right; }
182 tr.entry td.age { text-align: right; }
183 tr.entry.file td.filename a { margin-left: 16px; }
183 tr.entry.file td.filename a { margin-left: 16px; }
184 tr.entry.file td.filename_no_report a { margin-left: 16px; }
184 tr.entry.file td.filename_no_report a { margin-left: 16px; }
185
185
186 tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
186 tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
187 tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
187 tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
188
188
189 tr.changeset { height: 20px }
189 tr.changeset { height: 20px }
190 tr.changeset ul, ol { margin-top: 0px; margin-bottom: 0px; }
190 tr.changeset ul, ol { margin-top: 0px; margin-bottom: 0px; }
191 tr.changeset td.revision_graph { width: 15%; background-color: #fffffb; }
191 tr.changeset td.revision_graph { width: 15%; background-color: #fffffb; }
192 tr.changeset td.author { text-align: center; width: 15%; white-space:nowrap;}
192 tr.changeset td.author { text-align: center; width: 15%; white-space:nowrap;}
193 tr.changeset td.committed_on { text-align: center; width: 15%; white-space:nowrap;}
193 tr.changeset td.committed_on { text-align: center; width: 15%; white-space:nowrap;}
194
194
195 table.files tbody th {text-align:left;}
195 table.files tbody th {text-align:left;}
196 table.files tr.file td.filename { text-align: left; padding-left: 24px; }
196 table.files tr.file td.filename { text-align: left; padding-left: 24px; }
197 table.files tr.file td.digest { font-size: 80%; }
197 table.files tr.file td.digest { font-size: 80%; }
198
198
199 table.members td.roles, table.memberships td.roles { width: 45%; }
199 table.members td.roles, table.memberships td.roles { width: 45%; }
200
200
201 tr.message { height: 2.6em; }
201 tr.message { height: 2.6em; }
202 tr.message td.subject { padding-left: 20px; }
202 tr.message td.subject { padding-left: 20px; }
203 tr.message td.created_on { white-space: nowrap; }
203 tr.message td.created_on { white-space: nowrap; }
204 tr.message td.last_message { font-size: 80%; white-space: nowrap; }
204 tr.message td.last_message { font-size: 80%; white-space: nowrap; }
205 tr.message.locked td.subject { background: url(../images/locked.png) no-repeat 0 1px; }
205 tr.message.locked td.subject { background: url(../images/locked.png) no-repeat 0 1px; }
206 tr.message.sticky td.subject { background: url(../images/bullet_go.png) no-repeat 0 1px; font-weight: bold; }
206 tr.message.sticky td.subject { background: url(../images/bullet_go.png) no-repeat 0 1px; font-weight: bold; }
207
207
208 tr.version.closed, tr.version.closed a { color: #999; }
208 tr.version.closed, tr.version.closed a { color: #999; }
209 tr.version td.name { padding-left: 20px; }
209 tr.version td.name { padding-left: 20px; }
210 tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%; }
210 tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%; }
211 tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
211 tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
212
212
213 tr.user td {width:13%;white-space: nowrap;}
213 tr.user td {width:13%;white-space: nowrap;}
214 td.username, td.firstname, td.lastname, td.email {text-align:left !important;}
214 td.username, td.firstname, td.lastname, td.email {text-align:left !important;}
215 tr.user td.email { width:18%; }
215 tr.user td.email { width:18%; }
216 tr.user.locked, tr.user.registered { color: #aaa; }
216 tr.user.locked, tr.user.registered { color: #aaa; }
217 tr.user.locked a, tr.user.registered a { color: #aaa; }
217 tr.user.locked a, tr.user.registered a { color: #aaa; }
218
218
219 table.permissions td.role {color:#999;font-size:90%;font-weight:normal !important;text-align:center;vertical-align:bottom;}
219 table.permissions td.role {color:#999;font-size:90%;font-weight:normal !important;text-align:center;vertical-align:bottom;}
220
220
221 tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
221 tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
222
222
223 tr.time-entry { text-align: center; white-space: nowrap; }
223 tr.time-entry { text-align: center; white-space: nowrap; }
224 tr.time-entry td.issue, tr.time-entry td.comments, tr.time-entry td.subject, tr.time-entry td.activity { text-align: left; white-space: normal; }
224 tr.time-entry td.issue, tr.time-entry td.comments, tr.time-entry td.subject, tr.time-entry td.activity { text-align: left; white-space: normal; }
225 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
225 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
226 td.hours .hours-dec { font-size: 0.9em; }
226 td.hours .hours-dec { font-size: 0.9em; }
227
227
228 table.plugins td { vertical-align: middle; }
228 table.plugins td { vertical-align: middle; }
229 table.plugins td.configure { text-align: right; padding-right: 1em; }
229 table.plugins td.configure { text-align: right; padding-right: 1em; }
230 table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
230 table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
231 table.plugins span.description { display: block; font-size: 0.9em; }
231 table.plugins span.description { display: block; font-size: 0.9em; }
232 table.plugins span.url { display: block; font-size: 0.9em; }
232 table.plugins span.url { display: block; font-size: 0.9em; }
233
233
234 table.list tbody tr.group td { padding: 0.8em 0 0.5em 0.3em; font-weight: bold; border-bottom: 1px solid #ccc; text-align:left; }
234 table.list tbody tr.group td { padding: 0.8em 0 0.5em 0.3em; font-weight: bold; border-bottom: 1px solid #ccc; text-align:left; }
235 table.list tbody tr.group span.count {position:relative; top:-1px; color:#fff; font-size:10px; background:#9DB9D5; padding:0px 6px 1px 6px; border-radius:3px; margin-left:4px;}
235 table.list tbody tr.group span.count {position:relative; top:-1px; color:#fff; font-size:10px; background:#9DB9D5; padding:0px 6px 1px 6px; border-radius:3px; margin-left:4px;}
236 tr.group a.toggle-all { color: #aaa; font-size: 80%; font-weight: normal; display:none;}
236 tr.group a.toggle-all { color: #aaa; font-size: 80%; font-weight: normal; display:none;}
237 tr.group:hover a.toggle-all { display:inline;}
237 tr.group:hover a.toggle-all { display:inline;}
238 a.toggle-all:hover {text-decoration:none;}
238 a.toggle-all:hover {text-decoration:none;}
239
239
240 table.list tbody tr:hover { background-color:#ffffdd; }
240 table.list tbody tr:hover { background-color:#ffffdd; }
241 table.list tbody tr.group:hover { background-color:inherit; }
241 table.list tbody tr.group:hover { background-color:inherit; }
242 table td {padding:2px;}
242 table td {padding:2px;}
243 table p {margin:0;}
243 table p {margin:0;}
244 .odd {background-color:#f6f7f8;}
244 .odd {background-color:#f6f7f8;}
245 .even {background-color: #fff;}
245 .even {background-color: #fff;}
246
246
247 tr.builtin td.name {font-style:italic;}
247 tr.builtin td.name {font-style:italic;}
248
248
249 a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; }
249 a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; }
250 a.sort.asc { background-image: url(../images/sort_asc.png); }
250 a.sort.asc { background-image: url(../images/sort_asc.png); }
251 a.sort.desc { background-image: url(../images/sort_desc.png); }
251 a.sort.desc { background-image: url(../images/sort_desc.png); }
252
252
253 table.attributes { width: 100% }
253 table.attributes { width: 100% }
254 table.attributes th { vertical-align: top; text-align: left; }
254 table.attributes th { vertical-align: top; text-align: left; }
255 table.attributes td { vertical-align: top; }
255 table.attributes td { vertical-align: top; }
256
256
257 table.boards a.board, h3.comments { background: url(../images/comment.png) no-repeat 0% 50%; padding-left: 20px; }
257 table.boards a.board, h3.comments { background: url(../images/comment.png) no-repeat 0% 50%; padding-left: 20px; }
258 table.boards td.last-message {text-align:left;font-size:80%;}
258 table.boards td.last-message {text-align:left;font-size:80%;}
259
259
260 table.messages td.last_message {text-align:left;}
260 table.messages td.last_message {text-align:left;}
261
261
262 #query_form_content {font-size:90%;}
262 #query_form_content {font-size:90%;}
263
263
264 table.query-columns {
264 table.query-columns {
265 border-collapse: collapse;
265 border-collapse: collapse;
266 border: 0;
266 border: 0;
267 }
267 }
268
268
269 table.query-columns td.buttons {
269 table.query-columns td.buttons {
270 vertical-align: middle;
270 vertical-align: middle;
271 text-align: center;
271 text-align: center;
272 }
272 }
273 table.query-columns td.buttons input[type=button] {width:35px;}
273 table.query-columns td.buttons input[type=button] {width:35px;}
274
274
275 td.center {text-align:center;}
275 td.center {text-align:center;}
276
276
277 h3.version { background: url(../images/package.png) no-repeat 0% 50%; padding-left: 20px; }
277 h3.version { background: url(../images/package.png) no-repeat 0% 50%; padding-left: 20px; }
278
278
279 div.issues h3 { background: url(../images/ticket.png) no-repeat 0% 50%; padding-left: 20px; }
279 div.issues h3 { background: url(../images/ticket.png) no-repeat 0% 50%; padding-left: 20px; }
280 div.members h3 { background: url(../images/group.png) no-repeat 0% 50%; padding-left: 20px; }
280 div.members h3 { background: url(../images/group.png) no-repeat 0% 50%; padding-left: 20px; }
281 div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left: 20px; }
281 div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left: 20px; }
282 div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; }
282 div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; }
283
283
284 #watchers select {width: 95%; display: block;}
284 #watchers select {width: 95%; display: block;}
285 #watchers a.delete {opacity: 0.4; vertical-align: middle;}
285 #watchers a.delete {opacity: 0.4; vertical-align: middle;}
286 #watchers a.delete:hover {opacity: 1;}
286 #watchers a.delete:hover {opacity: 1;}
287 #watchers img.gravatar {margin: 0 4px 2px 0;}
287 #watchers img.gravatar {margin: 0 4px 2px 0;}
288
288
289 span#watchers_inputs {overflow:auto; display:block;}
289 span#watchers_inputs {overflow:auto; display:block;}
290 span.search_for_watchers {display:block;}
290 span.search_for_watchers {display:block;}
291 span.search_for_watchers, span.add_attachment {font-size:80%; line-height:2.5em;}
291 span.search_for_watchers, span.add_attachment {font-size:80%; line-height:2.5em;}
292 span.search_for_watchers a, span.add_attachment a {padding-left:16px; background: url(../images/bullet_add.png) no-repeat 0 50%; }
292 span.search_for_watchers a, span.add_attachment a {padding-left:16px; background: url(../images/bullet_add.png) no-repeat 0 50%; }
293
293
294
294
295 .highlight { background-color: #FCFD8D;}
295 .highlight { background-color: #FCFD8D;}
296 .highlight.token-1 { background-color: #faa;}
296 .highlight.token-1 { background-color: #faa;}
297 .highlight.token-2 { background-color: #afa;}
297 .highlight.token-2 { background-color: #afa;}
298 .highlight.token-3 { background-color: #aaf;}
298 .highlight.token-3 { background-color: #aaf;}
299
299
300 .box{
300 .box{
301 padding:6px;
301 padding:6px;
302 margin-bottom: 10px;
302 margin-bottom: 10px;
303 background-color:#f6f6f6;
303 background-color:#f6f6f6;
304 color:#505050;
304 color:#505050;
305 line-height:1.5em;
305 line-height:1.5em;
306 border: 1px solid #e4e4e4;
306 border: 1px solid #e4e4e4;
307 word-wrap: break-word;
307 word-wrap: break-word;
308 border-radius: 3px;
308 border-radius: 3px;
309 }
309 }
310
310
311 div.square {
311 div.square {
312 border: 1px solid #999;
312 border: 1px solid #999;
313 float: left;
313 float: left;
314 margin: .3em .4em 0 .4em;
314 margin: .3em .4em 0 .4em;
315 overflow: hidden;
315 overflow: hidden;
316 width: .6em; height: .6em;
316 width: .6em; height: .6em;
317 }
317 }
318 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
318 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
319 .contextual input, .contextual select {font-size:0.9em;}
319 .contextual input, .contextual select {font-size:0.9em;}
320 .message .contextual { margin-top: 0; }
320 .message .contextual { margin-top: 0; }
321
321
322 .splitcontent {overflow:auto;}
322 .splitcontent {overflow:auto;}
323 .splitcontentleft{float:left; width:49%;}
323 .splitcontentleft{float:left; width:49%;}
324 .splitcontentright{float:right; width:49%;}
324 .splitcontentright{float:right; width:49%;}
325 form {display: inline;}
325 form {display: inline;}
326 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
326 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
327 fieldset {border: 1px solid #e4e4e4; margin:0;}
327 fieldset {border: 1px solid #e4e4e4; margin:0;}
328 legend {color: #484848;}
328 legend {color: #484848;}
329 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
329 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
330 blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
330 blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
331 blockquote blockquote { margin-left: 0;}
331 blockquote blockquote { margin-left: 0;}
332 abbr, span.field-description[title] { border-bottom: 1px dotted #aaa; cursor: help; }
332 abbr, span.field-description[title] { border-bottom: 1px dotted #aaa; cursor: help; }
333 textarea.wiki-edit {width:99%; resize:vertical;}
333 textarea.wiki-edit {width:99%; resize:vertical;}
334 li p {margin-top: 0;}
334 li p {margin-top: 0;}
335 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px; border: 1px solid #d7d7d7; border-radius:3px;}
335 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px; border: 1px solid #d7d7d7; border-radius:3px;}
336 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
336 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
337 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
337 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
338 p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
338 p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
339 .ltr {direction:ltr !important; unicode-bidi:bidi-override;}
339 .ltr {direction:ltr !important; unicode-bidi:bidi-override;}
340 .rtl {direction:rtl !important; unicode-bidi:bidi-override;}
340 .rtl {direction:rtl !important; unicode-bidi:bidi-override;}
341
341
342 div.issue div.subject div div { padding-left: 16px; }
342 div.issue div.subject div div { padding-left: 16px; }
343 div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;}
343 div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;}
344 div.issue div.subject>div>p { margin-top: 0.5em; }
344 div.issue div.subject>div>p { margin-top: 0.5em; }
345 div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;}
345 div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;}
346 div.issue span.private, div.journal span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;}
346 div.issue span.private, div.journal span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;}
347 div.issue .next-prev-links {color:#999;}
347 div.issue .next-prev-links {color:#999;}
348 div.issue table.attributes th {width:22%;}
348 div.issue table.attributes th {width:22%;}
349 div.issue table.attributes td {width:28%;}
349 div.issue table.attributes td {width:28%;}
350
350
351 #issue_tree table.issues, #relations table.issues { border: 0; }
351 #issue_tree table.issues, #relations table.issues { border: 0; }
352 #issue_tree td.checkbox, #relations td.checkbox {display:none;}
352 #issue_tree td.checkbox, #relations td.checkbox {display:none;}
353 #relations td.buttons {padding:0;}
353 #relations td.buttons {padding:0;}
354
354
355 fieldset.collapsible {border-width: 1px 0 0 0;}
355 fieldset.collapsible {border-width: 1px 0 0 0;}
356 fieldset.collapsible>legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
356 fieldset.collapsible>legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
357 fieldset.collapsible.collapsed>legend { background-image: url(../images/arrow_collapsed.png); }
357 fieldset.collapsible.collapsed>legend { background-image: url(../images/arrow_collapsed.png); }
358
358
359 fieldset#date-range p { margin: 2px 0 2px 0; }
359 fieldset#date-range p { margin: 2px 0 2px 0; }
360 fieldset#filters table { border-collapse: collapse; }
360 fieldset#filters table { border-collapse: collapse; }
361 fieldset#filters table td { padding: 0; vertical-align: middle; }
361 fieldset#filters table td { padding: 0; vertical-align: middle; }
362 fieldset#filters tr.filter { height: 2.1em; }
362 fieldset#filters tr.filter { height: 2.1em; }
363 fieldset#filters td.field { width:230px; }
363 fieldset#filters td.field { width:230px; }
364 fieldset#filters td.operator { width:180px; }
364 fieldset#filters td.operator { width:180px; }
365 fieldset#filters td.operator select {max-width:170px;}
365 fieldset#filters td.operator select {max-width:170px;}
366 fieldset#filters td.values { white-space:nowrap; }
366 fieldset#filters td.values { white-space:nowrap; }
367 fieldset#filters td.values select {min-width:130px;}
367 fieldset#filters td.values select {min-width:130px;}
368 fieldset#filters td.values input {height:1em;}
368 fieldset#filters td.values input {height:1em;}
369 fieldset#filters td.add-filter { text-align: right; vertical-align: top; }
369 fieldset#filters td.add-filter { text-align: right; vertical-align: top; }
370
370
371 .toggle-multiselect {background: url(../images/bullet_toggle_plus.png) no-repeat 0% 40%; padding-left:8px; margin-left:0; cursor:pointer;}
371 .toggle-multiselect {background: url(../images/bullet_toggle_plus.png) no-repeat 0% 40%; padding-left:8px; margin-left:0; cursor:pointer;}
372 .buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; }
372 .buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; }
373
373
374 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
374 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
375 div#issue-changesets div.changeset { padding: 4px;}
375 div#issue-changesets div.changeset { padding: 4px;}
376 div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; }
376 div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; }
377 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
377 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
378
378
379 .journal ul.details img {margin:0 0 -3px 4px;}
379 .journal ul.details img {margin:0 0 -3px 4px;}
380 div.journal {overflow:auto;}
380 div.journal {overflow:auto;}
381 div.journal.private-notes {border-left:2px solid #d22; padding-left:4px; margin-left:-6px;}
381 div.journal.private-notes {border-left:2px solid #d22; padding-left:4px; margin-left:-6px;}
382
382
383 div#activity dl, #search-results { margin-left: 2em; }
383 div#activity dl, #search-results { margin-left: 2em; }
384 div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
384 div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
385 div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
385 div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
386 div#activity dt.me .time { border-bottom: 1px solid #999; }
386 div#activity dt.me .time { border-bottom: 1px solid #999; }
387 div#activity dt .time { color: #777; font-size: 80%; }
387 div#activity dt .time { color: #777; font-size: 80%; }
388 div#activity dd .description, #search-results dd .description { font-style: italic; }
388 div#activity dd .description, #search-results dd .description { font-style: italic; }
389 div#activity span.project:after, #search-results span.project:after { content: " -"; }
389 div#activity span.project:after, #search-results span.project:after { content: " -"; }
390 div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
390 div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
391 div#activity dt.grouped {margin-left:5em;}
391 div#activity dt.grouped {margin-left:5em;}
392 div#activity dd.grouped {margin-left:9em;}
392 div#activity dd.grouped {margin-left:9em;}
393
393
394 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
394 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
395
395
396 div#search-results-counts {float:right;}
396 div#search-results-counts {float:right;}
397 div#search-results-counts ul { margin-top: 0.5em; }
397 div#search-results-counts ul { margin-top: 0.5em; }
398 div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
398 div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
399
399
400 dt.issue { background-image: url(../images/ticket.png); }
400 dt.issue { background-image: url(../images/ticket.png); }
401 dt.issue-edit { background-image: url(../images/ticket_edit.png); }
401 dt.issue-edit { background-image: url(../images/ticket_edit.png); }
402 dt.issue-closed { background-image: url(../images/ticket_checked.png); }
402 dt.issue-closed { background-image: url(../images/ticket_checked.png); }
403 dt.issue-note { background-image: url(../images/ticket_note.png); }
403 dt.issue-note { background-image: url(../images/ticket_note.png); }
404 dt.changeset { background-image: url(../images/changeset.png); }
404 dt.changeset { background-image: url(../images/changeset.png); }
405 dt.news { background-image: url(../images/news.png); }
405 dt.news { background-image: url(../images/news.png); }
406 dt.message { background-image: url(../images/message.png); }
406 dt.message { background-image: url(../images/message.png); }
407 dt.reply { background-image: url(../images/comments.png); }
407 dt.reply { background-image: url(../images/comments.png); }
408 dt.wiki-page { background-image: url(../images/wiki_edit.png); }
408 dt.wiki-page { background-image: url(../images/wiki_edit.png); }
409 dt.attachment { background-image: url(../images/attachment.png); }
409 dt.attachment { background-image: url(../images/attachment.png); }
410 dt.document { background-image: url(../images/document.png); }
410 dt.document { background-image: url(../images/document.png); }
411 dt.project { background-image: url(../images/projects.png); }
411 dt.project { background-image: url(../images/projects.png); }
412 dt.time-entry { background-image: url(../images/time.png); }
412 dt.time-entry { background-image: url(../images/time.png); }
413
413
414 #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
414 #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
415
415
416 div#roadmap .related-issues { margin-bottom: 1em; }
416 div#roadmap .related-issues { margin-bottom: 1em; }
417 div#roadmap .related-issues td.checkbox { display: none; }
417 div#roadmap .related-issues td.checkbox { display: none; }
418 div#roadmap .wiki h1:first-child { display: none; }
418 div#roadmap .wiki h1:first-child { display: none; }
419 div#roadmap .wiki h1 { font-size: 120%; }
419 div#roadmap .wiki h1 { font-size: 120%; }
420 div#roadmap .wiki h2 { font-size: 110%; }
420 div#roadmap .wiki h2 { font-size: 110%; }
421 body.controller-versions.action-show div#roadmap .related-issues {width:70%;}
421 body.controller-versions.action-show div#roadmap .related-issues {width:70%;}
422
422
423 div#version-summary { float:right; width:28%; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
423 div#version-summary { float:right; width:28%; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
424 div#version-summary fieldset { margin-bottom: 1em; }
424 div#version-summary fieldset { margin-bottom: 1em; }
425 div#version-summary fieldset.time-tracking table { width:100%; }
425 div#version-summary fieldset.time-tracking table { width:100%; }
426 div#version-summary th, div#version-summary td.total-hours { text-align: right; }
426 div#version-summary th, div#version-summary td.total-hours { text-align: right; }
427
427
428 table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
428 table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
429 table#time-report tbody tr.subtotal { font-style: italic; color:#777;}
429 table#time-report tbody tr.subtotal { font-style: italic; color:#777;}
430 table#time-report tbody tr.subtotal td.hours { color:#b0b0b0; }
430 table#time-report tbody tr.subtotal td.hours { color:#b0b0b0; }
431 table#time-report tbody tr.total { font-weight: bold; background-color:#EEEEEE; border-top:1px solid #e4e4e4;}
431 table#time-report tbody tr.total { font-weight: bold; background-color:#EEEEEE; border-top:1px solid #e4e4e4;}
432 table#time-report .hours-dec { font-size: 0.9em; }
432 table#time-report .hours-dec { font-size: 0.9em; }
433
433
434 div.wiki-page .contextual a {opacity: 0.4}
434 div.wiki-page .contextual a {opacity: 0.4}
435 div.wiki-page .contextual a:hover {opacity: 1}
435 div.wiki-page .contextual a:hover {opacity: 1}
436
436
437 form .attributes select { width: 60%; }
437 form .attributes select { width: 60%; }
438 input#issue_subject, input#document_title { width: 99%; }
438 input#issue_subject, input#document_title { width: 99%; }
439 select#issue_done_ratio { width: 95px; }
439 select#issue_done_ratio { width: 95px; }
440
440
441 ul.projects {margin:0; padding-left:1em;}
441 ul.projects {margin:0; padding-left:1em;}
442 ul.projects ul {padding-left:1.6em;}
442 ul.projects ul {padding-left:1.6em;}
443 ul.projects.root {margin:0; padding:0;}
443 ul.projects.root {margin:0; padding:0;}
444 ul.projects li {list-style-type:none;}
444 ul.projects li {list-style-type:none;}
445
445
446 #projects-index ul.projects ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;}
446 #projects-index ul.projects ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;}
447 #projects-index ul.projects li.root {margin-bottom: 1em;}
447 #projects-index ul.projects li.root {margin-bottom: 1em;}
448 #projects-index ul.projects li.child {margin-top: 1em;}
448 #projects-index ul.projects li.child {margin-top: 1em;}
449 #projects-index ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
449 #projects-index ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
450 .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
450 .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
451
451
452 #notified-projects>ul, #tracker_project_ids>ul, #custom_field_project_ids>ul {max-height:250px; overflow-y:auto;}
452 #notified-projects>ul, #tracker_project_ids>ul, #custom_field_project_ids>ul {max-height:250px; overflow-y:auto;}
453
453
454 #related-issues li img {vertical-align:middle;}
454 #related-issues li img {vertical-align:middle;}
455
455
456 ul.properties {padding:0; font-size: 0.9em; color: #777;}
456 ul.properties {padding:0; font-size: 0.9em; color: #777;}
457 ul.properties li {list-style-type:none;}
457 ul.properties li {list-style-type:none;}
458 ul.properties li span {font-style:italic;}
458 ul.properties li span {font-style:italic;}
459
459
460 .total-hours { font-size: 110%; font-weight: bold; }
460 .total-hours { font-size: 110%; font-weight: bold; }
461 .total-hours span.hours-int { font-size: 120%; }
461 .total-hours span.hours-int { font-size: 120%; }
462
462
463 .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;}
463 .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;}
464 #user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select, #user_identity_url { width: 90%; }
464 #user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select, #user_identity_url { width: 90%; }
465
465
466 #workflow_copy_form select { width: 200px; }
466 #workflow_copy_form select { width: 200px; }
467 table.transitions td.enabled {background: #bfb;}
467 table.transitions td.enabled {background: #bfb;}
468 #workflow_form table select {font-size:90%; max-width:100px;}
468 #workflow_form table select {font-size:90%; max-width:100px;}
469 table.fields_permissions td.readonly {background:#ddd;}
469 table.fields_permissions td.readonly {background:#ddd;}
470 table.fields_permissions td.required {background:#d88;}
470 table.fields_permissions td.required {background:#d88;}
471
471
472 select.expandable {vertical-align:top;}
472 select.expandable {vertical-align:top;}
473
473
474 textarea#custom_field_possible_values {width: 95%; resize:vertical}
474 textarea#custom_field_possible_values {width: 95%; resize:vertical}
475 textarea#custom_field_default_value {width: 95%; resize:vertical}
475 textarea#custom_field_default_value {width: 95%; resize:vertical}
476
476
477 input#content_comments {width: 99%}
477 input#content_comments {width: 99%}
478
478
479 p.pagination {margin-top:8px; font-size: 90%}
479 p.pagination {margin-top:8px; font-size: 90%}
480
480
481 #search-form fieldset p {margin:0.2em 0;}
481 #search-form fieldset p {margin:0.2em 0;}
482
482
483 /***** Tabular forms ******/
483 /***** Tabular forms ******/
484 .tabular p{
484 .tabular p{
485 margin: 0;
485 margin: 0;
486 padding: 3px 0 3px 0;
486 padding: 3px 0 3px 0;
487 padding-left: 180px; /* width of left column containing the label elements */
487 padding-left: 180px; /* width of left column containing the label elements */
488 min-height: 1.8em;
488 min-height: 1.8em;
489 clear:left;
489 clear:left;
490 }
490 }
491
491
492 html>body .tabular p {overflow:hidden;}
492 html>body .tabular p {overflow:hidden;}
493
493
494 .tabular input, .tabular select {max-width:95%}
494 .tabular input, .tabular select {max-width:95%}
495 .tabular textarea {width:95%; resize:vertical;}
495 .tabular textarea {width:95%; resize:vertical;}
496
496
497 .tabular label{
497 .tabular label{
498 font-weight: bold;
498 font-weight: bold;
499 float: left;
499 float: left;
500 text-align: right;
500 text-align: right;
501 /* width of left column */
501 /* width of left column */
502 margin-left: -180px;
502 margin-left: -180px;
503 /* width of labels. Should be smaller than left column to create some right margin */
503 /* width of labels. Should be smaller than left column to create some right margin */
504 width: 175px;
504 width: 175px;
505 }
505 }
506
506
507 .tabular label.floating{
507 .tabular label.floating{
508 font-weight: normal;
508 font-weight: normal;
509 margin-left: 0px;
509 margin-left: 0px;
510 text-align: left;
510 text-align: left;
511 width: 270px;
511 width: 270px;
512 }
512 }
513
513
514 .tabular label.block{
514 .tabular label.block{
515 font-weight: normal;
515 font-weight: normal;
516 margin-left: 0px !important;
516 margin-left: 0px !important;
517 text-align: left;
517 text-align: left;
518 float: none;
518 float: none;
519 display: block;
519 display: block;
520 width: auto !important;
520 width: auto !important;
521 }
521 }
522
522
523 .tabular label.inline{
523 .tabular label.inline{
524 font-weight: normal;
524 font-weight: normal;
525 float:none;
525 float:none;
526 margin-left: 5px !important;
526 margin-left: 5px !important;
527 width: auto;
527 width: auto;
528 }
528 }
529
529
530 label.no-css {
530 label.no-css {
531 font-weight: inherit;
531 font-weight: inherit;
532 float:none;
532 float:none;
533 text-align:left;
533 text-align:left;
534 margin-left:0px;
534 margin-left:0px;
535 width:auto;
535 width:auto;
536 }
536 }
537 input#time_entry_comments { width: 90%;}
537 input#time_entry_comments { width: 90%;}
538
538
539 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
539 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
540
540
541 .tabular.settings p{ padding-left: 300px; }
541 .tabular.settings p{ padding-left: 300px; }
542 .tabular.settings label{ margin-left: -300px; width: 295px; }
542 .tabular.settings label{ margin-left: -300px; width: 295px; }
543 .tabular.settings textarea { width: 99%; }
543 .tabular.settings textarea { width: 99%; }
544
544
545 .settings.enabled_scm table {width:100%}
545 .settings.enabled_scm table {width:100%}
546 .settings.enabled_scm td.scm_name{ font-weight: bold; }
546 .settings.enabled_scm td.scm_name{ font-weight: bold; }
547
547
548 fieldset.settings label { display: block; }
548 fieldset.settings label { display: block; }
549 fieldset#notified_events .parent { padding-left: 20px; }
549 fieldset#notified_events .parent { padding-left: 20px; }
550
550
551 span.required {color: #bb0000;}
551 span.required {color: #bb0000;}
552 .summary {font-style: italic;}
552 .summary {font-style: italic;}
553
553
554 .check_box_group {
554 .check_box_group {
555 display:block;
555 display:block;
556 width:95%;
556 width:95%;
557 max-height:300px;
557 max-height:300px;
558 overflow-y:auto;
558 overflow-y:auto;
559 padding:2px 4px 4px 2px;
559 padding:2px 4px 4px 2px;
560 background:#fff;
560 background:#fff;
561 border:1px solid #9EB1C2;
561 border:1px solid #9EB1C2;
562 border-radius:2px
562 border-radius:2px
563 }
563 }
564 .check_box_group label {
564 .check_box_group label {
565 font-weight: normal;
565 font-weight: normal;
566 margin-left: 0px !important;
566 margin-left: 0px !important;
567 text-align: left;
567 text-align: left;
568 float: none;
568 float: none;
569 display: block;
569 display: block;
570 width: auto;
570 width: auto;
571 }
571 }
572 .check_box_group.bool_cf {border:0; background:inherit;}
572 .check_box_group.bool_cf {border:0; background:inherit;}
573 .check_box_group.bool_cf label {display: inline;}
573 .check_box_group.bool_cf label {display: inline;}
574
574
575 #attachments_fields input.description {margin-left:4px; width:340px;}
575 #attachments_fields input.description {margin-left:4px; width:340px;}
576 #attachments_fields span {display:block; white-space:nowrap;}
576 #attachments_fields span {display:block; white-space:nowrap;}
577 #attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../images/attachment.png) no-repeat 1px 50%; padding-left:18px;}
577 #attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../images/attachment.png) no-repeat 1px 50%; padding-left:18px;}
578 #attachments_fields .ajax-waiting input.filename {background:url(../images/hourglass.png) no-repeat 0px 50%;}
578 #attachments_fields .ajax-waiting input.filename {background:url(../images/hourglass.png) no-repeat 0px 50%;}
579 #attachments_fields .ajax-loading input.filename {background:url(../images/loading.gif) no-repeat 0px 50%;}
579 #attachments_fields .ajax-loading input.filename {background:url(../images/loading.gif) no-repeat 0px 50%;}
580 #attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; }
580 #attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; }
581 a.remove-upload {background: url(../images/delete.png) no-repeat 1px 50%; width:1px; display:inline-block; padding-left:16px;}
581 a.remove-upload {background: url(../images/delete.png) no-repeat 1px 50%; width:1px; display:inline-block; padding-left:16px;}
582 a.remove-upload:hover {text-decoration:none !important;}
582 a.remove-upload:hover {text-decoration:none !important;}
583
583
584 div.fileover { background-color: lavender; }
584 div.fileover { background-color: lavender; }
585
585
586 div.attachments { margin-top: 12px; }
586 div.attachments { margin-top: 12px; }
587 div.attachments p { margin:4px 0 2px 0; }
587 div.attachments p { margin:4px 0 2px 0; }
588 div.attachments img { vertical-align: middle; }
588 div.attachments img { vertical-align: middle; }
589 div.attachments span.author { font-size: 0.9em; color: #888; }
589 div.attachments span.author { font-size: 0.9em; color: #888; }
590
590
591 div.thumbnails {margin-top:0.6em;}
591 div.thumbnails {margin-top:0.6em;}
592 div.thumbnails div {background:#fff;border:2px solid #ddd;display:inline-block;margin-right:2px;}
592 div.thumbnails div {background:#fff;border:2px solid #ddd;display:inline-block;margin-right:2px;}
593 div.thumbnails img {margin: 3px;}
593 div.thumbnails img {margin: 3px;}
594
594
595 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
595 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
596 .other-formats span + span:before { content: "| "; }
596 .other-formats span + span:before { content: "| "; }
597
597
598 a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
598 a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
599
599
600 em.info {font-style:normal;font-size:90%;color:#888;display:block;}
600 em.info {font-style:normal;font-size:90%;color:#888;display:block;}
601 em.info.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;}
601 em.info.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;}
602
602
603 textarea.text_cf {width:95%; resize:vertical;}
603 textarea.text_cf {width:95%; resize:vertical;}
604 input.string_cf, input.link_cf {width:95%;}
604 input.string_cf, input.link_cf {width:95%;}
605 select.bool_cf {width:auto !important;}
605 select.bool_cf {width:auto !important;}
606
606
607 #tab-content-modules fieldset p {margin:3px 0 4px 0;}
607 #tab-content-modules fieldset p {margin:3px 0 4px 0;}
608
608
609 #tab-content-users .splitcontentleft {width: 64%;}
609 #tab-content-users .splitcontentleft {width: 64%;}
610 #tab-content-users .splitcontentright {width: 34%;}
610 #tab-content-users .splitcontentright {width: 34%;}
611 #tab-content-users fieldset {padding:1em; margin-bottom: 1em;}
611 #tab-content-users fieldset {padding:1em; margin-bottom: 1em;}
612 #tab-content-users fieldset legend {font-weight: bold;}
612 #tab-content-users fieldset legend {font-weight: bold;}
613 #tab-content-users fieldset label {display: block;}
613 #tab-content-users fieldset label {display: block;}
614 #tab-content-users #principals {max-height: 400px; overflow: auto;}
614 #tab-content-users #principals {max-height: 400px; overflow: auto;}
615
615
616 #users_for_watcher {height: 200px; overflow:auto;}
616 #users_for_watcher {height: 200px; overflow:auto;}
617 #users_for_watcher label {display: block;}
617 #users_for_watcher label {display: block;}
618
618
619 table.members td.name {padding-left: 20px;}
619 table.members td.name {padding-left: 20px;}
620 table.members td.group, table.members td.groupnonmember, table.members td.groupanonymous {background: url(../images/group.png) no-repeat 0% 1px;}
620 table.members td.group, table.members td.groupnonmember, table.members td.groupanonymous {background: url(../images/group.png) no-repeat 0% 1px;}
621
621
622 input#principal_search, input#user_search {width:90%}
622 input#principal_search, input#user_search {width:90%}
623 .roles-selection label {display:inline-block; width:210px;}
623 .roles-selection label {display:inline-block; width:210px;}
624
624
625 input.autocomplete {
625 input.autocomplete {
626 background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px !important;
626 background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px !important;
627 border:1px solid #9EB1C2; border-radius:2px; height:1.5em;
627 border:1px solid #9EB1C2; border-radius:2px; height:1.5em;
628 }
628 }
629 input.autocomplete.ajax-loading {
629 input.autocomplete.ajax-loading {
630 background-image: url(../images/loading.gif);
630 background-image: url(../images/loading.gif);
631 }
631 }
632
632
633 .role-visibility {padding-left:2em;}
633 .role-visibility {padding-left:2em;}
634
634
635 .objects-selection {
635 .objects-selection {
636 height: 300px;
636 height: 300px;
637 overflow: auto;
637 overflow: auto;
638 }
638 }
639
639
640 .objects-selection label {
640 .objects-selection label {
641 display: block;
641 display: block;
642 }
642 }
643
643
644 .objects-selection>div {
644 .objects-selection>div {
645 column-count: auto;
645 column-count: auto;
646 column-width: 200px;
646 column-width: 200px;
647 -webkit-column-count: auto;
647 -webkit-column-count: auto;
648 -webkit-column-width: 200px;
648 -webkit-column-width: 200px;
649 -webkit-column-gap : 0.5rem;
649 -webkit-column-gap : 0.5rem;
650 -webkit-column-rule: 1px solid #ccc;
650 -webkit-column-rule: 1px solid #ccc;
651 -moz-column-count: auto;
651 -moz-column-count: auto;
652 -moz-column-width: 200px;
652 -moz-column-width: 200px;
653 -moz-column-gap : 0.5rem;
653 -moz-column-gap : 0.5rem;
654 -moz-column-rule: 1px solid #ccc;
654 -moz-column-rule: 1px solid #ccc;
655 }
655 }
656
656
657 /***** Flash & error messages ****/
657 /***** Flash & error messages ****/
658 #errorExplanation, div.flash, .nodata, .warning, .conflict {
658 #errorExplanation, div.flash, .nodata, .warning, .conflict {
659 padding: 4px 4px 4px 30px;
659 padding: 4px 4px 4px 30px;
660 margin-bottom: 12px;
660 margin-bottom: 12px;
661 font-size: 1.1em;
661 font-size: 1.1em;
662 border: 2px solid;
662 border: 2px solid;
663 border-radius: 3px;
663 border-radius: 3px;
664 }
664 }
665
665
666 div.flash {margin-top: 8px;}
666 div.flash {margin-top: 8px;}
667
667
668 div.flash.error, #errorExplanation {
668 div.flash.error, #errorExplanation {
669 background: url(../images/exclamation.png) 8px 50% no-repeat;
669 background: url(../images/exclamation.png) 8px 50% no-repeat;
670 background-color: #ffe3e3;
670 background-color: #ffe3e3;
671 border-color: #dd0000;
671 border-color: #dd0000;
672 color: #880000;
672 color: #880000;
673 }
673 }
674
674
675 div.flash.notice {
675 div.flash.notice {
676 background: url(../images/true.png) 8px 5px no-repeat;
676 background: url(../images/true.png) 8px 5px no-repeat;
677 background-color: #dfffdf;
677 background-color: #dfffdf;
678 border-color: #9fcf9f;
678 border-color: #9fcf9f;
679 color: #005f00;
679 color: #005f00;
680 }
680 }
681
681
682 div.flash.warning, .conflict {
682 div.flash.warning, .conflict {
683 background: url(../images/warning.png) 8px 5px no-repeat;
683 background: url(../images/warning.png) 8px 5px no-repeat;
684 background-color: #FFEBC1;
684 background-color: #FFEBC1;
685 border-color: #FDBF3B;
685 border-color: #FDBF3B;
686 color: #A6750C;
686 color: #A6750C;
687 text-align: left;
687 text-align: left;
688 }
688 }
689
689
690 .nodata, .warning {
690 .nodata, .warning {
691 text-align: center;
691 text-align: center;
692 background-color: #FFEBC1;
692 background-color: #FFEBC1;
693 border-color: #FDBF3B;
693 border-color: #FDBF3B;
694 color: #A6750C;
694 color: #A6750C;
695 }
695 }
696
696
697 #errorExplanation ul { font-size: 0.9em;}
697 #errorExplanation ul { font-size: 0.9em;}
698 #errorExplanation h2, #errorExplanation p { display: none; }
698 #errorExplanation h2, #errorExplanation p { display: none; }
699
699
700 .conflict-details {font-size:80%;}
700 .conflict-details {font-size:80%;}
701
701
702 /***** Ajax indicator ******/
702 /***** Ajax indicator ******/
703 #ajax-indicator {
703 #ajax-indicator {
704 position: absolute; /* fixed not supported by IE */
704 position: absolute; /* fixed not supported by IE */
705 background-color:#eee;
705 background-color:#eee;
706 border: 1px solid #bbb;
706 border: 1px solid #bbb;
707 top:35%;
707 top:35%;
708 left:40%;
708 left:40%;
709 width:20%;
709 width:20%;
710 font-weight:bold;
710 font-weight:bold;
711 text-align:center;
711 text-align:center;
712 padding:0.6em;
712 padding:0.6em;
713 z-index:100;
713 z-index:100;
714 opacity: 0.5;
714 opacity: 0.5;
715 }
715 }
716
716
717 html>body #ajax-indicator { position: fixed; }
717 html>body #ajax-indicator { position: fixed; }
718
718
719 #ajax-indicator span {
719 #ajax-indicator span {
720 background-position: 0% 40%;
720 background-position: 0% 40%;
721 background-repeat: no-repeat;
721 background-repeat: no-repeat;
722 background-image: url(../images/loading.gif);
722 background-image: url(../images/loading.gif);
723 padding-left: 26px;
723 padding-left: 26px;
724 vertical-align: bottom;
724 vertical-align: bottom;
725 }
725 }
726
726
727 /***** Calendar *****/
727 /***** Calendar *****/
728 table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
728 table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
729 table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; }
729 table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; }
730 table.cal thead th.week-number {width: auto;}
730 table.cal thead th.week-number {width: auto;}
731 table.cal tbody tr {height: 100px;}
731 table.cal tbody tr {height: 100px;}
732 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
732 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
733 table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;}
733 table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;}
734 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
734 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
735 table.cal td.odd p.day-num {color: #bbb;}
735 table.cal td.odd p.day-num {color: #bbb;}
736 table.cal td.today {background:#ffffdd;}
736 table.cal td.today {background:#ffffdd;}
737 table.cal td.today p.day-num {font-weight: bold;}
737 table.cal td.today p.day-num {font-weight: bold;}
738 table.cal .starting a, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
738 table.cal .starting a, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
739 table.cal .ending a, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
739 table.cal .ending a, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
740 table.cal .starting.ending a, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}
740 table.cal .starting.ending a, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}
741 p.cal.legend span {display:block;}
741 p.cal.legend span {display:block;}
742
742
743 /***** Tooltips ******/
743 /***** Tooltips ******/
744 .tooltip{position:relative;z-index:24;}
744 .tooltip{position:relative;z-index:24;}
745 .tooltip:hover{z-index:25;color:#000;}
745 .tooltip:hover{z-index:25;color:#000;}
746 .tooltip span.tip{display: none; text-align:left;}
746 .tooltip span.tip{display: none; text-align:left;}
747
747
748 div.tooltip:hover span.tip{
748 div.tooltip:hover span.tip{
749 display:block;
749 display:block;
750 position:absolute;
750 position:absolute;
751 top:12px; left:24px; width:270px;
751 top:12px; left:24px; width:270px;
752 border:1px solid #555;
752 border:1px solid #555;
753 background-color:#fff;
753 background-color:#fff;
754 padding: 4px;
754 padding: 4px;
755 font-size: 0.8em;
755 font-size: 0.8em;
756 color:#505050;
756 color:#505050;
757 }
757 }
758
758
759 img.ui-datepicker-trigger {
759 img.ui-datepicker-trigger {
760 cursor: pointer;
760 cursor: pointer;
761 vertical-align: middle;
761 vertical-align: middle;
762 margin-left: 4px;
762 margin-left: 4px;
763 }
763 }
764
764
765 /***** Progress bar *****/
765 /***** Progress bar *****/
766 table.progress {
766 table.progress {
767 border-collapse: collapse;
767 border-collapse: collapse;
768 border-spacing: 0pt;
768 border-spacing: 0pt;
769 empty-cells: show;
769 empty-cells: show;
770 text-align: center;
770 text-align: center;
771 float:left;
771 float:left;
772 margin: 1px 6px 1px 0px;
772 margin: 1px 6px 1px 0px;
773 }
773 }
774
774
775 table.progress td { height: 1em; }
775 table.progress td { height: 1em; }
776 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
776 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
777 table.progress td.done { background: #D3EDD3 none repeat scroll 0%; }
777 table.progress td.done { background: #D3EDD3 none repeat scroll 0%; }
778 table.progress td.todo { background: #eee none repeat scroll 0%; }
778 table.progress td.todo { background: #eee none repeat scroll 0%; }
779 p.percent {font-size: 80%;}
779 p.percent {font-size: 80%;}
780 p.progress-info {clear: left; font-size: 80%; margin-top:-4px; color:#777;}
780 p.progress-info {clear: left; font-size: 80%; margin-top:-4px; color:#777;}
781
781
782 #roadmap table.progress td { height: 1.2em; }
782 #roadmap table.progress td { height: 1.2em; }
783 /***** Tabs *****/
783 /***** Tabs *****/
784 #content .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;}
784 #content .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;}
785 #content .tabs ul {margin:0; position:absolute; bottom:0; padding-left:0.5em; width: 2000px; border-bottom: 1px solid #bbbbbb;}
785 #content .tabs ul {margin:0; position:absolute; bottom:0; padding-left:0.5em; width: 2000px; border-bottom: 1px solid #bbbbbb;}
786 #content .tabs ul li {
786 #content .tabs ul li {
787 float:left;
787 float:left;
788 list-style-type:none;
788 list-style-type:none;
789 white-space:nowrap;
789 white-space:nowrap;
790 margin-right:4px;
790 margin-right:4px;
791 background:#fff;
791 background:#fff;
792 position:relative;
792 position:relative;
793 margin-bottom:-1px;
793 margin-bottom:-1px;
794 }
794 }
795 #content .tabs ul li a{
795 #content .tabs ul li a{
796 display:block;
796 display:block;
797 font-size: 0.9em;
797 font-size: 0.9em;
798 text-decoration:none;
798 text-decoration:none;
799 line-height:1.3em;
799 line-height:1.3em;
800 padding:4px 6px 4px 6px;
800 padding:4px 6px 4px 6px;
801 border: 1px solid #ccc;
801 border: 1px solid #ccc;
802 border-bottom: 1px solid #bbbbbb;
802 border-bottom: 1px solid #bbbbbb;
803 background-color: #f6f6f6;
803 background-color: #f6f6f6;
804 color:#999;
804 color:#999;
805 font-weight:bold;
805 font-weight:bold;
806 border-top-left-radius:3px;
806 border-top-left-radius:3px;
807 border-top-right-radius:3px;
807 border-top-right-radius:3px;
808 }
808 }
809
809
810 #content .tabs ul li a:hover {
810 #content .tabs ul li a:hover {
811 background-color: #ffffdd;
811 background-color: #ffffdd;
812 text-decoration:none;
812 text-decoration:none;
813 }
813 }
814
814
815 #content .tabs ul li a.selected {
815 #content .tabs ul li a.selected {
816 background-color: #fff;
816 background-color: #fff;
817 border: 1px solid #bbbbbb;
817 border: 1px solid #bbbbbb;
818 border-bottom: 1px solid #fff;
818 border-bottom: 1px solid #fff;
819 color:#444;
819 color:#444;
820 }
820 }
821
821
822 #content .tabs ul li a.selected:hover {background-color: #fff;}
822 #content .tabs ul li a.selected:hover {background-color: #fff;}
823
823
824 div.tabs-buttons { position:absolute; right: 0; width: 48px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; }
824 div.tabs-buttons { position:absolute; right: 0; width: 48px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; }
825
825
826 button.tab-left, button.tab-right {
826 button.tab-left, button.tab-right {
827 font-size: 0.9em;
827 font-size: 0.9em;
828 cursor: pointer;
828 cursor: pointer;
829 height:24px;
829 height:24px;
830 border: 1px solid #ccc;
830 border: 1px solid #ccc;
831 border-bottom: 1px solid #bbbbbb;
831 border-bottom: 1px solid #bbbbbb;
832 position:absolute;
832 position:absolute;
833 padding:4px;
833 padding:4px;
834 width: 20px;
834 width: 20px;
835 bottom: -1px;
835 bottom: -1px;
836 }
836 }
837
837
838 button.tab-left {
838 button.tab-left {
839 right: 20px;
839 right: 20px;
840 background: #eeeeee url(../images/bullet_arrow_left.png) no-repeat 50% 50%;
840 background: #eeeeee url(../images/bullet_arrow_left.png) no-repeat 50% 50%;
841 border-top-left-radius:3px;
841 border-top-left-radius:3px;
842 }
842 }
843
843
844 button.tab-right {
844 button.tab-right {
845 right: 0;
845 right: 0;
846 background: #eeeeee url(../images/bullet_arrow_right.png) no-repeat 50% 50%;
846 background: #eeeeee url(../images/bullet_arrow_right.png) no-repeat 50% 50%;
847 border-top-right-radius:3px;
847 border-top-right-radius:3px;
848 }
848 }
849
849
850 /***** Diff *****/
850 /***** Diff *****/
851 .diff_out { background: #fcc; }
851 .diff_out { background: #fcc; }
852 .diff_out span { background: #faa; }
852 .diff_out span { background: #faa; }
853 .diff_in { background: #cfc; }
853 .diff_in { background: #cfc; }
854 .diff_in span { background: #afa; }
854 .diff_in span { background: #afa; }
855
855
856 .text-diff {
856 .text-diff {
857 padding: 1em;
857 padding: 1em;
858 background-color:#f6f6f6;
858 background-color:#f6f6f6;
859 color:#505050;
859 color:#505050;
860 border: 1px solid #e4e4e4;
860 border: 1px solid #e4e4e4;
861 }
861 }
862
862
863 /***** Wiki *****/
863 /***** Wiki *****/
864 div.wiki table {
864 div.wiki table {
865 border-collapse: collapse;
865 border-collapse: collapse;
866 margin-bottom: 1em;
866 margin-bottom: 1em;
867 }
867 }
868
868
869 div.wiki table, div.wiki td, div.wiki th {
869 div.wiki table, div.wiki td, div.wiki th {
870 border: 1px solid #bbb;
870 border: 1px solid #bbb;
871 padding: 4px;
871 padding: 4px;
872 }
872 }
873
873
874 div.wiki .noborder, div.wiki .noborder td, div.wiki .noborder th {border:0;}
874 div.wiki .noborder, div.wiki .noborder td, div.wiki .noborder th {border:0;}
875
875
876 div.wiki .external {
876 div.wiki .external {
877 background-position: 0% 60%;
877 background-position: 0% 60%;
878 background-repeat: no-repeat;
878 background-repeat: no-repeat;
879 padding-left: 12px;
879 padding-left: 12px;
880 background-image: url(../images/external.png);
880 background-image: url(../images/external.png);
881 }
881 }
882
882
883 div.wiki a {word-wrap: break-word;}
883 div.wiki a {word-wrap: break-word;}
884 div.wiki a.new {color: #b73535;}
884 div.wiki a.new {color: #b73535;}
885
885
886 div.wiki ul, div.wiki ol {margin-bottom:1em;}
886 div.wiki ul, div.wiki ol {margin-bottom:1em;}
887 div.wiki li>ul, div.wiki li>ol {margin-bottom: 0;}
887 div.wiki li>ul, div.wiki li>ol {margin-bottom: 0;}
888
888
889 div.wiki pre {
889 div.wiki pre {
890 margin: 1em 1em 1em 1.6em;
890 margin: 1em 1em 1em 1.6em;
891 padding: 8px;
891 padding: 8px;
892 background-color: #fafafa;
892 background-color: #fafafa;
893 border: 1px solid #e2e2e2;
893 border: 1px solid #e2e2e2;
894 border-radius: 3px;
894 border-radius: 3px;
895 width:auto;
895 width:auto;
896 overflow-x: auto;
896 overflow-x: auto;
897 overflow-y: hidden;
897 overflow-y: hidden;
898 }
898 }
899
899
900 div.wiki ul.toc {
900 div.wiki ul.toc {
901 background-color: #ffffdd;
901 background-color: #ffffdd;
902 border: 1px solid #e4e4e4;
902 border: 1px solid #e4e4e4;
903 padding: 4px;
903 padding: 4px;
904 line-height: 1.2em;
904 line-height: 1.2em;
905 margin-bottom: 12px;
905 margin-bottom: 12px;
906 margin-right: 12px;
906 margin-right: 12px;
907 margin-left: 0;
907 margin-left: 0;
908 display: table
908 display: table
909 }
909 }
910 * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
910 * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
911
911
912 div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
912 div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
913 div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
913 div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
914 div.wiki ul.toc ul { margin: 0; padding: 0; }
914 div.wiki ul.toc ul { margin: 0; padding: 0; }
915 div.wiki ul.toc li {list-style-type:none; margin: 0; font-size:12px;}
915 div.wiki ul.toc li {list-style-type:none; margin: 0; font-size:12px;}
916 div.wiki ul.toc li li {margin-left: 1.5em; font-size:10px;}
916 div.wiki ul.toc li li {margin-left: 1.5em; font-size:10px;}
917 div.wiki ul.toc a {
917 div.wiki ul.toc a {
918 font-size: 0.9em;
918 font-size: 0.9em;
919 font-weight: normal;
919 font-weight: normal;
920 text-decoration: none;
920 text-decoration: none;
921 color: #606060;
921 color: #606060;
922 }
922 }
923 div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
923 div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
924
924
925 a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
925 a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
926 a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
926 a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
927 h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
927 h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
928
928
929 div.wiki img {vertical-align:middle; max-width:100%;}
929 div.wiki img {vertical-align:middle; max-width:100%;}
930
930
931 /***** My page layout *****/
931 /***** My page layout *****/
932 .block-receiver {
932 .block-receiver {
933 border:1px dashed #c0c0c0;
933 border:1px dashed #c0c0c0;
934 margin-bottom: 20px;
934 margin-bottom: 20px;
935 padding: 15px 0 15px 0;
935 padding: 15px 0 15px 0;
936 }
936 }
937
937
938 .mypage-box {
938 .mypage-box {
939 margin:0 0 20px 0;
939 margin:0 0 20px 0;
940 color:#505050;
940 color:#505050;
941 line-height:1.5em;
941 line-height:1.5em;
942 }
942 }
943
943
944 .handle {cursor: move;}
944 .handle {cursor: move;}
945
945
946 a.close-icon {
946 a.close-icon {
947 display:block;
947 display:block;
948 margin-top:3px;
948 margin-top:3px;
949 overflow:hidden;
949 overflow:hidden;
950 width:12px;
950 width:12px;
951 height:12px;
951 height:12px;
952 background-repeat: no-repeat;
952 background-repeat: no-repeat;
953 cursor:pointer;
953 cursor:pointer;
954 background-image:url('../images/close.png');
954 background-image:url('../images/close.png');
955 }
955 }
956 a.close-icon:hover {background-image:url('../images/close_hl.png');}
956 a.close-icon:hover {background-image:url('../images/close_hl.png');}
957
957
958 /***** Gantt chart *****/
958 /***** Gantt chart *****/
959 .gantt_hdr {
959 .gantt_hdr {
960 position:absolute;
960 position:absolute;
961 top:0;
961 top:0;
962 height:16px;
962 height:16px;
963 border-top: 1px solid #c0c0c0;
963 border-top: 1px solid #c0c0c0;
964 border-bottom: 1px solid #c0c0c0;
964 border-bottom: 1px solid #c0c0c0;
965 border-right: 1px solid #c0c0c0;
965 border-right: 1px solid #c0c0c0;
966 text-align: center;
966 text-align: center;
967 overflow: hidden;
967 overflow: hidden;
968 }
968 }
969
969
970 .gantt_hdr.nwday {background-color:#f1f1f1;}
970 .gantt_hdr.nwday {background-color:#f1f1f1; color:#999;}
971
971
972 .gantt_subjects { font-size: 0.8em; }
972 .gantt_subjects { font-size: 0.8em; }
973 .gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; }
973 .gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; }
974
974
975 .task {
975 .task {
976 position: absolute;
976 position: absolute;
977 height:8px;
977 height:8px;
978 font-size:0.8em;
978 font-size:0.8em;
979 color:#888;
979 color:#888;
980 padding:0;
980 padding:0;
981 margin:0;
981 margin:0;
982 line-height:16px;
982 line-height:16px;
983 white-space:nowrap;
983 white-space:nowrap;
984 }
984 }
985
985
986 .task.label {width:100%;}
986 .task.label {width:100%;}
987 .task.label.project, .task.label.version { font-weight: bold; }
987 .task.label.project, .task.label.version { font-weight: bold; }
988
988
989 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
989 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
990 .task_done { background:#00c600 url(../images/task_done.png); border: 1px solid #00c600; }
990 .task_done { background:#00c600 url(../images/task_done.png); border: 1px solid #00c600; }
991 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
991 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
992
992
993 .task_todo.parent { background: #888; border: 1px solid #888; height: 3px;}
993 .task_todo.parent { background: #888; border: 1px solid #888; height: 3px;}
994 .task_late.parent, .task_done.parent { height: 3px;}
994 .task_late.parent, .task_done.parent { height: 3px;}
995 .task.parent.marker.starting { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; left: 0px; top: -1px;}
995 .task.parent.marker.starting { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; left: 0px; top: -1px;}
996 .task.parent.marker.ending { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; right: 0px; top: -1px;}
996 .task.parent.marker.ending { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; right: 0px; top: -1px;}
997
997
998 .version.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
998 .version.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
999 .version.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
999 .version.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
1000 .version.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1000 .version.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1001 .version.marker { background-image:url(../images/version_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1001 .version.marker { background-image:url(../images/version_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1002
1002
1003 .project.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
1003 .project.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
1004 .project.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
1004 .project.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
1005 .project.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1005 .project.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1006 .project.marker { background-image:url(../images/project_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1006 .project.marker { background-image:url(../images/project_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1007
1007
1008 .version-behind-schedule a, .issue-behind-schedule a {color: #f66914;}
1008 .version-behind-schedule a, .issue-behind-schedule a {color: #f66914;}
1009 .version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;}
1009 .version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;}
1010
1010
1011 /***** Icons *****/
1011 /***** Icons *****/
1012 .icon {
1012 .icon {
1013 background-position: 0% 50%;
1013 background-position: 0% 50%;
1014 background-repeat: no-repeat;
1014 background-repeat: no-repeat;
1015 padding-left: 20px;
1015 padding-left: 20px;
1016 padding-top: 2px;
1016 padding-top: 2px;
1017 padding-bottom: 3px;
1017 padding-bottom: 3px;
1018 }
1018 }
1019
1019
1020 .icon-add { background-image: url(../images/add.png); }
1020 .icon-add { background-image: url(../images/add.png); }
1021 .icon-edit { background-image: url(../images/edit.png); }
1021 .icon-edit { background-image: url(../images/edit.png); }
1022 .icon-copy { background-image: url(../images/copy.png); }
1022 .icon-copy { background-image: url(../images/copy.png); }
1023 .icon-duplicate { background-image: url(../images/duplicate.png); }
1023 .icon-duplicate { background-image: url(../images/duplicate.png); }
1024 .icon-del { background-image: url(../images/delete.png); }
1024 .icon-del { background-image: url(../images/delete.png); }
1025 .icon-move { background-image: url(../images/move.png); }
1025 .icon-move { background-image: url(../images/move.png); }
1026 .icon-save { background-image: url(../images/save.png); }
1026 .icon-save { background-image: url(../images/save.png); }
1027 .icon-cancel { background-image: url(../images/cancel.png); }
1027 .icon-cancel { background-image: url(../images/cancel.png); }
1028 .icon-multiple { background-image: url(../images/table_multiple.png); }
1028 .icon-multiple { background-image: url(../images/table_multiple.png); }
1029 .icon-folder { background-image: url(../images/folder.png); }
1029 .icon-folder { background-image: url(../images/folder.png); }
1030 .open .icon-folder { background-image: url(../images/folder_open.png); }
1030 .open .icon-folder { background-image: url(../images/folder_open.png); }
1031 .icon-package { background-image: url(../images/package.png); }
1031 .icon-package { background-image: url(../images/package.png); }
1032 .icon-user { background-image: url(../images/user.png); }
1032 .icon-user { background-image: url(../images/user.png); }
1033 .icon-projects { background-image: url(../images/projects.png); }
1033 .icon-projects { background-image: url(../images/projects.png); }
1034 .icon-help { background-image: url(../images/help.png); }
1034 .icon-help { background-image: url(../images/help.png); }
1035 .icon-attachment { background-image: url(../images/attachment.png); }
1035 .icon-attachment { background-image: url(../images/attachment.png); }
1036 .icon-history { background-image: url(../images/history.png); }
1036 .icon-history { background-image: url(../images/history.png); }
1037 .icon-time { background-image: url(../images/time.png); }
1037 .icon-time { background-image: url(../images/time.png); }
1038 .icon-time-add { background-image: url(../images/time_add.png); }
1038 .icon-time-add { background-image: url(../images/time_add.png); }
1039 .icon-stats { background-image: url(../images/stats.png); }
1039 .icon-stats { background-image: url(../images/stats.png); }
1040 .icon-warning { background-image: url(../images/warning.png); }
1040 .icon-warning { background-image: url(../images/warning.png); }
1041 .icon-fav { background-image: url(../images/fav.png); }
1041 .icon-fav { background-image: url(../images/fav.png); }
1042 .icon-fav-off { background-image: url(../images/fav_off.png); }
1042 .icon-fav-off { background-image: url(../images/fav_off.png); }
1043 .icon-reload { background-image: url(../images/reload.png); }
1043 .icon-reload { background-image: url(../images/reload.png); }
1044 .icon-lock { background-image: url(../images/locked.png); }
1044 .icon-lock { background-image: url(../images/locked.png); }
1045 .icon-unlock { background-image: url(../images/unlock.png); }
1045 .icon-unlock { background-image: url(../images/unlock.png); }
1046 .icon-checked { background-image: url(../images/true.png); }
1046 .icon-checked { background-image: url(../images/true.png); }
1047 .icon-details { background-image: url(../images/zoom_in.png); }
1047 .icon-details { background-image: url(../images/zoom_in.png); }
1048 .icon-report { background-image: url(../images/report.png); }
1048 .icon-report { background-image: url(../images/report.png); }
1049 .icon-comment { background-image: url(../images/comment.png); }
1049 .icon-comment { background-image: url(../images/comment.png); }
1050 .icon-summary { background-image: url(../images/lightning.png); }
1050 .icon-summary { background-image: url(../images/lightning.png); }
1051 .icon-server-authentication { background-image: url(../images/server_key.png); }
1051 .icon-server-authentication { background-image: url(../images/server_key.png); }
1052 .icon-issue { background-image: url(../images/ticket.png); }
1052 .icon-issue { background-image: url(../images/ticket.png); }
1053 .icon-zoom-in { background-image: url(../images/zoom_in.png); }
1053 .icon-zoom-in { background-image: url(../images/zoom_in.png); }
1054 .icon-zoom-out { background-image: url(../images/zoom_out.png); }
1054 .icon-zoom-out { background-image: url(../images/zoom_out.png); }
1055 .icon-passwd { background-image: url(../images/textfield_key.png); }
1055 .icon-passwd { background-image: url(../images/textfield_key.png); }
1056 .icon-test { background-image: url(../images/bullet_go.png); }
1056 .icon-test { background-image: url(../images/bullet_go.png); }
1057 .icon-email-add { background-image: url(../images/email_add.png); }
1057 .icon-email-add { background-image: url(../images/email_add.png); }
1058
1058
1059 .icon-file { background-image: url(../images/files/default.png); }
1059 .icon-file { background-image: url(../images/files/default.png); }
1060 .icon-file.text-plain { background-image: url(../images/files/text.png); }
1060 .icon-file.text-plain { background-image: url(../images/files/text.png); }
1061 .icon-file.text-x-c { background-image: url(../images/files/c.png); }
1061 .icon-file.text-x-c { background-image: url(../images/files/c.png); }
1062 .icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); }
1062 .icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); }
1063 .icon-file.text-x-java { background-image: url(../images/files/java.png); }
1063 .icon-file.text-x-java { background-image: url(../images/files/java.png); }
1064 .icon-file.text-x-javascript { background-image: url(../images/files/js.png); }
1064 .icon-file.text-x-javascript { background-image: url(../images/files/js.png); }
1065 .icon-file.text-x-php { background-image: url(../images/files/php.png); }
1065 .icon-file.text-x-php { background-image: url(../images/files/php.png); }
1066 .icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); }
1066 .icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); }
1067 .icon-file.text-xml { background-image: url(../images/files/xml.png); }
1067 .icon-file.text-xml { background-image: url(../images/files/xml.png); }
1068 .icon-file.text-css { background-image: url(../images/files/css.png); }
1068 .icon-file.text-css { background-image: url(../images/files/css.png); }
1069 .icon-file.text-html { background-image: url(../images/files/html.png); }
1069 .icon-file.text-html { background-image: url(../images/files/html.png); }
1070 .icon-file.image-gif { background-image: url(../images/files/image.png); }
1070 .icon-file.image-gif { background-image: url(../images/files/image.png); }
1071 .icon-file.image-jpeg { background-image: url(../images/files/image.png); }
1071 .icon-file.image-jpeg { background-image: url(../images/files/image.png); }
1072 .icon-file.image-png { background-image: url(../images/files/image.png); }
1072 .icon-file.image-png { background-image: url(../images/files/image.png); }
1073 .icon-file.image-tiff { background-image: url(../images/files/image.png); }
1073 .icon-file.image-tiff { background-image: url(../images/files/image.png); }
1074 .icon-file.application-pdf { background-image: url(../images/files/pdf.png); }
1074 .icon-file.application-pdf { background-image: url(../images/files/pdf.png); }
1075 .icon-file.application-zip { background-image: url(../images/files/zip.png); }
1075 .icon-file.application-zip { background-image: url(../images/files/zip.png); }
1076 .icon-file.application-x-gzip { background-image: url(../images/files/zip.png); }
1076 .icon-file.application-x-gzip { background-image: url(../images/files/zip.png); }
1077
1077
1078 img.gravatar {
1078 img.gravatar {
1079 padding: 2px;
1079 padding: 2px;
1080 border: solid 1px #d5d5d5;
1080 border: solid 1px #d5d5d5;
1081 background: #fff;
1081 background: #fff;
1082 vertical-align: middle;
1082 vertical-align: middle;
1083 }
1083 }
1084
1084
1085 div.issue img.gravatar {
1085 div.issue img.gravatar {
1086 float: left;
1086 float: left;
1087 margin: 0 6px 0 0;
1087 margin: 0 6px 0 0;
1088 padding: 5px;
1088 padding: 5px;
1089 }
1089 }
1090
1090
1091 div.issue table img.gravatar {
1091 div.issue table img.gravatar {
1092 height: 14px;
1092 height: 14px;
1093 width: 14px;
1093 width: 14px;
1094 padding: 2px;
1094 padding: 2px;
1095 float: left;
1095 float: left;
1096 margin: 0 0.5em 0 0;
1096 margin: 0 0.5em 0 0;
1097 }
1097 }
1098
1098
1099 h2 img.gravatar {margin: -2px 4px -4px 0;}
1099 h2 img.gravatar {margin: -2px 4px -4px 0;}
1100 h3 img.gravatar {margin: -4px 4px -4px 0;}
1100 h3 img.gravatar {margin: -4px 4px -4px 0;}
1101 h4 img.gravatar {margin: -6px 4px -4px 0;}
1101 h4 img.gravatar {margin: -6px 4px -4px 0;}
1102 td.username img.gravatar {margin: 0 0.5em 0 0; vertical-align: top;}
1102 td.username img.gravatar {margin: 0 0.5em 0 0; vertical-align: top;}
1103 #activity dt img.gravatar {float: left; margin: 0 1em 1em 0;}
1103 #activity dt img.gravatar {float: left; margin: 0 1em 1em 0;}
1104 /* Used on 12px Gravatar img tags without the icon background */
1104 /* Used on 12px Gravatar img tags without the icon background */
1105 .icon-gravatar {float: left; margin-right: 4px;}
1105 .icon-gravatar {float: left; margin-right: 4px;}
1106
1106
1107 #activity dt, .journal {clear: left;}
1107 #activity dt, .journal {clear: left;}
1108
1108
1109 .journal-link {float: right;}
1109 .journal-link {float: right;}
1110
1110
1111 h2 img { vertical-align:middle; }
1111 h2 img { vertical-align:middle; }
1112
1112
1113 .hascontextmenu { cursor: context-menu; }
1113 .hascontextmenu { cursor: context-menu; }
1114
1114
1115 .sample-data {border:1px solid #ccc; border-collapse:collapse; background-color:#fff; margin:0.5em;}
1115 .sample-data {border:1px solid #ccc; border-collapse:collapse; background-color:#fff; margin:0.5em;}
1116 .sample-data td {border:1px solid #ccc; padding: 2px 4px; font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
1116 .sample-data td {border:1px solid #ccc; padding: 2px 4px; font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
1117 .sample-data tr:first-child td {font-weight:bold; text-align:center;}
1117 .sample-data tr:first-child td {font-weight:bold; text-align:center;}
1118
1118
1119 .ui-progressbar {position: relative;}
1119 .ui-progressbar {position: relative;}
1120 #progress-label {
1120 #progress-label {
1121 position: absolute; left: 50%; top: 4px;
1121 position: absolute; left: 50%; top: 4px;
1122 font-weight: bold;
1122 font-weight: bold;
1123 color: #555; text-shadow: 1px 1px 0 #fff;
1123 color: #555; text-shadow: 1px 1px 0 #fff;
1124 }
1124 }
1125
1125
1126 /* Custom JQuery styles */
1126 /* Custom JQuery styles */
1127 .ui-datepicker-title select {width:70px !important; margin-top:-2px !important; margin-right:4px !important;}
1127 .ui-datepicker-title select {width:70px !important; margin-top:-2px !important; margin-right:4px !important;}
1128
1128
1129
1129
1130 /************* CodeRay styles *************/
1130 /************* CodeRay styles *************/
1131 .syntaxhl div {display: inline;}
1131 .syntaxhl div {display: inline;}
1132 .syntaxhl .code pre { overflow: auto }
1132 .syntaxhl .code pre { overflow: auto }
1133
1133
1134 .syntaxhl .annotation { color:#007 }
1134 .syntaxhl .annotation { color:#007 }
1135 .syntaxhl .attribute-name { color:#b48 }
1135 .syntaxhl .attribute-name { color:#b48 }
1136 .syntaxhl .attribute-value { color:#700 }
1136 .syntaxhl .attribute-value { color:#700 }
1137 .syntaxhl .binary { color:#549 }
1137 .syntaxhl .binary { color:#549 }
1138 .syntaxhl .binary .char { color:#325 }
1138 .syntaxhl .binary .char { color:#325 }
1139 .syntaxhl .binary .delimiter { color:#325 }
1139 .syntaxhl .binary .delimiter { color:#325 }
1140 .syntaxhl .char { color:#D20 }
1140 .syntaxhl .char { color:#D20 }
1141 .syntaxhl .char .content { color:#D20 }
1141 .syntaxhl .char .content { color:#D20 }
1142 .syntaxhl .char .delimiter { color:#710 }
1142 .syntaxhl .char .delimiter { color:#710 }
1143 .syntaxhl .class { color:#258; font-weight:bold }
1143 .syntaxhl .class { color:#258; font-weight:bold }
1144 .syntaxhl .class-variable { color:#369 }
1144 .syntaxhl .class-variable { color:#369 }
1145 .syntaxhl .color { color:#0A0 }
1145 .syntaxhl .color { color:#0A0 }
1146 .syntaxhl .comment { color:#385 }
1146 .syntaxhl .comment { color:#385 }
1147 .syntaxhl .comment .char { color:#385 }
1147 .syntaxhl .comment .char { color:#385 }
1148 .syntaxhl .comment .delimiter { color:#385 }
1148 .syntaxhl .comment .delimiter { color:#385 }
1149 .syntaxhl .constant { color:#258; font-weight:bold }
1149 .syntaxhl .constant { color:#258; font-weight:bold }
1150 .syntaxhl .decorator { color:#B0B }
1150 .syntaxhl .decorator { color:#B0B }
1151 .syntaxhl .definition { color:#099; font-weight:bold }
1151 .syntaxhl .definition { color:#099; font-weight:bold }
1152 .syntaxhl .delimiter { color:black }
1152 .syntaxhl .delimiter { color:black }
1153 .syntaxhl .directive { color:#088; font-weight:bold }
1153 .syntaxhl .directive { color:#088; font-weight:bold }
1154 .syntaxhl .docstring { color:#D42; }
1154 .syntaxhl .docstring { color:#D42; }
1155 .syntaxhl .doctype { color:#34b }
1155 .syntaxhl .doctype { color:#34b }
1156 .syntaxhl .done { text-decoration: line-through; color: gray }
1156 .syntaxhl .done { text-decoration: line-through; color: gray }
1157 .syntaxhl .entity { color:#800; font-weight:bold }
1157 .syntaxhl .entity { color:#800; font-weight:bold }
1158 .syntaxhl .error { color:#F00; background-color:#FAA }
1158 .syntaxhl .error { color:#F00; background-color:#FAA }
1159 .syntaxhl .escape { color:#666 }
1159 .syntaxhl .escape { color:#666 }
1160 .syntaxhl .exception { color:#C00; font-weight:bold }
1160 .syntaxhl .exception { color:#C00; font-weight:bold }
1161 .syntaxhl .float { color:#06D }
1161 .syntaxhl .float { color:#06D }
1162 .syntaxhl .function { color:#06B; font-weight:bold }
1162 .syntaxhl .function { color:#06B; font-weight:bold }
1163 .syntaxhl .function .delimiter { color:#024; font-weight:bold }
1163 .syntaxhl .function .delimiter { color:#024; font-weight:bold }
1164 .syntaxhl .global-variable { color:#d70 }
1164 .syntaxhl .global-variable { color:#d70 }
1165 .syntaxhl .hex { color:#02b }
1165 .syntaxhl .hex { color:#02b }
1166 .syntaxhl .id { color:#33D; font-weight:bold }
1166 .syntaxhl .id { color:#33D; font-weight:bold }
1167 .syntaxhl .include { color:#B44; font-weight:bold }
1167 .syntaxhl .include { color:#B44; font-weight:bold }
1168 .syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black }
1168 .syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black }
1169 .syntaxhl .inline-delimiter { font-weight: bold; color: #666 }
1169 .syntaxhl .inline-delimiter { font-weight: bold; color: #666 }
1170 .syntaxhl .instance-variable { color:#33B }
1170 .syntaxhl .instance-variable { color:#33B }
1171 .syntaxhl .integer { color:#06D }
1171 .syntaxhl .integer { color:#06D }
1172 .syntaxhl .imaginary { color:#f00 }
1172 .syntaxhl .imaginary { color:#f00 }
1173 .syntaxhl .important { color:#D00 }
1173 .syntaxhl .important { color:#D00 }
1174 .syntaxhl .key { color: #606 }
1174 .syntaxhl .key { color: #606 }
1175 .syntaxhl .key .char { color: #60f }
1175 .syntaxhl .key .char { color: #60f }
1176 .syntaxhl .key .delimiter { color: #404 }
1176 .syntaxhl .key .delimiter { color: #404 }
1177 .syntaxhl .keyword { color:#939; font-weight:bold }
1177 .syntaxhl .keyword { color:#939; font-weight:bold }
1178 .syntaxhl .label { color:#970; font-weight:bold }
1178 .syntaxhl .label { color:#970; font-weight:bold }
1179 .syntaxhl .local-variable { color:#950 }
1179 .syntaxhl .local-variable { color:#950 }
1180 .syntaxhl .map .content { color:#808 }
1180 .syntaxhl .map .content { color:#808 }
1181 .syntaxhl .map .delimiter { color:#40A}
1181 .syntaxhl .map .delimiter { color:#40A}
1182 .syntaxhl .map { background-color:hsla(200,100%,50%,0.06); }
1182 .syntaxhl .map { background-color:hsla(200,100%,50%,0.06); }
1183 .syntaxhl .namespace { color:#707; font-weight:bold }
1183 .syntaxhl .namespace { color:#707; font-weight:bold }
1184 .syntaxhl .octal { color:#40E }
1184 .syntaxhl .octal { color:#40E }
1185 .syntaxhl .operator { }
1185 .syntaxhl .operator { }
1186 .syntaxhl .predefined { color:#369; font-weight:bold }
1186 .syntaxhl .predefined { color:#369; font-weight:bold }
1187 .syntaxhl .predefined-constant { color:#069 }
1187 .syntaxhl .predefined-constant { color:#069 }
1188 .syntaxhl .predefined-type { color:#0a8; font-weight:bold }
1188 .syntaxhl .predefined-type { color:#0a8; font-weight:bold }
1189 .syntaxhl .preprocessor { color:#579 }
1189 .syntaxhl .preprocessor { color:#579 }
1190 .syntaxhl .pseudo-class { color:#00C; font-weight:bold }
1190 .syntaxhl .pseudo-class { color:#00C; font-weight:bold }
1191 .syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
1191 .syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
1192 .syntaxhl .regexp .content { color:#808 }
1192 .syntaxhl .regexp .content { color:#808 }
1193 .syntaxhl .regexp .delimiter { color:#404 }
1193 .syntaxhl .regexp .delimiter { color:#404 }
1194 .syntaxhl .regexp .modifier { color:#C2C }
1194 .syntaxhl .regexp .modifier { color:#C2C }
1195 .syntaxhl .reserved { color:#080; font-weight:bold }
1195 .syntaxhl .reserved { color:#080; font-weight:bold }
1196 .syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
1196 .syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
1197 .syntaxhl .shell .content { color:#2B2 }
1197 .syntaxhl .shell .content { color:#2B2 }
1198 .syntaxhl .shell .delimiter { color:#161 }
1198 .syntaxhl .shell .delimiter { color:#161 }
1199 .syntaxhl .string .char { color: #46a }
1199 .syntaxhl .string .char { color: #46a }
1200 .syntaxhl .string .content { color: #46a }
1200 .syntaxhl .string .content { color: #46a }
1201 .syntaxhl .string .delimiter { color: #46a }
1201 .syntaxhl .string .delimiter { color: #46a }
1202 .syntaxhl .string .modifier { color: #46a }
1202 .syntaxhl .string .modifier { color: #46a }
1203 .syntaxhl .symbol { color:#d33 }
1203 .syntaxhl .symbol { color:#d33 }
1204 .syntaxhl .symbol .content { color:#d33 }
1204 .syntaxhl .symbol .content { color:#d33 }
1205 .syntaxhl .symbol .delimiter { color:#d33 }
1205 .syntaxhl .symbol .delimiter { color:#d33 }
1206 .syntaxhl .tag { color:#070; font-weight:bold }
1206 .syntaxhl .tag { color:#070; font-weight:bold }
1207 .syntaxhl .type { color:#339; font-weight:bold }
1207 .syntaxhl .type { color:#339; font-weight:bold }
1208 .syntaxhl .value { color: #088 }
1208 .syntaxhl .value { color: #088 }
1209 .syntaxhl .variable { color:#037 }
1209 .syntaxhl .variable { color:#037 }
1210
1210
1211 .syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
1211 .syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
1212 .syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
1212 .syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
1213 .syntaxhl .change { color: #bbf; background: #007 }
1213 .syntaxhl .change { color: #bbf; background: #007 }
1214 .syntaxhl .head { color: #f8f; background: #505 }
1214 .syntaxhl .head { color: #f8f; background: #505 }
1215 .syntaxhl .head .filename { color: white; }
1215 .syntaxhl .head .filename { color: white; }
1216
1216
1217 .syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
1217 .syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
1218 .syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
1218 .syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
1219
1219
1220 .syntaxhl .insert .insert { color: #0c0; background:transparent; font-weight:bold }
1220 .syntaxhl .insert .insert { color: #0c0; background:transparent; font-weight:bold }
1221 .syntaxhl .delete .delete { color: #c00; background:transparent; font-weight:bold }
1221 .syntaxhl .delete .delete { color: #c00; background:transparent; font-weight:bold }
1222 .syntaxhl .change .change { color: #88f }
1222 .syntaxhl .change .change { color: #88f }
1223 .syntaxhl .head .head { color: #f4f }
1223 .syntaxhl .head .head { color: #f4f }
1224
1224
1225 /***** Media print specific styles *****/
1225 /***** Media print specific styles *****/
1226 @media print {
1226 @media print {
1227 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
1227 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
1228 #main { background: #fff; }
1228 #main { background: #fff; }
1229 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
1229 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
1230 #wiki_add_attachment { display:none; }
1230 #wiki_add_attachment { display:none; }
1231 .hide-when-print { display: none; }
1231 .hide-when-print { display: none; }
1232 .autoscroll {overflow-x: visible;}
1232 .autoscroll {overflow-x: visible;}
1233 table.list {margin-top:0.5em;}
1233 table.list {margin-top:0.5em;}
1234 table.list th, table.list td {border: 1px solid #aaa;}
1234 table.list th, table.list td {border: 1px solid #aaa;}
1235 }
1235 }
1236
1236
1237 /* Accessibility specific styles */
1237 /* Accessibility specific styles */
1238 .hidden-for-sighted {
1238 .hidden-for-sighted {
1239 position:absolute;
1239 position:absolute;
1240 left:-10000px;
1240 left:-10000px;
1241 top:auto;
1241 top:auto;
1242 width:1px;
1242 width:1px;
1243 height:1px;
1243 height:1px;
1244 overflow:hidden;
1244 overflow:hidden;
1245 }
1245 }
General Comments 0
You need to be logged in to leave comments. Login now