]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2733 Display duplicated blocks by group in the resource viewer
authorFabrice Bellingard <bellingard@gmail.com>
Thu, 27 Oct 2011 15:51:55 +0000 (17:51 +0200)
committerFabrice Bellingard <bellingard@gmail.com>
Thu, 27 Oct 2011 15:52:53 +0000 (17:52 +0200)
Now waiting for the new table to feed the data that is displayed
by this new duplication tab.

plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties
sonar-server/pom.xml
sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications.html.erb
sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications_source_snippet.html.erb
sonar-server/src/main/webapp/javascripts/duplications.js [new file with mode: 0644]
sonar-server/src/main/webapp/stylesheets/style.css

index 33f4ff2e83efa3c518a599c11c55f36ab3d812f3..c8b954cb92a993e401b1599255edbbdff27e3aaf 100644 (file)
@@ -603,6 +603,8 @@ duplications.number_of_lines=Nb Lines
 duplications.from_line=From line
 duplications.file=File
 duplications.details=Details
+duplications.expand=Expand
+duplications.collapse=Collapse
 
 
 #------------------------------------------------------------------------------
index 2681bcd922917a42a55a187d76ed51f2a64b3ae3..e2ec8b14892489817b6e5d0fc3bfdcca5fda4eb2 100644 (file)
                 <include>**/dashboard-min.js</include>
                 <include>**/protovis-min.js</include>
                 <include>**/protovis-sonar-min.js</include>
+                <include>**/duplications-min.js</include>
               </includes>
               <output>${project.build.directory}/${project.build.finalName}/javascripts/sonar.js</output>
             </aggregation>
         <artifactId>maven-war-plugin</artifactId>
         <configuration>
           <packagingExcludes>
