##// END OF EJS Templates
Replaces del tags by a css style (a.issue.closed) for closed issue links....
Jean-Philippe Lang -
r1209:4f35ec97e88c
parent child
Show More
@@ -1,466 +1,466
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module ApplicationHelper
18 module ApplicationHelper
19 include Redmine::WikiFormatting::Macros::Definitions
19 include Redmine::WikiFormatting::Macros::Definitions
20
20
21 def current_role
21 def current_role
22 @current_role ||= User.current.role_for_project(@project)
22 @current_role ||= User.current.role_for_project(@project)
23 end
23 end
24
24
25 # Return true if user is authorized for controller/action, otherwise false
25 # Return true if user is authorized for controller/action, otherwise false
26 def authorize_for(controller, action)
26 def authorize_for(controller, action)
27 User.current.allowed_to?({:controller => controller, :action => action}, @project)
27 User.current.allowed_to?({:controller => controller, :action => action}, @project)
28 end
28 end
29
29
30 # Display a link if user is authorized
30 # Display a link if user is authorized
31 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
31 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
32 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
32 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
33 end
33 end
34
34
35 # Display a link to user's account page
35 # Display a link to user's account page
36 def link_to_user(user)
36 def link_to_user(user)
37 user ? link_to(user, :controller => 'account', :action => 'show', :id => user) : 'Anonymous'
37 user ? link_to(user, :controller => 'account', :action => 'show', :id => user) : 'Anonymous'
38 end
38 end
39
39
40 def link_to_issue(issue)
40 def link_to_issue(issue)
41 link_to "#{issue.tracker.name} ##{issue.id}", :controller => "issues", :action => "show", :id => issue
41 link_to "#{issue.tracker.name} ##{issue.id}", :controller => "issues", :action => "show", :id => issue
42 end
42 end
43
43
44 def toggle_link(name, id, options={})
44 def toggle_link(name, id, options={})
45 onclick = "Element.toggle('#{id}'); "
45 onclick = "Element.toggle('#{id}'); "
46 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
46 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
47 onclick << "return false;"
47 onclick << "return false;"
48 link_to(name, "#", :onclick => onclick)
48 link_to(name, "#", :onclick => onclick)
49 end
49 end
50
50
51 def show_and_goto_link(name, id, options={})
51 def show_and_goto_link(name, id, options={})
52 onclick = "Element.show('#{id}'); "
52 onclick = "Element.show('#{id}'); "
53 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
53 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
54 onclick << "Element.scrollTo('#{id}'); "
54 onclick << "Element.scrollTo('#{id}'); "
55 onclick << "return false;"
55 onclick << "return false;"
56 link_to(name, "#", options.merge(:onclick => onclick))
56 link_to(name, "#", options.merge(:onclick => onclick))
57 end
57 end
58
58
59 def image_to_function(name, function, html_options = {})
59 def image_to_function(name, function, html_options = {})
60 html_options.symbolize_keys!
60 html_options.symbolize_keys!
61 tag(:input, html_options.merge({
61 tag(:input, html_options.merge({
62 :type => "image", :src => image_path(name),
62 :type => "image", :src => image_path(name),
63 :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
63 :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
64 }))
64 }))
65 end
65 end
66
66
67 def prompt_to_remote(name, text, param, url, html_options = {})
67 def prompt_to_remote(name, text, param, url, html_options = {})
68 html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
68 html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
69 link_to name, {}, html_options
69 link_to name, {}, html_options
70 end
70 end
71
71
72 def format_date(date)
72 def format_date(date)
73 return nil unless date
73 return nil unless date
74 # "Setting.date_format.size < 2" is a temporary fix (content of date_format setting changed)
74 # "Setting.date_format.size < 2" is a temporary fix (content of date_format setting changed)
75 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
75 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
76 date.strftime(@date_format)
76 date.strftime(@date_format)
77 end
77 end
78
78
79 def format_time(time, include_date = true)
79 def format_time(time, include_date = true)
80 return nil unless time
80 return nil unless time
81 time = time.to_time if time.is_a?(String)
81 time = time.to_time if time.is_a?(String)
82 zone = User.current.time_zone
82 zone = User.current.time_zone
83 if time.utc?
83 if time.utc?
84 local = zone ? zone.adjust(time) : time.getlocal
84 local = zone ? zone.adjust(time) : time.getlocal
85 else
85 else
86 local = zone ? zone.adjust(time.getutc) : time
86 local = zone ? zone.adjust(time.getutc) : time
87 end
87 end
88 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
88 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
89 @time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
89 @time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
90 include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
90 include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
91 end
91 end
92
92
93 def html_hours(text)
93 def html_hours(text)
94 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
94 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
95 end
95 end
96
96
97 def authoring(created, author)
97 def authoring(created, author)
98 time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
98 time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
99 l(:label_added_time_by, author || 'Anonymous', time_tag)
99 l(:label_added_time_by, author || 'Anonymous', time_tag)
100 end
100 end
101
101
102 def l_or_humanize(s)
102 def l_or_humanize(s)
103 l_has_string?("label_#{s}".to_sym) ? l("label_#{s}".to_sym) : s.to_s.humanize
103 l_has_string?("label_#{s}".to_sym) ? l("label_#{s}".to_sym) : s.to_s.humanize
104 end
104 end
105
105
106 def day_name(day)
106 def day_name(day)
107 l(:general_day_names).split(',')[day-1]
107 l(:general_day_names).split(',')[day-1]
108 end
108 end
109
109
110 def month_name(month)
110 def month_name(month)
111 l(:actionview_datehelper_select_month_names).split(',')[month-1]
111 l(:actionview_datehelper_select_month_names).split(',')[month-1]
112 end
112 end
113
113
114 def pagination_links_full(paginator, count=nil, options={})
114 def pagination_links_full(paginator, count=nil, options={})
115 page_param = options.delete(:page_param) || :page
115 page_param = options.delete(:page_param) || :page
116 url_param = params.dup
116 url_param = params.dup
117 # don't reuse params if filters are present
117 # don't reuse params if filters are present
118 url_param.clear if url_param.has_key?(:set_filter)
118 url_param.clear if url_param.has_key?(:set_filter)
119
119
120 html = ''
120 html = ''
121 html << link_to_remote(('&#171; ' + l(:label_previous)),
121 html << link_to_remote(('&#171; ' + l(:label_previous)),
122 {:update => 'content',
122 {:update => 'content',
123 :url => url_param.merge(page_param => paginator.current.previous),
123 :url => url_param.merge(page_param => paginator.current.previous),
124 :complete => 'window.scrollTo(0,0)'},
124 :complete => 'window.scrollTo(0,0)'},
125 {:href => url_for(:params => url_param.merge(page_param => paginator.current.previous))}) + ' ' if paginator.current.previous
125 {:href => url_for(:params => url_param.merge(page_param => paginator.current.previous))}) + ' ' if paginator.current.previous
126
126
127 html << (pagination_links_each(paginator, options) do |n|
127 html << (pagination_links_each(paginator, options) do |n|
128 link_to_remote(n.to_s,
128 link_to_remote(n.to_s,
129 {:url => {:params => url_param.merge(page_param => n)},
129 {:url => {:params => url_param.merge(page_param => n)},
130 :update => 'content',
130 :update => 'content',
131 :complete => 'window.scrollTo(0,0)'},
131 :complete => 'window.scrollTo(0,0)'},
132 {:href => url_for(:params => url_param.merge(page_param => n))})
132 {:href => url_for(:params => url_param.merge(page_param => n))})
133 end || '')
133 end || '')
134
134
135 html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
135 html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
136 {:update => 'content',
136 {:update => 'content',
137 :url => url_param.merge(page_param => paginator.current.next),
137 :url => url_param.merge(page_param => paginator.current.next),
138 :complete => 'window.scrollTo(0,0)'},
138 :complete => 'window.scrollTo(0,0)'},
139 {:href => url_for(:params => url_param.merge(page_param => paginator.current.next))}) if paginator.current.next
139 {:href => url_for(:params => url_param.merge(page_param => paginator.current.next))}) if paginator.current.next
140
140
141 unless count.nil?
141 unless count.nil?
142 html << [" (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})", per_page_links(paginator.items_per_page)].compact.join(' | ')
142 html << [" (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})", per_page_links(paginator.items_per_page)].compact.join(' | ')
143 end
143 end
144
144
145 html
145 html
146 end
146 end
147
147
148 def per_page_links(selected=nil)
148 def per_page_links(selected=nil)
149 url_param = params.dup
149 url_param = params.dup
150 url_param.clear if url_param.has_key?(:set_filter)
150 url_param.clear if url_param.has_key?(:set_filter)
151
151
152 links = Setting.per_page_options_array.collect do |n|
152 links = Setting.per_page_options_array.collect do |n|
153 n == selected ? n : link_to_remote(n, {:update => "content", :url => params.dup.merge(:per_page => n)},
153 n == selected ? n : link_to_remote(n, {:update => "content", :url => params.dup.merge(:per_page => n)},
154 {:href => url_for(url_param.merge(:per_page => n))})
154 {:href => url_for(url_param.merge(:per_page => n))})
155 end
155 end
156 links.size > 1 ? l(:label_display_per_page, links.join(', ')) : nil
156 links.size > 1 ? l(:label_display_per_page, links.join(', ')) : nil
157 end
157 end
158
158
159 def html_title(*args)
159 def html_title(*args)
160 if args.empty?
160 if args.empty?
161 title = []
161 title = []
162 title << @project.name if @project
162 title << @project.name if @project
163 title += @html_title if @html_title
163 title += @html_title if @html_title
164 title << Setting.app_title
164 title << Setting.app_title
165 title.compact.join(' - ')
165 title.compact.join(' - ')
166 else
166 else
167 @html_title ||= []
167 @html_title ||= []
168 @html_title += args
168 @html_title += args
169 end
169 end
170 end
170 end
171
171
172 def accesskey(s)
172 def accesskey(s)
173 Redmine::AccessKeys.key_for s
173 Redmine::AccessKeys.key_for s
174 end
174 end
175
175
176 # Formats text according to system settings.
176 # Formats text according to system settings.
177 # 2 ways to call this method:
177 # 2 ways to call this method:
178 # * with a String: textilizable(text, options)
178 # * with a String: textilizable(text, options)
179 # * with an object and one of its attribute: textilizable(issue, :description, options)
179 # * with an object and one of its attribute: textilizable(issue, :description, options)
180 def textilizable(*args)
180 def textilizable(*args)
181 options = args.last.is_a?(Hash) ? args.pop : {}
181 options = args.last.is_a?(Hash) ? args.pop : {}
182 case args.size
182 case args.size
183 when 1
183 when 1
184 obj = nil
184 obj = nil
185 text = args.shift
185 text = args.shift
186 when 2
186 when 2
187 obj = args.shift
187 obj = args.shift
188 text = obj.send(args.shift).to_s
188 text = obj.send(args.shift).to_s
189 else
189 else
190 raise ArgumentError, 'invalid arguments to textilizable'
190 raise ArgumentError, 'invalid arguments to textilizable'
191 end
191 end
192 return '' if text.blank?
192 return '' if text.blank?
193
193
194 only_path = options.delete(:only_path) == false ? false : true
194 only_path = options.delete(:only_path) == false ? false : true
195
195
196 # when using an image link, try to use an attachment, if possible
196 # when using an image link, try to use an attachment, if possible
197 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
197 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
198
198
199 if attachments
199 if attachments
200 text = text.gsub(/!((\<|\=|\>)?(\([^\)]+\))?(\[[^\]]+\])?(\{[^\}]+\})?)(\S+\.(gif|jpg|jpeg|png))!/) do |m|
200 text = text.gsub(/!((\<|\=|\>)?(\([^\)]+\))?(\[[^\]]+\])?(\{[^\}]+\})?)(\S+\.(gif|jpg|jpeg|png))!/) do |m|
201 style = $1
201 style = $1
202 filename = $6
202 filename = $6
203 rf = Regexp.new(filename, Regexp::IGNORECASE)
203 rf = Regexp.new(filename, Regexp::IGNORECASE)
204 # search for the picture in attachments
204 # search for the picture in attachments
205 if found = attachments.detect { |att| att.filename =~ rf }
205 if found = attachments.detect { |att| att.filename =~ rf }
206 image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found.id
206 image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found.id
207 "!#{style}#{image_url}!"
207 "!#{style}#{image_url}!"
208 else
208 else
209 "!#{style}#{filename}!"
209 "!#{style}#{filename}!"
210 end
210 end
211 end
211 end
212 end
212 end
213
213
214 text = (Setting.text_formatting == 'textile') ?
214 text = (Setting.text_formatting == 'textile') ?
215 Redmine::WikiFormatting.to_html(text) { |macro, args| exec_macro(macro, obj, args) } :
215 Redmine::WikiFormatting.to_html(text) { |macro, args| exec_macro(macro, obj, args) } :
216 simple_format(auto_link(h(text)))
216 simple_format(auto_link(h(text)))
217
217
218 # different methods for formatting wiki links
218 # different methods for formatting wiki links
219 case options[:wiki_links]
219 case options[:wiki_links]
220 when :local
220 when :local
221 # used for local links to html files
221 # used for local links to html files
222 format_wiki_link = Proc.new {|project, title| "#{title}.html" }
222 format_wiki_link = Proc.new {|project, title| "#{title}.html" }
223 when :anchor
223 when :anchor
224 # used for single-file wiki export
224 # used for single-file wiki export
225 format_wiki_link = Proc.new {|project, title| "##{title}" }
225 format_wiki_link = Proc.new {|project, title| "##{title}" }
226 else
226 else
227 format_wiki_link = Proc.new {|project, title| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title) }
227 format_wiki_link = Proc.new {|project, title| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title) }
228 end
228 end
229
229
230 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
230 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
231
231
232 # Wiki links
232 # Wiki links
233 #
233 #
234 # Examples:
234 # Examples:
235 # [[mypage]]
235 # [[mypage]]
236 # [[mypage|mytext]]
236 # [[mypage|mytext]]
237 # wiki links can refer other project wikis, using project name or identifier:
237 # wiki links can refer other project wikis, using project name or identifier:
238 # [[project:]] -> wiki starting page
238 # [[project:]] -> wiki starting page
239 # [[project:|mytext]]
239 # [[project:|mytext]]
240 # [[project:mypage]]
240 # [[project:mypage]]
241 # [[project:mypage|mytext]]
241 # [[project:mypage|mytext]]
242 text = text.gsub(/(!)?(\[\[([^\]\|]+)(\|([^\]\|]+))?\]\])/) do |m|
242 text = text.gsub(/(!)?(\[\[([^\]\|]+)(\|([^\]\|]+))?\]\])/) do |m|
243 link_project = project
243 link_project = project
244 esc, all, page, title = $1, $2, $3, $5
244 esc, all, page, title = $1, $2, $3, $5
245 if esc.nil?
245 if esc.nil?
246 if page =~ /^([^\:]+)\:(.*)$/
246 if page =~ /^([^\:]+)\:(.*)$/
247 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
247 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
248 page = $2
248 page = $2
249 title ||= $1 if page.blank?
249 title ||= $1 if page.blank?
250 end
250 end
251
251
252 if link_project && link_project.wiki
252 if link_project && link_project.wiki
253 # check if page exists
253 # check if page exists
254 wiki_page = link_project.wiki.find_page(page)
254 wiki_page = link_project.wiki.find_page(page)
255 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
255 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
256 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
256 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
257 else
257 else
258 # project or wiki doesn't exist
258 # project or wiki doesn't exist
259 title || page
259 title || page
260 end
260 end
261 else
261 else
262 all
262 all
263 end
263 end
264 end
264 end
265
265
266 # Redmine links
266 # Redmine links
267 #
267 #
268 # Examples:
268 # Examples:
269 # Issues:
269 # Issues:
270 # #52 -> Link to issue #52
270 # #52 -> Link to issue #52
271 # Changesets:
271 # Changesets:
272 # r52 -> Link to revision 52
272 # r52 -> Link to revision 52
273 # Documents:
273 # Documents:
274 # document#17 -> Link to document with id 17
274 # document#17 -> Link to document with id 17
275 # document:Greetings -> Link to the document with title "Greetings"
275 # document:Greetings -> Link to the document with title "Greetings"
276 # document:"Some document" -> Link to the document with title "Some document"
276 # document:"Some document" -> Link to the document with title "Some document"
277 # Versions:
277 # Versions:
278 # version#3 -> Link to version with id 3
278 # version#3 -> Link to version with id 3
279 # version:1.0.0 -> Link to version named "1.0.0"
279 # version:1.0.0 -> Link to version named "1.0.0"
280 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
280 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
281 # Attachments:
281 # Attachments:
282 # attachment:file.zip -> Link to the attachment of the current object named file.zip
282 # attachment:file.zip -> Link to the attachment of the current object named file.zip
283 text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
283 text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
284 leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
284 leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
285 link = nil
285 link = nil
286 if esc.nil?
286 if esc.nil?
287 if prefix.nil? && sep == 'r'
287 if prefix.nil? && sep == 'r'
288 if project && (changeset = project.changesets.find_by_revision(oid))
288 if project && (changeset = project.changesets.find_by_revision(oid))
289 link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid},
289 link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid},
290 :class => 'changeset',
290 :class => 'changeset',
291 :title => truncate(changeset.comments, 100))
291 :title => truncate(changeset.comments, 100))
292 end
292 end
293 elsif sep == '#'
293 elsif sep == '#'
294 oid = oid.to_i
294 oid = oid.to_i
295 case prefix
295 case prefix
296 when nil
296 when nil
297 if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
297 if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
298 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
298 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
299 :class => 'issue',
299 :class => (issue.closed? ? 'issue closed' : 'issue'),
300 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
300 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
301 link = content_tag('del', link) if issue.closed?
301 link = content_tag('del', link) if issue.closed?
302 end
302 end
303 when 'document'
303 when 'document'
304 if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
304 if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
305 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
305 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
306 :class => 'document'
306 :class => 'document'
307 end
307 end
308 when 'version'
308 when 'version'
309 if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
309 if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
310 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
310 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
311 :class => 'version'
311 :class => 'version'
312 end
312 end
313 end
313 end
314 elsif sep == ':'
314 elsif sep == ':'
315 # removes the double quotes if any
315 # removes the double quotes if any
316 name = oid.gsub(%r{^"(.*)"$}, "\\1")
316 name = oid.gsub(%r{^"(.*)"$}, "\\1")
317 case prefix
317 case prefix
318 when 'document'
318 when 'document'
319 if project && document = project.documents.find_by_title(name)
319 if project && document = project.documents.find_by_title(name)
320 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
320 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
321 :class => 'document'
321 :class => 'document'
322 end
322 end
323 when 'version'
323 when 'version'
324 if project && version = project.versions.find_by_name(name)
324 if project && version = project.versions.find_by_name(name)
325 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
325 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
326 :class => 'version'
326 :class => 'version'
327 end
327 end
328 when 'attachment'
328 when 'attachment'
329 if attachments && attachment = attachments.detect {|a| a.filename == name }
329 if attachments && attachment = attachments.detect {|a| a.filename == name }
330 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
330 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
331 :class => 'attachment'
331 :class => 'attachment'
332 end
332 end
333 end
333 end
334 end
334 end
335 end
335 end
336 leading + (link || "#{prefix}#{sep}#{oid}")
336 leading + (link || "#{prefix}#{sep}#{oid}")
337 end
337 end
338
338
339 text
339 text
340 end
340 end
341
341
342 # Same as Rails' simple_format helper without using paragraphs
342 # Same as Rails' simple_format helper without using paragraphs
343 def simple_format_without_paragraph(text)
343 def simple_format_without_paragraph(text)
344 text.to_s.
344 text.to_s.
345 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
345 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
346 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
346 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
347 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
347 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
348 end
348 end
349
349
350 def error_messages_for(object_name, options = {})
350 def error_messages_for(object_name, options = {})
351 options = options.symbolize_keys
351 options = options.symbolize_keys
352 object = instance_variable_get("@#{object_name}")
352 object = instance_variable_get("@#{object_name}")
353 if object && !object.errors.empty?
353 if object && !object.errors.empty?
354 # build full_messages here with controller current language
354 # build full_messages here with controller current language
355 full_messages = []
355 full_messages = []
356 object.errors.each do |attr, msg|
356 object.errors.each do |attr, msg|
357 next if msg.nil?
357 next if msg.nil?
358 msg = msg.first if msg.is_a? Array
358 msg = msg.first if msg.is_a? Array
359 if attr == "base"
359 if attr == "base"
360 full_messages << l(msg)
360 full_messages << l(msg)
361 else
361 else
362 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
362 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
363 end
363 end
364 end
364 end
365 # retrieve custom values error messages
365 # retrieve custom values error messages
366 if object.errors[:custom_values]
366 if object.errors[:custom_values]
367 object.custom_values.each do |v|
367 object.custom_values.each do |v|
368 v.errors.each do |attr, msg|
368 v.errors.each do |attr, msg|
369 next if msg.nil?
369 next if msg.nil?
370 msg = msg.first if msg.is_a? Array
370 msg = msg.first if msg.is_a? Array
371 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
371 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
372 end
372 end
373 end
373 end
374 end
374 end
375 content_tag("div",
375 content_tag("div",
376 content_tag(
376 content_tag(
377 options[:header_tag] || "span", lwr(:gui_validation_error, full_messages.length) + ":"
377 options[:header_tag] || "span", lwr(:gui_validation_error, full_messages.length) + ":"
378 ) +
378 ) +
379 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
379 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
380 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
380 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
381 )
381 )
382 else
382 else
383 ""
383 ""
384 end
384 end
385 end
385 end
386
386
387 def lang_options_for_select(blank=true)
387 def lang_options_for_select(blank=true)
388 (blank ? [["(auto)", ""]] : []) +
388 (blank ? [["(auto)", ""]] : []) +
389 GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
389 GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
390 end
390 end
391
391
392 def label_tag_for(name, option_tags = nil, options = {})
392 def label_tag_for(name, option_tags = nil, options = {})
393 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
393 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
394 content_tag("label", label_text)
394 content_tag("label", label_text)
395 end
395 end
396
396
397 def labelled_tabular_form_for(name, object, options, &proc)
397 def labelled_tabular_form_for(name, object, options, &proc)
398 options[:html] ||= {}
398 options[:html] ||= {}
399 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
399 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
400 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
400 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
401 end
401 end
402
402
403 def check_all_links(form_name)
403 def check_all_links(form_name)
404 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
404 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
405 " | " +
405 " | " +
406 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
406 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
407 end
407 end
408
408
409 def progress_bar(pcts, options={})
409 def progress_bar(pcts, options={})
410 pcts = [pcts, pcts] unless pcts.is_a?(Array)
410 pcts = [pcts, pcts] unless pcts.is_a?(Array)
411 pcts[1] = pcts[1] - pcts[0]
411 pcts[1] = pcts[1] - pcts[0]
412 pcts << (100 - pcts[1] - pcts[0])
412 pcts << (100 - pcts[1] - pcts[0])
413 width = options[:width] || '100px;'
413 width = options[:width] || '100px;'
414 legend = options[:legend] || ''
414 legend = options[:legend] || ''
415 content_tag('table',
415 content_tag('table',
416 content_tag('tr',
416 content_tag('tr',
417 (pcts[0] > 0 ? content_tag('td', '', :width => "#{pcts[0].floor}%;", :class => 'closed') : '') +
417 (pcts[0] > 0 ? content_tag('td', '', :width => "#{pcts[0].floor}%;", :class => 'closed') : '') +
418 (pcts[1] > 0 ? content_tag('td', '', :width => "#{pcts[1].floor}%;", :class => 'done') : '') +
418 (pcts[1] > 0 ? content_tag('td', '', :width => "#{pcts[1].floor}%;", :class => 'done') : '') +
419 (pcts[2] > 0 ? content_tag('td', '', :width => "#{pcts[2].floor}%;", :class => 'todo') : '')
419 (pcts[2] > 0 ? content_tag('td', '', :width => "#{pcts[2].floor}%;", :class => 'todo') : '')
420 ), :class => 'progress', :style => "width: #{width};") +
420 ), :class => 'progress', :style => "width: #{width};") +
421 content_tag('p', legend, :class => 'pourcent')
421 content_tag('p', legend, :class => 'pourcent')
422 end
422 end
423
423
424 def context_menu_link(name, url, options={})
424 def context_menu_link(name, url, options={})
425 options[:class] ||= ''
425 options[:class] ||= ''
426 if options.delete(:selected)
426 if options.delete(:selected)
427 options[:class] << ' icon-checked disabled'
427 options[:class] << ' icon-checked disabled'
428 options[:disabled] = true
428 options[:disabled] = true
429 end
429 end
430 if options.delete(:disabled)
430 if options.delete(:disabled)
431 options.delete(:method)
431 options.delete(:method)
432 options.delete(:confirm)
432 options.delete(:confirm)
433 options.delete(:onclick)
433 options.delete(:onclick)
434 options[:class] << ' disabled'
434 options[:class] << ' disabled'
435 url = '#'
435 url = '#'
436 end
436 end
437 link_to name, url, options
437 link_to name, url, options
438 end
438 end
439
439
440 def calendar_for(field_id)
440 def calendar_for(field_id)
441 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
441 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
442 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
442 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
443 end
443 end
444
444
445 def wikitoolbar_for(field_id)
445 def wikitoolbar_for(field_id)
446 return '' unless Setting.text_formatting == 'textile'
446 return '' unless Setting.text_formatting == 'textile'
447
447
448 help_link = l(:setting_text_formatting) + ': ' +
448 help_link = l(:setting_text_formatting) + ': ' +
449 link_to(l(:label_help), compute_public_path('wiki_syntax', 'help', 'html'),
449 link_to(l(:label_help), compute_public_path('wiki_syntax', 'help', 'html'),
450 :onclick => "window.open(\"#{ compute_public_path('wiki_syntax', 'help', 'html') }\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")
450 :onclick => "window.open(\"#{ compute_public_path('wiki_syntax', 'help', 'html') }\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")
451
451
452 javascript_include_tag('jstoolbar/jstoolbar') +
452 javascript_include_tag('jstoolbar/jstoolbar') +
453 javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language}") +
453 javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language}") +
454 javascript_tag("var toolbar = new jsToolBar($('#{field_id}')); toolbar.setHelpLink('#{help_link}'); toolbar.draw();")
454 javascript_tag("var toolbar = new jsToolBar($('#{field_id}')); toolbar.setHelpLink('#{help_link}'); toolbar.draw();")
455 end
455 end
456
456
457 def content_for(name, content = nil, &block)
457 def content_for(name, content = nil, &block)
458 @has_content ||= {}
458 @has_content ||= {}
459 @has_content[name] = true
459 @has_content[name] = true
460 super(name, content, &block)
460 super(name, content, &block)
461 end
461 end
462
462
463 def has_content?(name)
463 def has_content?(name)
464 (@has_content && @has_content[name]) || false
464 (@has_content && @has_content[name]) || false
465 end
465 end
466 end
466 end
@@ -1,54 +1,50
1 <h2><%=l(:label_roadmap)%></h2>
1 <h2><%=l(:label_roadmap)%></h2>
2
2
3 <% if @versions.empty? %>
3 <% if @versions.empty? %>
4 <p class="nodata"><%= l(:label_no_data) %></p>
4 <p class="nodata"><%= l(:label_no_data) %></p>
5 <% else %>
5 <% else %>
6 <div id="roadmap">
6 <div id="roadmap">
7 <% @versions.each do |version| %>
7 <% @versions.each do |version| %>
8 <%= tag 'a', :name => version.name %>
8 <%= tag 'a', :name => version.name %>
9 <h3 class="icon22 icon22-package"><%= link_to h(version.name), :controller => 'versions', :action => 'show', :id => version %></h3>
9 <h3 class="icon22 icon22-package"><%= link_to h(version.name), :controller => 'versions', :action => 'show', :id => version %></h3>
10 <%= render :partial => 'versions/overview', :locals => {:version => version} %>
10 <%= render :partial => 'versions/overview', :locals => {:version => version} %>
11 <%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %>
11 <%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %>
12
12
13 <% issues = version.fixed_issues.find(:all,
13 <% issues = version.fixed_issues.find(:all,
14 :include => [:status, :tracker],
14 :include => [:status, :tracker],
15 :conditions => ["tracker_id in (#{@selected_tracker_ids.join(',')})"],
15 :conditions => ["tracker_id in (#{@selected_tracker_ids.join(',')})"],
16 :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id") unless @selected_tracker_ids.empty?
16 :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id") unless @selected_tracker_ids.empty?
17 issues ||= []
17 issues ||= []
18 %>
18 %>
19 <% if issues.size > 0 %>
19 <% if issues.size > 0 %>
20 <fieldset class="related-issues"><legend><%= l(:label_related_issues) %></legend>
20 <fieldset class="related-issues"><legend><%= l(:label_related_issues) %></legend>
21 <ul>
21 <ul>
22 <% issues.each do |issue| %>
22 <%- issues.each do |issue| -%>
23 <li>
23 <li class="issue <%= 'closed' if issue.closed? %>"><%= link_to_issue(issue) %>: <%=h issue.subject %></li>
24 <%= link = link_to_issue(issue)
24 <%- end -%>
25 issue.status.is_closed? ? content_tag("del", link) : link %>: <%=h issue.subject %>
26 <%= content_tag "em", "(#{l(:label_closed_issues)})" if issue.status.is_closed? %>
27 </li>
28 <% end %>
29 </ul>
25 </ul>
30 </fieldset>
26 </fieldset>
31 <% end %>
27 <% end %>
32 <% end %>
28 <% end %>
33 </div>
29 </div>
34 <% end %>
30 <% end %>
35
31
36 <% content_for :sidebar do %>
32 <% content_for :sidebar do %>
37 <% form_tag do %>
33 <% form_tag do %>
38 <h3><%= l(:label_roadmap) %></h3>
34 <h3><%= l(:label_roadmap) %></h3>
39 <% @trackers.each do |tracker| %>
35 <% @trackers.each do |tracker| %>
40 <label><%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s), :id => nil %>
36 <label><%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s), :id => nil %>
41 <%= tracker.name %></label><br />
37 <%= tracker.name %></label><br />
42 <% end %>
38 <% end %>
43 <br />
39 <br />
44 <label for="completed"><%= check_box_tag "completed", 1, params[:completed] %> <%= l(:label_show_completed_versions) %></label>
40 <label for="completed"><%= check_box_tag "completed", 1, params[:completed] %> <%= l(:label_show_completed_versions) %></label>
45 <p><%= submit_tag l(:button_apply), :class => 'button-small' %></p>
41 <p><%= submit_tag l(:button_apply), :class => 'button-small' %></p>
46 <% end %>
42 <% end %>
47
43
48 <h3><%= l(:label_version_plural) %></h3>
44 <h3><%= l(:label_version_plural) %></h3>
49 <% @versions.each do |version| %>
45 <% @versions.each do |version| %>
50 <%= link_to version.name, :anchor => version.name %><br />
46 <%= link_to version.name, :anchor => version.name %><br />
51 <% end %>
47 <% end %>
52 <% end %>
48 <% end %>
53
49
54 <% html_title(l(:label_roadmap)) %>
50 <% html_title(l(:label_roadmap)) %>
@@ -1,49 +1,48
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:button_edit), {:controller => 'versions', :action => 'edit', :id => @version}, :class => 'icon icon-edit' %>
2 <%= link_to_if_authorized l(:button_edit), {:controller => 'versions', :action => 'edit', :id => @version}, :class => 'icon icon-edit' %>
3 </div>
3 </div>
4
4
5 <h2><%= h(@version.name) %></h2>
5 <h2><%= h(@version.name) %></h2>
6
6
7 <div id="version-summary">
7 <div id="version-summary">
8 <% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
8 <% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
9 <fieldset><legend><%= l(:label_time_tracking) %></legend>
9 <fieldset><legend><%= l(:label_time_tracking) %></legend>
10 <table>
10 <table>
11 <tr>
11 <tr>
12 <td width="130px" align="right"><%= l(:field_estimated_hours) %></td>
12 <td width="130px" align="right"><%= l(:field_estimated_hours) %></td>
13 <td width="240px" class="total-hours"width="130px" align="right"><%= html_hours(lwr(:label_f_hour, @version.estimated_hours)) %></td>
13 <td width="240px" class="total-hours"width="130px" align="right"><%= html_hours(lwr(:label_f_hour, @version.estimated_hours)) %></td>
14 </tr>
14 </tr>
15 <% if User.current.allowed_to?(:view_time_entries, @project) %>
15 <% if User.current.allowed_to?(:view_time_entries, @project) %>
16 <tr>
16 <tr>
17 <td width="130px" align="right"><%= l(:label_spent_time) %></td>
17 <td width="130px" align="right"><%= l(:label_spent_time) %></td>
18 <td width="240px" class="total-hours"><%= html_hours(lwr(:label_f_hour, @version.spent_hours)) %></td>
18 <td width="240px" class="total-hours"><%= html_hours(lwr(:label_f_hour, @version.spent_hours)) %></td>
19 </tr>
19 </tr>
20 <% end %>
20 <% end %>
21 </table>
21 </table>
22 </fieldset>
22 </fieldset>
23 <% end %>
23 <% end %>
24
24
25 <div id="status_by">
25 <div id="status_by">
26 <%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %>
26 <%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %>
27 </div>
27 </div>
28 </div>
28 </div>
29
29
30 <div id="roadmap">
30 <div id="roadmap">
31 <%= render :partial => 'versions/overview', :locals => {:version => @version} %>
31 <%= render :partial => 'versions/overview', :locals => {:version => @version} %>
32 <%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
32 <%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
33
33
34 <% issues = @version.fixed_issues.find(:all,
34 <% issues = @version.fixed_issues.find(:all,
35 :include => [:status, :tracker],
35 :include => [:status, :tracker],
36 :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id") %>
36 :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id") %>
37 <% if issues.size > 0 %>
37 <% if issues.size > 0 %>
38 <fieldset class="related-issues"><legend><%= l(:label_related_issues) %></legend>
38 <fieldset class="related-issues"><legend><%= l(:label_related_issues) %></legend>
39 <ul>
39 <ul>
40 <% issues.each do |issue| -%>
40 <% issues.each do |issue| -%>
41 <li><%= link = link_to_issue(issue)
41 <li class="issue <%= 'closed' if issue.closed? %>"><%= link_to_issue(issue) %>: <%=h issue.subject %></li>
42 issue.status.is_closed? ? content_tag("del", link) : link %>: <%=h issue.subject %></li>
43 <% end -%>
42 <% end -%>
44 </ul>
43 </ul>
45 </fieldset>
44 </fieldset>
46 <% end %>
45 <% end %>
47 </div>
46 </div>
48
47
49 <% html_title @version.name %>
48 <% html_title @version.name %>
@@ -1,572 +1,574
1 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
1 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
2
2
3 h1, h2, h3, h4 { font-family: "Trebuchet MS", Verdana, sans-serif;}
3 h1, h2, h3, h4 { font-family: "Trebuchet MS", Verdana, sans-serif;}
4 h1 {margin:0; padding:0; font-size: 24px;}
4 h1 {margin:0; padding:0; font-size: 24px;}
5 h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
5 h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
6 h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
6 h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
7 h4, .wiki h3 {font-size: 12px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb; color: #444;}
7 h4, .wiki h3 {font-size: 12px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb; color: #444;}
8
8
9 /***** Layout *****/
9 /***** Layout *****/
10 #wrapper {background: white;}
10 #wrapper {background: white;}
11
11
12 #top-menu {background: #2C4056;color: #fff;height:1.5em; padding: 2px 6px 0px 6px;}
12 #top-menu {background: #2C4056;color: #fff;height:1.5em; padding: 2px 6px 0px 6px;}
13 #top-menu ul {margin: 0; padding: 0;}
13 #top-menu ul {margin: 0; padding: 0;}
14 #top-menu li {
14 #top-menu li {
15 float:left;
15 float:left;
16 list-style-type:none;
16 list-style-type:none;
17 margin: 0px 0px 0px 0px;
17 margin: 0px 0px 0px 0px;
18 padding: 0px 0px 0px 0px;
18 padding: 0px 0px 0px 0px;
19 white-space:nowrap;
19 white-space:nowrap;
20 }
20 }
21 #top-menu a {color: #fff; padding-right: 4px;}
21 #top-menu a {color: #fff; padding-right: 4px;}
22 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
22 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
23
23
24 #account {float:right;}
24 #account {float:right;}
25
25
26 #header {height:5.3em;margin:0;background-color:#507AAA;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;}
26 #header {height:5.3em;margin:0;background-color:#507AAA;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;}
27 #header a {color:#f8f8f8;}
27 #header a {color:#f8f8f8;}
28 #quick-search {float:right;}
28 #quick-search {float:right;}
29
29
30 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
30 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
31 #main-menu ul {margin: 0; padding: 0;}
31 #main-menu ul {margin: 0; padding: 0;}
32 #main-menu li {
32 #main-menu li {
33 float:left;
33 float:left;
34 list-style-type:none;
34 list-style-type:none;
35 margin: 0px 10px 0px 0px;
35 margin: 0px 10px 0px 0px;
36 padding: 0px 0px 0px 0px;
36 padding: 0px 0px 0px 0px;
37 white-space:nowrap;
37 white-space:nowrap;
38 }
38 }
39 #main-menu li a {
39 #main-menu li a {
40 display: block;
40 display: block;
41 color: #fff;
41 color: #fff;
42 text-decoration: none;
42 text-decoration: none;
43 margin: 0;
43 margin: 0;
44 padding: 4px 4px 4px 4px;
44 padding: 4px 4px 4px 4px;
45 background: #2C4056;
45 background: #2C4056;
46 }
46 }
47 #main-menu li a:hover, #main-menu li a.selected {background:#759FCF;}
47 #main-menu li a:hover, #main-menu li a.selected {background:#759FCF;}
48
48
49 #main {background: url(../images/mainbg.png) repeat-x; background-color:#EEEEEE;}
49 #main {background: url(../images/mainbg.png) repeat-x; background-color:#EEEEEE;}
50
50
51 #sidebar{ float: right; width: 17%; position: relative; z-index: 9; min-height: 600px; padding: 0; margin: 0;}
51 #sidebar{ float: right; width: 17%; position: relative; z-index: 9; min-height: 600px; padding: 0; margin: 0;}
52 * html #sidebar{ width: 17%; }
52 * html #sidebar{ width: 17%; }
53 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
53 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
54 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
54 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
55 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
55 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
56
56
57 #content { width: 80%; background: url(../images/contentbg.png) repeat-x; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; height:600px; min-height: 600px;}
57 #content { width: 80%; background: url(../images/contentbg.png) repeat-x; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; height:600px; min-height: 600px;}
58 * html #content{ width: 80%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
58 * html #content{ width: 80%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
59 html>body #content {
59 html>body #content {
60 height: auto;
60 height: auto;
61 min-height: 600px;
61 min-height: 600px;
62 }
62 }
63
63
64 #main.nosidebar #sidebar{ display: none; }
64 #main.nosidebar #sidebar{ display: none; }
65 #main.nosidebar #content{ width: auto; border-right: 0; }
65 #main.nosidebar #content{ width: auto; border-right: 0; }
66
66
67 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
67 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
68
68
69 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
69 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
70 #login-form table td {padding: 6px;}
70 #login-form table td {padding: 6px;}
71 #login-form label {font-weight: bold;}
71 #login-form label {font-weight: bold;}
72
72
73 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
73 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
74
74
75 /***** Links *****/
75 /***** Links *****/
76 a, a:link, a:visited{ color: #2A5685; text-decoration: none; }
76 a, a:link, a:visited{ color: #2A5685; text-decoration: none; }
77 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
77 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
78 a img{ border: 0; }
78 a img{ border: 0; }
79
79
80 a.issue.closed, .issue.closed a { text-decoration: line-through; }
81
80 /***** Tables *****/
82 /***** Tables *****/
81 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
83 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
82 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
84 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
83 table.list td { overflow: hidden; vertical-align: top;}
85 table.list td { overflow: hidden; vertical-align: top;}
84 table.list td.id { width: 2%; text-align: center;}
86 table.list td.id { width: 2%; text-align: center;}
85 table.list td.checkbox { width: 15px; padding: 0px;}
87 table.list td.checkbox { width: 15px; padding: 0px;}
86
88
87 tr.issue { text-align: center; white-space: nowrap; }
89 tr.issue { text-align: center; white-space: nowrap; }
88 tr.issue td.subject, tr.issue td.category { white-space: normal; }
90 tr.issue td.subject, tr.issue td.category { white-space: normal; }
89 tr.issue td.subject { text-align: left; }
91 tr.issue td.subject { text-align: left; }
90 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
92 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
91
93
92 tr.entry { border: 1px solid #f8f8f8; }
94 tr.entry { border: 1px solid #f8f8f8; }
93 tr.entry td { white-space: nowrap; }
95 tr.entry td { white-space: nowrap; }
94 tr.entry td.filename { width: 30%; }
96 tr.entry td.filename { width: 30%; }
95 tr.entry td.size { text-align: right; font-size: 90%; }
97 tr.entry td.size { text-align: right; font-size: 90%; }
96 tr.entry td.revision, tr.entry td.author { text-align: center; }
98 tr.entry td.revision, tr.entry td.author { text-align: center; }
97 tr.entry td.age { text-align: right; }
99 tr.entry td.age { text-align: right; }
98
100
99 tr.changeset td.author { text-align: center; width: 15%; }
101 tr.changeset td.author { text-align: center; width: 15%; }
100 tr.changeset td.committed_on { text-align: center; width: 15%; }
102 tr.changeset td.committed_on { text-align: center; width: 15%; }
101
103
102 tr.message { height: 2.6em; }
104 tr.message { height: 2.6em; }
103 tr.message td.last_message { font-size: 80%; }
105 tr.message td.last_message { font-size: 80%; }
104 tr.message.locked td.subject a { background-image: url(../images/locked.png); }
106 tr.message.locked td.subject a { background-image: url(../images/locked.png); }
105 tr.message.sticky td.subject a { background-image: url(../images/sticky.png); font-weight: bold; }
107 tr.message.sticky td.subject a { background-image: url(../images/sticky.png); font-weight: bold; }
106
108
107 tr.user td { width:13%; }
109 tr.user td { width:13%; }
108 tr.user td.email { width:18%; }
110 tr.user td.email { width:18%; }
109 tr.user td { white-space: nowrap; }
111 tr.user td { white-space: nowrap; }
110 tr.user.locked, tr.user.registered { color: #aaa; }
112 tr.user.locked, tr.user.registered { color: #aaa; }
111 tr.user.locked a, tr.user.registered a { color: #aaa; }
113 tr.user.locked a, tr.user.registered a { color: #aaa; }
112
114
113 tr.time-entry { text-align: center; white-space: nowrap; }
115 tr.time-entry { text-align: center; white-space: nowrap; }
114 tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; }
116 tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; }
115 tr.time-entry td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
117 tr.time-entry td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
116 tr.time-entry .hours-dec { font-size: 0.9em; }
118 tr.time-entry .hours-dec { font-size: 0.9em; }
117
119
118 table.list tbody tr:hover { background-color:#ffffdd; }
120 table.list tbody tr:hover { background-color:#ffffdd; }
119 table td {padding:2px;}
121 table td {padding:2px;}
120 table p {margin:0;}
122 table p {margin:0;}
121 .odd {background-color:#f6f7f8;}
123 .odd {background-color:#f6f7f8;}
122 .even {background-color: #fff;}
124 .even {background-color: #fff;}
123
125
124 .highlight { background-color: #FCFD8D;}
126 .highlight { background-color: #FCFD8D;}
125 .highlight.token-1 { background-color: #faa;}
127 .highlight.token-1 { background-color: #faa;}
126 .highlight.token-2 { background-color: #afa;}
128 .highlight.token-2 { background-color: #afa;}
127 .highlight.token-3 { background-color: #aaf;}
129 .highlight.token-3 { background-color: #aaf;}
128
130
129 .box{
131 .box{
130 padding:6px;
132 padding:6px;
131 margin-bottom: 10px;
133 margin-bottom: 10px;
132 background-color:#f6f6f6;
134 background-color:#f6f6f6;
133 color:#505050;
135 color:#505050;
134 line-height:1.5em;
136 line-height:1.5em;
135 border: 1px solid #e4e4e4;
137 border: 1px solid #e4e4e4;
136 }
138 }
137
139
138 div.square {
140 div.square {
139 border: 1px solid #999;
141 border: 1px solid #999;
140 float: left;
142 float: left;
141 margin: .3em .4em 0 .4em;
143 margin: .3em .4em 0 .4em;
142 overflow: hidden;
144 overflow: hidden;
143 width: .6em; height: .6em;
145 width: .6em; height: .6em;
144 }
146 }
145
147
146 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
148 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
147 .contextual input {font-size:0.9em;}
149 .contextual input {font-size:0.9em;}
148
150
149 .splitcontentleft{float:left; width:49%;}
151 .splitcontentleft{float:left; width:49%;}
150 .splitcontentright{float:right; width:49%;}
152 .splitcontentright{float:right; width:49%;}
151 form {display: inline;}
153 form {display: inline;}
152 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
154 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
153 fieldset {border: 1px solid #e4e4e4; margin:0;}
155 fieldset {border: 1px solid #e4e4e4; margin:0;}
154 legend {color: #484848;}
156 legend {color: #484848;}
155 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
157 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
156 textarea.wiki-edit { width: 99%; }
158 textarea.wiki-edit { width: 99%; }
157 li p {margin-top: 0;}
159 li p {margin-top: 0;}
158 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
160 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
159
161
160 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
162 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
161 div#issue-changesets .changeset { padding: 4px;}
163 div#issue-changesets .changeset { padding: 4px;}
162 div#issue-changesets .changeset { border-bottom: 1px solid #ddd; }
164 div#issue-changesets .changeset { border-bottom: 1px solid #ddd; }
163 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
165 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
164
166
165 div#activity dl { margin-left: 2em; }
167 div#activity dl { margin-left: 2em; }
166 div#activity dd { margin-bottom: 1em; }
168 div#activity dd { margin-bottom: 1em; }
167 div#activity dt { margin-bottom: 1px; }
169 div#activity dt { margin-bottom: 1px; }
168 div#activity dt .time { color: #777; font-size: 80%; }
170 div#activity dt .time { color: #777; font-size: 80%; }
169 div#activity dd .description { font-style: italic; }
171 div#activity dd .description { font-style: italic; }
170
172
171 div#roadmap fieldset.related-issues { margin-bottom: 1em; }
173 div#roadmap fieldset.related-issues { margin-bottom: 1em; }
172 div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; }
174 div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; }
173 div#roadmap .wiki h1:first-child { display: none; }
175 div#roadmap .wiki h1:first-child { display: none; }
174 div#roadmap .wiki h1 { font-size: 120%; }
176 div#roadmap .wiki h1 { font-size: 120%; }
175 div#roadmap .wiki h2 { font-size: 110%; }
177 div#roadmap .wiki h2 { font-size: 110%; }
176
178
177 div#version-summary { float:right; width:380px; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
179 div#version-summary { float:right; width:380px; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
178 div#version-summary fieldset { margin-bottom: 1em; }
180 div#version-summary fieldset { margin-bottom: 1em; }
179 div#version-summary .total-hours { text-align: right; }
181 div#version-summary .total-hours { text-align: right; }
180
182
181 table#time-report td.hours { text-align: right; padding-right: 0.5em; }
183 table#time-report td.hours { text-align: right; padding-right: 0.5em; }
182 table#time-report tbody tr { font-style: italic; color: #777; }
184 table#time-report tbody tr { font-style: italic; color: #777; }
183 table#time-report tbody tr.last-level { font-style: normal; color: #555; }
185 table#time-report tbody tr.last-level { font-style: normal; color: #555; }
184 table#time-report tbody tr.total { font-style: normal; font-weight: bold; color: #555; background-color:#EEEEEE; }
186 table#time-report tbody tr.total { font-style: normal; font-weight: bold; color: #555; background-color:#EEEEEE; }
185 table#time-report .hours-dec { font-size: 0.9em; }
187 table#time-report .hours-dec { font-size: 0.9em; }
186
188
187 .total-hours { font-size: 110%; font-weight: bold; }
189 .total-hours { font-size: 110%; font-weight: bold; }
188 .total-hours span.hours-int { font-size: 120%; }
190 .total-hours span.hours-int { font-size: 120%; }
189
191
190 .autoscroll {overflow-x: auto; padding:1px; width:100%; margin-bottom: 1.2em;}
192 .autoscroll {overflow-x: auto; padding:1px; width:100%; margin-bottom: 1.2em;}
191 #user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
193 #user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
192
194
193 .pagination {font-size: 90%}
195 .pagination {font-size: 90%}
194 p.pagination {margin-top:8px;}
196 p.pagination {margin-top:8px;}
195
197
196 /***** Tabular forms ******/
198 /***** Tabular forms ******/
197 .tabular p{
199 .tabular p{
198 margin: 0;
200 margin: 0;
199 padding: 5px 0 8px 0;
201 padding: 5px 0 8px 0;
200 padding-left: 180px; /*width of left column containing the label elements*/
202 padding-left: 180px; /*width of left column containing the label elements*/
201 height: 1%;
203 height: 1%;
202 clear:left;
204 clear:left;
203 }
205 }
204
206
205 .tabular label{
207 .tabular label{
206 font-weight: bold;
208 font-weight: bold;
207 float: left;
209 float: left;
208 text-align: right;
210 text-align: right;
209 margin-left: -180px; /*width of left column*/
211 margin-left: -180px; /*width of left column*/
210 width: 175px; /*width of labels. Should be smaller than left column to create some right
212 width: 175px; /*width of labels. Should be smaller than left column to create some right
211 margin*/
213 margin*/
212 }
214 }
213
215
214 .tabular label.floating{
216 .tabular label.floating{
215 font-weight: normal;
217 font-weight: normal;
216 margin-left: 0px;
218 margin-left: 0px;
217 text-align: left;
219 text-align: left;
218 width: 200px;
220 width: 200px;
219 }
221 }
220
222
221 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
223 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
222
224
223 .tabular.settings p{ padding-left: 300px; }
225 .tabular.settings p{ padding-left: 300px; }
224 .tabular.settings label{ margin-left: -300px; width: 295px; }
226 .tabular.settings label{ margin-left: -300px; width: 295px; }
225
227
226 .required {color: #bb0000;}
228 .required {color: #bb0000;}
227 .summary {font-style: italic;}
229 .summary {font-style: italic;}
228
230
229 #attachments_fields input[type=text] {margin-left: 8px; }
231 #attachments_fields input[type=text] {margin-left: 8px; }
230
232
231 div.attachments p { margin:4px 0 2px 0; }
233 div.attachments p { margin:4px 0 2px 0; }
232 div.attachments img { vertical-align: middle; }
234 div.attachments img { vertical-align: middle; }
233 div.attachments span.author { font-size: 0.9em; color: #888; }
235 div.attachments span.author { font-size: 0.9em; color: #888; }
234
236
235 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
237 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
236 .other-formats span + span:before { content: "| "; }
238 .other-formats span + span:before { content: "| "; }
237
239
238 a.feed { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
240 a.feed { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
239
241
240 /***** Flash & error messages ****/
242 /***** Flash & error messages ****/
241 #errorExplanation, div.flash, .nodata {
243 #errorExplanation, div.flash, .nodata {
242 padding: 4px 4px 4px 30px;
244 padding: 4px 4px 4px 30px;
243 margin-bottom: 12px;
245 margin-bottom: 12px;
244 font-size: 1.1em;
246 font-size: 1.1em;
245 border: 2px solid;
247 border: 2px solid;
246 }
248 }
247
249
248 div.flash {margin-top: 8px;}
250 div.flash {margin-top: 8px;}
249
251
250 div.flash.error, #errorExplanation {
252 div.flash.error, #errorExplanation {
251 background: url(../images/false.png) 8px 5px no-repeat;
253 background: url(../images/false.png) 8px 5px no-repeat;
252 background-color: #ffe3e3;
254 background-color: #ffe3e3;
253 border-color: #dd0000;
255 border-color: #dd0000;
254 color: #550000;
256 color: #550000;
255 }
257 }
256
258
257 div.flash.notice {
259 div.flash.notice {
258 background: url(../images/true.png) 8px 5px no-repeat;
260 background: url(../images/true.png) 8px 5px no-repeat;
259 background-color: #dfffdf;
261 background-color: #dfffdf;
260 border-color: #9fcf9f;
262 border-color: #9fcf9f;
261 color: #005f00;
263 color: #005f00;
262 }
264 }
263
265
264 .nodata {
266 .nodata {
265 text-align: center;
267 text-align: center;
266 background-color: #FFEBC1;
268 background-color: #FFEBC1;
267 border-color: #FDBF3B;
269 border-color: #FDBF3B;
268 color: #A6750C;
270 color: #A6750C;
269 }
271 }
270
272
271 #errorExplanation ul { font-size: 0.9em;}
273 #errorExplanation ul { font-size: 0.9em;}
272
274
273 /***** Ajax indicator ******/
275 /***** Ajax indicator ******/
274 #ajax-indicator {
276 #ajax-indicator {
275 position: absolute; /* fixed not supported by IE */
277 position: absolute; /* fixed not supported by IE */
276 background-color:#eee;
278 background-color:#eee;
277 border: 1px solid #bbb;
279 border: 1px solid #bbb;
278 top:35%;
280 top:35%;
279 left:40%;
281 left:40%;
280 width:20%;
282 width:20%;
281 font-weight:bold;
283 font-weight:bold;
282 text-align:center;
284 text-align:center;
283 padding:0.6em;
285 padding:0.6em;
284 z-index:100;
286 z-index:100;
285 filter:alpha(opacity=50);
287 filter:alpha(opacity=50);
286 opacity: 0.5;
288 opacity: 0.5;
287 }
289 }
288
290
289 html>body #ajax-indicator { position: fixed; }
291 html>body #ajax-indicator { position: fixed; }
290
292
291 #ajax-indicator span {
293 #ajax-indicator span {
292 background-position: 0% 40%;
294 background-position: 0% 40%;
293 background-repeat: no-repeat;
295 background-repeat: no-repeat;
294 background-image: url(../images/loading.gif);
296 background-image: url(../images/loading.gif);
295 padding-left: 26px;
297 padding-left: 26px;
296 vertical-align: bottom;
298 vertical-align: bottom;
297 }
299 }
298
300
299 /***** Calendar *****/
301 /***** Calendar *****/
300 table.cal {border-collapse: collapse; width: 100%; margin: 8px 0 6px 0;border: 1px solid #d7d7d7;}
302 table.cal {border-collapse: collapse; width: 100%; margin: 8px 0 6px 0;border: 1px solid #d7d7d7;}
301 table.cal thead th {width: 14%;}
303 table.cal thead th {width: 14%;}
302 table.cal tbody tr {height: 100px;}
304 table.cal tbody tr {height: 100px;}
303 table.cal th { background-color:#EEEEEE; padding: 4px; }
305 table.cal th { background-color:#EEEEEE; padding: 4px; }
304 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
306 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
305 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
307 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
306 table.cal td.odd p.day-num {color: #bbb;}
308 table.cal td.odd p.day-num {color: #bbb;}
307 table.cal td.today {background:#ffffdd;}
309 table.cal td.today {background:#ffffdd;}
308 table.cal td.today p.day-num {font-weight: bold;}
310 table.cal td.today p.day-num {font-weight: bold;}
309
311
310 /***** Tooltips ******/
312 /***** Tooltips ******/
311 .tooltip{position:relative;z-index:24;}
313 .tooltip{position:relative;z-index:24;}
312 .tooltip:hover{z-index:25;color:#000;}
314 .tooltip:hover{z-index:25;color:#000;}
313 .tooltip span.tip{display: none; text-align:left;}
315 .tooltip span.tip{display: none; text-align:left;}
314
316
315 div.tooltip:hover span.tip{
317 div.tooltip:hover span.tip{
316 display:block;
318 display:block;
317 position:absolute;
319 position:absolute;
318 top:12px; left:24px; width:270px;
320 top:12px; left:24px; width:270px;
319 border:1px solid #555;
321 border:1px solid #555;
320 background-color:#fff;
322 background-color:#fff;
321 padding: 4px;
323 padding: 4px;
322 font-size: 0.8em;
324 font-size: 0.8em;
323 color:#505050;
325 color:#505050;
324 }
326 }
325
327
326 /***** Progress bar *****/
328 /***** Progress bar *****/
327 table.progress {
329 table.progress {
328 border: 1px solid #D7D7D7;
330 border: 1px solid #D7D7D7;
329 border-collapse: collapse;
331 border-collapse: collapse;
330 border-spacing: 0pt;
332 border-spacing: 0pt;
331 empty-cells: show;
333 empty-cells: show;
332 text-align: center;
334 text-align: center;
333 float:left;
335 float:left;
334 margin: 1px 6px 1px 0px;
336 margin: 1px 6px 1px 0px;
335 }
337 }
336
338
337 table.progress td { height: 0.9em; }
339 table.progress td { height: 0.9em; }
338 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
340 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
339 table.progress td.done { background: #DEF0DE none repeat scroll 0%; }
341 table.progress td.done { background: #DEF0DE none repeat scroll 0%; }
340 table.progress td.open { background: #FFF none repeat scroll 0%; }
342 table.progress td.open { background: #FFF none repeat scroll 0%; }
341 p.pourcent {font-size: 80%;}
343 p.pourcent {font-size: 80%;}
342 p.progress-info {clear: left; font-style: italic; font-size: 80%;}
344 p.progress-info {clear: left; font-style: italic; font-size: 80%;}
343
345
344 /***** Tabs *****/
346 /***** Tabs *****/
345 #content .tabs {height: 2.6em; border-bottom: 1px solid #bbbbbb; margin-bottom:1.2em; position:relative;}
347 #content .tabs {height: 2.6em; border-bottom: 1px solid #bbbbbb; margin-bottom:1.2em; position:relative;}
346 #content .tabs ul {margin:0; position:absolute; bottom:-2px; padding-left:1em;}
348 #content .tabs ul {margin:0; position:absolute; bottom:-2px; padding-left:1em;}
347 #content .tabs>ul { bottom:-1px; } /* others */
349 #content .tabs>ul { bottom:-1px; } /* others */
348 #content .tabs ul li {
350 #content .tabs ul li {
349 float:left;
351 float:left;
350 list-style-type:none;
352 list-style-type:none;
351 white-space:nowrap;
353 white-space:nowrap;
352 margin-right:8px;
354 margin-right:8px;
353 background:#fff;
355 background:#fff;
354 }
356 }
355 #content .tabs ul li a{
357 #content .tabs ul li a{
356 display:block;
358 display:block;
357 font-size: 0.9em;
359 font-size: 0.9em;
358 text-decoration:none;
360 text-decoration:none;
359 line-height:1.3em;
361 line-height:1.3em;
360 padding:4px 6px 4px 6px;
362 padding:4px 6px 4px 6px;
361 border: 1px solid #ccc;
363 border: 1px solid #ccc;
362 border-bottom: 1px solid #bbbbbb;
364 border-bottom: 1px solid #bbbbbb;
363 background-color: #eeeeee;
365 background-color: #eeeeee;
364 color:#777;
366 color:#777;
365 font-weight:bold;
367 font-weight:bold;
366 }
368 }
367
369
368 #content .tabs ul li a:hover {
370 #content .tabs ul li a:hover {
369 background-color: #ffffdd;
371 background-color: #ffffdd;
370 text-decoration:none;
372 text-decoration:none;
371 }
373 }
372
374
373 #content .tabs ul li a.selected {
375 #content .tabs ul li a.selected {
374 background-color: #fff;
376 background-color: #fff;
375 border: 1px solid #bbbbbb;
377 border: 1px solid #bbbbbb;
376 border-bottom: 1px solid #fff;
378 border-bottom: 1px solid #fff;
377 }
379 }
378
380
379 #content .tabs ul li a.selected:hover {
381 #content .tabs ul li a.selected:hover {
380 background-color: #fff;
382 background-color: #fff;
381 }
383 }
382
384
383 /***** Diff *****/
385 /***** Diff *****/
384 .diff_out { background: #fcc; }
386 .diff_out { background: #fcc; }
385 .diff_in { background: #cfc; }
387 .diff_in { background: #cfc; }
386
388
387 /***** Wiki *****/
389 /***** Wiki *****/
388 div.wiki table {
390 div.wiki table {
389 border: 1px solid #505050;
391 border: 1px solid #505050;
390 border-collapse: collapse;
392 border-collapse: collapse;
391 }
393 }
392
394
393 div.wiki table, div.wiki td, div.wiki th {
395 div.wiki table, div.wiki td, div.wiki th {
394 border: 1px solid #bbb;
396 border: 1px solid #bbb;
395 padding: 4px;
397 padding: 4px;
396 }
398 }
397
399
398 div.wiki .external {
400 div.wiki .external {
399 background-position: 0% 60%;
401 background-position: 0% 60%;
400 background-repeat: no-repeat;
402 background-repeat: no-repeat;
401 padding-left: 12px;
403 padding-left: 12px;
402 background-image: url(../images/external.png);
404 background-image: url(../images/external.png);
403 }
405 }
404
406
405 div.wiki a.new {
407 div.wiki a.new {
406 color: #b73535;
408 color: #b73535;
407 }
409 }
408
410
409 div.wiki pre {
411 div.wiki pre {
410 margin: 1em 1em 1em 1.6em;
412 margin: 1em 1em 1em 1.6em;
411 padding: 2px;
413 padding: 2px;
412 background-color: #fafafa;
414 background-color: #fafafa;
413 border: 1px solid #dadada;
415 border: 1px solid #dadada;
414 width:95%;
416 width:95%;
415 overflow-x: auto;
417 overflow-x: auto;
416 }
418 }
417
419
418 div.wiki div.toc {
420 div.wiki div.toc {
419 background-color: #ffffdd;
421 background-color: #ffffdd;
420 border: 1px solid #e4e4e4;
422 border: 1px solid #e4e4e4;
421 padding: 4px;
423 padding: 4px;
422 line-height: 1.2em;
424 line-height: 1.2em;
423 margin-bottom: 12px;
425 margin-bottom: 12px;
424 margin-right: 12px;
426 margin-right: 12px;
425 display: table
427 display: table
426 }
428 }
427 * html div.wiki div.toc { width: 50%; } /* IE6 doesn't autosize div */
429 * html div.wiki div.toc { width: 50%; } /* IE6 doesn't autosize div */
428
430
429 div.wiki div.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
431 div.wiki div.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
430 div.wiki div.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
432 div.wiki div.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
431
433
432 div.wiki div.toc a {
434 div.wiki div.toc a {
433 display: block;
435 display: block;
434 font-size: 0.9em;
436 font-size: 0.9em;
435 font-weight: normal;
437 font-weight: normal;
436 text-decoration: none;
438 text-decoration: none;
437 color: #606060;
439 color: #606060;
438 }
440 }
439 div.wiki div.toc a:hover { color: #c61a1a; text-decoration: underline;}
441 div.wiki div.toc a:hover { color: #c61a1a; text-decoration: underline;}
440
442
441 div.wiki div.toc a.heading2 { margin-left: 6px; }
443 div.wiki div.toc a.heading2 { margin-left: 6px; }
442 div.wiki div.toc a.heading3 { margin-left: 12px; font-size: 0.8em; }
444 div.wiki div.toc a.heading3 { margin-left: 12px; font-size: 0.8em; }
443
445
444 /***** My page layout *****/
446 /***** My page layout *****/
445 .block-receiver {
447 .block-receiver {
446 border:1px dashed #c0c0c0;
448 border:1px dashed #c0c0c0;
447 margin-bottom: 20px;
449 margin-bottom: 20px;
448 padding: 15px 0 15px 0;
450 padding: 15px 0 15px 0;
449 }
451 }
450
452
451 .mypage-box {
453 .mypage-box {
452 margin:0 0 20px 0;
454 margin:0 0 20px 0;
453 color:#505050;
455 color:#505050;
454 line-height:1.5em;
456 line-height:1.5em;
455 }
457 }
456
458
457 .handle {
459 .handle {
458 cursor: move;
460 cursor: move;
459 }
461 }
460
462
461 a.close-icon {
463 a.close-icon {
462 display:block;
464 display:block;
463 margin-top:3px;
465 margin-top:3px;
464 overflow:hidden;
466 overflow:hidden;
465 width:12px;
467 width:12px;
466 height:12px;
468 height:12px;
467 background-repeat: no-repeat;
469 background-repeat: no-repeat;
468 cursor:pointer;
470 cursor:pointer;
469 background-image:url('../images/close.png');
471 background-image:url('../images/close.png');
470 }
472 }
471
473
472 a.close-icon:hover {
474 a.close-icon:hover {
473 background-image:url('../images/close_hl.png');
475 background-image:url('../images/close_hl.png');
474 }
476 }
475
477
476 /***** Gantt chart *****/
478 /***** Gantt chart *****/
477 .gantt_hdr {
479 .gantt_hdr {
478 position:absolute;
480 position:absolute;
479 top:0;
481 top:0;
480 height:16px;
482 height:16px;
481 border-top: 1px solid #c0c0c0;
483 border-top: 1px solid #c0c0c0;
482 border-bottom: 1px solid #c0c0c0;
484 border-bottom: 1px solid #c0c0c0;
483 border-right: 1px solid #c0c0c0;
485 border-right: 1px solid #c0c0c0;
484 text-align: center;
486 text-align: center;
485 overflow: hidden;
487 overflow: hidden;
486 }
488 }
487
489
488 .task {
490 .task {
489 position: absolute;
491 position: absolute;
490 height:8px;
492 height:8px;
491 font-size:0.8em;
493 font-size:0.8em;
492 color:#888;
494 color:#888;
493 padding:0;
495 padding:0;
494 margin:0;
496 margin:0;
495 line-height:0.8em;
497 line-height:0.8em;
496 }
498 }
497
499
498 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
500 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
499 .task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }
501 .task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }
500 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
502 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
501 .milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
503 .milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
502
504
503 /***** Icons *****/
505 /***** Icons *****/
504 .icon {
506 .icon {
505 background-position: 0% 40%;
507 background-position: 0% 40%;
506 background-repeat: no-repeat;
508 background-repeat: no-repeat;
507 padding-left: 20px;
509 padding-left: 20px;
508 padding-top: 2px;
510 padding-top: 2px;
509 padding-bottom: 3px;
511 padding-bottom: 3px;
510 }
512 }
511
513
512 .icon22 {
514 .icon22 {
513 background-position: 0% 40%;
515 background-position: 0% 40%;
514 background-repeat: no-repeat;
516 background-repeat: no-repeat;
515 padding-left: 26px;
517 padding-left: 26px;
516 line-height: 22px;
518 line-height: 22px;
517 vertical-align: middle;
519 vertical-align: middle;
518 }
520 }
519
521
520 .icon-add { background-image: url(../images/add.png); }
522 .icon-add { background-image: url(../images/add.png); }
521 .icon-edit { background-image: url(../images/edit.png); }
523 .icon-edit { background-image: url(../images/edit.png); }
522 .icon-copy { background-image: url(../images/copy.png); }
524 .icon-copy { background-image: url(../images/copy.png); }
523 .icon-del { background-image: url(../images/delete.png); }
525 .icon-del { background-image: url(../images/delete.png); }
524 .icon-move { background-image: url(../images/move.png); }
526 .icon-move { background-image: url(../images/move.png); }
525 .icon-save { background-image: url(../images/save.png); }
527 .icon-save { background-image: url(../images/save.png); }
526 .icon-cancel { background-image: url(../images/cancel.png); }
528 .icon-cancel { background-image: url(../images/cancel.png); }
527 .icon-file { background-image: url(../images/file.png); }
529 .icon-file { background-image: url(../images/file.png); }
528 .icon-folder { background-image: url(../images/folder.png); }
530 .icon-folder { background-image: url(../images/folder.png); }
529 .open .icon-folder { background-image: url(../images/folder_open.png); }
531 .open .icon-folder { background-image: url(../images/folder_open.png); }
530 .icon-package { background-image: url(../images/package.png); }
532 .icon-package { background-image: url(../images/package.png); }
531 .icon-home { background-image: url(../images/home.png); }
533 .icon-home { background-image: url(../images/home.png); }
532 .icon-user { background-image: url(../images/user.png); }
534 .icon-user { background-image: url(../images/user.png); }
533 .icon-mypage { background-image: url(../images/user_page.png); }
535 .icon-mypage { background-image: url(../images/user_page.png); }
534 .icon-admin { background-image: url(../images/admin.png); }
536 .icon-admin { background-image: url(../images/admin.png); }
535 .icon-projects { background-image: url(../images/projects.png); }
537 .icon-projects { background-image: url(../images/projects.png); }
536 .icon-logout { background-image: url(../images/logout.png); }
538 .icon-logout { background-image: url(../images/logout.png); }
537 .icon-help { background-image: url(../images/help.png); }
539 .icon-help { background-image: url(../images/help.png); }
538 .icon-attachment { background-image: url(../images/attachment.png); }
540 .icon-attachment { background-image: url(../images/attachment.png); }
539 .icon-index { background-image: url(../images/index.png); }
541 .icon-index { background-image: url(../images/index.png); }
540 .icon-history { background-image: url(../images/history.png); }
542 .icon-history { background-image: url(../images/history.png); }
541 .icon-time { background-image: url(../images/time.png); }
543 .icon-time { background-image: url(../images/time.png); }
542 .icon-stats { background-image: url(../images/stats.png); }
544 .icon-stats { background-image: url(../images/stats.png); }
543 .icon-warning { background-image: url(../images/warning.png); }
545 .icon-warning { background-image: url(../images/warning.png); }
544 .icon-fav { background-image: url(../images/fav.png); }
546 .icon-fav { background-image: url(../images/fav.png); }
545 .icon-fav-off { background-image: url(../images/fav_off.png); }
547 .icon-fav-off { background-image: url(../images/fav_off.png); }
546 .icon-reload { background-image: url(../images/reload.png); }
548 .icon-reload { background-image: url(../images/reload.png); }
547 .icon-lock { background-image: url(../images/locked.png); }
549 .icon-lock { background-image: url(../images/locked.png); }
548 .icon-unlock { background-image: url(../images/unlock.png); }
550 .icon-unlock { background-image: url(../images/unlock.png); }
549 .icon-checked { background-image: url(../images/true.png); }
551 .icon-checked { background-image: url(../images/true.png); }
550 .icon-details { background-image: url(../images/zoom_in.png); }
552 .icon-details { background-image: url(../images/zoom_in.png); }
551 .icon-report { background-image: url(../images/report.png); }
553 .icon-report { background-image: url(../images/report.png); }
552
554
553 .icon22-projects { background-image: url(../images/22x22/projects.png); }
555 .icon22-projects { background-image: url(../images/22x22/projects.png); }
554 .icon22-users { background-image: url(../images/22x22/users.png); }
556 .icon22-users { background-image: url(../images/22x22/users.png); }
555 .icon22-tracker { background-image: url(../images/22x22/tracker.png); }
557 .icon22-tracker { background-image: url(../images/22x22/tracker.png); }
556 .icon22-role { background-image: url(../images/22x22/role.png); }
558 .icon22-role { background-image: url(../images/22x22/role.png); }
557 .icon22-workflow { background-image: url(../images/22x22/workflow.png); }
559 .icon22-workflow { background-image: url(../images/22x22/workflow.png); }
558 .icon22-options { background-image: url(../images/22x22/options.png); }
560 .icon22-options { background-image: url(../images/22x22/options.png); }
559 .icon22-notifications { background-image: url(../images/22x22/notifications.png); }
561 .icon22-notifications { background-image: url(../images/22x22/notifications.png); }
560 .icon22-authent { background-image: url(../images/22x22/authent.png); }
562 .icon22-authent { background-image: url(../images/22x22/authent.png); }
561 .icon22-info { background-image: url(../images/22x22/info.png); }
563 .icon22-info { background-image: url(../images/22x22/info.png); }
562 .icon22-comment { background-image: url(../images/22x22/comment.png); }
564 .icon22-comment { background-image: url(../images/22x22/comment.png); }
563 .icon22-package { background-image: url(../images/22x22/package.png); }
565 .icon22-package { background-image: url(../images/22x22/package.png); }
564 .icon22-settings { background-image: url(../images/22x22/settings.png); }
566 .icon22-settings { background-image: url(../images/22x22/settings.png); }
565 .icon22-plugin { background-image: url(../images/22x22/plugin.png); }
567 .icon22-plugin { background-image: url(../images/22x22/plugin.png); }
566
568
567 /***** Media print specific styles *****/
569 /***** Media print specific styles *****/
568 @media print {
570 @media print {
569 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual { display:none; }
571 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual { display:none; }
570 #main { background: #fff; }
572 #main { background: #fff; }
571 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; }
573 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; }
572 }
574 }
General Comments 0
You need to be logged in to leave comments. Login now