Rev 1295 | Blame | Compare with Previous | Last modification | View Log | RSS feed
################################################################################ Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.# sits@users.sourceforge.net## This program is free software; you can redistribute it and modify it under# the terms of the GPL.# Action object for handling the viewing of a topic.package Codestriker::Action::ViewTopic;use strict;use Codestriker::Model::Topic;use Codestriker::Model::Comment;use Codestriker::Http::UrlBuilder;use Codestriker::Http::Render;use Codestriker::Repository::RepositoryFactory;use Codestriker::TopicListeners::Manager;# If the input is valid, display the topic.sub process($$$) {my ($type, $http_input, $http_response) = @_;my $query = $http_response->get_query();my $topicid = $http_input->get('topic');my $mode = $http_input->get('mode');my $brmode = $http_input->get('brmode');my $fview = $http_input->get('fview');my $tabwidth = $http_input->get('tabwidth');my $email = $http_input->get('email');my $feedback = $http_input->get('feedback');if (Codestriker::Model::Topic::exists($topicid) == 0) {# Topic no longer exists, most likely its been deleted.$http_response->error("Topic no longer exists.");}# Retrieve the appropriate topic details.my $topic = Codestriker::Model::Topic->new($topicid);# Retrieve the comment details for this topic, firstly determine how# many distinct comment lines are there.my @comments = $topic->read_comments();my %comment_map = ();foreach my $comment (@comments) {my $key = $comment->{filenumber} . "|" . $comment->{fileline} . "|" .$comment->{filenew};if (! exists $comment_map{$key}) {$comment_map{$key} = 1;}}# Retrieve the changed files which are a part of this review.my (@filenames, @revisions, @offsets, @binary, @numchanges);$topic->get_filestable(\@filenames,\@revisions,\@offsets,\@binary,\@numchanges);# Retrieve line-by-line versions of the data and description.my @document_description = split /\n/, $topic->{description};$http_response->generate_header(topic=>$topic,comments=>\@comments,topic_title=>"Topic Text: $topic->{title}",mode=>$mode, tabwidth=>$tabwidth,fview=>$fview,reload=>0, cache=>1);# Retrieve the repository object, if repository functionality is enabled.my $repository;if (scalar(@Codestriker::valid_repositories)) {$repository =Codestriker::Repository::RepositoryFactory->get($topic->{repository});} else {# Indicate not to activate any repository-related links.$topic->{repository} = "";}# Create the hash for the template variables.my $vars = {};$vars->{'feedback'} = $feedback;# Create the necessary template variables for generating the heading part# of the view topic display.# Obtain a new URL builder object.my $url_builder = Codestriker::Http::UrlBuilder->new($query);ProcessTopicHeader($vars, $topic, $url_builder);# Display the "update" message if the topic state has been changed.$vars->{'updated'} = $http_input->get('updated');$vars->{'rc_ok'} = $Codestriker::OK;$vars->{'rc_stale_version'} = $Codestriker::STALE_VERSION;$vars->{'rc_invalid_topic'} = $Codestriker::INVALID_TOPIC;if ($topic->{bug_ids} ne "") {my @bugs = split ', ', $topic->{bug_ids};my $bug_string = "";for (my $i = 0; $i <= $#bugs; $i++) {$bug_string .=$query->a({href=>"$Codestriker::bugtracker$bugs[$i]"},$bugs[$i]);$bug_string .= ', ' unless ($i == $#bugs);}$vars->{'bug_string'} = $bug_string;} else {$vars->{'bug_string'} = "";}$vars->{'document_reviewers'} =Codestriker->filter_email($topic->{reviewers});$vars->{'project_name'} = $topic->{project_name};$vars->{'number_of_lines'} = $topic->get_topic_size_in_lines();$vars->{'suggested_topic_size_lines'} =$Codestriker::suggested_topic_size_lines eq "" ? 0 :$Codestriker::suggested_topic_size_lines;# Prepare the data for displaying the state update option.# Make sure the old mode setting is no longer used.if ((! defined $mode) || $mode == $Codestriker::NORMAL_MODE) {$mode = $Codestriker::COLOURED_MODE;}if (! defined $brmode) {$brmode = $Codestriker::default_topic_br_mode;}if (! defined $fview) {$fview = $Codestriker::default_file_to_view;if (! defined $fview) {$fview = -1;}}$vars->{'mode'} = $mode;$vars->{'brmode'} = $brmode;$vars->{'states'} = \@Codestriker::topic_states;$vars->{'default_state'} = $topic->{state};# Set the description of the topic.my $data = "";for (my $i = 0; $i <= $#document_description; $i++) {$data .= $document_description[$i] . "\n";}$vars->{'description'} = $data;# Obtain the link to download the actual document text.$vars->{'download_url'} = $url_builder->download_url($topicid);# Fire the template on the topic heading information.my $template = Codestriker::Http::Template->new("viewtopic");$template->process($vars);# The rest of the output is non-template driven, as it is quite# complex.# Give the user the option of swapping between diff view modes.# If there are no files associated with the review, remove this# option.my $coloured_url =$url_builder->view_url($topicid, -1, $Codestriker::COLOURED_MODE,$brmode, $fview);my $coloured_mono_url =$url_builder->view_url($topicid, -1,$Codestriker::COLOURED_MONO_MODE, $brmode, $fview);my $br_normal_url =$url_builder->view_url($topicid, -1, $mode,$Codestriker::LINE_BREAK_NORMAL_MODE, $fview);my $br_assist_url =$url_builder->view_url($topicid, -1, $mode,$Codestriker::LINE_BREAK_ASSIST_MODE, $fview);if ($mode == $Codestriker::COLOURED_MODE) {print " View in " .$query->a({href=>$coloured_mono_url}, "monospace font") ." | ";} elsif ($mode == $Codestriker::COLOURED_MONO_MODE) {print " View in " .$query->a({href=>$coloured_url}, "variable-width font") ." | ";}if ($brmode == $Codestriker::LINE_BREAK_NORMAL_MODE) {print " View with " .$query->a({href=>$br_assist_url}, "minimal screen width") . ".";} elsif ($brmode == $Codestriker::LINE_BREAK_ASSIST_MODE) {print " View with " .$query->a({href=>$br_normal_url}, "minimal line breaks") . ".";}print " | ";# Display the option to change the tab width.my $newtabwidth = ($tabwidth == 4) ? 8 : 4;my $change_tabwidth_url;$change_tabwidth_url =$url_builder->view_url_extended($topicid, -1, $mode, $newtabwidth,"", "", 0, $brmode, $fview);print " Tab width set to $tabwidth (";print $query->a({href=>"$change_tabwidth_url"},"change to $newtabwidth");print ")\n";print $query->p if ($mode == $Codestriker::NORMAL_MODE);# Number of characters the line number should take, need the real lines# not the number of changed lines.my @document = split /\n/, $topic->{document};my $max_digit_width = length($#document+1);# Build the render which will be used to build this page.my $render = Codestriker::Http::Render->new($query, $url_builder, 1,$max_digit_width, $topicid,$mode, \@comments, $tabwidth,$repository, \@filenames,\@revisions, \@binary,\@numchanges, -1,$brmode, $fview);# Display the data that is being reviewed.$render->start();# Retrieve the delta set comprising this review.my $old_filename = "";# Determine which deltas are to be retrieved.my @deltas = ();if ($fview != -1) {# Get only the deltas for the selected file.@deltas = Codestriker::Model::Delta->get_delta_set($topicid, $fview);}else {# Get the whole delta data.@deltas = Codestriker::Model::Delta->get_delta_set($topicid, -1);}# Now render the selected deltas.for (my $i = 0; $i <= $#deltas; $i++) {my $delta = $deltas[$i];$render->delta($delta);}$render->finish();# Render the HTML trailer.my $trailer = Codestriker::Http::Template->new("trailer");$trailer->process();print $query->end_html();$http_response->generate_footer();# Fire the topic listener to indicate that the user has viewed the topic.Codestriker::TopicListeners::Manager::topic_viewed($email, $topic);}# This function is used by all of the view topic tabs to fill out the# common template items that are required by all, in addition to the view# topic file action.sub ProcessTopicHeader{my ($vars, $topic, $url_builder) = @_;# Handle the links in the three topic tabs.$vars->{'view_topicinfo_url'} =$url_builder->view_topicinfo_url($topic->{topicid});$vars->{'view_topic_url'} =## XX mode, last param$url_builder->view_url($topic->{topicid}, -1, 0);$vars->{'view_comments_url'} =$url_builder->view_comments_url($topic->{topicid});$vars->{'view_topic_properties_url'} =$url_builder->view_topic_properties_url($topic->{topicid});my @project_ids = ($topic->{project_id});$vars->{'list_open_topics_in_project_url'} =$url_builder->list_topics_url("", "", "", "", "", "", "", "", "","", [ 0 ], \@project_ids);# Retrieve the comment details for this topic.my @comments = $topic->read_comments();# Obtains how many comments there are, and the internal link to them.$vars->{'number_comments'} = $#comments + 1;# Obtain the view topic summary information, the title, bugs it relates# to, and who the participants are.$vars->{'title'} = $topic->{title};$vars->{'author'} = Codestriker->filter_email($topic->{author});$vars->{'document_creation_time'} =Codestriker->format_timestamp($topic->{creation_ts});$vars->{'topic'} = $topic->{topicid};$vars->{'reviewers'} = Codestriker->filter_email($topic->{reviewers});$vars->{'cc'} = Codestriker->filter_email($topic->{cc});# Get the list of obsoleted topics.my @obsoleted_topics = ();foreach my $id (@{ $topic->{obsoleted_topics} }) {my $obsoleted_topic = Codestriker::Model::Topic->new($id);my $entry = {};$entry->{title} = $obsoleted_topic->{title};$entry->{view_url} = $url_builder->view_url($id, -1);push @obsoleted_topics, $entry;}$vars->{'obsoleted_topics'} = \@obsoleted_topics;# Get the list of topics this has been obsoleted by.my @obsoleted_by = ();foreach my $id (@{ $topic->{obsoleted_by} }) {my $superseeded_topic = Codestriker::Model::Topic->new($id);my $entry = {};$entry->{title} = $superseeded_topic->{title};$entry->{view_url} = $url_builder->view_url($id, -1);push @obsoleted_by, $entry;}$vars->{'obsoleted_by'} = \@obsoleted_by;## 29-Aug-07 SJK: Add optional URL#$vars->{'desc_url'} = $topic->{desc_url};}1;