Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 1.9, 1.9.1, and 1.9.2

settings: edit widgets manage their own history, large cleanups

Still not ready for general consumption

Changeset 9cf0160cb7b4

Parent bbd39bd7dc6a

by Steve Borho

Changes to one file · Browse files at 9cf0160cb7b4 Showing diff from parent bbd39bd7dc6a Diff from another changeset...

 
34
35
36
37
38
39
40
 
 
 
 
 
 
41
42
43
 
81
82
83
84
85
86
87
88
 
89
90
91
92
 
93
94
95
 
 
 
 
 
 
96
97
98
99
 
100
101
102
 
111
112
113
114
115
116
117
 
118
119
120
121
122
123
124
 
125
126
127
128
129
 
130
131
132
 
156
157
158
 
159
160
161
 
462
463
464
465
466
467
468
469
470
471
 
472
473
474
 
489
490
491
492
 
493
 
494
495
496
497
498
 
499
500
 
 
501
502
503
504
505
506
 
507
508
509
510
511
512
 
 
 
 
513
514
515
 
525
526
527
528
529
 
 
 
 
 
530
531
532
533
 
 
 
 
 
 
 
 
 
534
535
536
 
537
538
539
 
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
 
 
561
562
563
564
565
566
 
 
567
568
569
 
570
 
571
572
 
573
574
575
576
577
 
578
579
580
 
590
591
592
593
594
 
 
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
 
 
617
618
619
 
621
622
623
624
 
625
626
627
 
668
669
670
671
 
672
673
674
 
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
 
699
700
701
702
703
704
705
706
 
 
 
707
708
709
710
711
712
713
714
 
717
718
719
 
 
 
 
 
 
 
 
 
 
 
 
 
720
721
722
 
723
 
724
725
726
727
728
729
 
730
 
731
732
733
 
34
35
36
 
37
38
39
40
41
42
43
44
45
46
47
48
 
86
87
88
 
 
 
 
 
89
90
91
92
 
93
94
95
96
97
98
99
100
101
102
103
104
105
 
106
107
108
109
 
118
119
120
 
 
 
 
121
122
123
124
125
126
127
 
128
129
130
131
132
 
133
134
135
136
 
160
161
162
163
164
165
166
 
467
468
469
 
470
 
471
472
473
474
475
476
477
478
 
493
494
495
 
496
497
498
499
 
 
 
 
500
501
 
502
503
504
505
506
507
508
 
509
510
511
512
513
514
515
516
517
518
519
520
521
522
 
532
533
534
 
 
535
536
537
538
539
540
 
 
 
541
542
543
544
545
546
547
548
549
550
551
 
552
553
554
555
 
558
559
560
 
 
 
 
 
 
 
 
 
 
 
 
 
561
 
 
562
563
564
565
 
 
 
 
566
567
568
569
 
570
571
572
573
574
575
576
577
578
579
 
580
581
582
583
 
593
594
595
 
 
596
597
598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
600
601
602
603
 
605
606
607
 
608
609
610
611
 
652
653
654
 
655
656
657
658
 
667
668
669
 
 
 
 
 
 
 
670
671
672
673
674
 
675
676
 
 
677
 
 
 
 
678
679
680
681
682
 
 
 
683
684
685
 
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
 
706
707
708
709
710
711
712
713
 
