PageRenderTime 62ms CodeModel.GetById 15ms app.highlight 42ms RepoModel.GetById 1ms app.codeStats 0ms

/tortoisehg/hgqt/shellconf.py

https://bitbucket.org/tortoisehg/hgtk/
Python | 302 lines | 265 code | 25 blank | 12 comment | 17 complexity | 434d28fb3557f82f31c07d0054cbb494 MD5 | raw file
  1# shellconf.py - User interface for the TortoiseHg shell extension settings
  2#
  3# Copyright 2009 Steve Borho <steve@borho.org>
  4# Copyright 2010 Adrian Buehlmann <adrian@cadifra.com>
  5#
  6# This software may be used and distributed according to the terms of the
  7# GNU General Public License version 2 or any later version.
  8
  9import sys
 10
 11from tortoisehg.hgqt.i18n import _
 12from tortoisehg.util import menuthg, hglib
 13
 14from PyQt4.QtCore import *
 15from PyQt4.QtGui import *
 16
 17from _winreg import (HKEY_CURRENT_USER, REG_SZ, REG_DWORD,
 18                     OpenKey, CreateKey, QueryValueEx, SetValueEx)
 19
 20THGKEY = 'TortoiseHg'
 21OVLKEY = 'TortoiseOverlays'
 22PROMOTEDITEMS = 'PromotedItems'
 23
 24# reading functions
 25def is_true(x): return x in ('1', 'True')
 26def nonzero(x): return x != 0
 27
 28# writing functions
 29def one_str(x):
 30    if x: return '1'
 31    return '0'
 32def one_int(x):
 33    if x: return 1
 34    return 0
 35
 36def noop(x): return x
 37
 38vars = {
 39    # name:
 40    #   default, regkey, regtype, evalfunc, wrfunc, checkbuttonattribute
 41    'EnableOverlays':
 42        [True,     THGKEY, REG_SZ, is_true, one_str, 'ovenable'],
 43    'LocalDisksOnly':
 44        [False,    THGKEY, REG_SZ, is_true, one_str, 'localonly'],
 45    'ShowTaskbarIcon':
 46        [True,     THGKEY, REG_SZ, is_true, one_str, 'show_taskbaricon'],
 47    'HighlightTaskbarIcon':
 48        [True,     THGKEY, REG_SZ, is_true, one_str, 'highlight_taskbaricon'],
 49    'HideMenuOutsideRepo':
 50        [False,    THGKEY, REG_SZ, is_true, one_str, 'hidecmenu'],
 51    PROMOTEDITEMS:
 52        ['commit', THGKEY, REG_SZ, noop, noop, None],
 53    'ShowUnversionedOverlay':
 54        [True, OVLKEY, REG_DWORD, nonzero, one_int, 'enableUnversionedHandler'],
 55    'ShowIgnoredOverlay':
 56        [True, OVLKEY, REG_DWORD, nonzero, one_int, 'enableIgnoredHandler'],
 57    'ShowLockedOverlay':
 58        [True, OVLKEY, REG_DWORD, nonzero, one_int, 'enableLockedHandler'],
 59    'ShowReadonlyOverlay':
 60        [True, OVLKEY, REG_DWORD, nonzero, one_int, 'enableReadonlyHandler'],
 61    'ShowDeletedOverlay':
 62        [True, OVLKEY, REG_DWORD, nonzero, one_int, 'enableDeletedHandler'],
 63    'ShowAddedOverlay':
 64        [True, OVLKEY, REG_DWORD, nonzero, one_int, 'enableAddedHandler']
 65}
 66
 67
 68class ShellConfigWindow(QDialog):
 69
 70    def __init__(self, parent=None):
 71        super(ShellConfigWindow, self).__init__(parent)
 72
 73        self.menu_cmds = {}
 74        self.dirty = False
 75
 76        layout = QVBoxLayout()
 77
 78        tw = QTabWidget()
 79        layout.addWidget(tw)
 80
 81        # cmenu tab
 82        cmenuwidget = QWidget()
 83        grid = QGridLayout()
 84        cmenuwidget.setLayout(grid)
 85        tw.addTab(cmenuwidget, _("Contex Menu"))
 86
 87        w = QLabel(_("Top menu items:"))
 88        grid.addWidget(w, 0, 0)
 89        self.topmenulist = w = QListWidget()
 90        grid.addWidget(w, 1, 0, 4, 1)
 91        w.itemClicked.connect(self.listItemClicked)
 92
 93        w = QLabel(_("Sub menu items:"))
 94        grid.addWidget(w, 0, 2)
 95        self.submenulist = w = QListWidget()
 96        grid.addWidget(w, 1, 2, 4, 1)
 97        w.itemClicked.connect(self.listItemClicked)
 98
 99        style = QApplication.style()
