|
@ -185,4 +185,5 @@ DEPENDENCIES
|
|||
sass-rails (~> 3.2.3)
|
||||
seems_rateable!
|
||||
shoulda (> 3.3.2)
|
||||
therubyracer
|
||||
uglifier (>= 1.0.3)
|
||||
|
|
|
@ -120,7 +120,7 @@ class AttachmentsController < ApplicationController
|
|||
end
|
||||
if @attachment.container
|
||||
# Make sure association callbacks are called
|
||||
@attachment.container.attachments.delete(@attachment)
|
||||
@attachment.container.def attachments.delete(@attachment)
|
||||
else
|
||||
@attachment.destroy
|
||||
end
|
||||
|
|
|
@ -568,7 +568,7 @@ class RepositoriesController < ApplicationController
|
|||
project = Project.find(params[:id])
|
||||
if !User.current.member_of?(project)
|
||||
if project.hidden_repo
|
||||
render_403
|
||||
#render_403
|
||||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
|
|
52
db/schema.rb
|
@ -174,6 +174,58 @@ ActiveRecord::Schema.define(:version => 20140618020535) do
|
|||
|
||||
add_index "changesets_issues", ["changeset_id", "issue_id"], :name => "changesets_issues_ids", :unique => true
|
||||
|
||||
create_table "code_review_assignments", :force => true do |t|
|
||||
t.integer "issue_id"
|
||||
t.integer "change_id"
|
||||
t.integer "attachment_id"
|
||||
t.string "file_path"
|
||||
t.string "rev"
|
||||
t.string "rev_to"
|
||||
t.string "action_type"
|
||||
t.integer "changeset_id"
|
||||
end
|
||||
|
||||
create_table "code_review_project_settings", :force => true do |t|
|
||||
t.integer "project_id"
|
||||
t.integer "tracker_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "updated_by"
|
||||
t.boolean "hide_code_review_tab", :default => false
|
||||
t.integer "auto_relation", :default => 1
|
||||
t.integer "assignment_tracker_id"
|
||||
t.text "auto_assign"
|
||||
t.integer "lock_version", :default => 0, :null => false
|
||||
t.boolean "tracker_in_review_dialog", :default => false
|
||||
end
|
||||
|
||||
create_table "code_review_user_settings", :force => true do |t|
|
||||
t.integer "user_id", :default => 0, :null => false
|
||||
t.integer "mail_notification", :default => 0, :null => false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "code_reviews", :force => true do |t|
|
||||
t.integer "project_id"
|
||||
t.integer "change_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "line"
|
||||
t.integer "updated_by_id"
|
||||
t.integer "lock_version", :default => 0, :null => false
|
||||
t.integer "status_changed_from"
|
||||
t.integer "status_changed_to"
|
||||
t.integer "issue_id"
|
||||
t.string "action_type"
|
||||
t.string "file_path"
|
||||
t.string "rev"
|
||||
t.string "rev_to"
|
||||
t.integer "attachment_id"
|
||||
t.integer "file_count", :default => 0, :null => false
|
||||
t.boolean "diff_all"
|
||||
end
|
||||
|
||||
create_table "comments", :force => true do |t|
|
||||
t.string "commented_type", :limit => 30, :default => "", :null => false
|
||||
t.integer "commented_id", :default => 0, :null => false
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,35 @@
|
|||
= Redmine Code Review Plugin
|
||||
|
||||
This is a plugin for Redmine which lets you annotate source code within the repository browser.
|
||||
|
||||
http://www.r-labs.org/wiki/r-labs/Code_Review
|
||||
|
||||
=== Plugin installation
|
||||
|
||||
1. Copy the plugin directory into the plugins directory
|
||||
|
||||
2. Migrate plugin:
|
||||
rake redmine:plugins:migrate RAILS_ENV=production
|
||||
|
||||
3. Start Redmine
|
||||
|
||||
4. Add code review module into your project.
|
||||
|
||||
5. Go to code review setting tab in the project setting page and select tracker.
|
||||
|
||||
=== Language contributors
|
||||
|
||||
* de.yml - Michael Diederich, Sebastian Bernhard
|
||||
* fr.yml - Thomas M
|
||||
* hu.yml - Péter Major
|
||||
* ko.yml - Ki-yong Kim, Ki Won Kim
|
||||
* nl.yml - Stefan Verstege
|
||||
* pt-br.yml - Alessandro Hecht
|
||||
* zh.yml - Marshall Wu
|
||||
* zh-tw.yml - Andrew Liu
|
||||
* ru.yml - Mykhaylo Sorochan
|
||||
* sk.yml - Milan Freml
|
||||
* es.yml - Ignacio Carrera
|
||||
* pl.yml - Rafal Grzymkowski
|
||||
* sv.yml - André Jonsson
|
||||
* bg.yml - Ivan Cenov, jwalkerbg
|
|
@ -0,0 +1,398 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2013 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class CodeReviewController < ApplicationController
|
||||
unloadable
|
||||
before_filter :find_project, :authorize, :find_user, :find_setting, :find_repository
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :journals
|
||||
helper :projects
|
||||
include ProjectsHelper
|
||||
helper :issues
|
||||
include IssuesHelper
|
||||
helper :code_review
|
||||
include CodeReviewHelper
|
||||
helper :custom_fields
|
||||
include CustomFieldsHelper
|
||||
|
||||
def index
|
||||
sort_init "#{Issue.table_name}.id", 'desc'
|
||||
sort_update ["#{Issue.table_name}.id", "#{Issue.table_name}.status_id", "#{Issue.table_name}.subject", "path", "updated_at", "user_id", "#{Changeset.table_name}.committer", "#{Changeset.table_name}.revision"]
|
||||
|
||||
limit = per_page_option
|
||||
@review_count = CodeReview.count(:conditions => ['project_id = ? and issue_id is NOT NULL', @project.id])
|
||||
@all_review_count = CodeReview.count(:conditions => ['project_id = ?', @project.id])
|
||||
@review_pages = Paginator.new self, @review_count, limit, params['page']
|
||||
@show_closed = (params['show_closed'] == 'true')
|
||||
show_closed_option = " and #{IssueStatus.table_name}.is_closed = ? "
|
||||
if (@show_closed)
|
||||
show_closed_option = ''
|
||||
end
|
||||
conditions = ["#{CodeReview.table_name}.project_id = ? and issue_id is NOT NULL" + show_closed_option, @project.id]
|
||||
unless (@show_closed)
|
||||
conditions << false
|
||||
end
|
||||
|
||||
@reviews = CodeReview.order(sort_clause).limit(limit).where(conditions).joins(
|
||||
"left join #{Change.table_name} on change_id = #{Change.table_name}.id left join #{Changeset.table_name} on #{Change.table_name}.changeset_id = #{Changeset.table_name}.id " +
|
||||
"left join #{Issue.table_name} on issue_id = #{Issue.table_name}.id " +
|
||||
"left join #{IssueStatus.table_name} on #{Issue.table_name}.status_id = #{IssueStatus.table_name}.id").offset(@review_pages.current.offset)
|
||||
@i_am_member = @user.member_of?(@project)
|
||||
render :template => 'code_review/index.html.erb', :layout => !request.xhr?
|
||||
end
|
||||
|
||||
def new
|
||||
begin
|
||||
CodeReview.transaction {
|
||||
@review = CodeReview.new
|
||||
@review.issue = Issue.new
|
||||
|
||||
if params[:issue] and params[:issue][:tracker_id]
|
||||
@review.issue.tracker_id = params[:issue][:tracker_id].to_i
|
||||
else
|
||||
@review.issue.tracker_id = @setting.tracker_id
|
||||
end
|
||||
@review.safe_attributes = params[:review]
|
||||
@review.project_id = @project.id
|
||||
@review.issue.project_id = @project.id
|
||||
|
||||
@review.user_id = @user.id
|
||||
@review.updated_by_id = @user.id
|
||||
@review.issue.start_date = Date.today
|
||||
@review.action_type = params[:action_type]
|
||||
@review.rev = params[:rev] unless params[:rev].blank?
|
||||
@review.rev_to = params[:rev_to] unless params[:rev_to].blank?
|
||||
@review.file_path = params[:path] unless params[:path].blank?
|
||||
@review.file_count = params[:file_count].to_i unless params[:file_count].blank?
|
||||
@review.attachment_id = params[:attachment_id].to_i unless params[:attachment_id].blank?
|
||||
@issue = @review.issue
|
||||
@review.issue.safe_attributes = params[:issue] unless params[:issue].blank?
|
||||
@review.diff_all = (params[:diff_all] == 'true')
|
||||
|
||||
@parent_candidate = get_parent_candidate(@review.rev) if @review.rev
|
||||
|
||||
if request.post?
|
||||
@review.issue.save!
|
||||
if @review.changeset
|
||||
@review.changeset.issues.each {|issue|
|
||||
create_relation @review, issue, @setting.issue_relation_type
|
||||
} if @setting.auto_relation?
|
||||
elsif @review.attachment and @review.attachment.container_type == 'Issue'
|
||||
issue = Issue.find_by_id(@review.attachment.container_id)
|
||||
create_relation @review, issue, @setting.issue_relation_type if @setting.auto_relation?
|
||||
end
|
||||
@review.open_assignment_issues(@user.id).each {|issue|
|
||||
create_relation @review, issue, IssueRelation::TYPE_RELATES
|
||||
watcher = Watcher.new
|
||||
watcher.watchable_id = @review.issue.id
|
||||
watcher.watchable_type = 'Issue'
|
||||
watcher.user = issue.author
|
||||
watcher.save!
|
||||
}
|
||||
@review.save!
|
||||
|
||||
render :partial => 'add_success', :status => 200
|
||||
return
|
||||
else
|
||||
change_id = params[:change_id].to_i unless params[:change_id].blank?
|
||||
@review.change = Change.find(change_id) if change_id
|
||||
@review.line = params[:line].to_i unless params[:line].blank?
|
||||
if (@review.changeset and @review.changeset.user_id)
|
||||
@review.issue.assigned_to_id = @review.changeset.user_id
|
||||
end
|
||||
@default_version_id = @review.issue.fixed_version.id if @review.issue.fixed_version
|
||||
if @review.changeset and @default_version_id.blank?
|
||||
@review.changeset.issues.each {|issue|
|
||||
if issue.fixed_version
|
||||
@default_version_id = issue.fixed_version.id
|
||||
break;
|
||||
end
|
||||
}
|
||||
end
|
||||
@review.open_assignment_issues(@user.id).each {|issue|
|
||||
if issue.fixed_version
|
||||
@default_version_id = issue.fixed_version.id
|
||||
break;
|
||||
end
|
||||
} unless @default_version_id
|
||||
|
||||
|
||||
end
|
||||
render :partial => 'new_form', :status => 200
|
||||
}
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render :partial => 'new_form', :status => 200
|
||||
end
|
||||
end
|
||||
|
||||
def assign
|
||||
code = {}
|
||||
code[:action_type] = params[:action_type] unless params[:action_type].blank?
|
||||
code[:rev] = params[:rev] unless params[:rev].blank?
|
||||
code[:rev_to] = params[:rev_to] unless params[:rev_to].blank?
|
||||
code[:path] = params[:path] unless params[:path].blank?
|
||||
code[:change_id] = params[:change_id].to_i unless params[:change_id].blank?
|
||||
code[:changeset_id] = params[:changeset_id].to_i unless params[:changeset_id].blank?
|
||||
code[:attachment_id] = params[:attachment_id].to_i unless params[:attachment_id].blank?
|
||||
code[:repository_id] = @repository_id if @repository_id
|
||||
|
||||
changeset = Changeset.find(code[:changeset_id]) if code[:changeset_id]
|
||||
if (changeset == nil and code[:change_id] != nil)
|
||||
change = Change.find(code[:change_id])
|
||||
changeset = change.changeset if change
|
||||
end
|
||||
attachment = Attachment.find(code[:attachment_id]) if code[:attachment_id]
|
||||
|
||||
issue = {}
|
||||
issue[:subject] = l(:code_review_requrest)
|
||||
issue[:subject] << " [#{changeset.text_tag}: #{changeset.short_comments}]" if changeset
|
||||
unless changeset
|
||||
issue[:subject] << " [#{attachment.filename}]" if attachment
|
||||
end
|
||||
issue[:tracker_id] = @setting.assignment_tracker_id if @setting.assignment_tracker_id
|
||||
|
||||
redirect_to :controller => 'issues', :action => "new" , :project_id => @project,
|
||||
:issue => issue, :code => code
|
||||
end
|
||||
|
||||
def update_diff_view
|
||||
@show_review_id = params[:review_id].to_i unless params[:review_id].blank?
|
||||
@show_review = CodeReview.find(@show_review_id) if @show_review_id
|
||||
@review = CodeReview.new
|
||||
@rev = params[:rev] unless params[:rev].blank?
|
||||
@rev_to = params[:rev_to] unless params[:rev_to].blank?
|
||||
@path = params[:path] unless params[:path].blank?
|
||||
@paths = []
|
||||
@paths << @path unless @path.blank?
|
||||
|
||||
@action_type = params[:action_type]
|
||||
changeset = @repository.find_changeset_by_name(@rev)
|
||||
if @paths.empty?
|
||||
changeset.filechanges.each{|chg|
|
||||
}
|
||||
end
|
||||
|
||||
url = @repository.url
|
||||
root_url = @repository.root_url
|
||||
if (url == nil || root_url == nil)
|
||||
fullpath = @path
|
||||
else
|
||||
rootpath = url[root_url.length, url.length - root_url.length]
|
||||
if rootpath.blank?
|
||||
fullpath = @path
|
||||
else
|
||||
fullpath = (rootpath + '/' + @path).gsub(/[\/]+/, '/')
|
||||
end
|
||||
end
|
||||
@change = nil
|
||||
changeset.filechanges.each{|chg|
|
||||
@change = chg if ((chg.path == fullpath) or ("/#{chg.path}" == fullpath)) or (chg.path == "/#{@path}")
|
||||
} unless @path.blank?
|
||||
|
||||
@changeset = changeset
|
||||
if @path
|
||||
@reviews = CodeReview.where(['file_path = ? and rev = ? and issue_id is NOT NULL', @path, @rev]).all
|
||||
else
|
||||
@reviews = CodeReview.where(['rev = ? and issue_id is NOT NULL', @rev]).all
|
||||
end
|
||||
@review.change_id = @change.id if @change
|
||||
|
||||
#render :partial => 'show_error'
|
||||
#return
|
||||
|
||||
|
||||
|
||||
render :partial => 'update_diff_view'
|
||||
end
|
||||
|
||||
def update_attachment_view
|
||||
@show_review_id = params[:review_id].to_i unless params[:review_id].blank?
|
||||
@attachment_id = params[:attachment_id].to_i
|
||||
@show_review = CodeReview.find(@show_review_id) if @show_review_id
|
||||
@review = CodeReview.new
|
||||
@action_type = 'attachment'
|
||||
@attachment = Attachment.find(@attachment_id)
|
||||
|
||||
@reviews = CodeReview.where(['attachment_id = (?) and issue_id is NOT NULL', @attachment_id]).all
|
||||
|
||||
render :partial => 'update_diff_view'
|
||||
end
|
||||
|
||||
def show
|
||||
@review = CodeReview.find(params[:review_id].to_i) unless params[:review_id].blank?
|
||||
@repository = @review.repository if @review
|
||||
@assignment = CodeReviewAssignment.find(params[:assignment_id].to_i) unless params[:assignment_id].blank?
|
||||
@repository_id = @assignment.repository_identifier if @assignment
|
||||
@issue = @review.issue if @review
|
||||
@allowed_statuses = @review.issue.new_statuses_allowed_to(User.current) if @review
|
||||
target = @review if @review
|
||||
target = @assignment if @assignment
|
||||
@repository_id = target.repository_identifier
|
||||
if request.xhr? or !params[:update].blank?
|
||||
render :partial => 'show'
|
||||
elsif target.path
|
||||
#@review = @review.root
|
||||
path = URI.decode(target.path)
|
||||
#path = '/' + path unless path.match(/^\//)
|
||||
action_name = target.action_type
|
||||
rev_to = ''
|
||||
rev_to = '&rev_to=' + target.rev_to if target.rev_to
|
||||
if action_name == 'attachment'
|
||||
attachment = target.attachment
|
||||
url = url_for(:controller => 'attachments', :action => 'show', :id => attachment.id) + '/' + URI.escape(attachment.filename)
|
||||
url << '?review_id=' + @review.id.to_s if @review
|
||||
redirect_to(url)
|
||||
else
|
||||
path = nil if target.diff_all
|
||||
url = url_for(:controller => 'repositories', :action => action_name, :id => @project,
|
||||
:repository_id => @repository_id, :rev => target.revision, :path => path)
|
||||
#url = url_for(:controller => 'repositories', :action => action_name, :id => @project, :repository_id => @repository_id) + path + '?rev=' + target.revision
|
||||
url << '?review_id=' + @review.id.to_s + rev_to if @review
|
||||
redirect_to url
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def reply
|
||||
begin
|
||||
@review = CodeReview.find(params[:review_id].to_i)
|
||||
@issue = @review.issue
|
||||
@issue.lock_version = params[:issue][:lock_version]
|
||||
comment = params[:reply][:comment]
|
||||
journal = @issue.init_journal(User.current, comment)
|
||||
@review.safe_attributes = params[:review]
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
|
||||
@issue.save!
|
||||
if !journal.new_record?
|
||||
# Only send notification if something was actually changed
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
end
|
||||
|
||||
render :partial => 'show'
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
# Optimistic locking exception
|
||||
@error = l(:notice_locking_conflict)
|
||||
render :partial => 'show'
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
CodeReview.transaction {
|
||||
@review = CodeReview.find(params[:review_id].to_i)
|
||||
journal = @review.issue.init_journal(User.current, nil)
|
||||
@allowed_statuses = @review.issue.new_statuses_allowed_to(User.current)
|
||||
@issue = @review.issue
|
||||
@issue.lock_version = params[:issue][:lock_version]
|
||||
@review.safe_attributes = params[:review]
|
||||
@review.updated_by_id = @user.id
|
||||
@review.save!
|
||||
@review.issue.save!
|
||||
@notice = l(:notice_review_updated)
|
||||
lang = current_language
|
||||
Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
|
||||
set_language lang if respond_to? 'set_language'
|
||||
render :partial => 'show'
|
||||
}
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
# Optimistic locking exception
|
||||
@error = l(:notice_locking_conflict)
|
||||
render :partial => 'show'
|
||||
rescue
|
||||
render :partial => 'show'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def destroy
|
||||
@review = CodeReview.find(params[:review_id].to_i)
|
||||
@review.issue.destroy if @review
|
||||
render :text => 'delete success.'
|
||||
end
|
||||
|
||||
def forward_to_revision
|
||||
path = params[:path]
|
||||
rev = params[:rev]
|
||||
changesets = @repository.latest_changesets(path, rev, Setting.repository_log_display_limit.to_i)
|
||||
change = changesets[0]
|
||||
|
||||
identifier = change.identifier
|
||||
redirect_to url_for(:controller => 'repositories', :action => 'entry', :id => @project, :repository_id => @repository_id) + '/' + path + '?rev=' + identifier.to_s
|
||||
|
||||
end
|
||||
|
||||
def preview
|
||||
@text = params[:review][:comment]
|
||||
@text = params[:reply][:comment] unless @text
|
||||
render :partial => 'common/preview'
|
||||
end
|
||||
|
||||
def update_revisions_view
|
||||
changeset_ids = []
|
||||
#changeset_ids = CGI.unescape(params[:changeset_ids]).split(',') unless params[:changeset_ids].blank?
|
||||
changeset_ids = params[:changeset_ids].split(',') unless params[:changeset_ids].blank?
|
||||
@changesets = []
|
||||
changeset_ids.each {|id|
|
||||
@changesets << @repository.find_changeset_by_name(id) unless id.blank?
|
||||
}
|
||||
render :partial => 'update_revisions'
|
||||
end
|
||||
|
||||
private
|
||||
def find_repository
|
||||
if params[:repository_id].present? and @project.repositories
|
||||
@repository = @project.repositories.find_by_identifier_param(params[:repository_id])
|
||||
else
|
||||
@repository = @project.repository
|
||||
end
|
||||
@repository_id = @repository.identifier_param if @repository.respond_to?("identifier_param")
|
||||
end
|
||||
|
||||
def find_project
|
||||
# @project variable must be set before calling the authorize filter
|
||||
@project = Project.find(params[:id])
|
||||
end
|
||||
|
||||
def find_user
|
||||
@user = User.current
|
||||
end
|
||||
|
||||
|
||||
def find_setting
|
||||
@setting = CodeReviewProjectSetting.find_or_create(@project)
|
||||
end
|
||||
|
||||
def get_parent_candidate(revision)
|
||||
changeset = @repository.find_changeset_by_name(revision)
|
||||
changeset.issues.each {|issue|
|
||||
return Issue.find(issue.parent_issue_id) if issue.parent_issue_id
|
||||
}
|
||||
nil
|
||||
end
|
||||
|
||||
def create_relation(review, issue, type)
|
||||
return unless issue.project == @project
|
||||
relation = IssueRelation.new
|
||||
relation.relation_type = type
|
||||
relation.issue_from_id = review.issue.id
|
||||
relation.issue_to_id = issue.id
|
||||
relation.save!
|
||||
end
|
||||
end
|
|
@ -0,0 +1,119 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class CodeReviewSettingsController < ApplicationController
|
||||
unloadable
|
||||
layout 'base'
|
||||
menu_item :code_review
|
||||
include CodeReviewAutoAssignSettings
|
||||
|
||||
before_filter :find_project, :authorize, :find_user
|
||||
|
||||
def update
|
||||
begin
|
||||
@setting = CodeReviewProjectSetting.find_or_create(@project)
|
||||
|
||||
@setting.safe_attributes = params[:setting]
|
||||
@setting.updated_by = @user.id
|
||||
params[:auto_assign][:filters] = params[:auto_assign][:filters].values unless params[:auto_assign][:filters].blank?
|
||||
@setting.auto_assign_settings = params[:auto_assign].to_yaml
|
||||
|
||||
@setting.save!
|
||||
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
# Optimistic locking exception
|
||||
flash[:error] = l(:notice_locking_conflict)
|
||||
end
|
||||
redirect_to :controller => 'projects', :action => "settings", :id => @project, :tab => 'code_review'
|
||||
|
||||
end
|
||||
|
||||
def add_filter
|
||||
setting = CodeReviewProjectSetting.find_or_create(@project)
|
||||
@auto_assign = setting.auto_assign_settings
|
||||
filters = params[:auto_assign][:filters].values unless params[:auto_assign][:filters].blank?
|
||||
filters = [] unless filters
|
||||
filters << params[:auto_assign_add_filter]
|
||||
|
||||
@auto_assign.filters = filters.collect{|f|
|
||||
filter = AssignmentFilter.new
|
||||
filter.attributes = f
|
||||
filter
|
||||
}
|
||||
@auto_assign.filter_enabled = true
|
||||
render :partial => "code_review_settings/filters"
|
||||
end
|
||||
|
||||
def edit_filter
|
||||
setting = CodeReviewProjectSetting.find_or_create(@project)
|
||||
@auto_assign = setting.auto_assign_settings
|
||||
num = params[:num].to_i
|
||||
filters = params[:auto_assign][:filters].values unless params[:auto_assign][:filters].blank?
|
||||
filters = [] unless filters
|
||||
i = 0
|
||||
@auto_assign.filters = filters.collect{|f|
|
||||
filter = AssignmentFilter.new
|
||||
if i == num
|
||||
filter.attributes = params[:auto_assign_edit_filter][num.to_s]
|
||||
else
|
||||
filter.attributes = f
|
||||
end
|
||||
i = i + 1
|
||||
filter
|
||||
}
|
||||
render :partial => "code_review_settings/filters"
|
||||
end
|
||||
|
||||
def sort
|
||||
setting = CodeReviewProjectSetting.find_or_create(@project)
|
||||
@auto_assign = setting.auto_assign_settings
|
||||
filters = params[:auto_assign][:filters].values unless params[:auto_assign][:filters].blank?
|
||||
filters = [] unless filters
|
||||
num = params[:auto_assign_filter][:num].to_i
|
||||
move_to = params[:auto_assign_filter][:move_to]
|
||||
|
||||
if move_to == 'highest'
|
||||
filters[num][:order] = 0
|
||||
elsif move_to == 'higher'
|
||||
filters[num][:order] = filters[num][:order].to_i - 15
|
||||
elsif move_to == 'lower'
|
||||
filters[num][:order] = filters[num][:order].to_i + 15
|
||||
elsif move_to == 'lowest'
|
||||
filters[num][:order] = 999999999
|
||||
end
|
||||
|
||||
@auto_assign.filters = filters.collect{|f|
|
||||
filter = AssignmentFilter.new
|
||||
filter.attributes = f
|
||||
filter
|
||||
}
|
||||
|
||||
|
||||
render :partial => "code_review_settings/filters"
|
||||
end
|
||||
private
|
||||
def find_project
|
||||
# @project variable must be set before calling the authorize filter
|
||||
@project = Project.find(params[:id])
|
||||
end
|
||||
|
||||
def find_user
|
||||
@user = User.current
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,37 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2011 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
module CodeReviewHelper
|
||||
unloadable
|
||||
def show_assignments(assignments, project, options = {})
|
||||
html = "#{l(:review_assignments)}:"
|
||||
assignments.each do |assignment|
|
||||
issue = assignment.issue
|
||||
html << link_to("##{issue.id} ", {:controller => 'issues', :action => 'show', :id => issue.id},
|
||||
:class => issue.css_classes, :title => "#{issue}(#{issue.status})")
|
||||
end if assignments
|
||||
|
||||
link = link_to(l(:button_add), {:controller => 'code_review',
|
||||
:action => 'assign', :id=>project, :action_type => options[:action_type],
|
||||
:rev => options[:rev], :rev_to => options[:rev_to], :path => options[:path],
|
||||
:change_id => options[:change_id], :attachment_id => options[:attachment_id],
|
||||
:changeset_id => options[:changeset_id]}, :class => 'icon icon-add')
|
||||
|
||||
html << link if link
|
||||
|
||||
html
|
||||
end
|
||||
end
|
|
@ -0,0 +1,175 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
class CodeReview < ActiveRecord::Base
|
||||
include Redmine::SafeAttributes
|
||||
unloadable
|
||||
belongs_to :project
|
||||
belongs_to :change
|
||||
belongs_to :issue
|
||||
belongs_to :updated_by, :class_name => 'User', :foreign_key => 'updated_by_id'
|
||||
belongs_to :attachment
|
||||
|
||||
validates_presence_of :project_id, :user_id, :updated_by_id, :issue,
|
||||
:subject, :action_type, :line
|
||||
|
||||
STATUS_OPEN = 0
|
||||
STATUS_CLOSED = 1
|
||||
|
||||
safe_attributes 'change_id', 'subject', 'line', 'parent_id', 'comment', 'status_id'
|
||||
|
||||
def before_create
|
||||
issue = Issue.new unless issue
|
||||
end
|
||||
|
||||
def is_closed?
|
||||
issue.closed?
|
||||
#self.root.status == STATUS_CLOSED
|
||||
end
|
||||
|
||||
def close
|
||||
issue.status = IssueStatus.find(5)
|
||||
#self.root.status = STATUS_CLOSED
|
||||
end
|
||||
|
||||
def reopen
|
||||
issue.status = IssueStatus.find(1)
|
||||
#self.root.status = STATUS_OPEN
|
||||
end
|
||||
|
||||
def committer
|
||||
return changeset.author if changeset
|
||||
end
|
||||
|
||||
def path
|
||||
begin
|
||||
return file_path if file_path
|
||||
return @path if @path
|
||||
if attachment_id
|
||||
@path = attachment.filename
|
||||
return @path
|
||||
end
|
||||
repository = changeset.repository
|
||||
url = repository.url
|
||||
root_url = repository.root_url
|
||||
if (url == nil || root_url == nil)
|
||||
@path = change.path
|
||||
return @path
|
||||
end
|
||||
rootpath = url[root_url.length, url.length - root_url.length]
|
||||
if rootpath == '/' || rootpath.blank?
|
||||
@path = change.path
|
||||
else
|
||||
@path = change.path[rootpath.length, change.path.length - rootpath.length]
|
||||
end
|
||||
rescue => ex
|
||||
return ex.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def revision
|
||||
return rev if rev
|
||||
changeset.revision if changeset
|
||||
end
|
||||
|
||||
def changeset
|
||||
@changeset ||= change.changeset if change
|
||||
end
|
||||
|
||||
def repository
|
||||
@repository ||= changeset.repository if changeset
|
||||
end
|
||||
|
||||
def repository_identifier
|
||||
return nil unless repository
|
||||
@repository_identifier ||= repository.identifier_param
|
||||
end
|
||||
|
||||
def comment=(str)
|
||||
issue.description = str if issue
|
||||
end
|
||||
|
||||
def comment
|
||||
issue.description if issue
|
||||
end
|
||||
|
||||
def before_save
|
||||
issue.project_id = project_id unless issue.project_id
|
||||
end
|
||||
|
||||
def validate
|
||||
unless issue.validate
|
||||
false
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def user=(u)
|
||||
issue.author = u
|
||||
end
|
||||
|
||||
def user_id=(id)
|
||||
issue.author_id = id
|
||||
end
|
||||
|
||||
def user_id
|
||||
issue.author_id
|
||||
end
|
||||
|
||||
def user
|
||||
issue.author if issue
|
||||
end
|
||||
|
||||
def subject=(s)
|
||||
issue.subject = s
|
||||
end
|
||||
|
||||
def subject
|
||||
issue.subject
|
||||
end
|
||||
|
||||
def parent_id= (p)
|
||||
issue.parent_issue_id = p
|
||||
end
|
||||
|
||||
def parent_id
|
||||
issue.parent_issue_id
|
||||
end
|
||||
|
||||
def status_id=(s)
|
||||
issue.status_id = s
|
||||
end
|
||||
|
||||
def status_id
|
||||
issue.status_id
|
||||
end
|
||||
|
||||
def open_assignment_issues(user_id)
|
||||
issues = []
|
||||
assignments = []
|
||||
assignments = change.code_review_assignments if change
|
||||
assignments = assignments + changeset.code_review_assignments if changeset
|
||||
assignments = assignments + attachment.code_review_assignments if attachment
|
||||
|
||||
assignments.each {|assignment|
|
||||
unless assignment.is_closed?
|
||||
issues << assignment.issue if user_id == assignment.issue.assigned_to_id
|
||||
end
|
||||
}
|
||||
|
||||
issues
|
||||
end
|
||||
end
|
|
@ -0,0 +1,80 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010-2011 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class CodeReviewAssignment < ActiveRecord::Base
|
||||
unloadable
|
||||
belongs_to :issue
|
||||
belongs_to :change
|
||||
belongs_to :changeset
|
||||
belongs_to :attachment
|
||||
validates_presence_of :issue_id
|
||||
|
||||
def is_closed?
|
||||
issue.closed?
|
||||
end
|
||||
|
||||
def path
|
||||
file_path
|
||||
end
|
||||
|
||||
def revision
|
||||
return rev if rev
|
||||
changeset.revision if changeset
|
||||
end
|
||||
|
||||
def repository
|
||||
@repository ||= change.changeset.repository if change
|
||||
@repository ||= changeset.repository if changeset
|
||||
@repository
|
||||
end
|
||||
|
||||
def repository_identifier
|
||||
return nil unless repository
|
||||
@repository_identifier ||= repository.identifier_param if repository.respond_to?("identifier_param")
|
||||
end
|
||||
|
||||
def self.create_with_changeset(changeset)
|
||||
project = changeset.project
|
||||
setting = CodeReviewProjectSetting.find_or_create(project)
|
||||
auto_assign = setting.auto_assign_settings
|
||||
assignment = CodeReviewAssignment.new
|
||||
issue = Issue.new
|
||||
issue.subject = auto_assign.subject
|
||||
issue.subject = l(:code_review_requrest) if issue.subject.blank?
|
||||
issue.subject = issue.subject.sub("$REV" , changeset.revision)
|
||||
issue.subject = issue.subject.sub("$COMMENTS" , changeset.comments.split(//u)[0..60].join) unless changeset.comments.blank?
|
||||
issue.tracker_id = setting.assignment_tracker_id
|
||||
issue.project = project
|
||||
issue.author = User.find(auto_assign.author_id)
|
||||
issue.assigned_to_id = auto_assign.select_assign_to(project, changeset.user)
|
||||
issue.description = auto_assign.description
|
||||
issue.description = issue.description.sub("$REV" , changeset.revision) unless issue.description.blank?
|
||||
issue.description = issue.description.sub("$COMMENTS" , changeset.comments) unless changeset.comments.blank?
|
||||
|
||||
issue.save!
|
||||
|
||||
assignment.issue_id = issue.id
|
||||
assignment.changeset_id = changeset.id
|
||||
assignment.save!
|
||||
assignment
|
||||
end
|
||||
|
||||
|
||||
def diff_all
|
||||
path.blank?
|
||||
end
|
||||
end
|
|
@ -0,0 +1,77 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2011 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
class CodeReviewProjectSetting < ActiveRecord::Base
|
||||
unloadable
|
||||
include Redmine::SafeAttributes
|
||||
include CodeReviewAutoAssignSettings
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :tracker
|
||||
belongs_to :assignment_tracker, :class_name => 'Tracker'
|
||||
|
||||
validates_presence_of :project_id
|
||||
validates_presence_of :tracker_id
|
||||
validates_presence_of :assignment_tracker_id
|
||||
|
||||
before_save :set_assignment_settings
|
||||
|
||||
safe_attributes 'tracker_id', 'assignment_tracker_id', 'hide_code_review_tab', 'auto_relation', 'tracker_in_review_dialog'
|
||||
|
||||
AUTORELATION_TYPE_NONE = 0
|
||||
AUTORELATION_TYPE_RELATES = 1
|
||||
AUTORELATION_TYPE_BLOCKS = 2
|
||||
|
||||
def self.find_or_create(project)
|
||||
setting = CodeReviewProjectSetting.find_by_project_id(project.id)
|
||||
unless setting
|
||||
setting = CodeReviewProjectSetting.new
|
||||
setting.project_id = project.id
|
||||
return setting if project.trackers.length == 0
|
||||
setting.tracker = project.trackers[0]
|
||||
setting.assignment_tracker = project.trackers[0]
|
||||
setting.save!
|
||||
end
|
||||
setting
|
||||
end
|
||||
|
||||
def auto_assign_settings
|
||||
@auto_assign_settings ||= AutoAssignSettings.load(auto_assign)
|
||||
end
|
||||
|
||||
def auto_assign_settings=(settings)
|
||||
@auto_assign_settings = settings
|
||||
end
|
||||
|
||||
def issue_relation_type
|
||||
return IssueRelation::TYPE_RELATES if auto_relation == CodeReviewProjectSetting::AUTORELATION_TYPE_RELATES
|
||||
return IssueRelation::TYPE_BLOCKS if auto_relation == CodeReviewProjectSetting::AUTORELATION_TYPE_BLOCKS
|
||||
return nil
|
||||
end
|
||||
|
||||
def auto_relation?
|
||||
issue_relation_type != nil
|
||||
end
|
||||
|
||||
private
|
||||
def set_assignment_settings
|
||||
if auto_assign_settings
|
||||
self.auto_assign = auto_assign_settings.to_s
|
||||
else
|
||||
self.auto_assign = nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,50 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2011 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
class CodeReviewUserSetting < ActiveRecord::Base
|
||||
unloadable
|
||||
belongs_to :user
|
||||
|
||||
validates_presence_of :user_id
|
||||
validates_presence_of :mail_notification
|
||||
validates_uniqueness_of :user_id
|
||||
|
||||
NOTIFCIATION_NONE = 0
|
||||
NOTIFICATION_INVOLVED_IN = 1
|
||||
NOTIFICATION_ALL = 2
|
||||
|
||||
def CodeReviewUserSetting.find_or_create(uid)
|
||||
setting = CodeReviewUserSetting.find_by_user_id(uid)
|
||||
return setting if setting
|
||||
setting = CodeReviewUserSetting.new
|
||||
setting.user_id = uid
|
||||
setting.mail_notification = NOTIFICATION_INVOLVED_IN
|
||||
setting.save
|
||||
return setting
|
||||
end
|
||||
|
||||
def mail_notification_none?
|
||||
mail_notification == NOTIFCIATION_NONE
|
||||
end
|
||||
|
||||
def mail_notification_involved_in?
|
||||
mail_notification == NOTIFICATION_INVOLVED_IN
|
||||
end
|
||||
|
||||
def mail_notification_all?
|
||||
mail_notification == NOTIFICATION_ALL
|
||||
end
|
||||
end
|
|
@ -0,0 +1,122 @@
|
|||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class ReviewMailer < Mailer
|
||||
|
||||
def review_add(project, review)
|
||||
redmine_headers 'Project' => review.project.identifier,
|
||||
'Review-Id' => review.id,
|
||||
'Review-Author' => review.user.login
|
||||
|
||||
recipients get_mail_addresses(review)
|
||||
|
||||
subject "[#{review.project.name} - #{l(:label_review_new)} - #{l(:label_review)}##{review.id}] "
|
||||
review_url = url_for(:controller => 'code_review', :action => 'show', :id => project, :review_id => review.id)
|
||||
|
||||
body :review => review, :review_url => review_url
|
||||
|
||||
return if (l(:this_is_checking_for_before_rails_2_2_2) == 'this_is_checking_for_before_rails_2_2_2')
|
||||
# 何故かrails 2.2 以後は以下の処理が必要
|
||||
|
||||
content_type "multipart/alternative"
|
||||
|
||||
part "text/plain" do |p|
|
||||
p.body = render_message("review_add.text.plain.erb", :body => body, :review=>review, :review_url => review_url)
|
||||
end
|
||||
|
||||
part "text/html" do |p|
|
||||
p.body = render_message("review_add.text.html.erb", :body => body, :review=>review, :review_url => review_url)
|
||||
end
|
||||
end
|
||||
|
||||
def review_reply(project, review)
|
||||
redmine_headers 'Project' => review.project.identifier,
|
||||
'Review-Id' => review.id,
|
||||
'Review-Author' => review.user.login
|
||||
|
||||
recipients recipients get_mail_addresses(review)
|
||||
|
||||
subject "[#{review.project.name} - Updated - #{l(:label_review)}##{review.root.id}] "
|
||||
review_url = url_for(:controller => 'code_review', :action => 'show', :id => project, :review_id => review.root.id)
|
||||
body :review => review, :review_url => review_url
|
||||
|
||||
return if (l(:this_is_checking_for_before_rails_2_2_2) == 'this_is_checking_for_before_rails_2_2_2')
|
||||
# 何故かrails 2.2 以後は以下の処理が必要
|
||||
|
||||
content_type "multipart/alternative"
|
||||
|
||||
part "text/plain" do |p|
|
||||
p.body = render_message("review_reply.text.plain.erb", :body => body, :review=>review, :review_url => review_url)
|
||||
end
|
||||
|
||||
part "text/html" do |p|
|
||||
p.body = render_message("review_reply.text.html.erb", :body => body, :review=>review, :review_url => review_url)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def review_status_changed(project, review)
|
||||
redmine_headers 'Project' => review.project.identifier,
|
||||
'Review-Id' => review.id,
|
||||
'Review-Author' => review.user.login
|
||||
|
||||
recipients recipients get_mail_addresses(review)
|
||||
|
||||
new_status = l(:label_review_open) if review.status_changed_to == CodeReview::STATUS_OPEN
|
||||
new_status = l(:label_review_closed) if review.status_changed_to == CodeReview::STATUS_CLOSED
|
||||
|
||||
subject "[#{review.project.name} - Updated - #{l(:label_review)}##{review.root.id}] Status changed to #{new_status}."
|
||||
review_url = url_for(:controller => 'code_review', :action => 'show', :id => project, :review_id => review.root.id)
|
||||
|
||||
body :review => review, :review_url => review_url
|
||||
|
||||
return if (l(:this_is_checking_for_before_rails_2_2_2) == 'this_is_checking_for_before_rails_2_2_2')
|
||||
# 何故かrails 2.2 以後は以下の処理が必要
|
||||
|
||||
content_type "multipart/alternative"
|
||||
|
||||
part "text/plain" do |p|
|
||||
p.body = render_message("review_status_changed.text.plain.erb", :body => body, :review=>review, :review_url => review_url)
|
||||
end
|
||||
|
||||
part "text/html" do |p|
|
||||
p.body = render_message("review_status_changed.text.html.erb", :body => body, :review=>review, :review_url => review_url)
|
||||
end
|
||||
end
|
||||
|
||||
def get_mail_addresses(review)
|
||||
mail_addresses = []
|
||||
review.root.users_for_notification.each{|u|
|
||||
mail_addresses << u.mail
|
||||
}
|
||||
committer = review.change.changeset.user
|
||||
if committer
|
||||
setting = CodeReviewUserSetting.find_or_create(committer.id)
|
||||
mail_addresses << committer.mail if setting and !setting.mail_notification_none?
|
||||
end
|
||||
|
||||
review.project.members.each{|member|
|
||||
user = member.user
|
||||
setting = CodeReviewUserSetting.find_or_create(user.id)
|
||||
next unless setting
|
||||
mail_addresses << user.mail if setting.mail_notification_all?
|
||||
}
|
||||
mail_addresses.compact.uniq
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<%= javascript_tag do %>
|
||||
|
||||
var line = <%= @review.line %>;
|
||||
var review_id = <%= @review.id %>;
|
||||
var file_count = <%= @review.file_count %>;
|
||||
hideForm();
|
||||
setShowReviewButton(line, review_id, false, file_count);
|
||||
|
||||
<% end %>
|
|
@ -0,0 +1,82 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
|
||||
<%
|
||||
is_target = false
|
||||
|
||||
if project and controller and project.module_enabled?(:code_review)
|
||||
is_target = true
|
||||
is_target = false unless User.current.allowed_to?({:controller => 'code_review', :action => 'update_diff_view'}, project)
|
||||
setting = CodeReviewProjectSetting.find(:first, :conditions => ['project_id = ?', project.id])
|
||||
is_target = false unless setting
|
||||
is_target = false if(setting && setting.tracker_id == nil)
|
||||
action_name = controller.action_name
|
||||
is_target = false unless action_name
|
||||
is_target = false unless (controller.class.name == 'RepositoriesController' or controller.class.name == 'AttachmentsController')
|
||||
if (is_target == true)
|
||||
context = {:project => project, :controller => controller, :requrest => request}
|
||||
%>
|
||||
<% if (controller.class.name == 'AttachmentsController') %>
|
||||
<%= render :partial => 'code_review/change_attachement_view', :locals => context %>
|
||||
<% elsif (action_name == 'show' or action_name == 'revisions') %>
|
||||
<%= render :partial => 'code_review/change_repository_view', :locals => context %>
|
||||
<% elsif (action_name == 'revision') %>
|
||||
<%= render :partial => 'code_review/change_revision_view', :locals => context %>
|
||||
<% elsif (action_name == 'diff' or action_name == 'entry' or action_name == 'annotate')%>
|
||||
<%if (controller.params[:rev].blank? or controller.params[:rev] == 'master')%>
|
||||
<%= render :partial => 'code_review/change_entry_norevision_view', :locals => context %>
|
||||
<% else
|
||||
changeset = @repository.find_changeset_by_name(controller.params[:rev])
|
||||
%>
|
||||
<% unless changeset %>
|
||||
<%= render :partial => 'code_review/change_entry_norevision_view', :locals => context %>
|
||||
<% else
|
||||
parameters = request.parameters
|
||||
rev_to = parameters['rev_to'] unless parameters['rev_to'].blank?
|
||||
review_id = parameters['review_id']
|
||||
rev = parameters['rev']
|
||||
path = parameters['path']
|
||||
|
||||
|
||||
repository_id = @repository.identifier_param if @repository.respond_to?("identifier_param")
|
||||
url = url_for :controller => 'code_review', :action => 'update_diff_view', :id => project, :repository_id => repository_id
|
||||
%>
|
||||
<div id="code_review">
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('#code_review').load('<%=url%>', {
|
||||
rev: '<%=rev%>',
|
||||
path:'<%=path%>',
|
||||
review_id: '<%=review_id%>',
|
||||
action_type:'<%=action_name%>',
|
||||
rev_to: '<%=rev_to%>'});
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%
|
||||
end
|
||||
end
|
||||
-%>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<%
|
||||
parameters = request.parameters
|
||||
id = parameters[:id].to_i
|
||||
attachment = Attachment.find(id)
|
||||
return '' unless attachment.is_text? or attachment.is_diff?
|
||||
review_id = parameters[:review_id] unless parameters[:review_id].blank?
|
||||
url = url_for :controller => 'code_review', :action => 'update_attachment_view', :id => project
|
||||
-%>
|
||||
<div id="code_review">
|
||||
<div id="review_comment"/>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('#code_review').load('<%=url%>', {'attachment_id': '<%=id%>', 'review_id': '<%=review_id%>'});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010-2011 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<%
|
||||
parameters = request.parameters
|
||||
path = parameters['path']
|
||||
rev = parameters['rev']
|
||||
repository_id = @repository.identifier_param if @repository.respond_to?("identifier_param")
|
||||
unless path.blank? or path.empty?
|
||||
changesets = @repository.latest_changesets(path, rev, Setting.repository_log_display_limit.to_i)
|
||||
change = changesets[0]
|
||||
|
||||
if change
|
||||
link = link_to(l(:label_add_review), {:controller => 'code_review',
|
||||
:action => 'forward_to_revision', :id => project, :path => path, :rev => rev, :repository_id => repository_id},
|
||||
:class => 'icon icon-edit')
|
||||
%>
|
||||
|
||||
<script type="text/javascript">
|
||||
make_addreview_link('<%=project.name%>', '<%=link%>');
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
|
@ -0,0 +1,41 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<%
|
||||
|
||||
if @changesets
|
||||
changeset_ids = ''
|
||||
@changesets.each { |changeset|
|
||||
changeset_ids << changeset.revision
|
||||
changeset_ids << ','
|
||||
}
|
||||
|
||||
repository_id = @repository.identifier_param if @repository.respond_to?("identifier_param")
|
||||
url = url_for :controller => 'code_review', :action => 'update_revisions_view', :id => project, :repository_id => repository_id
|
||||
%>
|
||||
|
||||
<div id="code_review_revisions"></div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('#code_review_revisions').load('<%=url%>', {changeset_ids: '<%=raw changeset_ids%>'});
|
||||
});
|
||||
</script>
|
||||
|
||||
<% end %>
|
|
@ -0,0 +1,73 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010-2011 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<%
|
||||
repository_id = @repository.identifier_param if @repository.respond_to?("identifier_param")
|
||||
if @changeset
|
||||
urlprefix = url_for(:controller => 'repositories', :action => 'revisions', :id => project, :repository_id => repository_id) +
|
||||
'/' + @changeset.identifier + '/entry'
|
||||
%>
|
||||
<div id="code_review_assignments">
|
||||
<%=h l(:review_assignments)%>
|
||||
<% @changeset.code_review_assignments.each do |assignment|
|
||||
issue = assignment.issue %>
|
||||
<%= link_to("##{issue.id} ", {:controller => 'issues', :action => 'show', :id => issue.id},
|
||||
:class => issue.css_classes, :title => "#{issue}(#{issue.status})") %>
|
||||
<% end if @changeset.code_review_assignments %>
|
||||
|
||||
<%= link_to(l(:button_add), {:controller => 'code_review',
|
||||
:action => 'assign', :id=>project,
|
||||
:rev => @changeset.revision,
|
||||
:changeset_id => @changeset.id, :repository_id => repository_id}, :class => 'icon icon-add') %>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#changes-legend').after($('#code_review_assignments'));
|
||||
urlprefix = '<%=urlprefix%>';
|
||||
<% @changeset.changes.each{|change| %>
|
||||
var reviewlist = [];
|
||||
<%
|
||||
cnt = 0
|
||||
change.code_reviews.each {|review|
|
||||
issue = review.issue
|
||||
url = link_to('#' + "#{issue.id} #{review.subject}(#{issue.status})",
|
||||
:controller => 'code_review', :action => 'show', :id => project, :review_id => review.id, :repository_id => repository_id)
|
||||
%>
|
||||
var review = new CodeReview(<%=review.id%>);
|
||||
review.url = '<%=url%>';
|
||||
<% if review.is_closed? %>
|
||||
review.is_closed = true;
|
||||
<% end %>
|
||||
reviewlist[<%=cnt%>] = review;
|
||||
<%
|
||||
cnt += 1
|
||||
|
||||
}
|
||||
relative_path = change.relative_path || ""
|
||||
if relative_path[0] != ?/
|
||||
relative_path = '/' + relative_path
|
||||
end
|
||||
escaped_relative_path = relative_path.gsub("'"){"\\'"}
|
||||
%>
|
||||
code_reviews_map['<%=escaped_relative_path-%>'] = reviewlist;
|
||||
<%
|
||||
}
|
||||
%>
|
||||
UpdateRevisionView();
|
||||
</script>
|
||||
<% end %>
|
|
@ -0,0 +1,84 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<% for journal in journals %>
|
||||
|
||||
<!-- skip initial entry of code review creation -->
|
||||
<% if not journal.initial? %>
|
||||
|
||||
<!-- header and notes/comments -->
|
||||
<%
|
||||
header = <<-HTML
|
||||
<h4>
|
||||
#{authoring journal.created_at, journal.user, :label => :label_updated_time_by}
|
||||
#{content_tag('a', '', :name => "note-#{journal.anchor}")}
|
||||
</h4>
|
||||
|
||||
<div class="profile-wrap">
|
||||
#{avatar(journal.user, :size => "40")}
|
||||
</div>
|
||||
HTML
|
||||
|
||||
if not journal.notes.blank?
|
||||
if User.current.logged?
|
||||
editable = User.current.allowed_to?(:edit_issue_notes, journal.project)
|
||||
if journal.user == User.current
|
||||
editable ||= User.current.allowed_to?(:edit_own_issue_notes, journal.project)
|
||||
end
|
||||
end
|
||||
|
||||
links = [].tap do |l|
|
||||
if editable
|
||||
l << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
|
||||
{ :controller => 'journals', :action => 'edit', :id => journal },
|
||||
:title => l(:button_edit))
|
||||
end
|
||||
end
|
||||
|
||||
css_classes = "wiki"
|
||||
css_classes << " editable" if editable
|
||||
|
||||
content = ''
|
||||
content << content_tag('div', links.join(' '), :class => 'contextual') unless links.empty?
|
||||
content << textilizable(journal, :notes)
|
||||
|
||||
header << content_tag("div", content, :id => "journal-#{journal.id}-notes", :class => css_classes)
|
||||
end
|
||||
%>
|
||||
|
||||
<!-- details such as attribute changes -->
|
||||
<%
|
||||
details = ''
|
||||
if journal.details.any?
|
||||
content = journal.details.collect do |detail|
|
||||
if d = journal.render_detail(detail)
|
||||
content_tag("li", d)
|
||||
end
|
||||
end.compact.join(' ')
|
||||
|
||||
details = content_tag("ul", content, :class => "details journal-attributes") unless content.empty?
|
||||
end
|
||||
%>
|
||||
|
||||
<!-- output HTML code -->
|
||||
<%= content_tag "div", "#{header}#{details}",
|
||||
{ :id => "change-#{journal.id}", :class => journal.css_classes } %>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
|
@ -0,0 +1,30 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<% if @project and @project.module_enabled?('code_review') %>
|
||||
<%
|
||||
baseurl = Redmine::Utils.relative_url_root
|
||||
|
||||
-%>
|
||||
<%= javascript_include_tag(baseurl + "/plugin_assets/redmine_code_review/javascripts/code_review.js") %>
|
||||
<%= javascript_include_tag(baseurl + '/javascripts/jstoolbar/jstoolbar.js') %>
|
||||
<%= javascript_include_tag(baseurl + '/javascripts/jstoolbar/textile.js') %>
|
||||
<%= javascript_include_tag(baseurl + "/javascripts/jstoolbar/lang/jstoolbar-#{@project.current_language}.js") %>
|
||||
<%= stylesheet_link_tag(baseurl + "/plugin_assets/redmine_code_review/stylesheets/code_review.css") %>
|
||||
<%= stylesheet_link_tag(baseurl + "/stylesheets/jstoolbar.css") %>
|
||||
<% end %>
|
|
@ -0,0 +1,56 @@
|
|||
<%#
|
||||
# To change this template, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
%>
|
||||
|
||||
<%
|
||||
unless User.current.allowed_to?({:controller => 'code_review', :action => 'show'}, project)
|
||||
return
|
||||
end
|
||||
|
||||
%>
|
||||
|
||||
<% if issue.code_review %>
|
||||
<%
|
||||
review = issue.code_review
|
||||
%>
|
||||
<tr>
|
||||
<td><b><%= l(:code_review) %>:</b></td>
|
||||
<td colspan="3">
|
||||
<%
|
||||
label = URI.decode("#{review.repository_identifier + ':' if review.repository_identifier}#{review.path}#{'@' + review.revision if review.revision}:line #{review.line}")
|
||||
-%>
|
||||
<%= link_to(label,
|
||||
:controller => 'code_review', :action => 'show', :id => project, :review_id => review.id, :repository_id => review.repository_identifier) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% if issue.code_review_assignment %>
|
||||
<%
|
||||
assignment = issue.code_review_assignment
|
||||
repository_id = assignment.repository_identifier
|
||||
%>
|
||||
<tr>
|
||||
<td><b><%= l(:review_assigned_for) %>:</b></td>
|
||||
<td colspan="3">
|
||||
<% if assignment.path %>
|
||||
<%
|
||||
label = URI.decode("#{repository_id + ':' if repository_id}#{assignment.path}#{'@' + assignment.revision if assignment.revision}")
|
||||
-%>
|
||||
<%= link_to(label,
|
||||
:controller => 'code_review', :action => 'show', :id => project, :assignment_id => assignment.id, :repository_id => repository_id) %>
|
||||
<% elsif assignment.revision %>
|
||||
<%
|
||||
repo = project unless repository_id
|
||||
repo ||= assignment.repository
|
||||
%>
|
||||
<%= l(:label_revision) + " "%>
|
||||
<%= link_to_revision(assignment.revision, repo) %>
|
||||
<% elsif assignment.attachment %>
|
||||
<%= link_to(assignment.attachment.filename, :controller => 'attachments', :action => 'show', :id => attachment.id) %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<% end %>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2013 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
|
||||
|
||||
<div class="box">
|
||||
<h2>
|
||||
<%= l(:label_line_number, :line => @review.line) %>
|
||||
</h2>
|
||||
<%= form_for @review,:as => :review,
|
||||
:url => {:controller => 'code_review', :action => 'new', :id=>@project}, :html => {:id => 'review_form'} do |f| %>
|
||||
<%= error_messages_for 'review' %>
|
||||
<%= error_messages_for 'issue' %>
|
||||
<%= error_messages_for 'relation' %>
|
||||
<%= f.hidden_field(:change_id) %>
|
||||
<%= f.hidden_field(:line) %>
|
||||
<%= hidden_field_tag(:action_type, @review.action_type) %>
|
||||
<%= hidden_field_tag(:rev, @review.revision) %>
|
||||
<%= hidden_field_tag(:rev_to, @review.rev_to) %>
|
||||
<%= hidden_field_tag(:path, @review.path) %>
|
||||
<%= hidden_field_tag(:file_count, @review.file_count) %>
|
||||
<%= hidden_field_tag(:attachment_id, @review.attachment_id) %>
|
||||
<%= hidden_field_tag(:repository_id, @repository_id) %>
|
||||
<%= hidden_field_tag(:diff_all, @review.diff_all) %>
|
||||
<p>
|
||||
<label><b><%=h l(:field_subject)%>:</b></label>
|
||||
<%= f.text_field :subject, :size => 70, :required => true %>
|
||||
</p>
|
||||
|
||||
<% if @setting.tracker_in_review_dialog %>
|
||||
<p>
|
||||
<label><b><%=h l(:label_tracker) %>:</b></label>
|
||||
<%= select :issue, :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(function(){
|
||||
$('#issue_tracker_id').change(function(){
|
||||
var url = "<%= url_for(:controller => 'code_review', :action => 'new') -%>";
|
||||
url = url + '?' + $('#review_form').serialize();
|
||||
$('#review-form').load(url);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<label><b><%=h l(:field_parent_issue)%>:</b></label>
|
||||
<%= f.text_field :parent_id, :size => 10 %>
|
||||
<% if @parent_candidate %>
|
||||
<%= raw l(:label_parent_suggestion, {:issue_id => link_to_issue(@parent_candidate)}) %>
|
||||
<input type="button" value="<%=h l(:general_text_Yes)%>" onclick="$('#review_parent_id').val(<%= @parent_candidate.id %>)"/>
|
||||
<% end %>
|
||||
</p>
|
||||
<% @issue.custom_field_values.each do |value| %>
|
||||
<% next unless value.required? -%>
|
||||
<p><%= custom_field_tag_with_label :issue, value %></p>
|
||||
<% end %>
|
||||
<p>
|
||||
<%= f.text_area :comment,
|
||||
:cols => 30,
|
||||
:rows => 12,
|
||||
:accesskey => accesskey(:edit),
|
||||
:class => 'wiki-edit' %>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
<label><b><%=h l(:field_assigned_to) %>:</b></label>
|
||||
<%= select :issue, :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %>
|
||||
</p>
|
||||
<% unless @project.issue_categories.empty? %>
|
||||
<p>
|
||||
<label><b><%=h l(:field_category) %>:</b></label>
|
||||
<%= select :issue, :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% unless @issue.assignable_versions.empty? %>
|
||||
<p>
|
||||
<label><b><%=h l(:field_fixed_version) %>:</b></label>
|
||||
<%= select :issue, :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true, :selected => @default_version_id %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
-%>
|
||||
<% if @issue.new_record? || @allowed_statuses.any? %>
|
||||
<p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
|
||||
<% else %>
|
||||
<p><label><%= l(:field_status) %></label> <%= h(@issue.status.name) %></p>
|
||||
<% end %>
|
||||
<p>
|
||||
<%
|
||||
submit_url = url_for(:controller => 'code_review', :action => 'new', :id=>@project)
|
||||
%>
|
||||
<%= button_to_function l(:button_apply), "$('#review-form').load('#{submit_url}', $('#review_form').serialize2json())" %>
|
||||
|
||||
<input type="button" value="<%=h l(:button_cancel) %> " onclick="javascript:hideForm();"/>
|
||||
<%= preview_link({ :controller => 'code_review', :action => 'preview', :id => @project}, 'review_form') %>
|
||||
</p>
|
||||
<div id="preview" class="wiki"></div>
|
||||
<%= wikitoolbar_for 'review_comment' %>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<p class="author">
|
||||
|
||||
<%= authoring reply.created_on, reply.user %>.
|
||||
</p>
|
||||
<%= avatar(reply.user, :size => "32") %>
|
||||
<ul>
|
||||
<% for detail in reply.details %>
|
||||
<li><%= show_detail(detail) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="wiki">
|
||||
<%= textilizable reply, :notes %>
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
|
@ -0,0 +1,187 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<div class="code-review-dialog" id="code-review-dialog-<%= @review.id%>">
|
||||
|
||||
<div class="code_review_body">
|
||||
|
||||
<!-- flash -->
|
||||
<%= error_messages_for 'review' -%>
|
||||
<%= error_messages_for 'reply' -%>
|
||||
<% if @notice -%>
|
||||
<div class="flash notice"><%= @notice -%></div>
|
||||
<% end -%>
|
||||
<% if @error -%>
|
||||
<div class="flash error"><%= @error -%></div>
|
||||
<% end -%>
|
||||
|
||||
<!-- code review view -->
|
||||
<div class="code_review_viewer issue">
|
||||
|
||||
<!-- toolbar -->
|
||||
<div class="contextual">
|
||||
<% if authorize_for('code_review', 'update') -%>
|
||||
<%= link_to_function l(:button_update), "$('#update-form-#{@review.id}').show();return false;", :class => 'icon icon-edit' %>
|
||||
<% end %>
|
||||
<% if authorize_for('code_review', 'destroy') -%>
|
||||
<%= link_to(l(:button_delete),
|
||||
{:controller => 'code_review',
|
||||
:action => 'destroy',
|
||||
:id => @project,
|
||||
:review_id => @review},
|
||||
:update => "show_review_#{@review.id}",
|
||||
:remote => true,
|
||||
:confirm => l(:text_are_you_sure),
|
||||
:success => "deleteReview(#{@review.id})",
|
||||
:class => 'icon icon-del') %>
|
||||
<% end -%>
|
||||
</div>
|
||||
|
||||
<!-- title -->
|
||||
<h2>
|
||||
<%= link_to h(@issue.tracker.name) + ' #' +@issue.id.to_s + ' (' + h(@review.issue.status) + ')',
|
||||
:controller => 'issues', :action => 'show', :id => @review.issue.id %>:
|
||||
<br />
|
||||
<%=h @review.subject %>
|
||||
</h2>
|
||||
|
||||
<!-- author and creation time -->
|
||||
<p class="author">
|
||||
<%= avatar(@review.user, :size => "64") %>
|
||||
<br />
|
||||
<%= authoring @review.created_at, @review.user %>.
|
||||
<%= l(:label_updated_time, distance_of_time_in_words(Time.now, @review.updated_at)) + '.' if @review.created_at != @review.updated_at %>
|
||||
</p>
|
||||
<hr />
|
||||
|
||||
<!-- review comment -->
|
||||
<div class="wiki">
|
||||
<%= textilizable @review, :comment %>
|
||||
</div>
|
||||
|
||||
<!-- review comment edit form -->
|
||||
<div class="box" id="update-form-<%= @review.id %>" style="display:none;">
|
||||
<%
|
||||
review_form_id = "review_form_#{@review.id}"
|
||||
-%>
|
||||
<%= form_for :review,
|
||||
:url => {:controller => 'code_review',
|
||||
:action => 'update',
|
||||
:id => @project},
|
||||
:update => "show_review_#{@review.id}",
|
||||
:html => {:id => review_form_id} do |f| %>
|
||||
<%= f.hidden_field :lock_version %>
|
||||
<%= hidden_field :issue, :lock_version%>
|
||||
<%= hidden_field_tag :review_id, @review.id %>
|
||||
<p>
|
||||
<label><b><%=h l(:field_subject)%>:</b></label>
|
||||
<%= f.text_field :subject, :size => 70, :value => @review.subject%>
|
||||
</p>
|
||||
<% if @allowed_statuses and @allowed_statuses.any? %>
|
||||
<p>
|
||||
<label><b><%=h l(:field_status)%>:</b></label>
|
||||
<%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<%= f.text_area :comment,
|
||||
:cols => 30,
|
||||
:rows => 10,
|
||||
:accesskey => accesskey(:edit),
|
||||
:class => 'wiki-edit',
|
||||
:id => 'review_comment_' + @review.id.to_s %>
|
||||
</p>
|
||||
<p>
|
||||
<%
|
||||
submit_url = url_for(:controller => 'code_review', :action => 'update', :id => @project)
|
||||
-%>
|
||||
<%= button_to_function l(:button_apply), "$('#show_review_#{@review.id}').load('#{submit_url}', $('##{review_form_id}').serialize())" %>
|
||||
<input type="button" value="<%=h l(:button_cancel) %>" onclick='$("#review_form_<%= @review.id %>").hide();' />
|
||||
<%= link_to_function l(:label_preview), "$('#preview_#{@review.id}').load('#{url_for(:controller => 'code_review', :action => 'preview', :id => @project)}', $('##{review_form_id}').serialize())" %>
|
||||
</p>
|
||||
<div id="preview_<%= @review.id%>" class="wiki"></div>
|
||||
<%= wikitoolbar_for 'review_comment_' + @review.id.to_s %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- review replies -->
|
||||
<% journals = @review.issue.journals.sort {|a, b| a.id <=> b.id } %>
|
||||
<% if respond_to?('render_journal') %>
|
||||
<% # ChiliProject -%>
|
||||
<% if journals.length > 0 %>
|
||||
<div id="history">
|
||||
<h3 class="rounded-background"><%= l(:label_history) %></h3>
|
||||
<%= render :partial => 'history', :locals => { :issue => @review.issue, :journals => journals } %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% # Redmine -%>
|
||||
<% if journals.length > 0 %>
|
||||
<h3><%= l(:label_history) %></h3>
|
||||
<% end %>
|
||||
<%= render :partial => 'reply', :collection => journals %>
|
||||
<% end %>
|
||||
|
||||
<!-- reply form -->
|
||||
<% if authorize_for('code_review', 'reply') -%>
|
||||
<p>
|
||||
<%= toggle_link l(:button_reply), "reply_#{@review.id}", :focus => 'reply_comment_' + @review.id.to_s %>
|
||||
</p>
|
||||
<%
|
||||
message_form_id = "message-form-#{@review.id}"
|
||||
-%>
|
||||
<div id="reply_<%= @review.id %>" style="display:none;" class="box">
|
||||
<%= form_for @reply, :as => :reply, :url => {:action => 'reply', :id => @project, :review_id => @review.id}, :html => {:id => message_form_id} do |f| %>
|
||||
<%= hidden_field_tag :review_id, @review.id %>
|
||||
<%= hidden_field :review, :lock_version%>
|
||||
<%= hidden_field :issue, :lock_version%>
|
||||
<% if @allowed_statuses and @allowed_statuses.any? %>
|
||||
<p>
|
||||
<label><%=h l(:field_status) %>:</label>
|
||||
<% # select :review, :status, {l(:label_review_closed) => CodeReview::STATUS_CLOSED, l(:label_review_open) => CodeReview::STATUS_OPEN} %>
|
||||
<%= select :review, :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<%= f.text_area :comment,
|
||||
:cols => 30,
|
||||
:rows => 10,
|
||||
:accesskey => accesskey(:edit),
|
||||
:class => 'wiki-edit',
|
||||
:id => 'reply_comment_' + @review.id.to_s %>
|
||||
</p>
|
||||
<p>
|
||||
<%
|
||||
submit_url = url_for(:controller => 'code_review', :action => 'reply', :id => @project)
|
||||
-%>
|
||||
<%= button_to_function l(:button_apply), "$('#show_review_#{@review.id}').load('#{submit_url}', $('##{message_form_id}').serialize())" %>
|
||||
<%
|
||||
reply_preview_id = "reply_preview_#{@review.id}"
|
||||
-%>
|
||||
<%= link_to_function l(:label_preview), "$('##{reply_preview_id}').load('#{url_for(:controller => 'code_review', :action => 'preview', :id => @project)}', $('##{message_form_id}').serialize())" %>
|
||||
</p>
|
||||
<div id="<%= reply_preview_id %>" class="wiki"></div>
|
||||
<%= wikitoolbar_for 'reply_comment_' + @review.id.to_s %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,24 @@
|
|||
<div id="error_message_div">
|
||||
<h1>Error</h1>
|
||||
|
||||
<p>change not found.</p>
|
||||
|
||||
@path = '<%=h @path %>'<br/>
|
||||
@changeset = <%=h @changeset %><br/>
|
||||
@rev = <%=h @rev %><br/>
|
||||
<% if @changeset %>
|
||||
<ul>
|
||||
<% for change in @changeset.changes do%>
|
||||
<li>
|
||||
'<%=h change.path%>'
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var innerhtml = $('content').innerHTML;
|
||||
$('content').innerHTML = $('error_message_div').innerHTML + innerhtml;
|
||||
$('error_message_div').innerHTML = "";
|
||||
</script>
|
|
@ -0,0 +1,77 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
|
||||
<div class="code_review">
|
||||
|
||||
</div>
|
||||
|
||||
<div id="review-form-frame">
|
||||
<div id="review-form">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="code-review-assign-form" />
|
||||
|
||||
<div id="code-review-assign-link" style="text-align: right;">
|
||||
<%
|
||||
change_id = ''
|
||||
change_id = @change.id if @change
|
||||
assignments = @change.code_review_assignments if @change
|
||||
attachment_id = @attachment.id if @attachment
|
||||
assignments = @attachment.code_review_assignments if @attachment
|
||||
escaped_path = @path.gsub("'"){"\\'"} if @path
|
||||
-%>
|
||||
|
||||
<%= raw show_assignments assignments, @project, {:action_type => @action_type, :rev => @rev, :rev_to => @rev_to, :path => @path, :change_id => change_id, :attachment_id => attachment_id} -%>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
repository_id = "<%= @repository_id %>";
|
||||
add_form_title = "<%= l(:label_add_review) %>";
|
||||
review_dialog_title = "<%= l(:code_review) %>";
|
||||
var addReviewUrl = '<%= url_for :controller => 'code_review', :action => 'new', :id => @project %>';
|
||||
var is_readonly = true;
|
||||
<% if authorize_for('code_review', 'new') -%>
|
||||
is_readonly = false;
|
||||
<% end %>
|
||||
var is_diff = false;
|
||||
<% if @action_type == 'diff' or (@attachment and @attachment.is_diff?) -%>
|
||||
is_diff = true;
|
||||
<% end %>
|
||||
action_type = '<%= @action_type %>';
|
||||
rev = '<%= @rev %>';
|
||||
rev_to = '<%= @rev_to %>';
|
||||
path = '<%= escaped_path -%>';
|
||||
|
||||
setAddReviewButton(addReviewUrl, '<%= @change.id if @change %>', '<%= image_tag('edit.png', :alt => l(:label_add_review), :title => l(:label_add_review)) %>', is_readonly, is_diff, '<%= @attachment_id%>' );
|
||||
|
||||
showReviewUrl = '<%= url_for :controller => 'code_review', :action => 'show', :id=>@project %>';
|
||||
showReviewImageTag = '<%= image_tag('review.png', :plugin => 'redmine_code_review', :alt => l(:label_show_review), :title => l(:label_show_review)) %>';
|
||||
showClosedReviewImageTag = '<%= image_tag('closed_review.png', :plugin => 'redmine_code_review', :alt => l(:label_show_review), :title => l(:label_show_review)) %>';
|
||||
|
||||
<% for review in @reviews do %>
|
||||
setShowReviewButton(<%= review.line %>, <%= review.id %>, <%= review.is_closed? %>, <%= review.file_count %> );
|
||||
<% end %>
|
||||
|
||||
<% if @show_review_id -%>
|
||||
popupReview(<%= @show_review_id %>);
|
||||
<% end -%>
|
||||
$('#content table.filecontent:first').before($('#code-review-assign-link'));
|
||||
</script>
|
|
@ -0,0 +1,49 @@
|
|||
<%#
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2011 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
%>
|
||||
|
||||
<script type="text/javascript">
|
||||
<% @changesets.each do |changeset| %>
|
||||
<%
|
||||
if changeset.review_count > 0
|
||||
progress = '<span style="white-space: nowrap">' + progress_bar([changeset.closed_review_pourcent, changeset.completed_review_pourcent],
|
||||
:width => '60px',
|
||||
:legend => "#{changeset.closed_review_count}/#{changeset.review_count} #{l(:label_closed_issues)}") + '</span>'
|
||||
elsif changeset.assignment_count > 0
|
||||
if (changeset.open_assignment_count > 0)
|
||||
progress = '<p class="progress-info" style="white-space: nowrap">' + l(:code_review_assigned) + '</p>'
|
||||
else
|
||||
progress = '<p class="progress-info" style="white-space: nowrap">' + l(:code_review_reviewed) + '</p>'
|
||||
end
|
||||
|
||||
else
|
||||
progress = '<p class="progress-info" style="white-space: nowrap;"><span style="white-space: nowrap;">' + l(:lable_no_code_reviews) + '</span>:<span style="white-space: nowrap;">' + link_to(l(:label_assign_review), {:controller => 'code_review',
|
||||
:action => 'assign', :id=>@project,
|
||||
:rev => changeset.revision,
|
||||
:changeset_id => changeset.id}) + '</span></p>'
|
||||
end
|
||||
%>
|
||||
|
||||
var count = new ReviewCount(<%= changeset.review_count %>, <%= changeset.open_review_count %>, '<%= raw progress %>');
|
||||
|
||||
review_counts['revision_<%=changeset.identifier %>'] = count;
|
||||
<% end %>
|
||||
UpdateRepositoryView('<%=l(:code_reviews)%>');
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
|
||||
<script>
|
||||
function change_option(flag) {
|
||||
var url = "<%= raw url_for(:controller => 'code_review', :action=>'index', :id => @project) %>";
|
||||
$('#content').load(url, {'show_closed': flag});
|
||||
}
|
||||
</script>
|
||||
<div id="code_review_list">
|
||||
<h2>
|
||||
<%=h l(:code_reviews) %>
|
||||
</h2>
|
||||
|
||||
<% if @all_review_count > 0 %>
|
||||
<p>
|
||||
<%= form_tag({:controller => 'code_review', :action=>'index', :id => @project}, :id => 'optionform') do %>
|
||||
<%= check_box_tag 'show_closed', 'true', @show_closed, :onchange => "change_option($('#show_closed').is(':checked'));"%> <%=h l(:label_show_closed_reviews) %>
|
||||
<% end %>
|
||||
<%# observe_field 'show_closed', :with => 'show_closed', :update => 'content' %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @reviews == nil or @reviews.length == 0 %>
|
||||
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||
<% else %>
|
||||
|
||||
|
||||
<table class="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<%= sort_header_tag "#{Issue.table_name}.id", :caption => '#' %>
|
||||
<%= sort_header_tag "#{Issue.table_name}.status_id", :caption => l(:field_status)%>
|
||||
<%= sort_header_tag "#{Issue.table_name}.subject", :caption => l(:field_subject)%>
|
||||
<%= sort_header_tag 'path', :caption => l(:label_code_path)%>
|
||||
<th>
|
||||
<%=h l(:label_code_line)%>
|
||||
</th>
|
||||
<%= sort_header_tag "#{Changeset.table_name}.revision", :caption => l(:label_revision)%>
|
||||
<%= sort_header_tag "#{Changeset.table_name}.committer", :caption => l(:label_code_author)%>
|
||||
<%= sort_header_tag 'user_id', :caption => l(:label_code_reviewer)%>
|
||||
<%= sort_header_tag 'updated_at', :caption => l(:label_date) %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for review in @reviews %>
|
||||
<tr class="<%= cycle 'odd', 'even' %>">
|
||||
<td>
|
||||
<%= link_to review.issue.id.to_s, {:controller => 'issues', :action => 'show',
|
||||
:id => review.issue.id}, :title => review.issue.subject %>
|
||||
</td>
|
||||
|
||||
<td class="status">
|
||||
<%=h review.issue.status %>
|
||||
</td>
|
||||
<td class="subject">
|
||||
<%=h review.issue.subject %>
|
||||
</td>
|
||||
<td class="path">
|
||||
<%
|
||||
review_path = URI.decode(review.path)
|
||||
codepath = review_path
|
||||
if (review_path.length > 55)
|
||||
codepath = review_path[0, 15] + '...' + review_path[review_path.length - 35, 35]
|
||||
end
|
||||
-%>
|
||||
<%= link_to(raw(codepath), {:controller => 'code_review', :action => 'show', :id => @project, :review_id => review.id}, :title => review_path) -%>
|
||||
</td>
|
||||
<td><%=h review.line %></td>
|
||||
<td><%=h review.revision %></td>
|
||||
<td><%=h review.committer %></td>
|
||||
<td><%=h review.user.name %></td>
|
||||
<td><%=h format_time(review.created_at) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="pagination"><%= pagination_links_full @review_pages, @review_count %></p>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= stylesheet_link_tag "code_review.css", :plugin => "redmine_code_review", :media => "screen" %>
|
||||
<% end %>
|
||||
</div>
|
|
@ -0,0 +1,117 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
|
||||
<p>
|
||||
<label><%=h l(:label_auto_assignment_filters)%></label>
|
||||
<%= check_box_tag "auto_assign[filter_enabled]", true, @auto_assign.filter_enabled?, :onchange => 'setAutoAssignSettingFiltersEnable();' %><%=h l(:button_activate)%>
|
||||
|
||||
</p>
|
||||
<div id="auto_assignment_filter_form" style="display: <%= @auto_assign.filter_enabled? ? 'true' : 'none'%>;">
|
||||
<div style="padding: 5px 0 8px 180px;">
|
||||
<div class="contextual">
|
||||
<%= link_to_function(l(:button_add), "$('#add_filter_form').show('blind');", :class => 'icon icon-add') %>
|
||||
</div>
|
||||
<table class="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 1em; text-align: right;">#</th>
|
||||
<th style="width: 8em;"><%=h l(:auto_assign_filter_assign)%>/<%=h l(:auto_assign_filter_drop) %></th>
|
||||
<th><%=h l(:auto_assign_filter_expression)%> </th>
|
||||
<th><%=h l(:button_sort) %> </th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @auto_assign.filters.each_with_index do |filter, i| -%>
|
||||
<% tr_class = cycle('odd', 'even') -%>
|
||||
<tr class="<%= tr_class %>" id="auto_assign_tr_<%= i%>">
|
||||
<td style="text-align: right"><%= i + 1 %>
|
||||
<%= hidden_field_tag "auto_assign[filters][#{i}][accept]", filter.accept? %>
|
||||
<%= hidden_field_tag "auto_assign[filters][#{i}][expression]", filter.expression %>
|
||||
<%= hidden_field_tag "auto_assign[filters][#{i}][order]", (i+1) * 10 %>
|
||||
</td>
|
||||
<td style="text-align: center"><%= filter.accept? ? l(:auto_assign_filter_assign) : l(:auto_assign_filter_drop)%> </td>
|
||||
<td style="text-align: center"><%= filter.expression %></td>
|
||||
<td align="center" style="width:15%;">
|
||||
<%
|
||||
name = 'auto_assign_filter'
|
||||
url = {:controller => 'code_review_settings', :action => 'sort', :id => @project, "#{name}[num]" => i}
|
||||
-%>
|
||||
<%=
|
||||
link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'highest'}), :method => :post, :title => l(:label_sort_highest), :update => 'auto_assignment_filters', :submit => 'code_review_form') +
|
||||
link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'higher'}), :method => :post, :title => l(:label_sort_higher), :update => 'auto_assignment_filters', :submit => 'code_review_form') +
|
||||
link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'lower'}), :method => :post, :title => l(:label_sort_lower), :update => 'auto_assignment_filters', :submit => 'code_review_form') +
|
||||
link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'lowest'}), :method => :post, :title => l(:label_sort_lowest), :update => 'auto_assignment_filters', :submit => 'code_review_form')
|
||||
-%>
|
||||
|
||||
</td>
|
||||
<td class="buttons">
|
||||
<span class="icon icon-del">
|
||||
<%= link_to_function(l(:button_delete), "$('#auto_assign_tr_#{i}').remove();")%>
|
||||
</span><span class="icon icon-edit">
|
||||
<%= link_to_function(l(:button_edit), "$('#auto_assign_tr_#{i}').hide();$('#auto_assign_edit_tr_#{i}').show()")%>
|
||||
</span>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="<%= tr_class %>" id="auto_assign_edit_tr_<%= i%>" style="display: none;">
|
||||
<td style="text-align: right">
|
||||
<%= i + 1 %>
|
||||
</td>
|
||||
<td style="text-align: center">
|
||||
<%= hidden_field_tag "auto_assign_edit_filter[#{i}][order]", (i + 1) * 10 %>
|
||||
<%= select_tag("auto_assign_edit_filter[#{i}][accept]",
|
||||
options_for_select([[l(:auto_assign_filter_assign), true], [l(:auto_assign_filter_drop), false]], filter.accept?)) %>
|
||||
</td>
|
||||
<td><%= text_field_tag("auto_assign_edit_filter[#{i}][expression]", filter.expression, :size => 60)%>
|
||||
</td>
|
||||
<td></td>
|
||||
<td style="white-space: nowrap">
|
||||
<%= button_to_function(l(:button_apply), "update_assign_filter(#{i})", :condition => "is_valid_expression($('#auto_assign_edit_filter_#{i}_expression'))") %>
|
||||
<%= button_to_function(l(:button_cancel), "$('#auto_assign_tr_#{i}').show();$('#auto_assign_edit_tr_#{i}').hide()") %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end -%>
|
||||
<tr id="add_filter_form" style="display: none;">
|
||||
<td style="text-align: right"><%= @auto_assign.filters.length + 1 %> </td>
|
||||
<td>
|
||||
<%= hidden_field_tag 'auto_assign_add_filter[order]', 999999999 %>
|
||||
<%= select_tag('auto_assign_add_filter[accept]',
|
||||
options_for_select([[l(:auto_assign_filter_assign), true], [l(:auto_assign_filter_drop), false]])) %>
|
||||
</td>
|
||||
<td><%= text_field_tag('auto_assign_add_filter[expression]', '', :size => 60)%>
|
||||
</td>
|
||||
<td></td>
|
||||
<td style="white-space: nowrap;">
|
||||
<%= button_to_function(l(:button_apply), "add_assign_filter()") %>
|
||||
<%= button_to_function(l(:button_cancel), "$('#add_filter_form').hide()") %>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<p>
|
||||
<label><%=h l(:label_default)%></label>
|
||||
<%= select(:auto_assign, :accept_for_default, [[l(:auto_assign_filter_assign), true], [l(:auto_assign_filter_drop), false]]) %>
|
||||
</p>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,163 @@
|
|||
<%
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2010-2012 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-%>
|
||||
<div id="code_review_settings">
|
||||
<script type="text/javascript">
|
||||
function setAutoAssignSettingFormEnable() {
|
||||
var form = $('#cr_auto_assign_settings');
|
||||
var flag = $('#auto_assign_enabled').is(':checked');
|
||||
if (flag) {
|
||||
form.show('blind');
|
||||
}
|
||||
else {
|
||||
form.hide('blind');
|
||||
}
|
||||
}
|
||||
|
||||
function setAutoAssignSettingFiltersEnable() {
|
||||
var form = $('#auto_assignment_filter_form');
|
||||
var flag = $('#auto_assign_filter_enabled').is(':checked');
|
||||
if (flag) {
|
||||
form.show('blind');
|
||||
}
|
||||
else {
|
||||
form.hide('blind');
|
||||
}
|
||||
}
|
||||
|
||||
function is_valid_expression(field) {
|
||||
var text = field[0].value;
|
||||
if (text == '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
new RegExp(text);
|
||||
}
|
||||
catch (e) {
|
||||
alert(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function add_assign_filter() {
|
||||
if (!is_valid_expression($('#auto_assign_add_filter_expression'))) {
|
||||
return false;
|
||||
}
|
||||
var url = '<%=url_for(:controller => 'code_review_settings', :action => 'add_filter', :id => @project) %>';
|
||||
var args = $('#code_review_form').serialize2json();
|
||||
$('#auto_assignment_filters').load(url, args);
|
||||
}
|
||||
|
||||
function update_assign_filter(num) {
|
||||
if (!is_valid_expression($('#auto_assign_edit_filter_' + num + '_expression'))) {
|
||||
return false;
|
||||
}
|
||||
var url = '<%=url_for(:controller => 'code_review_settings', :action => 'edit_filter', :id => @project) %>';
|
||||
var args = $('#code_review_form').serialize2json();
|
||||
args['num'] = num;
|
||||
$('#auto_assignment_filters').load(url, args);
|
||||
}
|
||||
</script>
|
||||
|
||||
<%
|
||||
@code_review_setting = CodeReviewProjectSetting.find_or_create(@project)
|
||||
%>
|
||||
|
||||
<%= labelled_form_for :setting, @code_review_setting,
|
||||
:url => {:controller => 'code_review_settings',
|
||||
:action => 'update', :id => @project, :tab => 'code_review',
|
||||
:partial => 'code_review_settings/update',
|
||||
:setting_id => @code_review_setting.id}, :html => {:id => 'code_review_form'} do |f| %>
|
||||
<%= error_messages_for 'code_review_setting' %>
|
||||
<div class="box">
|
||||
<%= f.hidden_field :lock_version %>
|
||||
<p><%= f.check_box :tracker_in_review_dialog %></p>
|
||||
|
||||
<b><%=h l(:select_tracker_for_code_reviews)%>:</b>
|
||||
<p><%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p>
|
||||
|
||||
<b><%=h l(:select_tracker_for_code_review_assignment)%>:</b>
|
||||
<p><%= f.select :assignment_tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p>
|
||||
|
||||
<p>
|
||||
<%= f.check_box :hide_code_review_tab %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label><%=h l(:label_if_revision_has_issues)%>:</label>
|
||||
<%= f.radio_button(:auto_relation, CodeReviewProjectSetting::AUTORELATION_TYPE_RELATES) %>
|
||||
<%=h l(:label_review_issue_relates) %>
|
||||
|
||||
<%= f.radio_button(:auto_relation, CodeReviewProjectSetting::AUTORELATION_TYPE_BLOCKS) %>
|
||||
<%=h l(:label_review_issue_blocks) %>
|
||||
|
||||
<%= f.radio_button(:auto_relation, CodeReviewProjectSetting::AUTORELATION_TYPE_NONE) %>
|
||||
<%=h l(:label_review_issue_do_nothing) %>
|
||||
|
||||
</p>
|
||||
<hr/>
|
||||
|
||||
<p>
|
||||
<%
|
||||
@auto_assign = @code_review_setting.auto_assign_settings
|
||||
@auto_assign.subject = l(:code_review_requrest) if @auto_assign.subject.blank?
|
||||
-%>
|
||||
<label><%=h l(:label_auto_assign_settings)%></label>
|
||||
<%= check_box_tag "auto_assign[enabled]", true, @auto_assign.enabled?, :onchange => 'setAutoAssignSettingFormEnable();'%><%=h l(:button_activate)%>
|
||||
</p>
|
||||
<div id="cr_auto_assign_settings" style="display: <%= @auto_assign.enabled? ? 'true' : 'none'%>;">
|
||||
<p>
|
||||
<label><%=h l(:field_author)%></label>
|
||||
<%= select :auto_assign, :author_id,
|
||||
(@project.users.collect {|user|
|
||||
[user.name, user.id]
|
||||
}), :selected => @auto_assign.author_id, :required => true %>
|
||||
</p>
|
||||
<p>
|
||||
<label><%=h l(:label_candidates_of_reviewer)%></label>
|
||||
<% @project.users.each do |user| %>
|
||||
<label class="floating"><%= check_box_tag 'auto_assign[assignable_list][]', user.id, @auto_assign.assignable?(user) %> <%=h user %></label>
|
||||
<% end %>
|
||||
</p>
|
||||
<p>
|
||||
<label><%=h l(:field_subject)%></label>
|
||||
<%= text_field(:auto_assign, :subject, :size => 70) %>
|
||||
</p>
|
||||
<p>
|
||||
<label><%=h l(:field_description) %></label>
|
||||
<%= text_area :auto_assign, :description,
|
||||
:cols => 30,
|
||||
:rows => 12,
|
||||
:accesskey => accesskey(:edit),
|
||||
:class => 'wiki-edit' %>
|
||||
</p>
|
||||
<p>
|
||||
<div id="auto_assignment_filters">
|
||||
<%= render :partial => 'code_review_settings/filters' %>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<%= submit_tag l(:button_update) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= wikitoolbar_for 'auto_assign_description' %>
|
After Width: | Height: | Size: 508 B |
After Width: | Height: | Size: 498 B |
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009-2013 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
var topZindex = 1000;
|
||||
var action_type = '';
|
||||
var rev = '';
|
||||
var rev_to = '';
|
||||
var path = '';
|
||||
var urlprefix = '';
|
||||
var review_form_dialog = null;
|
||||
var add_form_title = null;
|
||||
var review_dialog_title = null;
|
||||
var repository_id = null;
|
||||
var filenames = [];
|
||||
|
||||
var ReviewCount = function(total, open, progress){
|
||||
this.total = total;
|
||||
this.open = open;
|
||||
this.closed = total - open;
|
||||
this.progress = progress
|
||||
};
|
||||
|
||||
var CodeReview = function(id) {
|
||||
this.id = id;
|
||||
this.path = '';
|
||||
this.line = 0;
|
||||
this.url = '';
|
||||
this.is_closed = false;
|
||||
};
|
||||
|
||||
var review_counts = new Array();
|
||||
var code_reviews_map = new Array();
|
||||
var code_reviews_dialog_map = new Array();
|
||||
|
||||
function UpdateRepositoryView(title) {
|
||||
var header = $("table.changesets thead tr:first");
|
||||
var th = $('<th></th>');
|
||||
th.html(title);
|
||||
header.append(th);
|
||||
$('tr.changeset td.id a').each(function(i){
|
||||
var revision = this.getAttribute("href");
|
||||
revision = revision.substr(revision.lastIndexOf("/") + 1);
|
||||
var review = review_counts['revision_' + revision];
|
||||
var td = $('<td/>',{
|
||||
'class':'progress'
|
||||
});
|
||||
td.html(review.progress);
|
||||
$(this.parentNode.parentNode).append(td);
|
||||
});
|
||||
}
|
||||
//add function $.down
|
||||
if(! $.fn.down)
|
||||
(function($) {
|
||||
$.fn.down = function() {
|
||||
var el = this[0] && this[0].firstChild;
|
||||
while (el && el.nodeType != 1)
|
||||
el = el.nextSibling;
|
||||
return $(el);
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
function UpdateRevisionView() {
|
||||
$('li.change').each(function(){
|
||||
var li = $(this);
|
||||
if (li.hasClass('folder')) return;
|
||||
|
||||
var a = li.down('a');
|
||||
if (a.size() == 0) return;
|
||||
var path = a.attr('href').replace(urlprefix, '').replace(/\?.*$/, '');
|
||||
|
||||
var reviewlist = code_reviews_map[path];
|
||||
if (reviewlist == null) return;
|
||||
|
||||
var ul = $('<ul></ul>');
|
||||
for (var j = 0; j < reviewlist.length; j++) {
|
||||
var review = reviewlist[j];
|
||||
var icon = review.is_closed? 'icon-closed-review': 'icon-review';
|
||||
var item = $('<li></li>', {
|
||||
'class': 'icon ' + icon + ' code_review_summary'
|
||||
});
|
||||
item.html(review.url);
|
||||
ul.append(item);
|
||||
}
|
||||
li.append(ul);
|
||||
});
|
||||
}
|
||||
|
||||
function setAddReviewButton(url, change_id, image_tag, is_readonly, is_diff, attachment_id){
|
||||
var filetables = [];
|
||||
var j = 0;
|
||||
$('table').each(function(){
|
||||
if($(this).hasClass('filecontent')){
|
||||
filetables[j++] = this;
|
||||
}
|
||||
});
|
||||
j = 0;
|
||||
$('table.filecontent th.filename').each(function(){
|
||||
filenames[j] = $.trim($(this).text());
|
||||
j++;
|
||||
});
|
||||
addReviewUrl = url + '?change_id=' + change_id + '&action_type=' + action_type +
|
||||
'&rev=' + rev + '&rev_to=' + rev_to +
|
||||
'&attachment_id=' + attachment_id + '&repository_id=' + encodeURIComponent(repository_id);
|
||||
if (path != null && path.length > 0) {
|
||||
addReviewUrl = addReviewUrl + '&path=' + encodeURIComponent(path);
|
||||
}
|
||||
var num = 0;
|
||||
if (is_diff) {
|
||||
num = 1;
|
||||
}
|
||||
var i, l, tl;
|
||||
for (i = 0, tl = filetables.length; i < tl; i++) {
|
||||
var table = filetables[i];
|
||||
var trs = table.getElementsByTagName('tr');
|
||||
|
||||
for (j = 0,l = trs.length; j < l; j++) {
|
||||
var tr = trs[j];
|
||||
var ths = tr.getElementsByTagName('th');
|
||||
|
||||
var th = ths[num];
|
||||
if (th == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var th_html = th.innerHTML;
|
||||
|
||||
var line = th_html.match(/[0-9]+/);
|
||||
if (line == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var span_html = '<span white-space="nowrap" id="review_span_' + line + '_' + i + '">';
|
||||
|
||||
if (!is_readonly) {
|
||||
span_html += image_tag;
|
||||
}
|
||||
span_html += '</span>';
|
||||
th.innerHTML = th_html + span_html;
|
||||
|
||||
var img = th.getElementsByTagName('img')[0];
|
||||
if (img != null ) {
|
||||
img.id = 'add_revew_img_' + line + '_' + i;
|
||||
$(img).click(clickPencil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function clickPencil(e)
|
||||
{
|
||||
// alert('$(e.target).attr("id") = ' + $(e.target).attr("id"));
|
||||
var result = $(e.target).attr("id").match(/([0-9]+)_([0-9]+)/);
|
||||
var line = result[1];
|
||||
var file_count = eval(result[2]);
|
||||
var url = addReviewUrl + '&line=' + line + '&file_count=' + file_count;
|
||||
|
||||
if (path == null || path.length == 0) {
|
||||
url = url + '&path=' + encodeURIComponent(filenames[file_count]) + '&diff_all=true';
|
||||
}
|
||||
addReview(url);
|
||||
formPopup(e.pageX, e.pageY);
|
||||
e.preventDefault();
|
||||
}
|
||||
var addReviewUrl = null;
|
||||
var showReviewUrl = null;
|
||||
var showReviewImageTag = null;
|
||||
var showClosedReviewImageTag = null;
|
||||
|
||||
function setShowReviewButton(line, review_id, is_closed, file_count) {
|
||||
//alert('file_count = ' + file_count);
|
||||
var span = $('#review_span_' + line + '_' + file_count);
|
||||
if (span.size() == 0) {
|
||||
return;
|
||||
}
|
||||
var innerSpan = $('<span></span>',{id: 'review_' + review_id});
|
||||
span.append(innerSpan);
|
||||
innerSpan.html(is_closed? showClosedReviewImageTag : showReviewImageTag);
|
||||
var div = $('<div></div>', {
|
||||
'class':'draggable',
|
||||
id: 'show_review_' + review_id
|
||||
});
|
||||
$('#code_review').append(div);
|
||||
innerSpan.down('img').click(function(e) {
|
||||
var review_id = $(e.target).parent().attr('id').match(/[0-9]+/)[0];
|
||||
var span = $('#review_' + review_id); // span element of view review button
|
||||
var pos = span.offset();
|
||||
showReview(showReviewUrl, review_id, pos.left + 10 + 5, pos.top + 25);
|
||||
});
|
||||
}
|
||||
|
||||
function popupReview(review_id) {
|
||||
var span = $('#review_' + review_id); // span element of view review button
|
||||
var pos = span.offset();
|
||||
$('html,body').animate({ scrollTop: pos.top },
|
||||
{duration: 'fast',
|
||||
complete: function(){showReview(showReviewUrl, review_id, pos.left + 10 + 5, pos.top)}});
|
||||
// position and show popup dialog
|
||||
// create popup dialog
|
||||
//var win = showReview(showReviewUrl, review_id, pos.left + 10 + 5, pos.top);
|
||||
// win.toFront();
|
||||
}
|
||||
|
||||
function showReview(url, review_id, x, y) {
|
||||
if (code_reviews_dialog_map[review_id] != null) {
|
||||
var cur_win = code_reviews_dialog_map[review_id];
|
||||
cur_win.hide();
|
||||
code_reviews_dialog_map[review_id] = null;
|
||||
}
|
||||
$('#show_review_' + review_id).load(url, {review_id: review_id});
|
||||
var review = getReviewObjById(review_id);
|
||||
|
||||
var win = $('#show_review_' + review_id).dialog({
|
||||
show: {effect:'scale'},// ? 'top-left'
|
||||
//position: [x, y + 5],
|
||||
width:640,
|
||||
zIndex: topZindex,
|
||||
title: review_dialog_title
|
||||
});
|
||||
// win.getContent().style.color = "#484848";
|
||||
// win.getContent().style.background = "#ffffff";
|
||||
topZindex++;
|
||||
code_reviews_dialog_map[review_id] = win;
|
||||
return win
|
||||
}
|
||||
|
||||
function getReviewObjById(review_id) {
|
||||
for (var reviewlist in code_reviews_map) {
|
||||
for (var i = 0; i < reviewlist.length; i++) {
|
||||
var review = reviewlist[i];
|
||||
if (review.id == review_id) {
|
||||
return review;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function formPopup(x, y){
|
||||
//@see http://docs.jquery.com/UI/Effects/Scale
|
||||
var win = $('#review-form-frame').dialog({
|
||||
show: {effect:'scale', direction: 'both'},// ? 'top-left'
|
||||
// position: [x, y + 5],
|
||||
width:640,
|
||||
zIndex: topZindex,
|
||||
title: add_form_title
|
||||
});
|
||||
// win.getContent().style.background = "#ffffff";
|
||||
if (review_form_dialog != null) {
|
||||
review_form_dialog.destroy();
|
||||
review_form_dialog = null;
|
||||
}
|
||||
review_form_dialog = win;
|
||||
topZindex += 10;
|
||||
return false;
|
||||
}
|
||||
|
||||
function hideForm() {
|
||||
if (review_form_dialog == null) {
|
||||
return;
|
||||
}
|
||||
review_form_dialog.dialog('close');
|
||||
review_form_dialog = null;
|
||||
$('#review-form').html('');
|
||||
}
|
||||
function addReview(url) {
|
||||
$('#review-form').load(url);
|
||||
}
|
||||
|
||||
function deleteReview(review_id) {
|
||||
$('show_review_' + review_id).remove();
|
||||
$('review_' + review_id).remove();
|
||||
|
||||
}
|
||||
|
||||
function changeImage(review_id, is_closed) {
|
||||
var span = $('review_' + review_id);
|
||||
var new_image = null;
|
||||
var dummy = new Element('span');
|
||||
if (is_closed) {
|
||||
dummy.insert(showClosedReviewImageTag);
|
||||
}
|
||||
else {
|
||||
dummy.insert(showReviewImageTag);
|
||||
}
|
||||
new_image = dummy.down().getAttribute('src');
|
||||
//alert(new_image);
|
||||
span.down('img').setAttribute('src', new_image);
|
||||
|
||||
}
|
||||
|
||||
function make_addreview_link(project, link) {
|
||||
var alist = $('#content p a');
|
||||
if (alist == null) {
|
||||
return;
|
||||
}
|
||||
var a = alist[0];
|
||||
var p = a.parentNode;
|
||||
p.innerHTML = p.innerHTML + " | " + link;
|
||||
}
|
||||
|
||||
function call_update_revisions(url) {
|
||||
var changeset_ids = '';
|
||||
var links = $$('table.changesets tbody tr.changeset td.id a');
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
var link = links[i];
|
||||
var href = link.getAttribute('href');
|
||||
var id = href.replace(/^.*\/revisions\//, '');
|
||||
if (i > 0) {
|
||||
changeset_ids += ',';
|
||||
}
|
||||
changeset_ids += id;
|
||||
}
|
||||
new Ajax.Updater('code_review_revisions', url,
|
||||
{
|
||||
evalScripts:true,
|
||||
method:'get',
|
||||
parameters: 'changeset_ids=' + encodeURI(changeset_ids)
|
||||
});
|
||||
}
|
||||
|
||||
$.fn.serialize2json = function()
|
||||
{
|
||||
var o = {};
|
||||
var a = this.serializeArray();
|
||||
$.each(a, function() {
|
||||
if (o[this.name]) {
|
||||
if (!o[this.name].push) {
|
||||
o[this.name] = [o[this.name]];
|
||||
}
|
||||
o[this.name].push(this.value || '');
|
||||
} else {
|
||||
o[this.name] = this.value || '';
|
||||
}
|
||||
});
|
||||
return o;
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
dt.code_review {
|
||||
background-image: url(../images/review.png);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
# Code Review plugin for Redmine
|
||||
# Copyright (C) 2009 Haruyuki Iida
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#review-form-frame {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.autoscroll table.filecontent th.line-num {
|
||||
white-space: nowrap;
|
||||
vertical-align: bottom;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
table.filecontent th.line-num img{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.code-review-form-title {
|
||||
background-color: #002059;
|
||||
color: white;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
||||
.code_review_viewer {
|
||||
|
||||
min-width: 300px;
|
||||
/*
|
||||
max-width: 60%;
|
||||
*/
|
||||
/* max-height: 400px; */
|
||||
}
|
||||
|
||||
.code_review_viewer .issue{
|
||||
|
||||
}
|
||||
|
||||
.code_review_body {
|
||||
background-color: white;
|
||||
|
||||
padding:2px;
|
||||
|
||||
}
|
||||
|
||||
#code_review_list table.list td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#code_review_list table.list td.path {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#code_review_list table.list td.subject {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.icon-review {
|
||||
background-image: url(../images/review.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.icon-closed-review {
|
||||
background-image: url(../images/closed_review.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.icon-settings {
|
||||
background-image: url(../../../images/changeset.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
|
||||
li.code_review_summary {
|
||||
list-style-type: none;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,119 @@
|
|||
.overlay_alert {
|
||||
background-color: #85BBEF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity: 0.6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.alert_nw {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: transparent url(alert/top_left.gif) no-repeat bottom left;
|
||||
}
|
||||
|
||||
.alert_n {
|
||||
height: 5px;
|
||||
background: transparent url(alert/top.gif) repeat-x bottom left;
|
||||
}
|
||||
|
||||
.alert_ne {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: transparent url(alert/top_right.gif) no-repeat bottom left
|
||||
}
|
||||
|
||||
.alert_e {
|
||||
width: 5px;
|
||||
background: transparent url(alert/right.gif) repeat-y 0 0;
|
||||
}
|
||||
|
||||
.alert_w {
|
||||
width: 5px;
|
||||
background: transparent url(alert/left.gif) repeat-y 0 0;
|
||||
}
|
||||
|
||||
.alert_sw {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: transparent url(alert/bottom_left.gif) no-repeat 0 0;
|
||||
}
|
||||
|
||||
.alert_s {
|
||||
height: 5px;
|
||||
background: transparent url(alert/bottom.gif) repeat-x 0 0;
|
||||
}
|
||||
|
||||
.alert_se, .alert_sizer {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: transparent url(alert/bottom_right.gif) no-repeat 0 0;
|
||||
}
|
||||
|
||||
.alert_close {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_minimize {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_maximize {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_title {
|
||||
float:left;
|
||||
height:1px;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.alert_content {
|
||||
overflow:visible;
|
||||
color: #000;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
font: 12px arial;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
/* For alert/confirm dialog */
|
||||
.alert_window {
|
||||
background: #FFF;
|
||||
padding:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:400px;
|
||||
}
|
||||
|
||||
.alert_message {
|
||||
font: 12px arial;
|
||||
width:100%;
|
||||
color:#F00;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.alert_buttons {
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.alert_buttons input {
|
||||
width:20%;
|
||||
margin:10px;
|
||||
}
|
||||
|
||||
.alert_progress {
|
||||
float:left;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
height:16px;
|
||||
background: #FFF url('alert/progress.gif') no-repeat center center
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 70 B |
After Width: | Height: | Size: 49 B |
After Width: | Height: | Size: 49 B |
After Width: | Height: | Size: 84 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 84 B |
After Width: | Height: | Size: 70 B |
After Width: | Height: | Size: 49 B |
After Width: | Height: | Size: 49 B |
|
@ -0,0 +1,88 @@
|
|||
.overlay_alert_lite {
|
||||
background-color: #85BBEF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity: 0.6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.alert_lite_sizer {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_lite_close {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_lite_minimize {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_lite_maximize {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_lite_title {
|
||||
width:0px;
|
||||
height:0px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.alert_lite_content {
|
||||
overflow:auto;
|
||||
color: #000;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
|
||||
/* For alert/confirm dialog */
|
||||
.alert_lite_window {
|
||||
border:1px solid #F00;
|
||||
background: #FFF;
|
||||
padding:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:400px;
|
||||
}
|
||||
|
||||
.alert_lite_message {
|
||||
font-size:16px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
color:#F00;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.alert_lite_buttons {
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.alert_lite_buttons input {
|
||||
width:20%;
|
||||
margin:10px;
|
||||
}
|
||||
|
||||
.alert_lite_progress {
|
||||
float:left;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
height:16px;
|
||||
background: #FFF url('alert/progress.gif') no-repeat center center
|
||||
}
|
||||
|
||||
table.alert_lite_header {
|
||||
border:1px solid #F00;
|
||||
background:#FFF
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
.overlay_alphacube {
|
||||
background-color: #85BBEF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity: 0.6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.alphacube_nw {
|
||||
background: transparent url(alphacube/left-top.gif) no-repeat 0 0;
|
||||
width:10px;
|
||||
height:25px;
|
||||
}
|
||||
|
||||
.alphacube_n {
|
||||
background: transparent url(alphacube/top-middle.gif) repeat-x 0 0;
|
||||
height:25px;
|
||||
}
|
||||
|
||||
.alphacube_ne {
|
||||
background: transparent url(alphacube/right-top.gif) no-repeat 0 0;
|
||||
width:10px;
|
||||
height:25px;
|
||||
}
|
||||
|
||||
.alphacube_w {
|
||||
background: transparent url(alphacube/frame-left.gif) repeat-y top left;
|
||||
width:7px;
|
||||
}
|
||||
|
||||
.alphacube_e {
|
||||
background: transparent url(alphacube/frame-right.gif) repeat-y top right;
|
||||
width:7px;
|
||||
}
|
||||
|
||||
.alphacube_sw {
|
||||
background: transparent url(alphacube/bottom-left-c.gif) no-repeat 0 0;
|
||||
width:7px;
|
||||
height:7px;
|
||||
}
|
||||
|
||||
.alphacube_s {
|
||||
background: transparent url(alphacube/bottom-middle.gif) repeat-x 0 0;
|
||||
height:7px;
|
||||
}
|
||||
|
||||
.alphacube_se, .alphacube_sizer {
|
||||
background: transparent url(alphacube/bottom-right-c.gif) no-repeat 0 0;
|
||||
width:7px;
|
||||
height:7px;
|
||||
}
|
||||
|
||||
.alphacube_sizer {
|
||||
cursor:se-resize;
|
||||
}
|
||||
|
||||
.alphacube_close {
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
background: transparent url(alphacube/button-close-focus.gif) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:11px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.alphacube_minimize {
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
background: transparent url(alphacube/button-min-focus.gif) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:55px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.alphacube_maximize {
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
background: transparent url(alphacube/button-max-focus.gif) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:33px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.alphacube_title {
|
||||
float:left;
|
||||
height:14px;
|
||||
font-size:14px;
|
||||
text-align:center;
|
||||
margin-top:2px;
|
||||
width:100%;
|
||||
color:#123456;
|
||||
}
|
||||
|
||||
.alphacube_content {
|
||||
overflow:auto;
|
||||
color: #000;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
font: 12px arial;
|
||||
background:#FDFDFD;
|
||||
}
|
||||
|
||||
/* For alert/confirm dialog */
|
||||
.alphacube_window {
|
||||
border:1px solid #F00;
|
||||
background: #FFF;
|
||||
padding:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:400px;
|
||||
}
|
||||
|
||||
.alphacube_message {
|
||||
font: 12px arial;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.alphacube_buttons {
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.alphacube_buttons input {
|
||||
width:20%;
|
||||
margin:10px;
|
||||
}
|
||||
|
||||
.alphacube_progress {
|
||||
float:left;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
height:16px;
|
||||
background: #FFF url('alert/progress.gif') no-repeat center center
|
||||
}
|
||||
|
||||
.alphacube_wired_frame {
|
||||
background: #FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity: 0.6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 60 B |
After Width: | Height: | Size: 50 B |
After Width: | Height: | Size: 61 B |
After Width: | Height: | Size: 699 B |
After Width: | Height: | Size: 765 B |
After Width: | Height: | Size: 472 B |
After Width: | Height: | Size: 64 B |
After Width: | Height: | Size: 64 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 97 B |
|
@ -0,0 +1,51 @@
|
|||
<public:component>
|
||||
<public:attach event="onpropertychange" onevent="propertyChanged()" />
|
||||
<script>
|
||||
|
||||
var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32";
|
||||
var realSrc;
|
||||
var blankSrc = "blank.gif";
|
||||
|
||||
if (supported) fixImage();
|
||||
|
||||
function propertyChanged() {
|
||||
if (!supported) return;
|
||||
|
||||
var pName = event.propertyName;
|
||||
if (pName != "src") return;
|
||||
// if not set to blank
|
||||
if ( ! new RegExp(blankSrc).test(src))
|
||||
fixImage();
|
||||
};
|
||||
|
||||
function fixImage() {
|
||||
// get src
|
||||
var src = element.src;
|
||||
|
||||
// check for real change
|
||||
if (src == realSrc) {
|
||||
element.src = blankSrc;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! new RegExp(blankSrc).test(src)) {
|
||||
// backup old src
|
||||
realSrc = src;
|
||||
}
|
||||
|
||||
// test for png
|
||||
if ( /\.png$/.test( realSrc.toLowerCase() ) ) {
|
||||
// set blank image
|
||||
element.src = blankSrc;
|
||||
// set filter
|
||||
element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
|
||||
src + "',sizingMethod='scale')";
|
||||
}
|
||||
else {
|
||||
// remove filter
|
||||
element.runtimeStyle.filter = "";
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</public:component>
|
|
@ -0,0 +1,121 @@
|
|||
.overlay_darkX {
|
||||
background-color: #85BBEF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity: 0.6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.darkX_nw {
|
||||
background: transparent url(darkX/titlebar-left-focused.png) no-repeat 0 0;
|
||||
width:6px;
|
||||
height:21px;
|
||||
}
|
||||
.darkX_n {
|
||||
background: transparent url(darkX/titlebar-mid-focused.png) repeat-x 0 0;
|
||||
height:21px;
|
||||
}
|
||||
.darkX_ne {
|
||||
background: transparent url(darkX/titlebar-right-focused.png) no-repeat 0 0;
|
||||
width:6px;
|
||||
height:21px;
|
||||
}
|
||||
.darkX_w {
|
||||
background: transparent url(darkX/frame-left-focused.png) repeat-y top left;
|
||||
width:3px;
|
||||
}
|
||||
|
||||
.darkX_e {
|
||||
background: transparent url(darkX/frame-right-focused.png) repeat-y top right;
|
||||
width:3px;
|
||||
}
|
||||
|
||||
.darkX_sw {
|
||||
background: transparent url(darkX/frame-bottom-left-focused.png) no-repeat 0 0;
|
||||
width:5px;
|
||||
height:3px;
|
||||
}
|
||||
.darkX_s {
|
||||
background: transparent url(darkX/frame-bottom-mid-focused.png) repeat-x 0 0;
|
||||
height:3px;
|
||||
}
|
||||
.darkX_se, .darkX_sizer {
|
||||
background: transparent url(darkX/frame-bottom-right-focused.png) no-repeat 0 0;
|
||||
width:5px;
|
||||
height:3px;
|
||||
}
|
||||
|
||||
.darkX_sizer {
|
||||
cursor:se-resize;
|
||||
}
|
||||
|
||||
.darkX_close {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
background: transparent url(darkX/button-close-focused.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:5px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.darkX_minimize {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
background: transparent url(darkX/button-minimize-focused.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:26px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.darkX_maximize {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
background: transparent url(darkX/button-maximize-focused.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:47px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
|
||||
.darkX_title {
|
||||
float:left;
|
||||
height:14px;
|
||||
font-size:12px;
|
||||
text-align:center;
|
||||
margin-top:2px;
|
||||
width:100%;
|
||||
color:#FFF;
|
||||
}
|
||||
|
||||
.darkX_content {
|
||||
overflow:auto;
|
||||
color: #E6DF2A;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
background:#5E5148;
|
||||
}
|
||||
|
||||
|
||||
/* FOR IE */
|
||||
* html .darkX_minimize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-minimize-focused.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkX_maximize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-maximize-focused.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .darkX_close {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-close-focused.png", sizingMethod="crop");
|
||||
}
|
After Width: | Height: | Size: 904 B |
After Width: | Height: | Size: 882 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 180 B |
After Width: | Height: | Size: 175 B |
After Width: | Height: | Size: 180 B |
|
@ -0,0 +1,25 @@
|
|||
div.inspector div.inspectable {
|
||||
padding: 0.25em 0 0.25em 1em;
|
||||
background-color: Gray;
|
||||
color: white;
|
||||
border: outset 2px white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.inspector div.child {
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
#debug_window_content { /* DIV container for debug sizing*/
|
||||
width:250px;
|
||||
height:100px;
|
||||
background-color:#000;
|
||||
}
|
||||
|
||||
#debug { /* DIV container for debug contents*/
|
||||
padding:3px;
|
||||
color:#0f0;
|
||||
font-family:monaco, Tahoma, Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size:10px;
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
.overlay_dialog {
|
||||
background-color: #666666;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity: 0.6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.overlay___invisible__ {
|
||||
background-color: #666666;
|
||||
filter:alpha(opacity=0);
|
||||
-moz-opacity: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.dialog_nw {
|
||||
width: 9px;
|
||||
height: 23px;
|
||||
background: transparent url(default/top_left.gif) no-repeat 0 0;
|
||||
}
|
||||
|
||||
.dialog_n {
|
||||
background: transparent url(default/top_mid.gif) repeat-x 0 0;
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
.dialog_ne {
|
||||
width: 9px;
|
||||
height: 23px;
|
||||
background: transparent url(default/top_right.gif) no-repeat 0 0;
|
||||
}
|
||||
|
||||
.dialog_e {
|
||||
width: 2px;
|
||||
background: transparent url(default/center_right.gif) repeat-y 0 0;
|
||||
}
|
||||
|
||||
.dialog_w {
|
||||
width: 2px;
|
||||
background: transparent url(default/center_left.gif) repeat-y 0 0;
|
||||
}
|
||||
|
||||
.dialog_sw {
|
||||
width: 9px;
|
||||
height: 19px;
|
||||
background: transparent url(default/bottom_left.gif) no-repeat 0 0;
|
||||
}
|
||||
|
||||
.dialog_s {
|
||||
background: transparent url(default/bottom_mid.gif) repeat-x 0 0;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
.dialog_se {
|
||||
width: 9px;
|
||||
height: 19px;
|
||||
background: transparent url(default/bottom_right.gif) no-repeat 0 0;
|
||||
}
|
||||
|
||||
.dialog_sizer {
|
||||
width: 9px;
|
||||
height: 19px;
|
||||
background: transparent url(default/sizer.gif) no-repeat 0 0;
|
||||
cursor:se-resize;
|
||||
}
|
||||
|
||||
.dialog_close {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: transparent url(default/close.gif) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:5px;
|
||||
left:8px;
|
||||
cursor:pointer;
|
||||
z-index:2000;
|
||||
}
|
||||
|
||||
.dialog_minimize {
|
||||
width: 14px;
|
||||
height: 15px;
|
||||
background: transparent url(default/minimize.gif) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:5px;
|
||||
left:28px;
|
||||
cursor:pointer;
|
||||
z-index:2000;
|
||||
}
|
||||
|
||||
.dialog_maximize {
|
||||
width: 14px;
|
||||
height: 15px;
|
||||
background: transparent url(default/maximize.gif) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:5px;
|
||||
left:49px;
|
||||
cursor:pointer;
|
||||
z-index:2000;
|
||||
}
|
||||
|
||||
.dialog_title {
|
||||
float:left;
|
||||
height:14px;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
font-size:12px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
.dialog_content {
|
||||
overflow:auto;
|
||||
color: #DDD;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
background-color:#123;
|
||||
}
|
||||
|
||||
.top_draggable, .bottom_draggable {
|
||||
cursor:move;
|
||||
}
|
||||
|
||||
.status_bar {
|
||||
font-size:12px;
|
||||
}
|
||||
.status_bar input{
|
||||
font-size:12px;
|
||||
}
|
||||
|
||||
.wired_frame {
|
||||
display: block;
|
||||
position: absolute;
|
||||
border: 1px #000 dashed;
|
||||
}
|
||||
|
||||
/* DO NOT CHANGE THESE VALUES*/
|
||||
.dialog {
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.dialog table.table_window {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
margin: 0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.dialog table.table_window td , .dialog table.table_window th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dialog .title_window {
|
||||
-moz-user-select:none;
|
||||
}
|
||||
|
After Width: | Height: | Size: 187 B |
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 187 B |
After Width: | Height: | Size: 201 B |
After Width: | Height: | Size: 52 B |
After Width: | Height: | Size: 49 B |
After Width: | Height: | Size: 1014 B |
After Width: | Height: | Size: 1012 B |
After Width: | Height: | Size: 556 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1023 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 138 B |
After Width: | Height: | Size: 201 B |
After Width: | Height: | Size: 358 B |
After Width: | Height: | Size: 149 B |
After Width: | Height: | Size: 357 B |
After Width: | Height: | Size: 49 B |
|
@ -0,0 +1,3 @@
|
|||
/* PNG fix for all themes that uses PNG images on IE */
|
||||
td, div { behavior: url(../themes/iefix/iepngfix.htc) }
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<public:component>
|
||||
<public:attach event="onpropertychange" onevent="doFix()" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
// IE5.5+ PNG Alpha Fix v1.0RC4
|
||||
// (c) 2004-2005 Angus Turnbull http://www.twinhelix.com
|
||||
|
||||
// This is licensed under the CC-GNU LGPL, version 2.1 or later.
|
||||
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
|
||||
|
||||
// Modified/Simplified on 04/23/2007 by Sebastien Gruhier (http://www.xilinus.com)
|
||||
// To work only on background and to handle repeat bg
|
||||
|
||||
// This must be a path to a blank image. That's all the configuration you need.
|
||||
if (typeof blankImg == 'undefined') var blankImg = 'blank.gif';
|
||||
|
||||
var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
|
||||
|
||||
function filt(s, m)
|
||||
{
|
||||
if (filters[f])
|
||||
{
|
||||
filters[f].enabled = s ? true : false;
|
||||
if (s) with (filters[f]) { src = s; sizingMethod = m }
|
||||
}
|
||||
else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
|
||||
}
|
||||
|
||||
function doFix()
|
||||
{
|
||||
// Assume IE7 is OK.
|
||||
if (!/MSIE (5\.5|6\.)/.test(navigator.userAgent) ||
|
||||
(event && !/(background|src)/.test(event.propertyName))) return;
|
||||
|
||||
var bgImg = currentStyle.backgroundImage || style.backgroundImage;
|
||||
var bgRepeat = currentStyle.backgroundRepeat || style.backgroundRepeat;
|
||||
if (bgImg && bgImg != 'none')
|
||||
{
|
||||
if (bgImg.match(/^url[("']+(.*\.png)[)"']+$/i))
|
||||
{
|
||||
var s = RegExp.$1;
|
||||
if (currentStyle.width == 'auto' && currentStyle.height == 'auto')
|
||||
style.width = offsetWidth + 'px';
|
||||
style.backgroundImage = 'none';
|
||||
filt(s, bgRepeat == "no-repeat" ? 'crop' : 'scale');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doFix();
|
||||
|
||||
</script>
|
||||
</public:component>
|
|
@ -0,0 +1,960 @@
|
|||
.overlay___invisible__ {
|
||||
background-color: #666;
|
||||
filter:alpha(opacity=0);
|
||||
-moz-opacity: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.top_draggable, .bottom_draggable {
|
||||
cursor:move;
|
||||
}
|
||||
|
||||
.status_bar {
|
||||
font-size:12px;
|
||||
}
|
||||
.status_bar input{
|
||||
font-size:12px;
|
||||
}
|
||||
|
||||
.wired_frame {
|
||||
display:block;
|
||||
position:absolute;
|
||||
border:1px #000 dashed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.overlay_bluelighting {
|
||||
background-color:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.bluelighting_wired_frame {
|
||||
background:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.bluelighting_nw {
|
||||
background:transparent url(lighting/top-left-blue.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.bluelighting_n {
|
||||
background:transparent url(lighting/top-middle-blue.png) repeat-x 0 0;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.bluelighting_ne {
|
||||
background:transparent url(lighting/top-right-blue.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.bluelighting_w {
|
||||
background:transparent url(lighting/left-blue.png) repeat-y top left;
|
||||
width:9px;
|
||||
}
|
||||
|
||||
.bluelighting_e {
|
||||
background:transparent url(lighting/right-blue.png) repeat-y top right;
|
||||
width:15px;
|
||||
}
|
||||
|
||||
.bluelighting_sw {
|
||||
background:transparent url(lighting/bottom-left-blue.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.bluelighting_s {
|
||||
background:transparent url(lighting/bottom-middle-blue.png) repeat-x 0 0;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.bluelighting_se, .bluelighting_sizer {
|
||||
background:transparent url(lighting/bottom-right-blue.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.bluelighting_sizer {
|
||||
cursor:se-resize;
|
||||
}
|
||||
|
||||
.bluelighting_close {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-close-blue.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:10px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.bluelighting_maximize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-maximize-blue.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:25px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.bluelighting_minimize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-minimize-blue.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:40px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.bluelighting_title {
|
||||
float:left;
|
||||
height:14px;
|
||||
font-size:14px;
|
||||
font-weight:bold;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
text-align:center;
|
||||
margin-top:2px;
|
||||
width:100%;
|
||||
color:#17385B;
|
||||
}
|
||||
|
||||
.bluelighting_content {
|
||||
overflow:auto;
|
||||
color:#000;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:12px;
|
||||
background:#BFDBFF;
|
||||
}
|
||||
|
||||
/* For alert/confirm dialog */
|
||||
.bluelighting_window {
|
||||
border:1px solid #F00;
|
||||
background:#FFF;
|
||||
padding:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:400px;
|
||||
}
|
||||
|
||||
.bluelighting_message {
|
||||
font-size:12px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.bluelighting_buttons {
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.bluelighting_buttons input {
|
||||
border:1px solid #999;
|
||||
border-top-color:#CCC;
|
||||
border-left-color:#CCC;
|
||||
padding:2px;
|
||||
background-color:#FFF;
|
||||
color:#333;
|
||||
background-image:url(lighting/background_buttons.gif);
|
||||
background-repeat:repeat-x;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:10px;
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.bluelighting_progress {
|
||||
float:left;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
height:16px;
|
||||
background:transparent url('lighting/spinner.gif') no-repeat center center
|
||||
}
|
||||
|
||||
/* FOR IE */
|
||||
* html .bluelighting_nw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-blue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .bluelighting_n {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-blue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .bluelighting_ne {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-blue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .bluelighting_w {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-blue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .bluelighting_e {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-blue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .bluelighting_sw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-blue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .bluelighting_s {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-blue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .bluelighting_se, * html .bluelighting_sizer {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-blue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .bluelighting_close {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-blue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .bluelighting_minimize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-blue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .bluelighting_maximize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-blue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .bluelighting_content {
|
||||
background:#B8D7FF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.overlay_greylighting {
|
||||
background-color:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.greylighting_wired_frame {
|
||||
background:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.greylighting_nw {
|
||||
background:transparent url(lighting/top-left-grey.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.greylighting_n {
|
||||
background:transparent url(lighting/top-middle-grey.png) repeat-x 0 0;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.greylighting_ne {
|
||||
background:transparent url(lighting/top-right-grey.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.greylighting_w {
|
||||
background:transparent url(lighting/left-grey.png) repeat-y top left;
|
||||
width:9px;
|
||||
}
|
||||
|
||||
.greylighting_e {
|
||||
background:transparent url(lighting/right-grey.png) repeat-y top right;
|
||||
width:15px;
|
||||
}
|
||||
|
||||
.greylighting_sw {
|
||||
background:transparent url(lighting/bottom-left-grey.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.greylighting_s {
|
||||
background:transparent url(lighting/bottom-middle-grey.png) repeat-x 0 0;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.greylighting_se, .greylighting_sizer {
|
||||
background:transparent url(lighting/bottom-right-grey.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.greylighting_sizer {
|
||||
cursor:se-resize;
|
||||
}
|
||||
|
||||
.greylighting_close {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-close-grey.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:10px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.greylighting_maximize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-maximize-grey.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:25px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.greylighting_minimize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-minimize-grey.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:40px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.greylighting_title {
|
||||
float:left;
|
||||
height:14px;
|
||||
font-size:14px;
|
||||
font-weight:bold;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
text-align:center;
|
||||
margin-top:2px;
|
||||
width:100%;
|
||||
color:#525252;
|
||||
}
|
||||
|
||||
.greylighting_content {
|
||||
overflow:auto;
|
||||
color:#000;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:12px;
|
||||
background:#CDCDCD;
|
||||
}
|
||||
|
||||
/* For alert/confirm dialog */
|
||||
.greylighting_window {
|
||||
border:1px solid #F00;
|
||||
background:#FFF;
|
||||
padding:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:400px;
|
||||
}
|
||||
|
||||
.greylighting_message {
|
||||
font-size:12px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.greylighting_buttons {
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.greylighting_buttons input {
|
||||
border:1px solid #999;
|
||||
border-top-color:#CCC;
|
||||
border-left-color:#CCC;
|
||||
padding:2px;
|
||||
background-color:#FFF;
|
||||
color:#333;
|
||||
background-image:url(lighting/background_buttons.gif);
|
||||
background-repeat:repeat-x;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:10px;
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.greylighting_progress {
|
||||
float:left;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
height:16px;
|
||||
background:transparent url('lighting/spinner.gif') no-repeat center center
|
||||
}
|
||||
|
||||
/* FOR IE */
|
||||
* html .greylighting_nw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-grey.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greylighting_n {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-grey.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .greylighting_ne {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-grey.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greylighting_w {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-grey.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .greylighting_e {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-grey.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .greylighting_sw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-grey.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greylighting_s {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-grey.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html greylighting_se, * html .greylighting_sizer {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-grey.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greylighting_close {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-grey.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greylighting_minimize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-grey.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greylighting_maximize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-grey.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greylighting_content {
|
||||
background:#C7C7C7;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.overlay_greenlighting {
|
||||
background-color:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.greenlighting_wired_frame {
|
||||
background:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.greenlighting_nw {
|
||||
background:transparent url(lighting/top-left-green.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.greenlighting_n {
|
||||
background:transparent url(lighting/top-middle-green.png) repeat-x 0 0;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.greenlighting_ne {
|
||||
background:transparent url(lighting/top-right-green.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.greenlighting_w {
|
||||
background:transparent url(lighting/left-green.png) repeat-y top left;
|
||||
width:9px;
|
||||
}
|
||||
|
||||
.greenlighting_e {
|
||||
background:transparent url(lighting/right-green.png) repeat-y top right;
|
||||
width:15px;
|
||||
}
|
||||
|
||||
.greenlighting_sw {
|
||||
background:transparent url(lighting/bottom-left-green.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.greenlighting_s {
|
||||
background:transparent url(lighting/bottom-middle-green.png) repeat-x 0 0;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.greenlighting_se, .greenlighting_sizer {
|
||||
background:transparent url(lighting/bottom-right-green.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.greenlighting_sizer {
|
||||
cursor:se-resize;
|
||||
}
|
||||
|
||||
.greenlighting_close {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-close-green.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:10px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.greenlighting_maximize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-maximize-green.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:25px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.greenlighting_minimize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-minimize-green.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:40px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.greenlighting_title {
|
||||
float:left;
|
||||
height:14px;
|
||||
font-size:14px;
|
||||
font-weight:bold;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
text-align:center;
|
||||
margin-top:2px;
|
||||
width:100%;
|
||||
color:#2A6002;
|
||||
}
|
||||
|
||||
.greenlighting_content {
|
||||
overflow:auto;
|
||||
color:#000;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:12px;
|
||||
background:#ACFCAF;
|
||||
}
|
||||
|
||||
/* For alert/confirm dialog */
|
||||
.greenlighting_window {
|
||||
border:1px solid #F00;
|
||||
background:#FFF;
|
||||
padding:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:400px;
|
||||
}
|
||||
|
||||
.greenlighting_message {
|
||||
font-size:12px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.greenlighting_buttons {
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.greenlighting_buttons input {
|
||||
border:1px solid #999;
|
||||
border-top-color:#CCC;
|
||||
border-left-color:#CCC;
|
||||
padding:2px;
|
||||
background-color:#FFF;
|
||||
color:#333;
|
||||
background-image:url(lighting/background_buttons.gif);
|
||||
background-repeat:repeat-x;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:10px;
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.greenlighting_progress {
|
||||
float:left;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
height:16px;
|
||||
background:transparent url('lighting/spinner.gif') no-repeat center center
|
||||
}
|
||||
|
||||
/* FOR IE */
|
||||
* html .greenlighting_nw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-green.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greenlighting_n {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-green.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .greenlighting_ne {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-green.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greenlighting_w {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-green.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .greenlighting_e {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-green.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .greenlighting_sw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-green.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greenlighting_s {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-green.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html greenlighting_se, * html .greenlighting_sizer {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-green.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greenlighting_close {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-green.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greenlighting_minimize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-green.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greenlighting_maximize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-green.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .greenlighting_content {
|
||||
background:#A4FCA7;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.overlay_darkbluelighting {
|
||||
background-color:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.darkbluelighting_wired_frame {
|
||||
background:#FFF;
|
||||
filter:alpha(opacity=60);
|
||||
-moz-opacity:0.6;
|
||||
opacity:0.6;
|
||||
}
|
||||
|
||||
.darkbluelighting_nw {
|
||||
background:transparent url(lighting/top-left-darkblue.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.darkbluelighting_n {
|
||||
background:transparent url(lighting/top-middle-darkblue.png) repeat-x 0 0;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.darkbluelighting_ne {
|
||||
background:transparent url(lighting/top-right-darkblue.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
.darkbluelighting_w {
|
||||
background:transparent url(lighting/left-darkblue.png) repeat-y top left;
|
||||
width:9px;
|
||||
}
|
||||
|
||||
.darkbluelighting_e {
|
||||
background:transparent url(lighting/right-darkblue.png) repeat-y top right;
|
||||
width:15px;
|
||||
}
|
||||
|
||||
.darkbluelighting_sw {
|
||||
background:transparent url(lighting/bottom-left-darkblue.png) no-repeat 0 0;
|
||||
width:9px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.darkbluelighting_s {
|
||||
background:transparent url(lighting/bottom-middle-darkblue.png) repeat-x 0 0;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.darkbluelighting_se, .darkbluelighting_sizer {
|
||||
background:transparent url(lighting/bottom-right-darkblue.png) no-repeat 0 0;
|
||||
width:15px;
|
||||
height:15px;
|
||||
}
|
||||
|
||||
.darkbluelighting_sizer {
|
||||
cursor:se-resize;
|
||||
}
|
||||
|
||||
.darkbluelighting_close {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-close-darkblue.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:10px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.darkbluelighting_maximize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-maximize-darkblue.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:25px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.darkbluelighting_minimize {
|
||||
width:15px;
|
||||
height:9px;
|
||||
background:transparent url(lighting/button-minimize-darkblue.png) no-repeat 0 0;
|
||||
position:absolute;
|
||||
top:11px;
|
||||
right:40px;
|
||||
cursor:pointer;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.darkbluelighting_title {
|
||||
float:left;
|
||||
height:14px;
|
||||
font-size:14px;
|
||||
font-weight:bold;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
text-align:center;
|
||||
margin-top:2px;
|
||||
width:100%;
|
||||
color:#E4EFFD;
|
||||
}
|
||||
|
||||
.darkbluelighting_content {
|
||||
overflow:auto;
|
||||
color:#FFF;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:12px;
|
||||
background:#0413C0;
|
||||
}
|
||||
|
||||
/* For alert/confirm dialog */
|
||||
.darkbluelighting_window {
|
||||
border:1px solid #F00;
|
||||
background:#FFF;
|
||||
padding:20px;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:400px;
|
||||
}
|
||||
|
||||
.darkbluelighting_message {
|
||||
font-size:12px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.darkbluelighting_buttons {
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.darkbluelighting_buttons input {
|
||||
border:1px solid #999;
|
||||
border-top-color:#CCC;
|
||||
border-left-color:#CCC;
|
||||
padding:2px;
|
||||
background-color:#FFF;
|
||||
color:#333;
|
||||
background-image:url(lighting/background_buttons.gif);
|
||||
background-repeat:repeat-x;
|
||||
font-family:Verdana, Arial, sans-serif;
|
||||
font-size:10px;
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.darkbluelighting_progress {
|
||||
float:left;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
height:16px;
|
||||
background:transparent url('lighting/spinner.gif') no-repeat center center
|
||||
}
|
||||
|
||||
/* FOR IE */
|
||||
* html .darkbluelighting_nw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-darkblue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_n {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-darkblue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_ne {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-darkblue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_w {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-darkblue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_e {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-darkblue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_sw {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-darkblue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_s {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-darkblue.png", sizingMethod="scale");
|
||||
}
|
||||
|
||||
* html darkbluelighting_se, * html .darkbluelighting_sizer {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-darkblue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_close {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-darkblue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_minimize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-darkblue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_maximize {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-darkblue.png", sizingMethod="crop");
|
||||
}
|
||||
|
||||
* html .darkbluelighting_content {
|
||||
background:#020EBA;
|
||||
}
|
||||
|
After Width: | Height: | Size: 70 B |