Coverage for pyilper/shortcutconfig.py: 91%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

147 statements  

1#!/usr/bin/python3 

2# -*- coding: utf-8 -*- 

3# shortcutconfig for pyILPER 

4# 

5# (c) 2018 Joachim Siebold 

6# 

7# This program is free software; you can redistribute it and/or 

8# modify it under the terms of the GNU General Public License 

9# as published by the Free Software Foundation; either version 2 

10# of the License, or (at your option) any later version. 

11# 

12# This program is distributed in the hope that it will be useful, 

13# but WITHOUT ANY WARRANTY; without even the implied warranty of 

14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

15# GNU General Public License for more details. 

16# 

17# You should have received a copy of the GNU General Public License 

18# along with this program; if not, write to the Free Software 

19# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 

20# 

21# shortcutconfig class ------------------------------------------- 

22# 

23# Changelog 

24# 11.08.2018 jsi 

25# - first version 

26# 15.08.2018 jsi 

27# - SHORTCUT_INSERT shortcut type added 

28# 12.12.2021 jsi 

29# - add configversion parameter to open method 

30# 

31import copy 

32from PySide6 import QtCore, QtGui, QtWidgets 

33from .userconfig import cls_userconfig, ConfigError 

34 

35SHORTCUT_INPUT=0 

36SHORTCUT_EXEC=1 

37SHORTCUT_EDIT=2 

38SHORTCUT_INSERT=3 

39# 

40# Terminal shortcut table model class ----------------------------------------- 

41# 

42class ShortcutTableModel(QtCore.QAbstractTableModel): 

43 def __init__(self, datain, parent = None): 

44 super().__init__() 

45 self.arraydata = datain 

46 

47 def rowCount(self, parent): 

48 return len(self.arraydata) 

49 

50 def columnCount(self, parent): 

51 return len(self.arraydata[0]) 

52 

53 def data(self, index, role): 

54 if not index.isValid(): 

55 return None 

56 elif role != QtCore.Qt.DisplayRole: 

57 return None 

58 return (self.arraydata[index.row()][index.column()]) 

59 

60 def setData(self, index, value,role): 

61 if index.column()<2: 

62 self.arraydata[index.row()][index.column()] = value 

63 else: 

64 self.arraydata[index.row()][index.column()] = int(value) 

65 self.dataChanged.emit(index,index) # this updates the edited cell 

66 return True 

67 

68 def flags(self, index): 

69 return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable 

70 

71 def headerData(self,section,orientation,role): 

72 if role != QtCore.Qt.DisplayRole: 

73 return None 

74 if (orientation == QtCore.Qt.Horizontal): 

75 if section==0: 

76 return("Key") 

77 elif section==1: 

78 return("Text") 

79 elif section==2: 

80 return("Type") 

81 else: 

82 return("") 

83 

84 def getTable(self): 

85 return self.arraydata 

86 

87 def setAll(self,shortcutconfig): 

88 self.arraydata=shortcutconfig 

89 self.layoutChanged.emit() # this updates all cells 

90 

91# 

92# Custom delegate class --------------------------------------- 

93# 

94# This delegate does: 

95# - no editing for the first column (shortcut key) 

96# - text editing for the second column (shortcut text) 

97# - combo box editing for the third column (shortcut type) 

98# 

99class ShortcutDelegate(QtWidgets.QItemDelegate): 

100 

101 def __init__(self, parent=None): 

102 super(ShortcutDelegate, self).__init__(parent) 

103 self.items = ["Input only","Input+Endline","Input+2*Cursor left","Input+2*Cursor left+Insert"] 

104 

105# 

106# do not create an editor for the first column, create text editor for 

107# the second column and a QComboBox for the third column 

108# 

109 def createEditor(self, parent, option, index): 

110 editor= None 

111 if index.column()==1: 

112 editor= super(ShortcutDelegate,self).createEditor(parent,option,index) 

113 if index.column()==2: 

114 editor=QtWidgets.QComboBox(parent) 

115 editor.addItems(self.items) 

116 return(editor) 

117# 

118# set text for editing (second column) or current index (third column) 

119# 

120 def setEditorData(self, editor, index): 

121 # Gets display text if edit data hasn't been set. 

122 text = index.data(QtCore.Qt.EditRole) or index.data(QtCore.Qt.DisplayRole) 

123 if index.column()==1: 

124 editor.setText(str(text)) 

125 if index.column()==2: 

126 editor.setCurrentIndex(int(text)) 

127# 

128# return edited data to the model (text for second, index for third column) 

129# 

130 def setModelData(self,editor,model,index): 

131 if index.column()==1: 

132 model.setData(index,editor.text(),QtCore.Qt.EditRole) 

133 if index.column()==2: 

134 model.setData(index,editor.currentIndex(),QtCore.Qt.EditRole) 

135# 

136# paint item text for the third column and text for the other columns 

137# 

138 def paint(self, painter, option, index): 

139 if index.column()==2: 

140 text = self.items[index.data()] 

141 option.text = text 

142 QtWidgets.QApplication.style().drawControl(QtWidgets.QStyle.CE_ItemViewItem, option, painter) 

143 else: 

144 super(ShortcutDelegate, self).paint(painter,option,index) 

145 

146# 

147# Shortcut configuration class ----------------------------------- 