100        icon = style.standardIcon(QStyle.SP_ArrowLeft)
101        self.top_button = w = QPushButton(icon, '')
102        grid.addWidget(w, 2, 1)
103        w.clicked.connect(self.top_clicked)
104        icon = style.standardIcon(QStyle.SP_ArrowRight)
105        self.sub_button = w = QPushButton(icon, '')
106        grid.addWidget(w, 3, 1)
107        w.clicked.connect(self.sub_clicked)
108
109        grid.setRowStretch(1, 10)
110        grid.setRowStretch(4, 10)
111
112        def checkbox(label):
113            cb = QCheckBox(label)
114            cb.stateChanged.connect(self.stateChanged)
115            return cb
116
117        hidebox = QGroupBox(_('Menu Behavior'))
118        grid.addWidget(hidebox, 5, 0, 5, 3)
119        self.hidecmenu = checkbox(_('Hide context menu outside repositories'))
120        self.hidecmenu.setToolTip(_('Do not show menu items on unversioned '
121                                    'folders (use shift + click to override)'))
122        hidebox.setLayout(QVBoxLayout())
123        hidebox.layout().addWidget(self.hidecmenu)
124
125        # Icons tab
126        iconswidget = QWidget()
127        iconslayout = QVBoxLayout()
128        iconswidget.setLayout(iconslayout)
129        tw.addTab(iconswidget, _("Icons"))
130
131        # Overlays group
132        gbox = QGroupBox(_("Overlays"))
133        iconslayout.addWidget(gbox)
134        hb = QHBoxLayout()
135        gbox.setLayout(hb)
136        self.ovenable = cb = checkbox(_("Enabled overlays"))
137        hb.addWidget(cb)
138        self.localonly = checkbox(_("Local disks only"))
139        hb.addWidget(self.localonly)
140        hb.addStretch()
141
142        # Enabled Overlay Handlers group
143        gbox = QGroupBox(_("Enabled Overlay Handlers"))
144        iconslayout.addWidget(gbox)
145        grid = QGridLayout()
146        gbox.setLayout(grid)
147        grid.setColumnStretch(3, 10)
148        w = QLabel(_("Warning: affects all Tortoises, logoff required after change"))
149        grid.addWidget(w, 0, 0, 1, 3)
150        self.enableAddedHandler = w = checkbox(_("Added"))
151        grid.addWidget(w, 1, 0)
152        self.enableLockedHandler = w = checkbox(_("Locked*"))
153        grid.addWidget(w, 1, 1)
154        self.enableIgnoredHandler = w = checkbox(_("Ignored*"))
155        grid.addWidget(w, 1, 2)
156        self.enableUnversionedHandler = w = checkbox(_("Unversioned"))
157        grid.addWidget(w, 2, 0)
158        self.enableReadonlyHandler = w = checkbox(_("Readonly*"))
159        grid.addWidget(w, 2, 1)
160        self.enableDeletedHandler = w = checkbox(_("Deleted*"))
161        grid.addWidget(w, 2, 2)
162        w = QLabel(_("*: not used by TortoiseHg"))
163        grid.addWidget(w, 3, 0, 1, 3)
164
165        # Taskbar group
166        gbox = QGroupBox(_("Taskbar"))
167        iconslayout.addWidget(gbox)
168        hb = QHBoxLayout()
169        gbox.setLayout(hb)
170        self.show_taskbaricon = cb = checkbox(_("Show Icon"))
171        hb.addWidget(cb)
172        self.highlight_taskbaricon = cb = checkbox(_("Highlight Icon"))
173        hb.addWidget(cb)
174        hb.addStretch()
175
176        iconslayout.addStretch()
177
178        # dialog buttons
179        BB = QDialogButtonBox
180        bb = QDialogButtonBox(BB.Ok|BB.Cancel|BB.Apply)
181        self.apply_button = bb.button(BB.Apply)
182        bb.accepted.connect(self.accept)
183        bb.rejected.connect(self.reject)
184        bb.button(BB.Apply).clicked.connect(self.apply)
185        bb.button(BB.Ok).setDefault(True)
186        layout.addWidget(bb)
187
188        self.setLayout(layout)
189        self.setWindowTitle(_("TortoiseHg Shell Configuration"))
190
191        self.load_shell_configs()
192
193    def load_shell_configs(self):
194        for name, info in vars.iteritems():
195            default, regkey, regtype, evalfunc, wrfunc, cbattr = info
196            try:
197                hkey = OpenKey(HKEY_CURRENT_USER, 'Software\\' + regkey)
198                v = QueryValueEx(hkey, name)[0]
199                vars[name][0] = evalfunc(v)
200            except (WindowsError, EnvironmentError):
201                pass
202            if cbattr != None:
203                checkbutton = getattr(self, cbattr)
204                checkbutton.setChecked(vars[name][0])
205
206        promoteditems = vars[PROMOTEDITEMS][0]
207        self.set_menulists(promoteditems)
208
209        self.dirty = False
210        self.update_states()
211
212    def set_menulists(self, promoteditems):
213        for list in (self.topmenulist, self.submenulist):
214            list.clear()
215            list.setSortingEnabled(True)
216        promoted = [pi.strip() for pi in promoteditems.split(',')]
217        for cmd, info in menuthg.thgcmenu.items():
218            label = info['label']
219            item = QListWidgetItem(hglib.tounicode(label['str']))
220            item._id = label['id']
221            if cmd in promoted:
222                self.topmenulist.addItem(item)
223            else:
224                self.submenulist.addItem(item)
225            self.menu_cmds[item._id] = cmd
226
227    def store_shell_configs(self):
228        if not  self.dirty:
229            return
230
231        promoted = []
232        list = self.topmenulist
233        for row in range(list.count()):
234            cmd = self.menu_cmds[list.item(row)._id]
235            promoted.append(cmd)
236
237        hkey = CreateKey(HKEY_CURRENT_USER, "Software\\" + THGKEY)
238        SetValueEx(hkey, PROMOTEDITEMS, 0, REG_SZ, ','.join(promoted))
239
240        for name, info in vars.iteritems():
241            default, regkey, regtype, evalfunc, wrfunc, cbattr = info
242            if cbattr == None:
243                continue
244            checkbutton = getattr(self, cbattr)
245            v = wrfunc(checkbutton.isChecked())
246            hkey = CreateKey(HKEY_CURRENT_USER, 'Software\\' + regkey)
247            SetValueEx(hkey, name, 0, regtype, v)
248
249        self.dirty = False
250        self.update_states()
251
252    def accept(self):
253        self.store_shell_configs()
254        QDialog.accept(self)
255
256    def reject(self):
257        QDialog.reject(self)
258
259    def apply(self):
260        self.store_shell_configs()
261
262    def top_clicked(self):
263        self.move_selected(self.submenulist, self.topmenulist)
264
265    def sub_clicked(self):
266        self.move_selected(self.topmenulist, self.submenulist)
267
268    def move_selected(self, fromlist, tolist):
269        row = fromlist.currentRow()
270        if row < 0:
271            return
272        item = fromlist.takeItem(row)
273        tolist.addItem(item)
274        tolist.setCurrentItem(item)
275        fromlist.setCurrentItem(None)
276        self.dirty = True
277        self.update_states()
278
279    def update_states(self):
280        self.top_button.setEnabled(len(self.submenulist.selectedItems()) > 0)
281        self.sub_button.setEnabled(len(self.topmenulist.selectedItems()) > 0)
282        self.apply_button.setEnabled(self.dirty)
283
284    def stateChanged(self, state):
285        self.dirty = True
286        self.update_states()
287
288    def listItemClicked(self, item):
289        itemlist = item.listWidget()
290        for list in (self.topmenulist, self.submenulist):
291            if list != itemlist:
292                list.setCurrentItem(None)
293        self.update_states()
294
295def run(ui, *pats, **opts):
296    return ShellConfigWindow()
297
298if __name__ == "__main__":
299    app = QApplication(sys.argv)
300    form = ShellConfigWindow()
301    form.show()
302    app.exec_()