maint: prefer functions over methods
[git-cola.git] / cola / widgets / prefs.py
blobc2e0570f438834e5c6d09498dbcba2d0bffecad2
1 from __future__ import division, absolute_import, unicode_literals
2 import os
4 from qtpy import QtCore
5 from qtpy import QtWidgets
7 from . import defs
8 from . import standard
9 from .. import cmds
10 from .. import qtutils
11 from ..i18n import N_
12 from ..models import prefs
13 from ..models.prefs import Defaults
16 def preferences(context, model=None, parent=None):
17 if model is None:
18 model = prefs.PreferencesModel(context)
19 view = PreferencesView(context, model, parent=parent)
20 view.show()
21 view.raise_()
22 return view
25 class FormWidget(QtWidgets.QWidget):
27 def __init__(self, context, model, parent, source='user'):
28 QtWidgets.QWidget.__init__(self, parent)
29 self.context = context
30 self.cfg = context.cfg
31 self.model = model
32 self.config_to_widget = {}
33 self.widget_to_config = {}
34 self.source = source
35 self.defaults = {}
36 self.setLayout(QtWidgets.QFormLayout())
38 def add_row(self, label, widget):
39 self.layout().addRow(label, widget)
41 def set_config(self, config_dict):
42 self.config_to_widget.update(config_dict)
43 for config, (widget, default) in config_dict.items():
44 self.widget_to_config[config] = widget
45 self.defaults[config] = default
46 self.connect_widget_to_config(widget, config)
48 def connect_widget_to_config(self, widget, config):
49 if isinstance(widget, QtWidgets.QSpinBox):
50 widget.valueChanged.connect(self._int_config_changed(config))
52 elif isinstance(widget, QtWidgets.QCheckBox):
53 widget.toggled.connect(self._bool_config_changed(config))
55 elif isinstance(widget, QtWidgets.QLineEdit):
56 widget.editingFinished.connect(
57 self._text_config_changed(config, widget))
58 widget.returnPressed.connect(
59 self._text_config_changed(config, widget))
61 def _int_config_changed(self, config):
62 def runner(value):
63 cmds.do(prefs.SetConfig, self.model, self.source, config, value)
64 return runner
66 def _bool_config_changed(self, config):
67 def runner(value):
68 cmds.do(prefs.SetConfig, self.model, self.source, config, value)
69 return runner
71 def _text_config_changed(self, config, widget):
72 def runner():
73 value = widget.text()
74 cmds.do(prefs.SetConfig, self.model, self.source, config, value)
75 return runner
77 def update_from_config(self):
78 if self.source == 'user':
79 getter = self.cfg.get_user_or_system
80 else:
81 getter = self.cfg.get
83 for config, widget in self.widget_to_config.items():
84 value = getter(config)
85 if value is None:
86 value = self.defaults[config]
87 set_widget_value(widget, value)
90 def set_widget_value(widget, value):
91 widget.blockSignals(True)
92 if isinstance(widget, QtWidgets.QSpinBox):
93 widget.setValue(value)
94 elif isinstance(widget, QtWidgets.QLineEdit):
95 widget.setText(value)
96 elif isinstance(widget, QtWidgets.QCheckBox):
97 widget.setChecked(value)
98 widget.blockSignals(False)
101 class RepoFormWidget(FormWidget):
103 def __init__(self, context, model, parent, source):
104 FormWidget.__init__(self, context, model, parent, source=source)
105 self.name = QtWidgets.QLineEdit()
106 self.email = QtWidgets.QLineEdit()
108 self.diff_context = standard.SpinBox(value=5, mini=2, maxi=9995)
109 self.merge_verbosity = standard.SpinBox(value=5, maxi=5)
110 self.merge_summary = qtutils.checkbox(checked=True)
111 self.merge_diffstat = qtutils.checkbox(checked=True)
112 self.display_untracked = qtutils.checkbox(checked=True)
113 self.show_path = qtutils.checkbox(checked=True)
114 self.tabwidth = standard.SpinBox(value=8, maxi=42)
115 self.textwidth = standard.SpinBox(value=72, maxi=150)
117 tooltip = N_('Detect conflict markers in unmerged files')
118 self.check_conflicts = qtutils.checkbox(checked=True, tooltip=tooltip)
120 tooltip = N_(
121 'Prevent "Stage" from staging all files when nothing is selected')
122 self.safe_mode = qtutils.checkbox(checked=False, tooltip=tooltip)
124 self.add_row(N_('User Name'), self.name)
125 self.add_row(N_('Email Address'), self.email)
126 self.add_row(N_('Tab Width'), self.tabwidth)
127 self.add_row(N_('Text Width'), self.textwidth)
128 self.add_row(N_('Merge Verbosity'), self.merge_verbosity)
129 self.add_row(N_('Number of Diff Context Lines'), self.diff_context)
130 self.add_row(N_('Summarize Merge Commits'), self.merge_summary)
131 self.add_row(N_('Show Full Paths in the Window Title'), self.show_path)
132 self.add_row(N_('Show Diffstat After Merge'), self.merge_diffstat)
133 self.add_row(N_('Display Untracked Files'), self.display_untracked)
134 self.add_row(N_('Detect Conflict Markers'), self.check_conflicts)
135 self.add_row(N_('Safe Mode'), self.safe_mode)
137 self.set_config({
138 prefs.CHECKCONFLICTS:
139 (self.check_conflicts, Defaults.check_conflicts),
140 prefs.DIFFCONTEXT: (self.diff_context, Defaults.diff_context),
141 prefs.DISPLAY_UNTRACKED:
142 (self.display_untracked, Defaults.display_untracked),
143 prefs.USER_NAME: (self.name, ''),
144 prefs.USER_EMAIL: (self.email, ''),
145 prefs.MERGE_DIFFSTAT:
146 (self.merge_diffstat, Defaults.merge_diffstat),
147 prefs.MERGE_SUMMARY: (self.merge_summary, Defaults.merge_summary),
148 prefs.MERGE_VERBOSITY:
149 (self.merge_verbosity, Defaults.merge_verbosity),
150 prefs.SAFE_MODE: (self.safe_mode, Defaults.safe_mode),
151 prefs.SHOW_PATH: (self.show_path, Defaults.show_path),
152 prefs.TABWIDTH: (self.tabwidth, Defaults.tabwidth),
153 prefs.TEXTWIDTH: (self.textwidth, Defaults.textwidth),
157 class SettingsFormWidget(FormWidget):
159 def __init__(self, context, model, parent):
160 FormWidget.__init__(self, context, model, parent)
162 self.fixed_font = QtWidgets.QFontComboBox()
163 self.font_size = standard.SpinBox(value=12, mini=8, maxi=192)
165 self.maxrecent = standard.SpinBox(maxi=99)
166 self.tabwidth = standard.SpinBox(maxi=42)
167 self.textwidth = standard.SpinBox(maxi=150)
169 self.editor = QtWidgets.QLineEdit()
170 self.historybrowser = QtWidgets.QLineEdit()
171 self.blameviewer = QtWidgets.QLineEdit()
172 self.difftool = QtWidgets.QLineEdit()
173 self.mergetool = QtWidgets.QLineEdit()
175 self.linebreak = qtutils.checkbox()
176 self.keep_merge_backups = qtutils.checkbox()
177 self.sort_bookmarks = qtutils.checkbox()
178 self.bold_headers = qtutils.checkbox()
179 self.save_window_settings = qtutils.checkbox()
180 self.check_spelling = qtutils.checkbox()
181 self.expandtab = qtutils.checkbox()
183 self.add_row(N_('Fixed-Width Font'), self.fixed_font)
184 self.add_row(N_('Font Size'), self.font_size)
185 self.add_row(N_('Editor'), self.editor)
186 self.add_row(N_('History Browser'), self.historybrowser)
187 self.add_row(N_('Blame Viewer'), self.blameviewer)
188 self.add_row(N_('Diff Tool'), self.difftool)
189 self.add_row(N_('Merge Tool'), self.mergetool)
190 self.add_row(N_('Recent repository count'), self.maxrecent)
191 self.add_row(N_('Auto-Wrap Lines'), self.linebreak)
192 self.add_row(N_('Insert spaces instead of tabs'), self.expandtab)
193 self.add_row(N_('Sort bookmarks alphabetically'), self.sort_bookmarks)
194 self.add_row(N_('Keep *.orig Merge Backups'), self.keep_merge_backups)
195 self.add_row(N_('Bold on dark headers instead of italic '
196 '(restart required)'), self.bold_headers)
197 self.add_row(N_('Save GUI Settings'), self.save_window_settings)
198 self.add_row(N_('Check spelling'), self.check_spelling)
200 self.set_config({
201 prefs.SAVEWINDOWSETTINGS:
202 (self.save_window_settings, Defaults.save_window_settings),
203 prefs.TABWIDTH: (self.tabwidth, Defaults.tabwidth),
204 prefs.EXPANDTAB: (self.expandtab, Defaults.expandtab),
205 prefs.TEXTWIDTH: (self.textwidth, Defaults.textwidth),
206 prefs.LINEBREAK: (self.linebreak, Defaults.linebreak),
207 prefs.MAXRECENT: (self.maxrecent, Defaults.maxrecent),
208 prefs.SORT_BOOKMARKS:
209 (self.sort_bookmarks, Defaults.sort_bookmarks),
210 prefs.BOLD_HEADERS: (self.bold_headers, Defaults.bold_headers),
211 prefs.DIFFTOOL: (self.difftool, Defaults.difftool),
212 prefs.EDITOR:
213 (self.editor, os.getenv('VISUAL', Defaults.editor)),
214 prefs.HISTORY_BROWSER:
215 (self.historybrowser, prefs.default_history_browser()),
216 prefs.BLAME_VIEWER: (self.blameviewer, Defaults.blame_viewer),
217 prefs.MERGE_KEEPBACKUP:
218 (self.keep_merge_backups, Defaults.merge_keep_backup),
219 prefs.MERGETOOL: (self.mergetool, Defaults.mergetool),
220 prefs.SPELL_CHECK: (self.check_spelling, Defaults.spellcheck),
223 self.fixed_font.currentFontChanged.connect(self.current_font_changed)
224 self.font_size.valueChanged.connect(self.font_size_changed)
226 def update_from_config(self):
227 FormWidget.update_from_config(self)
228 context = self.context
229 block = self.fixed_font.blockSignals(True)
230 font = qtutils.diff_font(context)
231 self.fixed_font.setCurrentFont(font)
232 self.fixed_font.blockSignals(block)
234 block = self.font_size.blockSignals(True)
235 font_size = font.pointSize()
236 self.font_size.setValue(font_size)
237 self.font_size.blockSignals(block)
239 def font_size_changed(self, size):
240 font = self.fixed_font.currentFont()
241 font.setPointSize(size)
242 cmds.do(prefs.SetConfig, self.model,
243 'user', prefs.FONTDIFF, font.toString())
245 def current_font_changed(self, font):
246 cmds.do(prefs.SetConfig, self.model,
247 'user', prefs.FONTDIFF, font.toString())
250 class PreferencesView(standard.Dialog):
252 def __init__(self, context, model, parent=None):
253 standard.Dialog.__init__(self, parent=parent)
254 self.context = context
255 self.setWindowTitle(N_('Preferences'))
256 if parent is not None:
257 self.setWindowModality(QtCore.Qt.WindowModal)
259 self.resize(600, 360)
261 self.tab_bar = QtWidgets.QTabBar()
262 self.tab_bar.setDrawBase(False)
263 self.tab_bar.addTab(N_('All Repositories'))
264 self.tab_bar.addTab(N_('Current Repository'))
265 self.tab_bar.addTab(N_('Settings'))
267 self.user_form = RepoFormWidget(context, model, self, source='user')
268 self.repo_form = RepoFormWidget(context, model, self, source='repo')
269 self.options_form = SettingsFormWidget(context, model, self)
271 self.stack_widget = QtWidgets.QStackedWidget()
272 self.stack_widget.addWidget(self.user_form)
273 self.stack_widget.addWidget(self.repo_form)
274 self.stack_widget.addWidget(self.options_form)
276 self.close_button = qtutils.close_button()
278 self.button_layout = qtutils.hbox(defs.no_margin, defs.spacing,
279 qtutils.STRETCH, self.close_button)
281 self.main_layout = qtutils.vbox(defs.margin, defs.spacing,
282 self.tab_bar, self.stack_widget,
283 self.button_layout)
284 self.setLayout(self.main_layout)
286 self.tab_bar.currentChanged.connect(self.stack_widget.setCurrentIndex)
287 self.stack_widget.currentChanged.connect(self.update_widget)
289 qtutils.connect_button(self.close_button, self.accept)
290 qtutils.add_close_action(self)
292 self.update_widget(0)
294 def update_widget(self, idx):
295 widget = self.stack_widget.widget(idx)
296 widget.update_from_config()