Revision 1298:4f746d8966dd .svn/pristine/34

View differences:

.svn/pristine/34/3426569be9b65b6dce3f0afa56586bb79fc07741.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
module Redmine
19
  module Acts
20
    module Customizable
21
      def self.included(base)
22
        base.extend ClassMethods
23
      end
24

  
25
      module ClassMethods
26
        def acts_as_customizable(options = {})
27
          return if self.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
28
          cattr_accessor :customizable_options
29
          self.customizable_options = options
30
          has_many :custom_values, :as => :customized,
31
                                   :include => :custom_field,
32
                                   :order => "#{CustomField.table_name}.position",
33
                                   :dependent => :delete_all
34
          before_validation { |customized| customized.custom_field_values if customized.new_record? }
35
          # Trigger validation only if custom values were changed
36
          validates_associated :custom_values, :on => :update, :if => Proc.new { |customized| customized.custom_field_values_changed? }
37
          send :include, Redmine::Acts::Customizable::InstanceMethods
38
          # Save custom values when saving the customized object
39
          after_save :save_custom_field_values
40
        end
41
      end
42

  
43
      module InstanceMethods
44
        def self.included(base)
45
          base.extend ClassMethods
46
        end
47
        
48
        def available_custom_fields
49
          CustomField.find(:all, :conditions => "type = '#{self.class.name}CustomField'",
50
                                 :order => 'position')
51
        end
52
        
53
        # Sets the values of the object's custom fields
54
        # values is an array like [{'id' => 1, 'value' => 'foo'}, {'id' => 2, 'value' => 'bar'}]
55
        def custom_fields=(values)
56
          values_to_hash = values.inject({}) do |hash, v|
57
            v = v.stringify_keys
58
            if v['id'] && v.has_key?('value')
59
              hash[v['id']] = v['value']
60
            end
61
            hash
62
          end
63
          self.custom_field_values = values_to_hash
64
        end
65

  
66
        # Sets the values of the object's custom fields
67
        # values is a hash like {'1' => 'foo', 2 => 'bar'}
68
        def custom_field_values=(values)
69
          @custom_field_values_changed = true
70
          values = values.stringify_keys
71
          custom_field_values.each do |custom_value|
72
            custom_value.value = values[custom_value.custom_field_id.to_s] if values.has_key?(custom_value.custom_field_id.to_s)
73
          end if values.is_a?(Hash)
74
        end
75
        
76
        def custom_field_values
77
          @custom_field_values ||= available_custom_fields.collect { |x| custom_values.detect { |v| v.custom_field == x } || custom_values.build(:customized => self, :custom_field => x, :value => nil) }
78
        end
79
        
80
        def visible_custom_field_values
81
          custom_field_values.select(&:visible?)
82
        end
83
        
84
        def custom_field_values_changed?
85
          @custom_field_values_changed == true
86
        end
87
        
88
        def custom_value_for(c)
89
          field_id = (c.is_a?(CustomField) ? c.id : c.to_i)
90
          custom_values.detect {|v| v.custom_field_id == field_id }
91
        end
92
        
93
        def save_custom_field_values
94
          self.custom_values = custom_field_values
95
          custom_field_values.each(&:save)
96
          @custom_field_values_changed = false
97
          @custom_field_values = nil
98
        end
99
        
100
        def reset_custom_values!
101
          @custom_field_values = nil
102
          @custom_field_values_changed = true
103
          values = custom_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
104
          custom_values.each {|cv| cv.destroy unless custom_field_values.include?(cv)}
105
        end
106
        
107
        module ClassMethods
108
        end
109
      end
110
    end
111
  end
112
end
.svn/pristine/34/342bfb95b19c2d2bc64485e9d4d12de5afbbc42e.svn-base
1
Return-Path: <JSmith@somenet.foo>
2
Received: from osiris ([127.0.0.1])
3
	by OSIRIS
4
	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
5
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
6
From: "John Smith" <JSmith@somenet.foo>
7
To: <redmine@somenet.foo>
8
Subject: New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...
9
Date: Sun, 22 Jun 2008 12:28:07 +0200
10
MIME-Version: 1.0
11
Content-Type: text/plain;
12
	format=flowed;
13
	charset="iso-8859-1";
14
	reply-type=original
