You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

user_preference.rb 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2021 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require 'redmine/my_page'
  19. class UserPreference < ActiveRecord::Base
  20. include Redmine::SafeAttributes
  21. belongs_to :user
  22. serialize :others
  23. before_save :set_others_hash, :clear_unused_block_settings
  24. safe_attributes(
  25. 'hide_mail',
  26. 'time_zone',
  27. 'comments_sorting',
  28. 'warn_on_leaving_unsaved',
  29. 'no_self_notified',
  30. 'notify_about_high_priority_issues',
  31. 'textarea_font',
  32. 'recently_used_projects',
  33. 'history_default_tab',
  34. 'default_issue_query',
  35. 'default_project_query',
  36. 'toolbar_language_options')
  37. TEXTAREA_FONT_OPTIONS = ['monospace', 'proportional']
  38. 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]
  39. def initialize(attributes=nil, *args)
  40. super
  41. if new_record?
  42. unless attributes && attributes.key?(:hide_mail)
  43. self.hide_mail = Setting.default_users_hide_mail?
  44. end
  45. unless attributes && attributes.key?(:time_zone)
  46. self.time_zone = Setting.default_users_time_zone
  47. end
  48. unless attributes && attributes.key?(:no_self_notified)
  49. self.no_self_notified = Setting.default_users_no_self_notified
  50. end
  51. end
  52. self.others ||= {}
  53. end
  54. def set_others_hash
  55. self.others ||= {}
  56. end
  57. def [](attr_name)
  58. if has_attribute? attr_name
  59. super
  60. else
  61. others ? others[attr_name] : nil
  62. end
  63. end
  64. def []=(attr_name, value)
  65. if has_attribute? attr_name
  66. super
  67. else
  68. h = (read_attribute(:others) || {}).dup
  69. h.update(attr_name => value)
  70. write_attribute(:others, h)
  71. value
  72. end
  73. end
  74. def comments_sorting; self[:comments_sorting]; end
  75. def comments_sorting=(order); self[:comments_sorting]=order; end
  76. def warn_on_leaving_unsaved; self[:warn_on_leaving_unsaved] || '1'; end
  77. def warn_on_leaving_unsaved=(value); self[:warn_on_leaving_unsaved]=value; end
  78. def no_self_notified; (self[:no_self_notified] == true || self[:no_self_notified] == '1'); end
  79. def no_self_notified=(value); self[:no_self_notified]=value; end
  80. def notify_about_high_priority_issues; (self[:notify_about_high_priority_issues] == true || self[:notify_about_high_priority_issues] == '1'); end
  81. def notify_about_high_priority_issues=(value); self[:notify_about_high_priority_issues]=value; end
  82. def activity_scope; Array(self[:activity_scope]); end
  83. def activity_scope=(value); self[:activity_scope]=value; end
  84. def textarea_font; self[:textarea_font]; end
  85. def textarea_font=(value); self[:textarea_font]=value; end
  86. def recently_used_projects; (self[:recently_used_projects] || 3).to_i; end
  87. def recently_used_projects=(value); self[:recently_used_projects] = value.to_i; end
  88. def history_default_tab; self[:history_default_tab]; end
  89. def history_default_tab=(value); self[:history_default_tab]=value; end
  90. def toolbar_language_options
  91. self[:toolbar_language_options].presence || DEFAULT_TOOLBAR_LANGUAGE_OPTIONS.join(',')
  92. end
  93. def toolbar_language_options=(value)
  94. languages =
  95. value.to_s.delete(' ').split(',').select do |lang|
  96. Redmine::SyntaxHighlighting.language_supported?(lang)
  97. end.compact
  98. self[:toolbar_language_options] = languages.join(',')
  99. end
  100. def default_issue_query; self[:default_issue_query] end
  101. def default_issue_query=(value); self[:default_issue_query]=value; end
  102. def default_project_query; self[:default_project_query] end
  103. def default_project_query=(value); self[:default_project_query]=value; end
  104. # Returns the names of groups that are displayed on user's page
  105. # Example:
  106. # preferences.my_page_groups
  107. # # => ['top', 'left, 'right']
  108. def my_page_groups
  109. Redmine::MyPage.groups
  110. end
  111. def my_page_layout
  112. self[:my_page_layout] ||= Redmine::MyPage.default_layout.deep_dup
  113. end
  114. def my_page_layout=(arg)
  115. self[:my_page_layout] = arg
  116. end
  117. def my_page_settings(block=nil)
  118. s = self[:my_page_settings] ||= {}
  119. if block
  120. s[block] ||= {}
  121. else
  122. s
  123. end
  124. end
  125. def my_page_settings=(arg)
  126. self[:my_page_settings] = arg
  127. end
  128. # Removes block from the user page layout
  129. # Example:
  130. # preferences.remove_block('news')
  131. def remove_block(block)
  132. block = block.to_s.underscore
  133. my_page_layout.each_key do |group|
  134. my_page_layout[group].delete(block)
  135. end
  136. my_page_layout
  137. end
  138. # Adds block to the user page layout
  139. # Returns nil if block is not valid or if it's already
  140. # present in the user page layout
  141. def add_block(block)
  142. block = block.to_s.underscore
  143. return unless Redmine::MyPage.valid_block?(block, my_page_layout.values.flatten)
  144. remove_block(block)
  145. # add it to the first group
  146. group = my_page_groups.first
  147. my_page_layout[group] ||= []
  148. my_page_layout[group].unshift(block)
  149. end
  150. # Sets the block order for the given group.
  151. # Example:
  152. # preferences.order_blocks('left', ['issueswatched', 'news'])
  153. def order_blocks(group, blocks)
  154. group = group.to_s
  155. if Redmine::MyPage.groups.include?(group) && blocks.present?
  156. blocks = blocks.map(&:underscore) & my_page_layout.values.flatten
  157. blocks.each {|block| remove_block(block)}
  158. my_page_layout[group] = blocks
  159. end
  160. end
  161. def update_block_settings(block, settings)
  162. block = block.to_s
  163. block_settings = my_page_settings(block).merge(settings.symbolize_keys)
  164. my_page_settings[block] = block_settings
  165. end
  166. def clear_unused_block_settings
  167. blocks = my_page_layout.values.flatten
  168. my_page_settings.keep_if {|block, settings| blocks.include?(block)}
  169. end
  170. private :clear_unused_block_settings
  171. end