Package pytsonui :: Module config
[hide private]
[frames] | no frames]

Source Code for Module pytsonui.config

  1  import os 
  2   
  3  from PythonQt.QtCore import Qt, QLocale 
  4  from PythonQt.QtGui import (QDialog, QHeaderView, QTableWidgetItem, 
  5                              QToolButton, QIcon, QColor, QFont, QMessageBox, 
  6                              QCheckBox, QColorDialog, QFileDialog, QInputDialog) 
  7   
  8  import ts3defines 
  9   
 10  from . import setupUi, ts3print 
 11  from .repository import RepositoryDialog, InstallDialog 
 12   
 13  import pytson 
 14  import ts3client 
 15  import devtools 
 16   
 17   
18 -class ConfigurationDialog(QDialog, pytson.Translatable):
19 # [(objectName, store, [children])] 20 CONF_WIDGETS = [("tabWidget", False, [ 21 ("pluginsTab", False, [ 22 ("differentApiButton", True, []), 23 ("pluginsTable", True, []), 24 ("reloadButton", True, []), 25 ("repositoryButton", True, []), 26 ("versionEdit", True, []), 27 ("nameEdit", True, []), 28 ("authorEdit", True, []), 29 ("descriptionEdit", True, []), 30 ("keywordEdit", True, []), 31 ("apiEdit", True, []), 32 ("requiredApiEdit", True, []) 33 ]), 34 ("generalTab", False, [ 35 ("languageGroup", False, [ 36 ("languageButton", True, []), 37 ("languageCombo", True, []), 38 ]), 39 ("siteGroup", False, [ 40 ("siteTable", True, []), 41 ("sitereloadButton", True, []), 42 ("siteaddButton", True, []), 43 ("siteremoveButton", True, []), 44 ]), 45 ("loadMenusButton", True, []), 46 ("verboseButton", True, []), 47 ]), 48 ("consoleTab", False, [ 49 ("colorsBox", False, [ 50 ("bgColorButton", True, []), 51 ("textColorButton", True, []), 52 ]), 53 ("fontBox", False, [ 54 ("fontFamilyCombo", True, []), 55 ("fontSizeSpin", True, []), 56 ]), 57 ("tabsBox", False, [ 58 ("tabcompleteButton", True, []), 59 ("spacesButton", True, []), 60 ("tabwidthSpin", True, []), 61 ("tabwidthLabel", True, []), 62 ]), 63 ("startupBox", False, [ 64 ("scriptEdit", True, []), 65 ("scriptButton", True, []), 66 ("silentButton", True, []), 67 ]), 68 ]), 69 ])] 70
71 - def __init__(self, cfg, host, parent=None):
72 super(QDialog, self).__init__(parent) 73 74 self.setAttribute(Qt.WA_DeleteOnClose) 75 76 self.cfg = cfg 77 self.host = host 78 self.rpd = None 79 self.sitepkgs = None 80 81 try: 82 setupUi(self, pytson.getPluginPath("ressources", 83 "pyTSon-configdialog.ui"), 84 widgets=self.CONF_WIDGETS) 85 self.pluginsTable.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) 86 self.siteTable.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) 87 88 self.setupValues() 89 self.setupSlots() 90 except Exception as e: 91 self.delete() 92 raise e
93
94 - def setupList(self):
95 self.pluginsTable.clear() 96 self.pluginsTable.setRowCount(len(self.host.plugins)) 97 98 try: 99 ico = ts3client.IconPack.current() 100 ico.open() 101 except Exception as e: 102 ico = None 103 ts3print(self._tr("Error loading iconpack: {exception}"). 104 format(exception=e), ts3defines.LogLevel.LogLevel_ERROR, 105 "pyTSon.ConfigurationDialog.setupList", 0) 106 107 row = 0 108 diffapi = self.cfg.getboolean("general", "differentApi", 109 fallback=False) 110 for key, p in self.host.plugins.items(): 111 if diffapi or p.apiVersion == pytson.getCurrentApiVersion(): 112 item = QTableWidgetItem(p.name) 113 item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | 114 Qt.ItemIsEnabled) 115 item.setCheckState(Qt.Checked if key in self.host.active 116 else Qt.Unchecked) 117 item.setData(Qt.UserRole, key) 118 self.pluginsTable.setItem(row, 0, item) 119 120 if p.offersConfigure: 121 setbutton = QToolButton() 122 setbutton.connect("clicked()", lambda n=p.name: 123 self.onSettingsButtonClicked(n)) 124 setbutton.setToolTip(self._tr("Configure")) 125 if ico: 126 setbutton.setIcon(QIcon(ico.icon("SETTINGS"))) 127 self.pluginsTable.setCellWidget(row, 1, setbutton) 128 129 if p.name not in self.host.active: 130 setbutton.setEnabled(False) 131 132 rembutton = QToolButton() 133 if ico: 134 rembutton.setIcon(QIcon(ico.icon("DELETE"))) 135 rembutton.connect("clicked()", lambda n=p.name: 136 self.onRemoveButtonClicked(n)) 137 rembutton.setToolTip(self._tr("Remove")) 138 self.pluginsTable.setCellWidget(row, 2, rembutton) 139 140 row += 1 141 142 if ico: 143 ico.close() 144 145 self.pluginsTable.setRowCount(row) 146 self.pluginsTable.sortItems(0)
147
148 - def setupValues(self):
149 if self.cfg.getboolean("general", "differentApi", fallback=False): 150 self.differentApiButton.setChecked(Qt.Checked) 151 else: 152 self.differentApiButton.setChecked(Qt.Unchecked) 153 self.requiredApiEdit.setText(pytson.getCurrentApiVersion()) 154 155 if self.cfg.getboolean("general", "loadAllMenus", fallback=False): 156 self.loadMenusButton.setChecked(Qt.Checked) 157 else: 158 self.loadMenusButton.setChecked(Qt.Unchecked) 159 160 bgcolor = QColor(self.cfg.get("console", "backgroundColor")).name() 161 self.bgColorButton.setStyleSheet("background-color: %s;" % bgcolor) 162 txtcolor = QColor(self.cfg.get("console", "textColor")).name() 163 self.textColorButton.setStyleSheet("background-color: %s;" % txtcolor) 164 165 f = QFont(self.cfg.get("console", "fontFamily")) 166 self.fontFamilyCombo.setCurrentFont(f) 167 self.fontSizeSpin.setValue(self.cfg.getint("console", "fontSize")) 168 169 if self.cfg.getboolean("console", "tabcomplete"): 170 self.tabcompleteButton.setChecked(True) 171 self.spacesButton.setEnabled(False) 172 self.tabwidthSpin.setEnabled(False) 173 self.tabwidthLabel.setEnabled(False) 174 else: 175 self.tabcompleteButton.setChecked(False) 176 177 self.spacesButton.setChecked(self.cfg.getboolean("console", "spaces")) 178 self.tabwidthSpin.setValue(self.cfg.getint("console", "tabwidth")) 179 180 self.scriptEdit.setText(self.cfg.get("console", "startup")) 181 self.silentButton.setChecked(self.cfg.getboolean("console", 182 "silentStartup")) 183 184 self.languageCombo.addItem("Default", "en_US") 185 for loc in pytson.locales(): 186 qloc = QLocale(loc) 187 self.languageCombo.addItem(qloc.nativeLanguageName(), loc) 188 189 if self.cfg.get("general", "language") == loc: 190 self.languageCombo.setCurrentIndex(self.languageCombo.count - 1) 191 192 if self.cfg.get("general", "language") == "inherited": 193 self.languageButton.setChecked(True) 194 self.languageCombo.setEnabled(False) 195 196 if self.cfg.getboolean("general", "verbose"): 197 self.verboseButton.setChecked(True) 198 199 self.setupList() 200 self.reloadSite()
201
202 - def setupSlots(self):
203 # you can of course connect signal-slots manually, 204 # scriptEdit.textEdited for example is connected by setupui 205 self.differentApiButton.connect("stateChanged(int)", 206 self.onDifferentApiButtonChanged) 207 self.pluginsTable.connect("currentCellChanged(int, int, int, int)", 208 self.onPluginsTableCurrentItemChanged) 209 self.pluginsTable.connect("itemChanged(QTableWidgetItem*)", 210 self.onPluginsTableItemChanged) 211 self.reloadButton.connect("clicked()", self.onReloadButtonClicked) 212 213 self.loadMenusButton.connect("stateChanged(int)", 214 self.onLoadMenusButtonChanged) 215 216 self.bgColorButton.connect("clicked()", 217 self.onBackgroundColorButtonClicked) 218 self.textColorButton.connect("clicked()", 219 self.onTextColorButtonClicked) 220 self.fontFamilyCombo.connect("currentFontChanged(QFont)", 221 self.onFontFamilyComboChanged) 222 self.fontSizeSpin.connect("valueChanged(int)", 223 self.onFontSizeSpinChanged) 224 self.tabcompleteButton.connect("stateChanged(int)", 225 self.onTabcompleteButtonChanged) 226 self.spacesButton.connect("stateChanged(int)", 227 self.onSpacesButtonChanged) 228 self.tabwidthSpin.connect("valueChanged(int)", 229 self.onTabwidthSpinChanged) 230 self.languageButton.connect("stateChanged(int)", 231 self.onLanguageButtonStateChanged) 232 self.languageCombo.connect("currentIndexChanged(int)", 233 self.onLanguageComboCurrentIndexChanged) 234 self.verboseButton.connect("stateChanged(int)", 235 self.onVerboseButtonStateChanged) 236 self.sitereloadButton.connect("clicked()", self.reloadSite)
237
238 - def onLoadMenusButtonChanged(self, state):
239 if state == Qt.Checked: 240 self.cfg.set("general", "loadAllMenus", "True") 241 else: 242 self.cfg.set("general", "loadAllMenus", "False") 243 244 QMessageBox.information(self, self._tr("Restart required"), 245 self._tr("Changes only take effect after a " 246 "restart."))
247
248 - def onDifferentApiButtonChanged(self, state):
249 if state == Qt.Checked: 250 self.cfg.set("general", "differentApi", "True") 251 else: 252 self.cfg.set("general", "differentApi", "False") 253 254 self.host.reload() 255 self.host.start() 256 self.setupList()
257
258 - def onPluginsTableCurrentItemChanged(self, currow, curcol, prevrow, 259 prevcol):
260 cur = self.pluginsTable.item(currow, 0) 261 if not cur: 262 self.nameEdit.clear() 263 self.versionEdit.clear() 264 self.authorEdit.clear() 265 self.descriptionEdit.clear() 266 self.keywordEdit.clear() 267 self.apiEdit.clear() 268 else: 269 p = self.host.plugins[cur.data(Qt.UserRole)] 270 271 self.nameEdit.setText(p.name) 272 self.versionEdit.setText(p.version) 273 self.authorEdit.setText(p.author) 274 self.descriptionEdit.setPlainText(p.description) 275 self.keywordEdit.setText(p.commandKeyword) 276 self.apiEdit.setText(p.apiVersion)
277
278 - def onPluginsTableItemChanged(self, item):
279 checked = item.checkState() == Qt.Checked 280 name = item.data(Qt.UserRole) 281 282 if checked and name not in self.host.active: 283 if self.host.activate(name): 284 if self.host.active[name].offersConfigure: 285 self.pluginsTable.cellWidget(item.row(), 286 1).setEnabled(True) 287 else: 288 item.setCheckState(Qt.Unchecked) 289 QMessageBox.critical(self, self._tr("Activation failed"), 290 self._tr("Error starting plugin, check " 291 "your client log for more information")) 292 elif not checked and name in self.host.active: 293 if self.host.active[name].offersConfigure: 294 self.pluginsTable.cellWidget(item.row(), 1).setEnabled(False) 295 self.host.deactivate(name)
296
297 - def onRemoveButtonClicked(self, pluginname):
298 if pluginname in self.host.plugins: 299 if self.cfg.getboolean("general", "uninstallQuestion"): 300 def cbox_state_changed(state): 301 if state == Qt.Checked: 302 self.cfg.set("general", "uninstallQuestion", "False") 303 else: 304 self.cfg.set("general", "uninstallQuestion", "True")
305 306 cbox = QCheckBox(self._tr("Don't ask me again")) 307 cbox.connect("stateChanged(int)", cbox_state_changed) 308 309 msgbox = QMessageBox(self) 310 msgbox.setInformativeText(self._tr("Do you really want to " 311 "delete plugin {name}?\n" 312 "This will erase all " 313 "script data of the " 314 "plugin from disk."). 315 format(name=pluginname)) 316 msgbox.setIcon(4) # QMessageBox::Icon::Question = 4 317 msgbox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) 318 msgbox.setDefaultButton(QMessageBox.Cancel) 319 msgbox.setCheckBox(cbox) 320 321 if msgbox.exec_() != QMessageBox.Ok: 322 return 323 324 if pluginname in self.host.active: 325 self.host.deactivate(pluginname) 326 327 devtools.PluginInstaller.removePlugin(pluginname) 328 self.host.reload() 329 self.host.start() 330 self.setupList()
331
332 - def onReloadButtonClicked(self):
333 self.host.reload() 334 self.host.start() 335 self.setupList()
336
337 - def onSettingsButtonClicked(self, pluginname):
338 if pluginname in self.host.active: 339 self.host.active[pluginname].configure(self)
340
341 - def onBackgroundColorButtonClicked(self):
342 curcolor = QColor(self.cfg.get("console", "backgroundColor")) 343 c = QColorDialog.getColor(curcolor, self, 344 self._tr("Console Background Color")) 345 if c.isValid(): 346 self.cfg.set("console", "backgroundColor", c.name()) 347 self.bgColorButton.setStyleSheet("background-color: %s;" % 348 c.name())
349
350 - def onTextColorButtonClicked(self):
351 curcolor = QColor(self.cfg.get("console", "textColor")) 352 c = QColorDialog.getColor(curcolor, self, 353 self._tr("Console Text Color")) 354 if c.isValid(): 355 self.cfg.set("console", "textColor", c.name()) 356 self.textColorButton.setStyleSheet("background-color: %s;" % 357 c.name())
358
359 - def onFontFamilyComboChanged(self, font):
360 self.cfg.set("console", "fontFamily", font.family())
361
362 - def onFontSizeSpinChanged(self, size):
363 self.cfg.set("console", "fontSize", str(size))
364
365 - def onTabcompleteButtonChanged(self, state):
366 checked = state == Qt.Checked 367 self.cfg.set("console", "tabcomplete", str(checked)) 368 self.spacesButton.setEnabled(not checked) 369 self.tabwidthSpin.setEnabled(not checked) 370 self.tabwidthLabel.setEnabled(not checked)
371
372 - def onSpacesButtonChanged(self, state):
373 self.cfg.set("console", "spaces", str(state == Qt.Checked))
374
375 - def onTabwidthSpinChanged(self, width):
376 self.cfg.set("console", "tabwidth", str(width))
377
378 - def on_scriptButton_clicked(self):
379 curdir = os.path.dirname(self.cfg.get("console", "startup")) 380 fname = QFileDialog.getOpenFileName(self, self._tr("Startup script"), 381 curdir, "Python scripts (*.py)") 382 if fname != "": 383 self.scriptEdit.setText(fname) 384 self.scriptEdit.setStyleSheet("border: 1px solid black") 385 386 self.cfg.set("console", "startup", fname)
387
388 - def on_scriptEdit_textEdited(self, text):
389 if os.path.exists(text) and os.path.isfile(text): 390 self.scriptEdit.setStyleSheet("border: 1px solid black") 391 392 self.cfg.set("console", "startup", text) 393 else: 394 self.scriptEdit.setStyleSheet("border: 1px solid red")
395
396 - def on_silentButton_toggled(self, act):
397 self.cfg.set("console", "silentStartup", str(act))
398
399 - def on_repositoryButton_clicked(self):
400 if not self.rpd: 401 self.rpd = RepositoryDialog(self.host, self) 402 403 self.rpd.show() 404 self.rpd.raise_()
405
406 - def onLanguageComboCurrentIndexChanged(self, idx):
407 self.cfg.set("general", "language", self.languageCombo.currentData)
408
409 - def onLanguageButtonStateChanged(self, state):
410 if state == Qt.Checked: 411 self.cfg.set("general", "language", "inherited") 412 else: 413 self.cfg.set("general", "language", self.languageCombo.currentData) 414 415 self.languageCombo.setEnabled(state == Qt.Unchecked)
416
417 - def onVerboseButtonStateChanged(self, state):
418 self.cfg.set("general", "verbose", str(state == Qt.Checked))
419
420 - def reloadSite(self):
421 self.siteTable.clearContents() 422 423 self.sitepkgs = devtools.installedPackages() 424 self.siteTable.setRowCount(len(self.sitepkgs)) 425 426 for i, pkg in enumerate(self.sitepkgs): 427 item = QTableWidgetItem(pkg["name"]) 428 item.setData(Qt.UserRole, i) 429 self.siteTable.setItem(i, 0, item) 430 431 item = QTableWidgetItem(pkg["version"]) 432 item.setData(Qt.UserRole, i) 433 self.siteTable.setItem(i, 1, item) 434 435 self.siteTable.sortItems(0)
436
437 - def on_siteTable_itemSelectionChanged(self):
438 self.siteremoveButton.setEnabled(self.siteTable.selectedItems())
439
440 - def on_siteaddButton_clicked(self):
441 pkg = QInputDialog.getText(self, self._tr("Install site package"), 442 self._tr("Package name[==version]")).strip() 443 444 if pkg != "": 445 self.installer = InstallDialog(self.host, self) 446 self.installer.show() 447 self.installer.installPackage(pkg) 448 self.reloadSite()
449
450 - def on_siteremoveButton_clicked(self):
451 ids = {it.data(Qt.UserRole) for it in self.siteTable.selectedItems()} 452 453 if ids: 454 if (QMessageBox.question(self, self._tr("Remove site packages"), 455 self._tr("Are you sure to remove the " 456 "selected packages? Some " 457 "plugins might not work " 458 "properly.")) == 459 QMessageBox.Yes): 460 try: 461 for idx in ids: 462 devtools.removePackage(self.sitepkgs[idx]["name"], 463 self.sitepkgs[idx]["version"]) 464 except Exception as e: 465 QMessageBox.critical(self, self._tr("Error"), str(e)) 466 467 self.reloadSite()
468