-            **/*.log,*.iml,WEB-INF/script/,WEB-INF/test/,javascripts/application*.js,javascripts/prototype*.js,javascripts/scriptaculous*.js,javascripts/tablekit*.js,javascripts/tablekit*.js,javascripts/prototip*.js,javascripts/dashboard*.js,javascripts/protovis.js,javascripts/protovis-min.js
+            **/*.log,*.iml,WEB-INF/script/,WEB-INF/test/,javascripts/application*.js,javascripts/prototype*.js,javascripts/scriptaculous*.js,javascripts/tablekit*.js,javascripts/tablekit*.js,javascripts/prototip*.js,javascripts/dashboard*.js,javascripts/protovis.js,javascripts/protovis-min.js,javascripts/duplications.js,javascripts/duplications-min.js
           </packagingExcludes>
           <warSourceExcludes>
             **/*
index 61c30b9aee9a91cd80e31c64080ba006512fed2f..6261b8333fef3a608c32afe0079e84662a17b29f 100644 (file)
@@ -56,9 +56,12 @@ class ResourceController < ApplicationController
   end
   
   def show_duplication_snippet
-    @resource = Project.by_key(params[:id])
-    if (@resource && has_role?(:user, @resource))
-      render :partial => 'duplications_source_snippet', :locals => {:resource => @resource, :from_line => params[:from_line].to_i, :to_line => params[:to_line].to_i}
+    resource = Project.by_key(params[:id])
+    if (resource && has_role?(:user, resource))
+      original_resource = Project.by_key(params[:original_resource_id])
+      render :partial => 'duplications_source_snippet', 
+             :locals => {:resource => resource, :original_resource => original_resource, :from_line => params[:from_line].to_i, :to_line => params[:to_line].to_i, :lines_count => params[:lines_count].to_i, 
+                         :source_div => params[:source_div], :external => resource.root_id != original_resource.root_id}
     else
       access_denied
     end
@@ -185,6 +188,7 @@ class ResourceController < ApplicationController
   def render_duplications
     duplications_data = @snapshot.measure('duplications_data');
     
+    # create duplication groups
     @duplication_groups = []
     if duplications_data && duplications_data.measure_data && duplications_data.measure_data.data
       dups = Document.new duplications_data.measure_data.data.to_s
@@ -196,6 +200,13 @@ class ResourceController < ApplicationController
       end
     end
     
+    # And sort them 
+    # TODO => still needs to be sorted with inner dups before outer dups in a single block (can test only when new table available)
+    @duplication_groups.each do |group|
+      group.sort! {|dup1, dup2| dup1[:from_line].to_i <=> dup2[:from_line].to_i}
+    end
+    @duplication_groups.sort! {|group1, group2| group1[0][:from_line].to_i <=> group2[0][:from_line].to_i}
+    
     render :action => 'index', :layout => !request.xhr?
   end
   
index 659920e9c2e06d1889b5e581887c052b165ce8f3..1745af879e99d1a81e00778575154fc7a224e4d2 100644 (file)
@@ -333,7 +333,10 @@ module ApplicationHelper
         link_to(name || resource.name, {:overwrite_params => {:id => (resource.copy_resource_id||resource.id), :period => period_index, :tab => options[:tab], :rule => options[:rule]}}, :title => options[:title])
       end
     else
-      link_to(name || resource.name, {:controller => 'resource', :action => 'index', :id => resource.id, :period => period_index, :tab => options[:tab], :rule => options[:rule]}, :popup => ['resource', 'height=800,width=900,scrollbars=1,resizable=1'], :title => options[:title])
+      if options[:line]
+        anchor= 'L' + options[:line].to_s
+      end
+      link_to(name || resource.name, {:controller => 'resource', :action => 'index', :anchor => anchor, :id => resource.id, :period => period_index, :tab => options[:tab], :rule => options[:rule]}, :popup => ['resource', 'height=800,width=900,scrollbars=1,resizable=1'], :title => options[:title])
     end
   end
 
index 50ee96547cb7fad47ab690c08d81ad71261e04c2..9aabe2e583a832d715532283c5d4341028207ec8 100644 (file)
@@ -29,6 +29,7 @@
 <%= javascript_include_tag 'dashboard' %>
 <%= javascript_include_tag 'protovis' %>
 <%= javascript_include_tag 'protovis-sonar' %>
+<%= javascript_include_tag 'duplications' %>
 <% end %>
 <!--[if lte IE 6]>
 <link href="<%= ApplicationController.root_context -%>/ie6/index" media="all" rel="stylesheet" type="text/css" />
index fc9bbb1b8094378e6df6c6b3553149d43aa8a2ce..e55fb2f9e9b59d4551046db2cffc67bee5805165 100644 (file)
     <%
         group.each_with_index do |dup, index|
           resource = dup[:resource]
+          external = resource.root_id != @resource.root_id
+          lines_count = dup[:lines_count].to_i
           from_line = dup[:from_line].to_i
-          to_line = from_line+5
-          update_snippet_script = "new Ajax.Updater('source-#{group_index}', '#{url_for :action => :show_duplication_snippet, :params => {:id => resource.id, :from_line => from_line, :to_line => to_line}}', {asynchronous:true, evalScripts:true}); return false;"
-          groupClass = "group" + group_index.to_s
-          groupRowClass = "row" + group_index.to_s + "-" + index.to_s
+          to_line = from_line + (lines_count > 5 ? 5 : lines_count)
+          group_class = "group#{group_index}"
+          group_row_class = "row#{group_index}-#{index}"
+          source_div = "source-#{group_index}"
+          update_snippet_script = "updateDuplicationLines('#{url_for :action => :show_duplication_snippet, :params => {:id => resource.id, :original_resource_id => @resource.id, :from_line => from_line, :lines_count => lines_count, :source_div => source_div}}','#{group_class}', '#{group_row_class}', '#{source_div}', #{lines_count}, #{from_line}, #{to_line});"
     %>
       <tr class="hoverable <%= row_style -%>">        
         <td class="center group-item">
-          <div class="<%= groupClass -%> <%= groupRowClass -%> clickable <%= 'selected' if resource==@resource -%>" 
-               onclick="updateDuplicationLines(this, '<%= groupClass -%>', '<%= groupRowClass -%>'); <%= update_snippet_script -%>" style="border-right-width: 0px;">
-          <%= dup[:lines_count] -%>
+          <div class="<%= group_class -%> <%= group_row_class -%> clickable <%= 'selected' if resource==@resource -%>" 
+               onclick="<%= update_snippet_script -%>" style="border-right-width: 0px; margin-left: 2px;">
+          <%= lines_count -%>
           <div>
         </td>
         <td class="center group-item">
-          <div class="group<%= group_index -%> <%= groupRowClass -%> clickable <%= 'selected' if resource==@resource -%>" 
-               onclick="updateDuplicationLines(this, '<%= groupClass -%>', '<%= groupRowClass -%>'); <%= update_snippet_script -%>" style="border-right-width: 0px;border-left-width: 0px;">
+          <div class="<%= group_class -%> <%= group_row_class -%> clickable <%= 'selected' if resource==@resource -%>" 
+               onclick="<%= update_snippet_script -%>" style="border-right-width: 0px;border-left-width: 0px;">
             <%= from_line -%>
           </div>
         </td>
           <% if resource==@resource
                cell_content = resource.name
              else
-               cell_content = link_to_resource(resource, resource.name)
+               cell_content = link_to_resource(resource, resource.name, {:line => from_line})
              end
           %>
-          <div class="group<%= group_index -%> <%= groupRowClass -%> clickable <%= 'selected' if resource==@resource -%>" 
-               onclick="updateDuplicationLines(this, '<%= groupClass -%>', '<%= groupRowClass -%>'); <%= update_snippet_script -%>" style="padding-right: 20px; border-right-width: 0px;border-left-width: 0px;">
+          <div class="<%= group_class -%> <%= group_row_class -%> clickable nowrap <%= 'selected' if resource==@resource -%>" 
+               onclick="<%= update_snippet_script -%>" style="padding-right: 20px; border-right-width: 0px;border-left-width: 0px;">
             <%= cell_content -%>
-          <div>
+            <% if external %>
+              <%= image_tag "links/external.png" -%>
+            <% end %>
+          </div>
         </td>
         
         <% if index==0 %>
         <td rowspan="<%= group_size+1 -%>" class="source-snippet">
-          <div id="source-<%= group_index -%>">
-            <%= render :partial => 'duplications_source_snippet', :locals => {:resource => resource, :from_line => from_line, :to_line => to_line} -%>            
+          <div id="<%= source_div -%>">
+            <%= render :partial => 'duplications_source_snippet', :locals => {:resource => resource, :original_resource => @resource, :from_line => from_line, :to_line => to_line, :lines_count => lines_count, :source_div => source_div, :external => external} -%>
           </div>
         </td>
         <% end %>
index 7b4faa9a565276416bd3f44361d77a223e632276..511cc1c1f3c541abcd5d06e653610368ec3bf1c8 100644 (file)
@@ -1,2 +1,36 @@
-<%= resource.key -%>
-<%= snapshot_source_to_html(resource.last_snapshot, {:line_range => (from_line)..(to_line)}) -%>            
+<div class="<%= 'expanded' if to_line == from_line + lines_count -%>">
+  <div style="line-height:20px; margin-left:24px;">
+    <% 
+      if external 
+        parent_project = resource.project 
+    %>
+      <%= link_to_resource(parent_project, parent_project.path_name, {:dashboard => true}) -%>
+      <%= image_tag "links/external.png" -%>
+      <br/>
+    <% 
+      end 
+    %>
+    <b><%= resource.name(true) -%></b>
+  </div>
+  
+  <%= snapshot_source_to_html(resource.last_snapshot, {:line_range => (from_line)..(to_line)}) -%>
+  
+  <% if lines_count > 5 %>
+  <div class="small" style="line-height:20px; margin-left:24px;">
+    <% 
+      if to_line < from_line + lines_count
+        link_text =  message('duplications.expand')
+        to_line = from_line + lines_count
+      else
+        link_text =  message('duplications.collapse')
+        to_line = from_line + 5
+      end 
+    %> 
+    <%= link_to_remote link_text, 
+                       :url => {:action => :show_duplication_snippet, :params => {:id => resource.id, :original_resource_id => original_resource.id, :from_line => from_line, :to_line => to_line, :lines_count => lines_count, :source_div => source_div}},
+                       :update => source_div,
+                       :before => "$('#{source_div}').addClassName('loading');",
+                       :complete => "$('#{source_div}').removeClassName('loading');" -%>
+  </div>
+  <% end %>
+</div>
\ No newline at end of file
diff --git a/sonar-server/src/main/webapp/javascripts/duplications.js b/sonar-server/src/main/webapp/javascripts/duplications.js
new file mode 100644 (file)
index 0000000..642ca55
--- /dev/null
@@ -0,0 +1,25 @@
+// JS scripts used in the duplication tab of the resource viewer
+
+function updateDuplicationLines(url, groupClass, groupRowClass, sourceDivId, linesCount, fromLine, toLine) {
+  // handle first the style of the selectable rows
+  divs = $$('.'+groupClass);
+  for ( i = 0; i < divs.size(); i++) {
+         divs[i].removeClassName('selected');
+  }
+  divs = $$('.'+groupRowClass);
+  for ( i = 0; i < divs.size(); i++) {
+         divs[i].addClassName('selected');
+  }
+  
+  // then show that a request is pending
+  $(sourceDivId).addClassName('loading');
+  
+  // and send the Ajax request
+  if ($(sourceDivId).childElements()[0].hasClassName('expanded')) {
+       toLine = fromLine + linesCount;
+  }
+  
+  new Ajax.Updater(sourceDivId, url + "&to_line=" + toLine, {asynchronous:true, evalScripts:true, onComplete:function(request){$(sourceDivId).removeClassName('loading');}});
+  
+  return false;
+}
\ No newline at end of file
index 24ed0b4dd7ee74d72a208e033ca18aba771638a9..f2a5f0ec921f5c5671e8fd2e972f483c01744986 100644 (file)
@@ -255,6 +255,10 @@ div#sidebar .selected a, div#sidebar .selected a:hover, div#sidebar.selected a:v
   text-align: center;
 }
 
+.nowrap {
+  white-space: nowrap;
+}
+
 code {
   font-size: 93%;
 }
@@ -641,7 +645,7 @@ table.form td {
 }
 table.form td.keyCell {
   width: 1%;
-  white-space: nowrap;  
+  white-space: nowrap; 
   text-align: right;
   font-weight: bold;
   vertical-align: top;