OSDN Git Service

fix form extend
[pettanr/pettanr.git] / lib / peta / leaf.rb
1 module Peta
2   class Leaf < Content
3     self.abstract_class = true
4     
5     # Dynamic ClassMethods
6     
7     def self.load_manifest
8       super
9       # Class Methods
10       pm = Manifest.manifest.models[self.my_peta.parent_model_name].classify
11       define_singleton_method("parent_model") do 
12         pm
13       end
14       # Instance Methods
15     end
16     
17     def self.element?
18       true
19     end
20     
21     def self.root_model
22       self.parent_model
23     end
24     
25     def root
26       self.__send__ self.class.root_model.item_name
27     end
28     
29     def own? operators
30       self.root.own? operators
31     end
32     
33     def visible? operators
34       return false unless super
35       self.root.visible? operators
36     end
37     
38     def self.play_list_where cid
39       ['scroll_panels.scroll_id = ?', cid]
40     end
41     
42     def self.play_list scroll, author, offset = 0, limit = ScrollPanel.default_panel_size
43       ScrollPanel.where(self.play_list_where(scroll.id)).includes(ScrollPanel.list_opt).order('scroll_panels.t').offset(offset).limit(limit)
44     end
45     
46     def self.play_sheet_where sid
47       ['story_sheets.story_id = ?', sid]
48     end
49     
50     def self.play_sheet story, operators, page = 1
51       ss = StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).order('story_sheets.t').offset(page -1).limit(1).first
52       if ss 
53         if ss.sheet
54           Sheet.show(ss.sheet.id, operators)
55         else
56           nil
57         end
58       else
59         nil
60       end
61     end
62     
63     def self.play_paginate story, page
64       Kaminari.paginate_array(Array.new(StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).count, nil)).page(page).per(1)
65     end
66     
67     def self.new_t binder_id
68       r = ScrollPanel.max_t(binder_id)
69       r.blank? ? 0 : r.to_i + 1
70     end
71     
72     def self.max_t binder_id
73       self.class..maximum(:t, :conditions => ['scroll_id = ?', binder_id])
74     end
75     
76     def self.find_t binder_id, t
77       self.class.find(:first, :conditions => ['scroll_id = ? and t = ?', binder_id, t])
78     end
79     
80     def self.collect_t scroll_panel
81       r = self.class.find(:all, :conditions => ['scroll_id = ?', scroll_panel.scroll_id], :order => 't')
82       r.map {|sp| sp.t}
83     end
84     
85     def self.top_sheet story, author
86       StorySheet.play_list(story, author).first
87     end
88     
89     def self.collect_t story_sheet
90       r = StorySheet.find(:all, :conditions => ['story_id = ?', story_sheet.story_id], :order => 't')
91       r.map {|sp| sp.t}
92     end
93     
94     def self.serial? ary
95       i = 0
96       ary.compact.sort.each do |t|
97         break false unless t == i
98         i += 1
99       end
100       ary.compact.size == i
101     end
102     
103     def self.validate_t scroll_panel
104       ScrollPanel.serial?(ScrollPanel.collect_t(scroll_panel))
105     end
106     
107     def insert_shift
108       ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and t >= ?', self.scroll_id, self.t])
109     end
110     
111     def lesser_shift old_t
112       self.t = 0 if self.t < 0
113       ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and (t >= ? and t < ?)', self.scroll_id, self.t, old_t])
114     end
115     
116     def higher_shift old_t
117       nf = ScrollPanel.find_t(self.scroll_id, self.t)
118       max_t = ScrollPanel.max_t(self.scroll_id).to_i
119       self.t = max_t if self.t > max_t
120       ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ? and t <= ?)', self.scroll_id, old_t, self.t])
121     end
122     
123     def update_shift old_t
124       if self.t > old_t
125         higher_shift old_t
126       else
127         lesser_shift old_t
128       end
129     end
130     
131     def rotate old_t = nil
132       if self.new_record?
133         if self.t.blank?
134           self.t = ScrollPanel.new_t self.scroll_id
135         else
136           self.insert_shift
137         end
138       else
139         if self.t.blank?
140         else
141           self.update_shift old_t
142         end
143       end
144     end
145     
146     def allow? operators
147       return nil if self.scroll_id == nil or self.panel_id == nil
148       self.scroll.own?(operators) and self.panel.usable?(operators)
149     end
150     
151     def destroy_and_shorten
152       res = false
153       ScrollPanel.transaction do
154         ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ?)', self.scroll_id, self.t])
155         raise ActiveRecord::Rollback unless self.destroy
156         res = true
157       end
158       res
159     end
160     
161   end
162 end
163