1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
# frozen_string_literal: true
# Redmine - project management software
# Copyright (C) 2006-2022 Jean-Philippe Lang
#
# 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.
require 'redmine/my_page'
class UserPreference < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :user
serialize :others
before_save :set_others_hash, :clear_unused_block_settings
safe_attributes(
'hide_mail',
'time_zone',
'comments_sorting',
'warn_on_leaving_unsaved',
'no_self_notified',
'notify_about_high_priority_issues',
'textarea_font',
'recently_used_projects',
'history_default_tab',
'default_issue_query',
'default_project_query',
'toolbar_language_options',
'auto_watch_on')
TEXTAREA_FONT_OPTIONS = ['monospace', 'proportional']
DEFAULT_TOOLBAR_LANGUAGE_OPTIONS = %w[c cpp csharp css diff go groovy html java javascript objc perl php python r ruby sass scala shell sql swift xml yaml]
AUTO_WATCH_ON_OPTIONS = ['issue_contributed_to']
def initialize(attributes=nil, *args)
super
if new_record?
unless attributes && attributes.key?(:hide_mail)
self.hide_mail = Setting.default_users_hide_mail?
end
unless attributes && attributes.key?(:time_zone)
self.time_zone = Setting.default_users_time_zone
end
unless attributes && attributes.key?(:no_self_notified)
self.no_self_notified = Setting.default_users_no_self_notified
end
unless attributes && attributes.key?(:auto_watch_on)
self.auto_watch_on = AUTO_WATCH_ON_OPTIONS
end
end
self.others ||= {}
end
def set_others_hash
self.others ||= {}
end
def [](attr_name)
if has_attribute? attr_name
super
else
others ? others[attr_name] : nil
end
end
def []=(attr_name, value)
if has_attribute? attr_name
super
else
h = (read_attribute(:others) || {}).dup
h.update(attr_name => value)
write_attribute(:others, h)
value
end
end
def comments_sorting; self[:comments_sorting]; end
def comments_sorting=(order); self[:comments_sorting]=order; end
def warn_on_leaving_unsaved; self[:warn_on_leaving_unsaved] || '1'; end
def warn_on_leaving_unsaved=(value); self[:warn_on_leaving_unsaved]=value; end
def no_self_notified; (self[:no_self_notified] == true || self[:no_self_notified] == '1'); end
def no_self_notified=(value); self[:no_self_notified]=value; end
def notify_about_high_priority_issues; (self[:notify_about_high_priority_issues] == true || self[:notify_about_high_priority_issues] == '1'); end
def notify_about_high_priority_issues=(value); self[:notify_about_high_priority_issues]=value; end
def activity_scope; Array(self[:activity_scope]); end
def activity_scope=(value); self[:activity_scope]=value; end
def textarea_font; self[:textarea_font]; end
def textarea_font=(value); self[:textarea_font]=value; end
def recently_used_projects; (self[:recently_used_projects] || 3).to_i; end
def recently_used_projects=(value); self[:recently_used_projects] = value.to_i; end
def history_default_tab; self[:history_default_tab]; end
def history_default_tab=(value); self[:history_default_tab]=value; end
def toolbar_language_options
self[:toolbar_language_options].presence || DEFAULT_TOOLBAR_LANGUAGE_OPTIONS.join(',')
end
def toolbar_language_options=(value)
languages =
value.to_s.delete(' ').split(',').select do |lang|
Redmine::SyntaxHighlighting.language_supported?(lang)
end.compact
self[:toolbar_language_options] = languages.join(',')
end
def default_issue_query; self[:default_issue_query] end
def default_issue_query=(value); self[:default_issue_query]=value; end
def default_project_query; self[:default_project_query] end
def default_project_query=(value); self[:default_project_query]=value; end
def auto_watch_on; self[:auto_watch_on] || []; end
def auto_watch_on=(values); self[:auto_watch_on]=values; end
def auto_watch_on?(action); self.auto_watch_on.include?(action.to_s); end
# Returns the names of groups that are displayed on user's page
# Example:
# preferences.my_page_groups
# # => ['top', 'left, 'right']
def my_page_groups
Redmine::MyPage.groups
end
def my_page_layout
self[:my_page_layout] ||= Redmine::MyPage.default_layout.deep_dup
end
def my_page_layout=(arg)
self[:my_page_layout] = arg
end
def my_page_settings(block=nil)
s = self[:my_page_settings] ||= {}
if block
s[block] ||= {}
else
s
end
end
def my_page_settings=(arg)
self[:my_page_settings] = arg
end
# Removes block from the user page layout
# Example:
# preferences.remove_block('news')
def remove_block(block)
block = block.to_s.underscore
my_page_layout.each_key do |group|
my_page_layout[group].delete(block)
end
my_page_layout
end
# Adds block to the user page layout
# Returns nil if block is not valid or if it's already
# present in the user page layout
def add_block(block)
block = block.to_s.underscore
return unless Redmine::MyPage.valid_block?(block, my_page_layout.values.flatten)
remove_block(block)
# add it to the first group
group = my_page_groups.first
my_page_layout[group] ||= []
my_page_layout[group].unshift(block)
end
# Sets the block order for the given group.
# Example:
# preferences.order_blocks('left', ['issueswatched', 'news'])
def order_blocks(group, blocks)
group = group.to_s
if Redmine::MyPage.groups.include?(group) && blocks.present?
blocks = blocks.map(&:underscore) & my_page_layout.values.flatten
blocks.each {|block| remove_block(block)}
my_page_layout[group] = blocks
end
end
def update_block_settings(block, settings)
block = block.to_s
block_settings = my_page_settings(block).merge(settings.symbolize_keys)
my_page_settings[block] = block_settings
end
def clear_unused_block_settings
blocks = my_page_layout.values.flatten
my_page_settings.keep_if {|block, settings| blocks.include?(block)}
end
private :clear_unused_block_settings
end
|