1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2009 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing a dialog to enter lexer associations for the project. 8""" 9 10import os 11 12from PyQt5.QtCore import Qt, pyqtSlot 13from PyQt5.QtWidgets import QHeaderView, QTreeWidgetItem, QDialog 14 15from .Ui_LexerAssociationDialog import Ui_LexerAssociationDialog 16 17 18class LexerAssociationDialog(QDialog, Ui_LexerAssociationDialog): 19 """ 20 Class implementing a dialog to enter lexer associations for the project. 21 """ 22 def __init__(self, project, parent=None): 23 """ 24 Constructor 25 26 @param project reference to the project object 27 @param parent reference to the parent widget (QWidget) 28 """ 29 super().__init__(parent) 30 self.setupUi(self) 31 32 self.editorLexerList.headerItem().setText( 33 self.editorLexerList.columnCount(), "") 34 header = self.editorLexerList.header() 35 header.setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents) 36 header.setSortIndicator(0, Qt.SortOrder.AscendingOrder) 37 38 try: 39 self.extsep = os.extsep 40 except AttributeError: 41 self.extsep = "." 42 43 self.extras = ["-----------", self.tr("Alternative")] 44 45 import QScintilla.Lexers 46 languages = ( 47 [''] + 48 sorted(QScintilla.Lexers.getSupportedLanguages().keys()) + 49 self.extras 50 ) 51 for lang in languages: 52 self.editorLexerCombo.addItem( 53 QScintilla.Lexers.getLanguageIcon(lang, False), 54 lang) 55 56 from pygments.lexers import get_all_lexers 57 pygmentsLexers = [''] + sorted(lex[0] for lex in get_all_lexers()) 58 self.pygmentsLexerCombo.addItems(pygmentsLexers) 59 60 # set initial values 61 self.project = project 62 for ext, lexer in list(self.project.pdata["LEXERASSOCS"].items()): 63 QTreeWidgetItem(self.editorLexerList, [ext, lexer]) 64 self.editorLexerList.sortByColumn(0, Qt.SortOrder.AscendingOrder) 65 66 @pyqtSlot() 67 def on_addLexerButton_clicked(self): 68 """ 69 Private slot to add the lexer association displayed to the list. 70 """ 71 ext = self.editorFileExtEdit.text() 72 if ext.startswith(self.extsep): 73 ext.replace(self.extsep, "") 74 lexer = self.editorLexerCombo.currentText() 75 if lexer in self.extras: 76 pygmentsLexer = self.pygmentsLexerCombo.currentText() 77 if not pygmentsLexer: 78 lexer = pygmentsLexer 79 else: 80 lexer = "Pygments|{0}".format(pygmentsLexer) 81 if ext and lexer: 82 itmList = self.editorLexerList.findItems( 83 ext, Qt.MatchFlags(Qt.MatchFlag.MatchExactly), 0) 84 if itmList: 85 index = self.editorLexerList.indexOfTopLevelItem(itmList[0]) 86 itm = self.editorLexerList.takeTopLevelItem(index) 87 # __IGNORE_WARNING__ 88 del itm 89 QTreeWidgetItem(self.editorLexerList, [ext, lexer]) 90 self.editorFileExtEdit.clear() 91 self.editorLexerCombo.setCurrentIndex(0) 92 self.pygmentsLexerCombo.setCurrentIndex(0) 93 self.editorLexerList.sortItems( 94 self.editorLexerList.sortColumn(), 95 self.editorLexerList.header().sortIndicatorOrder()) 96 97 @pyqtSlot() 98 def on_deleteLexerButton_clicked(self): 99 """ 100 Private slot to delete the currently selected lexer association of the 101 list. 102 """ 103 itmList = self.editorLexerList.selectedItems() 104 if itmList: 105 index = self.editorLexerList.indexOfTopLevelItem(itmList[0]) 106 itm = self.editorLexerList.takeTopLevelItem(index) 107 # __IGNORE_WARNING__ 108 del itm 109 110 self.editorLexerList.clearSelection() 111 self.editorFileExtEdit.clear() 112 self.editorLexerCombo.setCurrentIndex(0) 113 114 def on_editorLexerList_itemClicked(self, itm, column): 115 """ 116 Private slot to handle the clicked signal of the lexer association 117 list. 118 119 @param itm reference to the selecte item (QTreeWidgetItem) 120 @param column column the item was clicked or activated (integer) 121 (ignored) 122 """ 123 if itm is None: 124 self.editorFileExtEdit.clear() 125 self.editorLexerCombo.setCurrentIndex(0) 126 self.pygmentsLexerCombo.setCurrentIndex(0) 127 else: 128 self.editorFileExtEdit.setText(itm.text(0)) 129 lexer = itm.text(1) 130 if lexer.startswith("Pygments|"): 131 pygmentsLexer = lexer.split("|")[1] 132 pygmentsIndex = self.pygmentsLexerCombo.findText(pygmentsLexer) 133 lexer = self.tr("Alternative") 134 else: 135 pygmentsIndex = 0 136 index = self.editorLexerCombo.findText(lexer) 137 self.editorLexerCombo.setCurrentIndex(index) 138 self.pygmentsLexerCombo.setCurrentIndex(pygmentsIndex) 139 140 def on_editorLexerList_itemActivated(self, itm, column): 141 """ 142 Private slot to handle the activated signal of the lexer association 143 list. 144 145 @param itm reference to the selecte item (QTreeWidgetItem) 146 @param column column the item was clicked or activated (integer) 147 (ignored) 148 """ 149 self.on_editorLexerList_itemClicked(itm, column) 150 151 @pyqtSlot(int) 152 def on_editorLexerCombo_currentIndexChanged(self, index): 153 """ 154 Private slot to handle the selection of a lexer. 155 156 @param index index of the current item 157 @type int 158 """ 159 text = self.editorLexerCombo.itemText(index) 160 if text in self.extras: 161 self.pygmentsLexerCombo.setEnabled(True) 162 self.pygmentsLabel.setEnabled(True) 163 else: 164 self.pygmentsLexerCombo.setEnabled(False) 165 self.pygmentsLabel.setEnabled(False) 166 167 def transferData(self): 168 """ 169 Public slot to transfer the associations into the projects data 170 structure. 171 """ 172 self.project.pdata["LEXERASSOCS"] = {} 173 for index in range(self.editorLexerList.topLevelItemCount()): 174 itm = self.editorLexerList.topLevelItem(index) 175 pattern = itm.text(0) 176 self.project.pdata["LEXERASSOCS"][pattern] = itm.text(1) 177