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 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2019 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. 'toolbar_language_options')
  35. TEXTAREA_FONT_OPTIONS = ['monospace', 'proportional']
  36. 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]
  37. def initialize(attributes=nil, *args)
  38. super
  39. if new_record?
  40. unless attributes && attributes.key?(:hide_mail)
  41. self.hide_mail = Setting.default_users_hide_mail?
  42. end
  43. unless attributes && attributes.key?(:time_zone)
  44. self.time_zone = Setting.default_users_time_zone
  45. end
  46. unless attributes && attributes.key?(:no_self_notified)
  47. self.no_self_notified = true
  48. end
  49. end
  50. self.others ||= {}
  51. end
  52. def set_others_hash
  53. self.others ||= {}
  54. end
  55. def [](attr_name)
  56. if has_attribute? attr_name
  57. super
  58. else
  59. others ? others[attr_name] : nil
  60. end
  61. end
  62. def []=(attr_name, value)
  63. if has_attribute? attr_name
  64. super
  65. else
  66. h = (read_attribute(:others) || {}).dup
  67. h.update(attr_name => value)
  68. write_attribute(:others, h)
  69. value
  70. end
  71. end
  72. def comments_sorting; self[:comments_sorting] end
  73. def comments_sorting=(order); self[:comments_sorting]=order end
  74. def warn_on_leaving_unsaved; self[:warn_on_leaving_unsaved] || '1'; end
  75. def warn_on_leaving_unsaved=(value); self[:warn_on_leaving_unsaved]=value; end
  76. def no_self_notified; (self[:no_self_notified] == true || self[:no_self_notified] == '1'); end
  77. def no_self_notified=(value); self[:no_self_notified]=value; end
  78. def notify_about_high_priority_issues; (self[:notify_about_high_priority_issues] == true || self[:notify_about_high_priority_issues] == '1'); end
  79. def notify_about_high_priority_issues=(value); self[:notify_about_high_priority_issues]=value; end
  80. def activity_scope; Array(self[:activity_scope]) ; end
  81. def activity_scope=(value); self[:activity_scope]=value ; end
  82. def textarea_font; self[:textarea_font] end
  83. def textarea_font=(value); self[:textarea_font]=value; end
  84. def recently_used_projects; (self[:recently_used_projects] || 3).to_i; end
  85. def recently_used_projects=(value); self[:recently_used_projects] = value.to_i; end
  86. def history_default_tab; self[:history_default_tab]; end
  87. def history_default_tab=(value); self[:history_default_tab]=value; end
  88. def toolbar_language_options
  89. self[:toolbar_language_options].presence || DEFAULT_TOOLBAR_LANGUAGE_OPTIONS.join(',')
  90. end
  91. def toolbar_language_options=(value)
  92. languages = value.to_s.delete(' ').split(',').select{|lang| Redmine::SyntaxHighlighting.language_supported?(lang) }.compact
  93. self[:toolbar_language_options] = languages.join(',')
  94. end
  95. # Returns the names of groups that are displayed on user's page
  96. # Example:
  97. # preferences.my_page_groups
  98. # # => ['top', 'left, 'right']
  99. def my_page_groups
  100. Redmine::MyPage.groups
  101. end
  102. def my_page_layout
  103. self[:my_page_layout] ||= Redmine::MyPage.default_layout.deep_dup
  104. end
  105. def my_page_layout=(arg)
  106. self[:my_page_layout] = arg
  107. end
  108. def my_page_settings(block=nil)
  109. s = self[:my_page_settings] ||= {}
  110. if block
  111. s[block] ||= {}
  112. else
  113. s
  114. end
  115. end
  116. def my_page_settings=(arg)
  117. self[:my_page_settings] = arg
  118. end
  119. # Removes block from the user page layout
  120. # Example:
  121. # preferences.remove_block('news')
  122. def remove_block(block)
  123. block = block.to_s.underscore
  124. my_page_layout.each_key do |group|
  125. my_page_layout[group].delete(block)
  126. end
  127. my_page_layout
  128. end
  129. # Adds block to the user page layout
  130. # Returns nil if block is not valid or if it's already
  131. # present in the user page layout
  132. def add_block(block)
  133. block = block.to_s.underscore
  134. return unless Redmine::MyPage.valid_block?(block, my_page_layout.values.flatten)
  135. remove_block(block)
  136. # add it to the first group
  137. group = my_page_groups.first
  138. my_page_layout[group] ||= []
  139. my_page_layout[group].unshift(block)
  140. end
  141. # Sets the block order for the given group.
  142. # Example:
  143. # preferences.order_blocks('left', ['issueswatched', 'news'])
  144. def order_blocks(group, blocks)
  145. group = group.to_s
  146. if Redmine::MyPage.groups.include?(group) && blocks.present?
  147. blocks = blocks.map(&:underscore) & my_page_layout.values.flatten
  148. blocks.each {|block| remove_block(block)}
  149. my_page_layout[group] = blocks
  150. end
  151. end
  152. def update_block_settings(block, settings)
  153. block = block.to_s
  154. block_settings = my_page_settings(block).merge(settings.symbolize_keys)
  155. my_page_settings[block] = block_settings
  156. end
  157. def clear_unused_block_settings
  158. blocks = my_page_layout.values.flatten
  159. my_page_settings.keep_if {|block, settings| blocks.include?(block)}
  160. end
  161. private :clear_unused_block_settings
  162. end