15
Content-Transfer-Encoding: 7bit
16
X-Priority: 3
17
X-MSMail-Priority: Normal
18
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
19
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
20

  
21
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
22
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
23
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
24
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
25
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
26
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
27
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
28
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
29
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et 
30
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
31
platea dictumst.
32

  
33
--- This line starts with a delimiter and should not be stripped
34

  
35
This paragraph is before delimiters.
36

  
37
BREAK
38

  
39
This paragraph is between delimiters.
40

  
41
---
42

  
43
This paragraph is after the delimiter so it shouldn't appear.
44

  
45
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
46
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
47
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
48
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, 
49
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo 
50
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
51

  
52
Project: onlinestore
53
Status: Resolved
54
due date: 2010-12-31
55
Start Date:2010-01-01
56
Assigned to: John Smith
57

  
.svn/pristine/34/345b699f46121e103fdce4587bf3ec87db1cc445.svn-base
1
module ActiveRecord
2
  module Acts
3
    module Tree
4
      def self.included(base)
5
        base.extend(ClassMethods)
6
      end
7

  
8
      # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
9
      # association. This requires that you have a foreign key column, which by default is called +parent_id+.
10
      #
11
      #   class Category < ActiveRecord::Base
12
      #     acts_as_tree :order => "name"
13
      #   end
14
      #
15
      #   Example:
16
      #   root
17
      #    \_ child1
18
      #         \_ subchild1
19
      #         \_ subchild2
20
      #
21
      #   root      = Category.create("name" => "root")
22
      #   child1    = root.children.create("name" => "child1")
23
      #   subchild1 = child1.children.create("name" => "subchild1")
24
      #
25
      #   root.parent   # => nil
26
      #   child1.parent # => root
27
      #   root.children # => [child1]
28
      #   root.children.first.children.first # => subchild1
29
      #
30
      # In addition to the parent and children associations, the following instance methods are added to the class
31
      # after calling <tt>acts_as_tree</tt>:
32
      # * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>)
33
      # * <tt>self_and_siblings</tt> - Returns all the children of the parent, including the current node (<tt>[subchild1, subchild2]</tt> when called on <tt>subchild1</tt>)
34
      # * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>)
35
      # * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>)
36
      module ClassMethods
37
        # Configuration options are:
38
        #
39
        # * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
40
        # * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
41
        # * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
42
        def acts_as_tree(options = {})
43
          configuration = { :foreign_key => "parent_id", :dependent => :destroy, :order => nil, :counter_cache => nil }
44
          configuration.update(options) if options.is_a?(Hash)
45

  
46
          belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
47
          has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => configuration[:dependent]
48

  
49
          scope :roots, where("#{configuration[:foreign_key]} IS NULL").order(configuration[:order])
50

  
51
          send :include, ActiveRecord::Acts::Tree::InstanceMethods
52
        end
53
      end
54

  
55
      module InstanceMethods
56
        # Returns list of ancestors, starting from parent until root.
57
        #
58
        #   subchild1.ancestors # => [child1, root]
59
        def ancestors
60
          node, nodes = self, []
61
          nodes << node = node.parent while node.parent
62
          nodes
63
        end
64

  
65
        # Returns list of descendants.
66
        #
67
        #   root.descendants # => [child1, subchild1, subchild2]
68
        def descendants(depth=nil)
69
          depth ||= 0
70
          result = children.dup
71
          unless depth == 1
72
            result += children.collect {|child| child.descendants(depth-1)}.flatten
73
          end
74
          result
75
        end
76

  
77
        # Returns list of descendants and a reference to the current node.
78
        #
79
        #   root.self_and_descendants # => [root, child1, subchild1, subchild2]
80
        def self_and_descendants(depth=nil)
81
          [self] + descendants(depth)
82
        end
83

  
84
        # Returns the root node of the tree.
85
        def root
86
          node = self
87
          node = node.parent while node.parent
88
          node
89
        end
90

  
91
        # Returns all siblings of the current node.
92
        #
93
        #   subchild1.siblings # => [subchild2]
94
        def siblings
95
          self_and_siblings - [self]
96
        end
97

  
98
        # Returns all siblings and a reference to the current node.
99
        #
100
        #   subchild1.self_and_siblings # => [subchild1, subchild2]
101
        def self_and_siblings
102
          parent ? parent.children : self.class.roots
103
        end
104
      end
105
    end
106
  end
107
end
.svn/pristine/34/34e888bcdeab7ab62509c340e12806f908468391.svn-base
1
author: James Adam
2
email: james.adam@gmail.com
3
homepage: http://www.rails-engines.org
4
summary: Enhances the plugin mechanism to perform more flexible sharing
5
description: The Rails Engines plugin allows the sharing of almost any type of code or asset that you could use in a Rails application, including controllers, models, stylesheets, and views.
6
license: MIT
7
version: 2.3.2

Also available in: Unified diff