##// END OF EJS Templates
scm: git: show only filename and filesize if setting of reporting last commit is disable (#8365, #7047)....
Toshi MARUYAMA -
r5655:d65c3d438d28
parent child
Show More
@@ -1,316 +1,320
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 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 class Repository < ActiveRecord::Base
19 19 include Redmine::Ciphering
20 20
21 21 belongs_to :project
22 22 has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
23 23 has_many :changes, :through => :changesets
24 24
25 25 serialize :extra_info
26 26
27 27 # Raw SQL to delete changesets and changes in the database
28 28 # has_many :changesets, :dependent => :destroy is too slow for big repositories
29 29 before_destroy :clear_changesets
30 30
31 31 validates_length_of :password, :maximum => 255, :allow_nil => true
32 32 # Checks if the SCM is enabled when creating a repository
33 33 validate_on_create { |r| r.errors.add(:type, :invalid) unless Setting.enabled_scm.include?(r.class.name.demodulize) }
34 34
35 35 def self.human_attribute_name(attribute_key_name)
36 36 attr_name = attribute_key_name
37 37 if attr_name == "log_encoding"
38 38 attr_name = "commit_logs_encoding"
39 39 end
40 40 super(attr_name)
41 41 end
42 42
43 43 # Removes leading and trailing whitespace
44 44 def url=(arg)
45 45 write_attribute(:url, arg ? arg.to_s.strip : nil)
46 46 end
47 47
48 48 # Removes leading and trailing whitespace
49 49 def root_url=(arg)
50 50 write_attribute(:root_url, arg ? arg.to_s.strip : nil)
51 51 end
52 52
53 53 def password
54 54 read_ciphered_attribute(:password)
55 55 end
56 56
57 57 def password=(arg)
58 58 write_ciphered_attribute(:password, arg)
59 59 end
60 60
61 61 def scm_adapter
62 62 self.class.scm_adapter_class
63 63 end
64 64
65 65 def scm
66 66 @scm ||= self.scm_adapter.new(url, root_url,
67 67 login, password, path_encoding)
68 68 update_attribute(:root_url, @scm.root_url) if root_url.blank?
69 69 @scm
70 70 end
71 71
72 72 def scm_name
73 73 self.class.scm_name
74 74 end
75 75
76 76 def merge_extra_info(arg)
77 77 h = extra_info || {}
78 78 return h if arg.nil?
79 79 h.merge!(arg)
80 80 write_attribute(:extra_info, h)
81 81 end
82 82
83 def report_last_commit
84 true
85 end
86
83 87 def supports_cat?
84 88 scm.supports_cat?
85 89 end
86 90
87 91 def supports_annotate?
88 92 scm.supports_annotate?
89 93 end
90 94
91 95 def supports_all_revisions?
92 96 true
93 97 end
94 98
95 99 def supports_directory_revisions?
96 100 false
97 101 end
98 102
99 103 def entry(path=nil, identifier=nil)
100 104 scm.entry(path, identifier)
101 105 end
102 106
103 107 def entries(path=nil, identifier=nil)
104 108 scm.entries(path, identifier)
105 109 end
106 110
107 111 def branches
108 112 scm.branches
109 113 end
110 114
111 115 def tags
112 116 scm.tags
113 117 end
114 118
115 119 def default_branch
116 120 scm.default_branch
117 121 end
118 122
119 123 def properties(path, identifier=nil)
120 124 scm.properties(path, identifier)
121 125 end
122 126
123 127 def cat(path, identifier=nil)
124 128 scm.cat(path, identifier)
125 129 end
126 130
127 131 def diff(path, rev, rev_to)
128 132 scm.diff(path, rev, rev_to)
129 133 end
130 134
131 135 def diff_format_revisions(cs, cs_to, sep=':')
132 136 text = ""
133 137 text << cs_to.format_identifier + sep if cs_to
134 138 text << cs.format_identifier if cs
135 139 text
136 140 end
137 141
138 142 # Returns a path relative to the url of the repository
139 143 def relative_path(path)
140 144 path
141 145 end
142 146
143 147 # Finds and returns a revision with a number or the beginning of a hash
144 148 def find_changeset_by_name(name)
145 149 return nil if name.blank?
146 150 changesets.find(:first, :conditions => (name.match(/^\d*$/) ?
147 151 ["revision = ?", name.to_s] : ["revision LIKE ?", name + '%']))
148 152 end
149 153
150 154 def latest_changeset
151 155 @latest_changeset ||= changesets.find(:first)
152 156 end
153 157
154 158 # Returns the latest changesets for +path+
155 159 # Default behaviour is to search in cached changesets
156 160 def latest_changesets(path, rev, limit=10)
157 161 if path.blank?
158 162 changesets.find(
159 163 :all,
160 164 :include => :user,
161 165 :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
162 166 :limit => limit)
163 167 else
164 168 changes.find(
165 169 :all,
166 170 :include => {:changeset => :user},
167 171 :conditions => ["path = ?", path.with_leading_slash],
168 172 :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
169 173 :limit => limit
170 174 ).collect(&:changeset)
171 175 end
172 176 end
173 177
174 178 def scan_changesets_for_issue_ids
175 179 self.changesets.each(&:scan_comment_for_issue_ids)
176 180 end
177 181
178 182 # Returns an array of committers usernames and associated user_id
179 183 def committers
180 184 @committers ||= Changeset.connection.select_rows(
181 185 "SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}")
182 186 end
183 187
184 188 # Maps committers username to a user ids
185 189 def committer_ids=(h)
186 190 if h.is_a?(Hash)
187 191 committers.each do |committer, user_id|
188 192 new_user_id = h[committer]
189 193 if new_user_id && (new_user_id.to_i != user_id.to_i)
190 194 new_user_id = (new_user_id.to_i > 0 ? new_user_id.to_i : nil)
191 195 Changeset.update_all(
192 196 "user_id = #{ new_user_id.nil? ? 'NULL' : new_user_id }",
193 197 ["repository_id = ? AND committer = ?", id, committer])
194 198 end
195 199 end
196 200 @committers = nil
197 201 @found_committer_users = nil
198 202 true
199 203 else
200 204 false
201 205 end
202 206 end
203 207
204 208 # Returns the Redmine User corresponding to the given +committer+
205 209 # It will return nil if the committer is not yet mapped and if no User
206 210 # with the same username or email was found
207 211 def find_committer_user(committer)
208 212 unless committer.blank?
209 213 @found_committer_users ||= {}
210 214 return @found_committer_users[committer] if @found_committer_users.has_key?(committer)
211 215
212 216 user = nil
213 217 c = changesets.find(:first, :conditions => {:committer => committer}, :include => :user)
214 218 if c && c.user
215 219 user = c.user
216 220 elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
217 221 username, email = $1.strip, $3
218 222 u = User.find_by_login(username)
219 223 u ||= User.find_by_mail(email) unless email.blank?
220 224 user = u
221 225 end
222 226 @found_committer_users[committer] = user
223 227 user
224 228 end
225 229 end
226 230
227 231 def repo_log_encoding
228 232 encoding = log_encoding.to_s.strip
229 233 encoding.blank? ? 'UTF-8' : encoding
230 234 end
231 235
232 236 # Fetches new changesets for all repositories of active projects
233 237 # Can be called periodically by an external script
234 238 # eg. ruby script/runner "Repository.fetch_changesets"
235 239 def self.fetch_changesets
236 240 Project.active.has_module(:repository).find(:all, :include => :repository).each do |project|
237 241 if project.repository
238 242 begin
239 243 project.repository.fetch_changesets
240 244 rescue Redmine::Scm::Adapters::CommandFailed => e
241 245 logger.error "scm: error during fetching changesets: #{e.message}"
242 246 end
243 247 end
244 248 end
245 249 end
246 250
247 251 # scan changeset comments to find related and fixed issues for all repositories
248 252 def self.scan_changesets_for_issue_ids
249 253 find(:all).each(&:scan_changesets_for_issue_ids)
250 254 end
251 255
252 256 def self.scm_name
253 257 'Abstract'
254 258 end
255 259
256 260 def self.available_scm
257 261 subclasses.collect {|klass| [klass.scm_name, klass.name]}
258 262 end
259 263
260 264 def self.factory(klass_name, *args)
261 265 klass = "Repository::#{klass_name}".constantize
262 266 klass.new(*args)
263 267 rescue
264 268 nil
265 269 end
266 270
267 271 def self.scm_adapter_class
268 272 nil
269 273 end
270 274
271 275 def self.scm_command
272 276 ret = ""
273 277 begin
274 278 ret = self.scm_adapter_class.client_command if self.scm_adapter_class
275 279 rescue Redmine::Scm::Adapters::CommandFailed => e
276 280 logger.error "scm: error during get command: #{e.message}"
277 281 end
278 282 ret
279 283 end
280 284
281 285 def self.scm_version_string
282 286 ret = ""
283 287 begin
284 288 ret = self.scm_adapter_class.client_version_string if self.scm_adapter_class
285 289 rescue Redmine::Scm::Adapters::CommandFailed => e
286 290 logger.error "scm: error during get version string: #{e.message}"
287 291 end
288 292 ret
289 293 end
290 294
291 295 def self.scm_available
292 296 ret = false
293 297 begin
294 298 ret = self.scm_adapter_class.client_available if self.scm_adapter_class
295 299 rescue Redmine::Scm::Adapters::CommandFailed => e
296 300 logger.error "scm: error during get scm available: #{e.message}"
297 301 end
298 302 ret
299 303 end
300 304
301 305 private
302 306
303 307 def before_save
304 308 # Strips url and root_url
305 309 url.strip!
306 310 root_url.strip!
307 311 true
308 312 end
309 313
310 314 def clear_changesets
311 315 cs, ch, ci = Changeset.table_name, Change.table_name, "#{table_name_prefix}changesets_issues#{table_name_suffix}"
312 316 connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
313 317 connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
314 318 connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
315 319 end
316 320 end
@@ -1,173 +1,177
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 # Copyright (C) 2007 Patrick Aljord patcito@Ε‹mail.com
4 4 #
5 5 # This program is free software; you can redistribute it and/or
6 6 # modify it under the terms of the GNU General Public License
7 7 # as published by the Free Software Foundation; either version 2
8 8 # of the License, or (at your option) any later version.
9 9 #
10 10 # This program is distributed in the hope that it will be useful,
11 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 # GNU General Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License
16 16 # along with this program; if not, write to the Free Software
17 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 18
19 19 require 'redmine/scm/adapters/git_adapter'
20 20
21 21 class Repository::Git < Repository
22 22 attr_protected :root_url
23 23 validates_presence_of :url
24 24
25 25 def self.human_attribute_name(attribute_key_name)
26 26 attr_name = attribute_key_name
27 27 if attr_name == "url"
28 28 attr_name = "path_to_repository"
29 29 end
30 30 super(attr_name)
31 31 end
32 32
33 33 def self.scm_adapter_class
34 34 Redmine::Scm::Adapters::GitAdapter
35 35 end
36 36
37 37 def self.scm_name
38 38 'Git'
39 39 end
40 40
41 def report_last_commit
42 extra_report_last_commit
43 end
44
41 45 def extra_report_last_commit
42 46 return false if extra_info.nil?
43 47 v = extra_info["extra_report_last_commit"]
44 48 return false if v.nil?
45 49 v.to_s != '0'
46 50 end
47 51
48 52 def supports_directory_revisions?
49 53 true
50 54 end
51 55
52 56 def repo_log_encoding
53 57 'UTF-8'
54 58 end
55 59
56 60 # Returns the identifier for the given git changeset
57 61 def self.changeset_identifier(changeset)
58 62 changeset.scmid
59 63 end
60 64
61 65 # Returns the readable identifier for the given git changeset
62 66 def self.format_changeset_identifier(changeset)
63 67 changeset.revision[0, 8]
64 68 end
65 69
66 70 def branches
67 71 scm.branches
68 72 end
69 73
70 74 def tags
71 75 scm.tags
72 76 end
73 77
74 78 def find_changeset_by_name(name)
75 79 return nil if name.nil? || name.empty?
76 80 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
77 81 return e if e
78 82 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
79 83 end
80 84
81 85 def entries(path=nil, identifier=nil)
82 86 scm.entries(path,
83 87 identifier,
84 88 options = {:report_last_commit => extra_report_last_commit})
85 89 end
86 90
87 91 # In Git and Mercurial, revisions are not in date order.
88 92 # Mercurial fixed issues.
89 93 # * Redmine Takes Too Long On Large Mercurial Repository
90 94 # http://www.redmine.org/issues/3449
91 95 # * Sorting for changesets might go wrong on Mercurial repos
92 96 # http://www.redmine.org/issues/3567
93 97 # Database revision column is text, so Redmine can not sort by revision.
94 98 # Mercurial has revision number, and revision number guarantees revision order.
95 99 # Mercurial adapter uses "hg log -r 0:tip --limit 10"
96 100 # to get limited revisions from old to new.
97 101 # And Mercurial model stored revisions ordered by database id in database.
98 102 # So, Mercurial can use correct order revisions.
99 103 #
100 104 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
101 105 #
102 106 # With SCM's that have a sequential commit numbering, redmine is able to be
103 107 # clever and only fetch changesets going forward from the most recent one
104 108 # it knows about.
105 109 # However, with git, you never know if people have merged
106 110 # commits into the middle of the repository history, so we should parse
107 111 # the entire log.
108 112 #
109 113 # Since it's way too slow for large repositories,
110 114 # we only parse 1 week before the last known commit.
111 115 #
112 116 # The repository can still be fully reloaded by calling #clear_changesets
113 117 # before fetching changesets (eg. for offline resync)
114 118 def fetch_changesets
115 119 c = changesets.find(:first, :order => 'committed_on DESC')
116 120 since = (c ? c.committed_on - 7.days : nil)
117 121
118 122 revisions = scm.revisions('', nil, nil, {:all => true, :since => since, :reverse => true})
119 123 return if revisions.nil? || revisions.empty?
120 124
121 125 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
122 126
123 127 # Clean out revisions that are no longer in git
124 128 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
125 129
126 130 # Subtract revisions that redmine already knows about
127 131 recent_revisions = recent_changesets.map{|c| c.scmid}
128 132 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
129 133
130 134 # Save the remaining ones to the database
131 135 unless revisions.nil?
132 136 revisions.each do |rev|
133 137 transaction do
134 138 save_revision(rev)
135 139 end
136 140 end
137 141 end
138 142 end
139 143
140 144 def save_revision(rev)
141 145 changeset = Changeset.new(
142 146 :repository => self,
143 147 :revision => rev.identifier,
144 148 :scmid => rev.scmid,
145 149 :committer => rev.author,
146 150 :committed_on => rev.time,
147 151 :comments => rev.message
148 152 )
149 153 if changeset.save
150 154 rev.paths.each do |file|
151 155 Change.create(
152 156 :changeset => changeset,
153 157 :action => file[:action],
154 158 :path => file[:path])
155 159 end
156 160 end
157 161 end
158 162 private :save_revision
159 163
160 164 def latest_changesets(path,rev,limit=10)
161 165 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
162 166 return [] if revisions.nil? || revisions.empty?
163 167
164 168 changesets.find(
165 169 :all,
166 170 :conditions => [
167 171 "scmid IN (?)",
168 172 revisions.map!{|c| c.scmid}
169 173 ],
170 174 :order => 'committed_on DESC'
171 175 )
172 176 end
173 177 end
@@ -1,15 +1,17
1 1 <table class="list entries" id="browser">
2 2 <thead>
3 3 <tr id="root">
4 4 <th><%= l(:field_name) %></th>
5 5 <th><%= l(:field_filesize) %></th>
6 <th><%= l(:label_revision) %></th>
7 <th><%= l(:label_age) %></th>
8 <th><%= l(:field_author) %></th>
9 <th><%= l(:field_comments) %></th>
6 <% if @repository.report_last_commit %>
7 <th><%= l(:label_revision) %></th>
8 <th><%= l(:label_age) %></th>
9 <th><%= l(:field_author) %></th>
10 <th><%= l(:field_comments) %></th>
11 <% end %>
10 12 </tr>
11 13 </thead>
12 14 <tbody>
13 15 <%= render :partial => 'dir_list_content' %>
14 16 </tbody>
15 17 </table>
@@ -1,27 +1,30
1 1 <% @entries.each do |entry| %>
2 2 <% tr_id = Digest::MD5.hexdigest(entry.path)
3 3 depth = params[:depth].to_i %>
4 4 <% ent_path = Redmine::CodesetUtil.replace_invalid_utf8(entry.path) %>
5 5 <% ent_name = Redmine::CodesetUtil.replace_invalid_utf8(entry.name) %>
6 6 <tr id="<%= tr_id %>" class="<%= h params[:parent_id] %> entry <%= entry.kind %>">
7 <td style="padding-left: <%=18 * depth%>px;" class="filename">
7 <td style="padding-left: <%=18 * depth%>px;" class="<%=
8 @repository.report_last_commit ? "filename" : "filename_no_report" %>";>
8 9 <% if entry.is_dir? %>
9 10 <span class="expander" onclick="<%= remote_function :url => {:action => 'show', :id => @project, :path => to_path_param(ent_path), :rev => @rev, :depth => (depth + 1), :parent_id => tr_id},
10 11 :method => :get,
11 12 :update => { :success => tr_id },
12 13 :position => :after,
13 14 :success => "scmEntryLoaded('#{tr_id}')",
14 15 :condition => "scmEntryClick('#{tr_id}')"%>">&nbsp</span>
15 16 <% end %>
16 17 <%= link_to h(ent_name),
17 18 {:action => (entry.is_dir? ? 'show' : 'changes'), :id => @project, :path => to_path_param(ent_path), :rev => @rev},
18 19 :class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
19 20 </td>
20 21 <td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
21 22 <% changeset = @project.repository.find_changeset_by_name(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %>
23 <% if @repository.report_last_commit %>
22 24 <td class="revision"><%= link_to_revision(changeset, @project) if changeset %></td>
23 25 <td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
24 26 <td class="author"><%= changeset.nil? ? h(Redmine::CodesetUtil.replace_invalid_utf8(entry.lastrev.author.to_s.split('<').first)) : changeset.author if entry.lastrev %></td>
25 27 <td class="comments"><%=h truncate(changeset.comments, :length => 50) unless changeset.nil? %></td>
28 <% end %>
26 29 </tr>
27 30 <% end %>
@@ -1,975 +1,977
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;}
5 5 h1 {margin:0; padding:0; font-size: 24px;}
6 6 h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
7 7 h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
8 8 h4, .wiki h3 {font-size: 13px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb; color: #444;}
9 9
10 10 /***** Layout *****/
11 11 #wrapper {background: white;}
12 12
13 13 #top-menu {background: #2C4056; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
14 14 #top-menu ul {margin: 0; padding: 0;}
15 15 #top-menu li {
16 16 float:left;
17 17 list-style-type:none;
18 18 margin: 0px 0px 0px 0px;
19 19 padding: 0px 0px 0px 0px;
20 20 white-space:nowrap;
21 21 }
22 22 #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
23 23 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
24 24
25 25 #account {float:right;}
26 26
27 27 #header {height:5.3em;margin:0;background-color:#507AAA;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;}
28 28 #header a {color:#f8f8f8;}
29 29 #header h1 a.ancestor { font-size: 80%; }
30 30 #quick-search {float:right;}
31 31
32 32 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
33 33 #main-menu ul {margin: 0; padding: 0;}
34 34 #main-menu li {
35 35 float:left;
36 36 list-style-type:none;
37 37 margin: 0px 2px 0px 0px;
38 38 padding: 0px 0px 0px 0px;
39 39 white-space:nowrap;
40 40 }
41 41 #main-menu li a {
42 42 display: block;
43 43 color: #fff;
44 44 text-decoration: none;
45 45 font-weight: bold;
46 46 margin: 0;
47 47 padding: 4px 10px 4px 10px;
48 48 }
49 49 #main-menu li a:hover {background:#759FCF; color:#fff;}
50 50 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
51 51
52 52 #admin-menu ul {margin: 0; padding: 0;}
53 53 #admin-menu li {margin: 0; padding: 0 0 12px 0; list-style-type:none;}
54 54
55 55 #admin-menu a { background-position: 0% 40%; background-repeat: no-repeat; padding-left: 20px; padding-top: 2px; padding-bottom: 3px;}
56 56 #admin-menu a.projects { background-image: url(../images/projects.png); }
57 57 #admin-menu a.users { background-image: url(../images/user.png); }
58 58 #admin-menu a.groups { background-image: url(../images/group.png); }
59 59 #admin-menu a.roles { background-image: url(../images/database_key.png); }
60 60 #admin-menu a.trackers { background-image: url(../images/ticket.png); }
61 61 #admin-menu a.issue_statuses { background-image: url(../images/ticket_edit.png); }
62 62 #admin-menu a.workflows { background-image: url(../images/ticket_go.png); }
63 63 #admin-menu a.custom_fields { background-image: url(../images/textfield.png); }
64 64 #admin-menu a.enumerations { background-image: url(../images/text_list_bullets.png); }
65 65 #admin-menu a.settings { background-image: url(../images/changeset.png); }
66 66 #admin-menu a.plugins { background-image: url(../images/plugin.png); }
67 67 #admin-menu a.info { background-image: url(../images/help.png); }
68 68 #admin-menu a.server_authentication { background-image: url(../images/server_key.png); }
69 69
70 70 #main {background-color:#EEEEEE;}
71 71
72 72 #sidebar{ float: right; width: 22%; position: relative; z-index: 9; padding: 0; margin: 0;}
73 73 * html #sidebar{ width: 22%; }
74 74 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
75 75 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
76 76 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
77 77 #sidebar .contextual { margin-right: 1em; }
78 78
79 79 #content { width: 75%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
80 80 * html #content{ width: 75%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
81 81 html>body #content { min-height: 600px; }
82 82 * html body #content { height: 600px; } /* IE */
83 83
84 84 #main.nosidebar #sidebar{ display: none; }
85 85 #main.nosidebar #content{ width: auto; border-right: 0; }
86 86
87 87 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
88 88
89 89 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
90 90 #login-form table td {padding: 6px;}
91 91 #login-form label {font-weight: bold;}
92 92 #login-form input#username, #login-form input#password { width: 300px; }
93 93
94 94 input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; }
95 95
96 96 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
97 97
98 98 /***** Links *****/
99 99 a, a:link, a:visited{ color: #2A5685; text-decoration: none; }
100 100 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
101 101 a img{ border: 0; }
102 102
103 103 a.issue.closed, a.issue.closed:link, a.issue.closed:visited { color: #999; text-decoration: line-through; }
104 104
105 105 /***** Tables *****/
106 106 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
107 107 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
108 108 table.list td { vertical-align: top; }
109 109 table.list td.id { width: 2%; text-align: center;}
110 110 table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
111 111 table.list td.checkbox input {padding:0px;}
112 112 table.list td.buttons { width: 15%; white-space:nowrap; text-align: right; }
113 113 table.list td.buttons a { padding-right: 0.6em; }
114 114 table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
115 115
116 116 tr.project td.name a { white-space:nowrap; }
117 117
118 118 tr.project.idnt td.name span {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
119 119 tr.project.idnt-1 td.name {padding-left: 0.5em;}
120 120 tr.project.idnt-2 td.name {padding-left: 2em;}
121 121 tr.project.idnt-3 td.name {padding-left: 3.5em;}
122 122 tr.project.idnt-4 td.name {padding-left: 5em;}
123 123 tr.project.idnt-5 td.name {padding-left: 6.5em;}
124 124 tr.project.idnt-6 td.name {padding-left: 8em;}
125 125 tr.project.idnt-7 td.name {padding-left: 9.5em;}
126 126 tr.project.idnt-8 td.name {padding-left: 11em;}
127 127 tr.project.idnt-9 td.name {padding-left: 12.5em;}
128 128
129 129 tr.issue { text-align: center; white-space: nowrap; }
130 130 tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text { white-space: normal; }
131 131 tr.issue td.subject { text-align: left; }
132 132 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
133 133
134 134 tr.issue.idnt td.subject a {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
135 135 tr.issue.idnt-1 td.subject {padding-left: 0.5em;}
136 136 tr.issue.idnt-2 td.subject {padding-left: 2em;}
137 137 tr.issue.idnt-3 td.subject {padding-left: 3.5em;}
138 138 tr.issue.idnt-4 td.subject {padding-left: 5em;}
139 139 tr.issue.idnt-5 td.subject {padding-left: 6.5em;}
140 140 tr.issue.idnt-6 td.subject {padding-left: 8em;}
141 141 tr.issue.idnt-7 td.subject {padding-left: 9.5em;}
142 142 tr.issue.idnt-8 td.subject {padding-left: 11em;}
143 143 tr.issue.idnt-9 td.subject {padding-left: 12.5em;}
144 144
145 145 tr.entry { border: 1px solid #f8f8f8; }
146 146 tr.entry td { white-space: nowrap; }
147 147 tr.entry td.filename { width: 30%; }
148 tr.entry td.filename_no_report { width: 70%; }
148 149 tr.entry td.size { text-align: right; font-size: 90%; }
149 150 tr.entry td.revision, tr.entry td.author { text-align: center; }
150 151 tr.entry td.age { text-align: right; }
151 152 tr.entry.file td.filename a { margin-left: 16px; }
153 tr.entry.file td.filename_no_report a { margin-left: 16px; }
152 154
153 155 tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
154 156 tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
155 157
156 158 tr.changeset td.author { text-align: center; width: 15%; }
157 159 tr.changeset td.committed_on { text-align: center; width: 15%; }
158 160
159 161 table.files tr.file td { text-align: center; }
160 162 table.files tr.file td.filename { text-align: left; padding-left: 24px; }
161 163 table.files tr.file td.digest { font-size: 80%; }
162 164
163 165 table.members td.roles, table.memberships td.roles { width: 45%; }
164 166
165 167 tr.message { height: 2.6em; }
166 168 tr.message td.subject { padding-left: 20px; }
167 169 tr.message td.created_on { white-space: nowrap; }
168 170 tr.message td.last_message { font-size: 80%; white-space: nowrap; }
169 171 tr.message.locked td.subject { background: url(../images/locked.png) no-repeat 0 1px; }
170 172 tr.message.sticky td.subject { background: url(../images/bullet_go.png) no-repeat 0 1px; font-weight: bold; }
171 173
172 174 tr.version.closed, tr.version.closed a { color: #999; }
173 175 tr.version td.name { padding-left: 20px; }
174 176 tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%; }
175 177 tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
176 178
177 179 tr.user td { width:13%; }
178 180 tr.user td.email { width:18%; }
179 181 tr.user td { white-space: nowrap; }
180 182 tr.user.locked, tr.user.registered { color: #aaa; }
181 183 tr.user.locked a, tr.user.registered a { color: #aaa; }
182 184
183 185 tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
184 186
185 187 tr.time-entry { text-align: center; white-space: nowrap; }
186 188 tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; white-space: normal; }
187 189 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
188 190 td.hours .hours-dec { font-size: 0.9em; }
189 191
190 192 table.plugins td { vertical-align: middle; }
191 193 table.plugins td.configure { text-align: right; padding-right: 1em; }
192 194 table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
193 195 table.plugins span.description { display: block; font-size: 0.9em; }
194 196 table.plugins span.url { display: block; font-size: 0.9em; }
195 197
196 198 table.list tbody tr.group td { padding: 0.8em 0 0.5em 0.3em; font-weight: bold; border-bottom: 1px solid #ccc; }
197 199 table.list tbody tr.group span.count { color: #aaa; font-size: 80%; }
198 200 tr.group a.toggle-all { color: #aaa; font-size: 80%; font-weight: normal; display:none;}
199 201 tr.group:hover a.toggle-all { display:inline;}
200 202 a.toggle-all:hover {text-decoration:none;}
201 203
202 204 table.list tbody tr:hover { background-color:#ffffdd; }
203 205 table.list tbody tr.group:hover { background-color:inherit; }
204 206 table td {padding:2px;}
205 207 table p {margin:0;}
206 208 .odd {background-color:#f6f7f8;}
207 209 .even {background-color: #fff;}
208 210
209 211 a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; }
210 212 a.sort.asc { background-image: url(../images/sort_asc.png); }
211 213 a.sort.desc { background-image: url(../images/sort_desc.png); }
212 214
213 215 table.attributes { width: 100% }
214 216 table.attributes th { vertical-align: top; text-align: left; }
215 217 table.attributes td { vertical-align: top; }
216 218
217 219 table.boards a.board, h3.comments { background: url(../images/comment.png) no-repeat 0% 50%; padding-left: 20px; }
218 220
219 221 td.center {text-align:center;}
220 222
221 223 h3.version { background: url(../images/package.png) no-repeat 0% 50%; padding-left: 20px; }
222 224
223 225 div.issues h3 { background: url(../images/ticket.png) no-repeat 0% 50%; padding-left: 20px; }
224 226 div.members h3 { background: url(../images/group.png) no-repeat 0% 50%; padding-left: 20px; }
225 227 div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left: 20px; }
226 228 div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; }
227 229
228 230 #watchers ul {margin: 0; padding: 0;}
229 231 #watchers li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;}
230 232 #watchers select {width: 95%; display: block;}
231 233 #watchers a.delete {opacity: 0.4;}
232 234 #watchers a.delete:hover {opacity: 1;}
233 235 #watchers img.gravatar {vertical-align: middle;margin: 0 4px 2px 0;}
234 236
235 237 .highlight { background-color: #FCFD8D;}
236 238 .highlight.token-1 { background-color: #faa;}
237 239 .highlight.token-2 { background-color: #afa;}
238 240 .highlight.token-3 { background-color: #aaf;}
239 241
240 242 .box{
241 243 padding:6px;
242 244 margin-bottom: 10px;
243 245 background-color:#f6f6f6;
244 246 color:#505050;
245 247 line-height:1.5em;
246 248 border: 1px solid #e4e4e4;
247 249 }
248 250
249 251 div.square {
250 252 border: 1px solid #999;
251 253 float: left;
252 254 margin: .3em .4em 0 .4em;
253 255 overflow: hidden;
254 256 width: .6em; height: .6em;
255 257 }
256 258 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
257 259 .contextual input, .contextual select {font-size:0.9em;}
258 260 .message .contextual { margin-top: 0; }
259 261
260 262 .splitcontentleft{float:left; width:49%;}
261 263 .splitcontentright{float:right; width:49%;}
262 264 form {display: inline;}
263 265 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
264 266 fieldset {border: 1px solid #e4e4e4; margin:0;}
265 267 legend {color: #484848;}
266 268 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
267 269 blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
268 270 blockquote blockquote { margin-left: 0;}
269 271 acronym { border-bottom: 1px dotted; cursor: help; }
270 272 textarea.wiki-edit { width: 99%; }
271 273 li p {margin-top: 0;}
272 274 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
273 275 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
274 276 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
275 277 p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
276 278
277 279 div.issue div.subject div div { padding-left: 16px; }
278 280 div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;}
279 281 div.issue div.subject>div>p { margin-top: 0.5em; }
280 282 div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;}
281 283 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; -moz-border-radius: 2px;}
282 284
283 285 #issue_tree table.issues, #relations table.issues { border: 0; }
284 286 #issue_tree td.checkbox, #relations td.checkbox {display:none;}
285 287 #relations td.buttons {padding:0;}
286 288
287 289 fieldset.collapsible { border-width: 1px 0 0 0; font-size: 0.9em; }
288 290 fieldset.collapsible legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
289 291 fieldset.collapsible.collapsed legend { background-image: url(../images/arrow_collapsed.png); }
290 292
291 293 fieldset#date-range p { margin: 2px 0 2px 0; }
292 294 fieldset#filters table { border-collapse: collapse; }
293 295 fieldset#filters table td { padding: 0; vertical-align: middle; }
294 296 fieldset#filters tr.filter { height: 2em; }
295 297 fieldset#filters td.add-filter { text-align: right; vertical-align: top; }
296 298 .buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; }
297 299
298 300 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
299 301 div#issue-changesets div.changeset { padding: 4px;}
300 302 div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; }
301 303 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
302 304
303 305 div#activity dl, #search-results { margin-left: 2em; }
304 306 div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
305 307 div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
306 308 div#activity dt.me .time { border-bottom: 1px solid #999; }
307 309 div#activity dt .time { color: #777; font-size: 80%; }
308 310 div#activity dd .description, #search-results dd .description { font-style: italic; }
309 311 div#activity span.project:after, #search-results span.project:after { content: " -"; }
310 312 div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
311 313
312 314 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
313 315
314 316 div#search-results-counts {float:right;}
315 317 div#search-results-counts ul { margin-top: 0.5em; }
316 318 div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
317 319
318 320 dt.issue { background-image: url(../images/ticket.png); }
319 321 dt.issue-edit { background-image: url(../images/ticket_edit.png); }
320 322 dt.issue-closed { background-image: url(../images/ticket_checked.png); }
321 323 dt.issue-note { background-image: url(../images/ticket_note.png); }
322 324 dt.changeset { background-image: url(../images/changeset.png); }
323 325 dt.news { background-image: url(../images/news.png); }
324 326 dt.message { background-image: url(../images/message.png); }
325 327 dt.reply { background-image: url(../images/comments.png); }
326 328 dt.wiki-page { background-image: url(../images/wiki_edit.png); }
327 329 dt.attachment { background-image: url(../images/attachment.png); }
328 330 dt.document { background-image: url(../images/document.png); }
329 331 dt.project { background-image: url(../images/projects.png); }
330 332 dt.time-entry { background-image: url(../images/time.png); }
331 333
332 334 #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
333 335
334 336 div#roadmap .related-issues { margin-bottom: 1em; }
335 337 div#roadmap .related-issues td.checkbox { display: none; }
336 338 div#roadmap .wiki h1:first-child { display: none; }
337 339 div#roadmap .wiki h1 { font-size: 120%; }
338 340 div#roadmap .wiki h2 { font-size: 110%; }
339 341 body.controller-versions.action-show div#roadmap .related-issues {width:auto;}
340 342
341 343 div#version-summary { float:right; width:380px; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
342 344 div#version-summary fieldset { margin-bottom: 1em; }
343 345 div#version-summary .total-hours { text-align: right; }
344 346
345 347 table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
346 348 table#time-report tbody tr { font-style: italic; color: #777; }
347 349 table#time-report tbody tr.last-level { font-style: normal; color: #555; }
348 350 table#time-report tbody tr.total { font-style: normal; font-weight: bold; color: #555; background-color:#EEEEEE; }
349 351 table#time-report .hours-dec { font-size: 0.9em; }
350 352
351 353 form .attributes { margin-bottom: 8px; }
352 354 form .attributes p { padding-top: 1px; padding-bottom: 2px; }
353 355 form .attributes select { width: 60%; }
354 356 input#issue_subject { width: 99%; }
355 357 select#issue_done_ratio { width: 95px; }
356 358
357 359 ul.projects { margin: 0; padding-left: 1em; }
358 360 ul.projects.root { margin: 0; padding: 0; }
359 361 ul.projects ul.projects { border-left: 3px solid #e0e0e0; }
360 362 ul.projects li.root { list-style-type:none; margin-bottom: 1em; }
361 363 ul.projects li.child { list-style-type:none; margin-top: 1em;}
362 364 ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
363 365 .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
364 366
365 367 #tracker_project_ids ul { margin: 0; padding-left: 1em; }
366 368 #tracker_project_ids li { list-style-type:none; }
367 369
368 370 ul.properties {padding:0; font-size: 0.9em; color: #777;}
369 371 ul.properties li {list-style-type:none;}
370 372 ul.properties li span {font-style:italic;}
371 373
372 374 .total-hours { font-size: 110%; font-weight: bold; }
373 375 .total-hours span.hours-int { font-size: 120%; }
374 376
375 377 .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;}
376 378 #user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select { width: 90%; }
377 379
378 380 #workflow_copy_form select { width: 200px; }
379 381
380 382 textarea#custom_field_possible_values {width: 99%}
381 383
382 384 .pagination {font-size: 90%}
383 385 p.pagination {margin-top:8px;}
384 386
385 387 /***** Tabular forms ******/
386 388 .tabular p{
387 389 margin: 0;
388 390 padding: 5px 0 8px 0;
389 391 padding-left: 180px; /*width of left column containing the label elements*/
390 392 height: 1%;
391 393 clear:left;
392 394 }
393 395
394 396 html>body .tabular p {overflow:hidden;}
395 397
396 398 .tabular label{
397 399 font-weight: bold;
398 400 float: left;
399 401 text-align: right;
400 402 margin-left: -180px; /*width of left column*/
401 403 width: 175px; /*width of labels. Should be smaller than left column to create some right
402 404 margin*/
403 405 }
404 406
405 407 .tabular label.floating{
406 408 font-weight: normal;
407 409 margin-left: 0px;
408 410 text-align: left;
409 411 width: 270px;
410 412 }
411 413
412 414 .tabular label.block{
413 415 font-weight: normal;
414 416 margin-left: 0px !important;
415 417 text-align: left;
416 418 float: none;
417 419 display: block;
418 420 width: auto;
419 421 }
420 422
421 423 .tabular label.inline{
422 424 float:none;
423 425 margin-left: 5px !important;
424 426 width: auto;
425 427 }
426 428
427 429 input#time_entry_comments { width: 90%;}
428 430
429 431 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
430 432
431 433 .tabular.settings p{ padding-left: 300px; }
432 434 .tabular.settings label{ margin-left: -300px; width: 295px; }
433 435 .tabular.settings textarea { width: 99%; }
434 436
435 437 fieldset.settings label { display: block; }
436 438 fieldset#notified_events .parent { padding-left: 20px; }
437 439
438 440 .required {color: #bb0000;}
439 441 .summary {font-style: italic;}
440 442
441 443 #attachments_fields input[type=text] {margin-left: 8px; }
442 444
443 445 div.attachments { margin-top: 12px; }
444 446 div.attachments p { margin:4px 0 2px 0; }
445 447 div.attachments img { vertical-align: middle; }
446 448 div.attachments span.author { font-size: 0.9em; color: #888; }
447 449
448 450 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
449 451 .other-formats span + span:before { content: "| "; }
450 452
451 453 a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
452 454
453 455 /* Project members tab */
454 456 div#tab-content-members .splitcontentleft, div#tab-content-memberships .splitcontentleft, div#tab-content-users .splitcontentleft { width: 64% }
455 457 div#tab-content-members .splitcontentright, div#tab-content-memberships .splitcontentright, div#tab-content-users .splitcontentright { width: 34% }
456 458 div#tab-content-members fieldset, div#tab-content-memberships fieldset, div#tab-content-users fieldset { padding:1em; margin-bottom: 1em; }
457 459 div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; }
458 460 div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; }
459 461 div#tab-content-members fieldset div, div#tab-content-users fieldset div { max-height: 400px; overflow:auto; }
460 462
461 463 table.members td.group { padding-left: 20px; background: url(../images/group.png) no-repeat 0% 50%; }
462 464
463 465 input#principal_search, input#user_search {width:100%}
464 466
465 467 * html div#tab-content-members fieldset div { height: 450px; }
466 468
467 469 /***** Flash & error messages ****/
468 470 #errorExplanation, div.flash, .nodata, .warning {
469 471 padding: 4px 4px 4px 30px;
470 472 margin-bottom: 12px;
471 473 font-size: 1.1em;
472 474 border: 2px solid;
473 475 }
474 476
475 477 div.flash {margin-top: 8px;}
476 478
477 479 div.flash.error, #errorExplanation {
478 480 background: url(../images/exclamation.png) 8px 50% no-repeat;
479 481 background-color: #ffe3e3;
480 482 border-color: #dd0000;
481 483 color: #880000;
482 484 }
483 485
484 486 div.flash.notice {
485 487 background: url(../images/true.png) 8px 5px no-repeat;
486 488 background-color: #dfffdf;
487 489 border-color: #9fcf9f;
488 490 color: #005f00;
489 491 }
490 492
491 493 div.flash.warning {
492 494 background: url(../images/warning.png) 8px 5px no-repeat;
493 495 background-color: #FFEBC1;
494 496 border-color: #FDBF3B;
495 497 color: #A6750C;
496 498 text-align: left;
497 499 }
498 500
499 501 .nodata, .warning {
500 502 text-align: center;
501 503 background-color: #FFEBC1;
502 504 border-color: #FDBF3B;
503 505 color: #A6750C;
504 506 }
505 507
506 508 #errorExplanation ul { font-size: 0.9em;}
507 509 #errorExplanation h2, #errorExplanation p { display: none; }
508 510
509 511 /***** Ajax indicator ******/
510 512 #ajax-indicator {
511 513 position: absolute; /* fixed not supported by IE */
512 514 background-color:#eee;
513 515 border: 1px solid #bbb;
514 516 top:35%;
515 517 left:40%;
516 518 width:20%;
517 519 font-weight:bold;
518 520 text-align:center;
519 521 padding:0.6em;
520 522 z-index:100;
521 523 filter:alpha(opacity=50);
522 524 opacity: 0.5;
523 525 }
524 526
525 527 html>body #ajax-indicator { position: fixed; }
526 528
527 529 #ajax-indicator span {
528 530 background-position: 0% 40%;
529 531 background-repeat: no-repeat;
530 532 background-image: url(../images/loading.gif);
531 533 padding-left: 26px;
532 534 vertical-align: bottom;
533 535 }
534 536
535 537 /***** Calendar *****/
536 538 table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
537 539 table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; }
538 540 table.cal thead th.week-number {width: auto;}
539 541 table.cal tbody tr {height: 100px;}
540 542 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
541 543 table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;}
542 544 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
543 545 table.cal td.odd p.day-num {color: #bbb;}
544 546 table.cal td.today {background:#ffffdd;}
545 547 table.cal td.today p.day-num {font-weight: bold;}
546 548 table.cal .starting a, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
547 549 table.cal .ending a, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
548 550 table.cal .starting.ending a, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}
549 551 p.cal.legend span {display:block;}
550 552
551 553 /***** Tooltips ******/
552 554 .tooltip{position:relative;z-index:24;}
553 555 .tooltip:hover{z-index:25;color:#000;}
554 556 .tooltip span.tip{display: none; text-align:left;}
555 557
556 558 div.tooltip:hover span.tip{
557 559 display:block;
558 560 position:absolute;
559 561 top:12px; left:24px; width:270px;
560 562 border:1px solid #555;
561 563 background-color:#fff;
562 564 padding: 4px;
563 565 font-size: 0.8em;
564 566 color:#505050;
565 567 }
566 568
567 569 /***** Progress bar *****/
568 570 table.progress {
569 571 border: 1px solid #D7D7D7;
570 572 border-collapse: collapse;
571 573 border-spacing: 0pt;
572 574 empty-cells: show;
573 575 text-align: center;
574 576 float:left;
575 577 margin: 1px 6px 1px 0px;
576 578 }
577 579
578 580 table.progress td { height: 0.9em; }
579 581 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
580 582 table.progress td.done { background: #DEF0DE none repeat scroll 0%; }
581 583 table.progress td.open { background: #FFF none repeat scroll 0%; }
582 584 p.pourcent {font-size: 80%;}
583 585 p.progress-info {clear: left; font-style: italic; font-size: 80%;}
584 586
585 587 /***** Tabs *****/
586 588 #content .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;}
587 589 #content .tabs ul {margin:0; position:absolute; bottom:0; padding-left:1em; width: 2000px; border-bottom: 1px solid #bbbbbb;}
588 590 #content .tabs ul li {
589 591 float:left;
590 592 list-style-type:none;
591 593 white-space:nowrap;
592 594 margin-right:8px;
593 595 background:#fff;
594 596 position:relative;
595 597 margin-bottom:-1px;
596 598 }
597 599 #content .tabs ul li a{
598 600 display:block;
599 601 font-size: 0.9em;
600 602 text-decoration:none;
601 603 line-height:1.3em;
602 604 padding:4px 6px 4px 6px;
603 605 border: 1px solid #ccc;
604 606 border-bottom: 1px solid #bbbbbb;
605 607 background-color: #eeeeee;
606 608 color:#777;
607 609 font-weight:bold;
608 610 }
609 611
610 612 #content .tabs ul li a:hover {
611 613 background-color: #ffffdd;
612 614 text-decoration:none;
613 615 }
614 616
615 617 #content .tabs ul li a.selected {
616 618 background-color: #fff;
617 619 border: 1px solid #bbbbbb;
618 620 border-bottom: 1px solid #fff;
619 621 }
620 622
621 623 #content .tabs ul li a.selected:hover {
622 624 background-color: #fff;
623 625 }
624 626
625 627 div.tabs-buttons { position:absolute; right: 0; width: 48px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; }
626 628
627 629 button.tab-left, button.tab-right {
628 630 font-size: 0.9em;
629 631 cursor: pointer;
630 632 height:24px;
631 633 border: 1px solid #ccc;
632 634 border-bottom: 1px solid #bbbbbb;
633 635 position:absolute;
634 636 padding:4px;
635 637 width: 20px;
636 638 bottom: -1px;
637 639 }
638 640
639 641 button.tab-left {
640 642 right: 20px;
641 643 background: #eeeeee url(../images/bullet_arrow_left.png) no-repeat 50% 50%;
642 644 }
643 645
644 646 button.tab-right {
645 647 right: 0;
646 648 background: #eeeeee url(../images/bullet_arrow_right.png) no-repeat 50% 50%;
647 649 }
648 650
649 651 /***** Auto-complete *****/
650 652 div.autocomplete {
651 653 position:absolute;
652 654 width:400px;
653 655 margin:0;
654 656 padding:0;
655 657 }
656 658 div.autocomplete ul {
657 659 list-style-type:none;
658 660 margin:0;
659 661 padding:0;
660 662 }
661 663 div.autocomplete ul li {
662 664 list-style-type:none;
663 665 display:block;
664 666 margin:-1px 0 0 0;
665 667 padding:2px;
666 668 cursor:pointer;
667 669 font-size: 90%;
668 670 border: 1px solid #ccc;
669 671 border-left: 1px solid #ccc;
670 672 border-right: 1px solid #ccc;
671 673 background-color:white;
672 674 }
673 675 div.autocomplete ul li.selected { background-color: #ffb;}
674 676 div.autocomplete ul li span.informal {
675 677 font-size: 80%;
676 678 color: #aaa;
677 679 }
678 680
679 681 #parent_issue_candidates ul li {width: 500px;}
680 682 #related_issue_candidates ul li {width: 500px;}
681 683
682 684 /***** Diff *****/
683 685 .diff_out { background: #fcc; }
684 686 .diff_out span { background: #faa; }
685 687 .diff_in { background: #cfc; }
686 688 .diff_in span { background: #afa; }
687 689
688 690 .text-diff {
689 691 padding: 1em;
690 692 background-color:#f6f6f6;
691 693 color:#505050;
692 694 border: 1px solid #e4e4e4;
693 695 }
694 696
695 697 /***** Wiki *****/
696 698 div.wiki table {
697 699 border: 1px solid #505050;
698 700 border-collapse: collapse;
699 701 margin-bottom: 1em;
700 702 }
701 703
702 704 div.wiki table, div.wiki td, div.wiki th {
703 705 border: 1px solid #bbb;
704 706 padding: 4px;
705 707 }
706 708
707 709 div.wiki .external {
708 710 background-position: 0% 60%;
709 711 background-repeat: no-repeat;
710 712 padding-left: 12px;
711 713 background-image: url(../images/external.png);
712 714 }
713 715
714 716 div.wiki a.new {
715 717 color: #b73535;
716 718 }
717 719
718 720 div.wiki pre {
719 721 margin: 1em 1em 1em 1.6em;
720 722 padding: 2px 2px 2px 0;
721 723 background-color: #fafafa;
722 724 border: 1px solid #dadada;
723 725 width:auto;
724 726 overflow-x: auto;
725 727 overflow-y: hidden;
726 728 }
727 729
728 730 div.wiki ul.toc {
729 731 background-color: #ffffdd;
730 732 border: 1px solid #e4e4e4;
731 733 padding: 4px;
732 734 line-height: 1.2em;
733 735 margin-bottom: 12px;
734 736 margin-right: 12px;
735 737 margin-left: 0;
736 738 display: table
737 739 }
738 740 * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
739 741
740 742 div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
741 743 div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
742 744 div.wiki ul.toc ul { margin: 0; padding: 0; }
743 745 div.wiki ul.toc li { list-style-type:none; margin: 0;}
744 746 div.wiki ul.toc li li { margin-left: 1.5em; }
745 747 div.wiki ul.toc li li li { font-size: 0.8em; }
746 748
747 749 div.wiki ul.toc a {
748 750 font-size: 0.9em;
749 751 font-weight: normal;
750 752 text-decoration: none;
751 753 color: #606060;
752 754 }
753 755 div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
754 756
755 757 a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
756 758 a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
757 759 h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
758 760
759 761 div.wiki img { vertical-align: middle; }
760 762
761 763 /***** My page layout *****/
762 764 .block-receiver {
763 765 border:1px dashed #c0c0c0;
764 766 margin-bottom: 20px;
765 767 padding: 15px 0 15px 0;
766 768 }
767 769
768 770 .mypage-box {
769 771 margin:0 0 20px 0;
770 772 color:#505050;
771 773 line-height:1.5em;
772 774 }
773 775
774 776 .handle {
775 777 cursor: move;
776 778 }
777 779
778 780 a.close-icon {
779 781 display:block;
780 782 margin-top:3px;
781 783 overflow:hidden;
782 784 width:12px;
783 785 height:12px;
784 786 background-repeat: no-repeat;
785 787 cursor:pointer;
786 788 background-image:url('../images/close.png');
787 789 }
788 790
789 791 a.close-icon:hover {
790 792 background-image:url('../images/close_hl.png');
791 793 }
792 794
793 795 /***** Gantt chart *****/
794 796 .gantt_hdr {
795 797 position:absolute;
796 798 top:0;
797 799 height:16px;
798 800 border-top: 1px solid #c0c0c0;
799 801 border-bottom: 1px solid #c0c0c0;
800 802 border-right: 1px solid #c0c0c0;
801 803 text-align: center;
802 804 overflow: hidden;
803 805 }
804 806
805 807 .gantt_subjects { font-size: 0.8em; }
806 808 .gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; }
807 809
808 810 .task {
809 811 position: absolute;
810 812 height:8px;
811 813 font-size:0.8em;
812 814 color:#888;
813 815 padding:0;
814 816 margin:0;
815 817 line-height:16px;
816 818 white-space:nowrap;
817 819 }
818 820
819 821 .task.label {width:100%;}
820 822 .task.label.project, .task.label.version { font-weight: bold; }
821 823
822 824 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
823 825 .task_done { background:#00c600 url(../images/task_done.png); border: 1px solid #00c600; }
824 826 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
825 827
826 828 .task_todo.parent { background: #888; border: 1px solid #888; height: 3px;}
827 829 .task_late.parent, .task_done.parent { height: 3px;}
828 830 .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;}
829 831 .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;}
830 832
831 833 .version.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
832 834 .version.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
833 835 .version.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
834 836 .version.marker { background-image:url(../images/version_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
835 837
836 838 .project.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
837 839 .project.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
838 840 .project.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
839 841 .project.marker { background-image:url(../images/project_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
840 842
841 843 .version-behind-schedule a, .issue-behind-schedule a {color: #f66914;}
842 844 .version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;}
843 845
844 846 /***** Icons *****/
845 847 .icon {
846 848 background-position: 0% 50%;
847 849 background-repeat: no-repeat;
848 850 padding-left: 20px;
849 851 padding-top: 2px;
850 852 padding-bottom: 3px;
851 853 }
852 854
853 855 .icon-add { background-image: url(../images/add.png); }
854 856 .icon-edit { background-image: url(../images/edit.png); }
855 857 .icon-copy { background-image: url(../images/copy.png); }
856 858 .icon-duplicate { background-image: url(../images/duplicate.png); }
857 859 .icon-del { background-image: url(../images/delete.png); }
858 860 .icon-move { background-image: url(../images/move.png); }
859 861 .icon-save { background-image: url(../images/save.png); }
860 862 .icon-cancel { background-image: url(../images/cancel.png); }
861 863 .icon-multiple { background-image: url(../images/table_multiple.png); }
862 864 .icon-folder { background-image: url(../images/folder.png); }
863 865 .open .icon-folder { background-image: url(../images/folder_open.png); }
864 866 .icon-package { background-image: url(../images/package.png); }
865 867 .icon-user { background-image: url(../images/user.png); }
866 868 .icon-projects { background-image: url(../images/projects.png); }
867 869 .icon-help { background-image: url(../images/help.png); }
868 870 .icon-attachment { background-image: url(../images/attachment.png); }
869 871 .icon-history { background-image: url(../images/history.png); }
870 872 .icon-time { background-image: url(../images/time.png); }
871 873 .icon-time-add { background-image: url(../images/time_add.png); }
872 874 .icon-stats { background-image: url(../images/stats.png); }
873 875 .icon-warning { background-image: url(../images/warning.png); }
874 876 .icon-fav { background-image: url(../images/fav.png); }
875 877 .icon-fav-off { background-image: url(../images/fav_off.png); }
876 878 .icon-reload { background-image: url(../images/reload.png); }
877 879 .icon-lock { background-image: url(../images/locked.png); }
878 880 .icon-unlock { background-image: url(../images/unlock.png); }
879 881 .icon-checked { background-image: url(../images/true.png); }
880 882 .icon-details { background-image: url(../images/zoom_in.png); }
881 883 .icon-report { background-image: url(../images/report.png); }
882 884 .icon-comment { background-image: url(../images/comment.png); }
883 885 .icon-summary { background-image: url(../images/lightning.png); }
884 886 .icon-server-authentication { background-image: url(../images/server_key.png); }
885 887 .icon-issue { background-image: url(../images/ticket.png); }
886 888 .icon-zoom-in { background-image: url(../images/zoom_in.png); }
887 889 .icon-zoom-out { background-image: url(../images/zoom_out.png); }
888 890
889 891 .icon-file { background-image: url(../images/files/default.png); }
890 892 .icon-file.text-plain { background-image: url(../images/files/text.png); }
891 893 .icon-file.text-x-c { background-image: url(../images/files/c.png); }
892 894 .icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); }
893 895 .icon-file.text-x-php { background-image: url(../images/files/php.png); }
894 896 .icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); }
895 897 .icon-file.text-xml { background-image: url(../images/files/xml.png); }
896 898 .icon-file.image-gif { background-image: url(../images/files/image.png); }
897 899 .icon-file.image-jpeg { background-image: url(../images/files/image.png); }
898 900 .icon-file.image-png { background-image: url(../images/files/image.png); }
899 901 .icon-file.image-tiff { background-image: url(../images/files/image.png); }
900 902 .icon-file.application-pdf { background-image: url(../images/files/pdf.png); }
901 903 .icon-file.application-zip { background-image: url(../images/files/zip.png); }
902 904 .icon-file.application-x-gzip { background-image: url(../images/files/zip.png); }
903 905
904 906 img.gravatar {
905 907 padding: 2px;
906 908 border: solid 1px #d5d5d5;
907 909 background: #fff;
908 910 }
909 911
910 912 div.issue img.gravatar {
911 913 float: right;
912 914 margin: 0 0 0 1em;
913 915 padding: 5px;
914 916 }
915 917
916 918 div.issue table img.gravatar {
917 919 height: 14px;
918 920 width: 14px;
919 921 padding: 2px;
920 922 float: left;
921 923 margin: 0 0.5em 0 0;
922 924 }
923 925
924 926 h2 img.gravatar {
925 927 padding: 3px;
926 928 margin: -2px 4px -4px 0;
927 929 vertical-align: top;
928 930 }
929 931
930 932 h4 img.gravatar {
931 933 padding: 3px;
932 934 margin: -6px 0 -4px 0;
933 935 vertical-align: top;
934 936 }
935 937
936 938 td.username img.gravatar {
937 939 margin: 0 0.5em 0 0;
938 940 vertical-align: top;
939 941 }
940 942
941 943 #activity dt img.gravatar {
942 944 float: left;
943 945 margin: 0 1em 1em 0;
944 946 }
945 947
946 948 /* Used on 12px Gravatar img tags without the icon background */
947 949 .icon-gravatar {
948 950 float: left;
949 951 margin-right: 4px;
950 952 }
951 953
952 954 #activity dt,
953 955 .journal {
954 956 clear: left;
955 957 }
956 958
957 959 .journal-link {
958 960 float: right;
959 961 }
960 962
961 963 h2 img { vertical-align:middle; }
962 964
963 965 .hascontextmenu { cursor: context-menu; }
964 966
965 967 /***** Media print specific styles *****/
966 968 @media print {
967 969 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
968 970 #main { background: #fff; }
969 971 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
970 972 #wiki_add_attachment { display:none; }
971 973 .hide-when-print { display: none; }
972 974 .autoscroll {overflow-x: visible;}
973 975 table.list {margin-top:0.5em;}
974 976 table.list th, table.list td {border: 1px solid #aaa;}
975 977 }
General Comments 0
You need to be logged in to leave comments. Login now