714
715
716
717
718
719
@@ -34,10 +34,15 @@
  self.opts = opts   self.setEditable(opts.get('canedit', False))   self.setValidator(opts.get('validator', None)) - self.previous = []   self.defaults = opts.get('defaults', [])   self.curvalue = False   self.loaded = False + if 'nohist' in opts: + self.previous = [] + else: + settings = opts['settings'] + slist = settings.value('settings/'+opts['cpath']).toStringList() + self.previous = [s for s in slist]   self.resetList()     def resetList(self): @@ -81,22 +86,24 @@
    ## common APIs for all edit widgets   - def setHistory(self, oldvalues): - self.previous = oldvalues - self.resetList() - - def setCurValue(self, curvalue): + def setValue(self, curvalue):   self.curvalue = curvalue   self.resetList()   - def getValue(self): + def value(self):   utext = self.currentText()   if utext == _unspecstr:   return False + if 'nohist' in self.opts or utext in self.defaults + self.previous: + return hglib.fromunicode(utext) + self.previous.insert(0, utext) + self.previous = self.previous[:10] + settings = QSettings() + settings.setValue('settings/'+opts['cpath'], self.previous)   return hglib.fromunicode(utext)     def isDirty(self): - return self.getValue() != self.curvalue + return self.value() != self.curvalue    class PasswordEntry(QLineEdit):   def __init__(self, parent=None, **opts): @@ -111,22 +118,19 @@
    ## common APIs for all edit widgets   - def setHistory(self, oldvalues): - pass # orly? - - def setCurValue(self, curvalue): + def setValue(self, curvalue):   self.curvalue = curvalue   if curvalue:   self.setText(curvalue)   else:   self.setText('')   - def getValue(self): + def value(self):   utext = self.text()   return utext and hglib.fromunicode(utext) or False     def isDirty(self): - return self.getValue() != self.curvalue + return self.value() != self.curvalue    def genEditCombo(opts, defaults=[]):   # supplied opts keys: cpath, tooltip, descwidget, defaults @@ -156,6 +160,7 @@
   def genDeferredCombo(opts, func):   opts['defer'] = func + opts['nohist'] = True   return SettingsCombo(**opts)    def findDiffTools(): @@ -462,13 +467,12 @@
  bothbox.addWidget(pageList, 0)   bothbox.addWidget(stack, 1)   pageList.currentRowChanged.connect(stack.setCurrentIndex) - self.stack = stack   - self.dirty = False   self.pages = {}   self.stack = stack     s = QSettings() + self.settings = s   self.restoreGeometry(s.value('settings/geom').toByteArray())     desctext = QTextBrowser() @@ -489,27 +493,30 @@
  self.addPage(meta['name'])     combo.setCurrentIndex(configrepo and CONF_REPO or CONF_GLOBAL) - combo.currentIndexChanged.connect(self.refresh) + combo.currentIndexChanged.connect(self.fileselect)   self.refresh() + self.focusField(focus or 'ui.merge')   - # TODO: focus 'general' page or specified field - pageList.setCurrentRow(0) - - def fileselect(self, combo): + def fileselect(self, newindex):   'select another hgrc file' - if self.dirty: + combo = self.confcombo + if self.isDirty():   ret = qctlib.CustomPrompt(_('Confirm Switch'),   _('Switch after saving changes?'), self,   (_('&Save'), _('&Discard'), _('&Cancel')),   default=2, esc=2).run()   if ret == 2: - repo = combo.currentIndex() == CONF_GLOBAL + repo = newindex == CONF_GLOBAL   combo.setCurrentIndex(repo and CONF_REPO or CONF_GLOBAL)   return   elif ret == 0:   self.applyChanges()   self.refresh()   + def editClicked(self, button): + 'Open internal editor in stacked widget' + pass +   def refresh(self, *args):   # determine target config file   if self.confcombo.currentIndex() == CONF_REPO: @@ -525,15 +532,24 @@
  #set_tortoise_icon(self, 'settings_user.ico')     # refresh config values - self.ini = self.load_config(self.rcpath) - self.refreshHistory() + self.ini = self.loadIniFile(self.rcpath) + for info, widgets in self.pages.values(): + for row, (label, cpath, values, tooltip) in enumerate(info): + curvalue = self.readCPath(cpath) + widgets[row].setValue(curvalue)   - def editClicked(self, button): - 'Open internal editor in stacked widget' - pass + def isDirty(self): + if self.readonly: + return False + for info, widgets in self.pages.values(): + for w in widgets: + if w.isDirty(): + print w.opts['cpath'] + return True + return False     def reloadClicked(self, button): - if self.dirty: + if self.isDirty():   d = QMessageBox.question(self, _('Confirm Reload'),   _('Unsaved changes will be lost.\n'   'Do you want to reload?'), @@ -542,39 +558,26 @@
  return   self.refresh()   - def canExit(self): - if self.dirty and not self.readonly: - ret = qtlib.CustomPrompt(_('Confirm Exit'), - _('Apply changes before exit?'), self, - (_('&Yes'), _('&No (discard changes)'), - _ ('&Cancel')), default=2, esc=2).run() - if ret == 2: - return False - elif ret == 0: - self.applyChanges() - return True - return True -   def focusField(self, focusfield): - '''Set page and focus to requested datum''' - for meta, info in INFO: + 'Set page and focus to requested datum' + for i, (meta, info) in enumerate(INFO):   for n, (label, cpath, values, tip) in enumerate(info):   if cpath == focusfield: - name = meta['name'] - self.show_page(name) - widgets = self.pages[name][3] - widgets[n].grab_focus() + self.stack.setCurrentIndex(i) + self.pages[meta['name']][1][n].setFocus()   return   - def fillFrame(self, frame, info): + def fillFrame(self, info):   widgets = [] + frame = QFrame()   form = QFormLayout()   frame.setLayout(form) + self.stack.addWidget(frame)     # supplied opts keys: cpath, tooltip, descwidget, defaults   for row, (label, cpath, values, tooltip) in enumerate(info):   opts = {'label':label, 'cpath':cpath, 'tooltip':tooltip, - 'descwidget':self.desctext} + 'descwidget':self.desctext, 'settings':self.settings}   if isinstance(values, tuple):   func = values[0]   w = func(opts, values[1]) @@ -590,30 +593,11 @@
  if name == data[0]['name']:   meta, info = data   break - frame = QFrame() - widgets = self.fillFrame(frame, info) + widgets = self.fillFrame(info) + self.pages[name] = info, widgets   - # add to notebook - pagenum = self.stack.addWidget(frame) - self.pages[name] = (pagenum, info, frame, widgets) - - def refreshHistory(self, pagename=None): - # sotre modification status - prev_dirty = self.dirty - - # update configured values - if pagename is None: - pages = self.pages.values() - pages = [(key,) + data for key, data in self.pages.items()] - else: - pages = ((pagename,) + self.pages[pagename],) - for name, page_num, info, frame, widgets in pages: - for row, (label, cpath, values, tooltip) in enumerate(info): - curvalue = self.get_ini_config(cpath) - widgets[row].setCurValue(curvalue) - - def get_ini_config(self, cpath): - '''Retrieve a value from the parsed config file''' + def readCPath(self, cpath): + 'Retrieve a value from the parsed config file'   try:   # Presumes single section/key level depth   section, key = cpath.split('.', 1) @@ -621,7 +605,7 @@
  except KeyError:   return None   - def load_config(self, rcpath): + def loadIniFile(self, rcpath):   for fn in rcpath:   if os.path.exists(fn):   break @@ -668,7 +652,7 @@
  self.readonly = True   return cfg   - def recordNewValue(self, cpath, newvalue, keephistory=True): + def recordNewValue(self, cpath, newvalue):   # 'newvalue' is in local encoding   section, key = cpath.split('.', 1)   if newvalue == False: @@ -683,32 +667,19 @@
  else:   self.ini.new_namespace(section)   self.ini[section][key] = newvalue - if not keephistory: - return - if cpath not in self.history.get_keys(): - self.history.set_value(cpath, []) - elif newvalue in self.history.get_keys(): - self.history.get_value(cpath).remove(newvalue) - self.history.mrul(cpath).add(newvalue)     def applyChanges(self):   if self.readonly:   #dialog? Read only access, please install ...   return - print 'not ready to write yet' + print 'leave on training wheels'   return - # Reload history, since it may have been modified externally - self.history.read()   - # Flush changes on all pages - for page_num, info, vbox, widgets in self.pages.values(): - for n, (label, cpath, values, tip) in enumerate(info): - newvalue = hglib.fromutf(widgets[n].child.get_text()) + for info, widgets in self.pages.values(): + for row, (label, cpath, values, tip) in enumerate(info): + newvalue = widgets[row].value()   self.recordNewValue(cpath, newvalue)   - self.history.write() - self.refreshHistory() -   try:   f = open(self.fn, 'w')   f.write(str(self.ini)) @@ -717,17 +688,32 @@
  qtlib.WarningMsgBox(_('Unable to write configuration file'),   str(e), parent=self)   + def canExit(self): + if self.isDirty(): + ret = qtlib.CustomPrompt(_('Confirm Exit'), + _('Apply changes before exit?'), self, + (_('&Yes'), _('&No (discard changes)'), + _ ('&Cancel')), default=2, esc=2).run() + if ret == 2: + return False + elif ret == 0: + self.applyChanges() + return True + return True +   def accept(self):   self.applyChanges() - s = QSettings() + s = self.settings   s.setValue('settings/geom', self.saveGeometry()) + s.sync()   QDialog.accept(self)     def reject(self):   if not self.canExit():   return - s = QSettings() + s = self.settings   s.setValue('settings/geom', self.saveGeometry()) + s.sync()   QDialog.reject(self)    def run(ui, *pats, **opts):