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