148# 

149class cls_ShortcutConfigWindow(QtWidgets.QDialog): 

150 

151 def __init__(self): 

152 super().__init__() 

153 self.setWindowTitle('Terminal shortcut config') 

154 self.vlayout = QtWidgets.QVBoxLayout() 

155# 

156# table widget 

157# 

158 self.tablemodel=ShortcutTableModel(SHORTCUTCONFIG.get_all()) 

159 self.tableview= QtWidgets.QTableView() 

160 self.tableview.setModel(self.tablemodel) 

161 self.tableview.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) 

162 self.tableview.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) 

163 self.delegate= ShortcutDelegate() 

164 self.tableview.setItemDelegate(self.delegate) 

165 self.vlayout.addWidget(self.tableview) 

166# 

167# ok/cancel button box 

168#  

169 self.buttonBox = QtWidgets.QDialogButtonBox() 

170 self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Reset| QtWidgets.QDialogButtonBox.Ok) 

171 self.buttonBox.setCenterButtons(True) 

172 self.buttonBox.accepted.connect(self.do_ok) 

173 self.buttonBox.rejected.connect(self.do_cancel) 

174 self.buttonBox.button(QtWidgets.QDialogButtonBox.Reset).clicked.connect(self.do_reset) 

175 self.vlayout.addWidget(self.buttonBox) 

176 self.setLayout(self.vlayout) 

177 

178 def do_ok(self): 

179 SHORTCUTCONFIG.set_all(self.tablemodel.getTable()) 

180 super().accept() 

181 

182 def do_cancel(self): 

183 super().reject() 

184# 

185# reset populates table with the default configuration 

186# 

187 def do_reset(self): 

188 self.tablemodel.setAll(SHORTCUTCONFIG.default_config()) 

189 

190 @staticmethod 

191 def getShortcutConfig(): 

192 dialog= cls_ShortcutConfigWindow() 

193 dialog.resize(650,600) 

194 result= dialog.exec() 

195 if result== QtWidgets.QDialog.Accepted: 

196 return True 

197 else: 

198 return False 

199 

200 

201class ShortcutConfigError(Exception): 

202 def __init__(self,msg,add_msg= None): 

203 self.msg= msg 

204 self.add_msg = add_msg 

205 

206 

207class cls_shortcutconfig: 

208# 

209# initialize: set shortcutconfig to the default configuration 

210# 

211 def __init__(self): 

212 self.__shortcutconfig__= None 

213 self.__userconfig__ = None 

214 return 

215# 

216# default config 

217# 

218 def default_config(self): 

219 return [ 

220 ["ALT-A","",0], 

221 ["ALT-B","",0], 

222 ["ALT-C","",0], 

223 ["ALT-D","",0], 

224 ["ALT-E","",0], 

225 ["ALT-F","",0], 

226 ["ALT-G","",0], 

227 ["ALT-H","",0], 

228 ["ALT-I","Reserved!",0], 

229 ["ALT-J","",0], 

230 ["ALT-K","",0], 

231 ["ALT-L","Reserved!",0], 

232 ["ALT-M","",0], 

233 ["ALT-N","",0], 

234 ["ALT-O","",0], 

235 ["ALT-P","",0], 

236 ["ALT-Q","",0], 

237 ["ALT-R","",0], 

238 ["ALT-S","",0], 

239 ["ALT-T","",0], 

240 ["ALT-U","",0], 

241 ["ALT-V","",0], 

242 ["ALT-W","",0], 

243 ["ALT-X","",0], 

244 ["ALT-Y","",0], 

245 ["ALT-Z","",0]] 

246 

247# 

248# open: read in the shortcut configuration. If the configuration file does not  

249# exist, the default configuration is written to the shortcut config file 

250# If clean is true do not read an existing config file 

251# 

252 def open(self,name,configversion,instance,production,clean): 

253 self.__userconfig__= cls_userconfig(name,"shortcutconfig",configversion,instance,clean) 

254 if clean: 

255 return 

256 try: 

257 self.__shortcutconfig__= self.__userconfig__.read(self.default_config()) 

258 except ConfigError as e: 

259 raise ShortcutConfigError(e.msg,e.add_msg) 

260# 

261# Get the list of shortcuts 

262# 

263 def get_shortcutlist(self): 

264 shortcutlist= [] 

265 for p in self.__shortcutconfig__: 

266 shortcutlist.append(p[0]) 

267 return shortcutlist 

268# 

269# Get the config of the nth shortcut 

270# 

271 def get_shortcut(self,n): 

272 return(self.__shortcutconfig__[n][1:]) 

273# 

274# Get the whole table as a copy 

275# 

276 def get_all(self): 

277 return copy.deepcopy(self.__shortcutconfig__) 

278 

279# 

280# Populate the whole table 

281# 

282 def set_all(self,newlist): 

283 self.__shortcutconfig__= [] 

284 self.__shortcutconfig__= copy.deepcopy(newlist) 

285 

286# 

287# Save the shortcutconfig to the configuration file 

288# 

289 def save(self): 

290 try: 

291 self.__userconfig__.write(self.__shortcutconfig__) 

292 except ConfigError as e: 

293 raise ShortcutConfigError(e.msg,e.add_msg) 

294# 

295SHORTCUTCONFIG= cls_shortcutconfig()