From 26d8ce799faf10b023691a33895335c2e607f0fe Mon Sep 17 00:00:00 2001 From: consp Date: Wed, 21 Apr 2021 23:04:14 +0200 Subject: [PATCH] Added status bar showing theme status. Added check for vdv/splash/brand to validate the theme is available --- src/apim.py | 29 +++++- src/encoder.py | 4 +- src/statics.py | 233 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 259 insertions(+), 7 deletions(-) diff --git a/src/apim.py b/src/apim.py index c9179ac..823534c 100644 --- a/src/apim.py +++ b/src/apim.py @@ -6,7 +6,7 @@ raise Exception("Must be using Python 3.4 or up") # QT Imports try: - from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QHBoxLayout, QLabel, QFileDialog, QGroupBox, QMessageBox, QComboBox, QScrollArea, QSizePolicy, QTabWidget, QLineEdit + from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QHBoxLayout, QLabel, QFileDialog, QGroupBox, QMessageBox, QComboBox, QScrollArea, QSizePolicy, QTabWidget, QLineEdit, QStatusBar from PyQt5.QtGui import QDoubleValidator, QRegExpValidator from PyQt5.QtCore import QRegExp, Qt from functools import partial @@ -19,7 +19,7 @@ # local imports from asbuilt import AsBuilt from encoder import print_bits_known_de07_08, ItemEncoder, print_duplicates -from statics import JumpTables, Fields +from statics import JumpTables, Fields, ThemeConfig # global imports import argparse @@ -143,11 +143,15 @@ def launch_picker(self): self.button_save_as = QPushButton("Save as ...") if self.button_save_as is None else self.button_save_as self.button_save_as.clicked.connect(self.save_file_as) self.button_save.clicked.connect(self.save) + self.syncversion = QComboBox() + self.syncversion.addItems(["3.0-3.2", "3.4"]) + self.syncversion.setCurrentIndex(1) self.button_group_layout.addWidget(self.button_open) self.button_group_layout.addWidget(self.button_save) self.button_group_layout.addWidget(self.button_save_as) self.button_group_layout.addWidget(self.button_exit) + self.button_group_layout.addWidget(self.syncversion) self.button_group.setLayout(self.button_group_layout) ## Block group @@ -231,7 +235,7 @@ def launch_picker(self): setup_layout.addWidget(scroll_area) setup.setLayout(setup_layout) - items = self.encoder.QtItemList(x, self.asbuilt, self.textblocks[x-1]) + items = self.encoder.QtItemList(x, self.asbuilt, self.textblocks[x-1], self.themechange) for item in items: block_items_layout.addLayout(item) self.tab.append(setup) @@ -249,8 +253,26 @@ def launch_picker(self): self.picker_window.setLayout(self.picker_layout) self.current_window = self.picker_window #self.picker_window.setSizePolicy(QSizePolicy.Expanding) + self.statusBar = QStatusBar() + self.picker_layout.addWidget(self.statusBar) + self.statusBar.showMessage("") self.picker_window.show() + def themechange(self): + + animation = int(self.textblocks[1][2].text(), 16) + theme = int(self.textblocks[2][2].text(), 16) + brand = (int(self.textblocks[0][5].text(), 16) & 0b11100000) >> 5 + + #print(theme, animation, brand, self.syncversion.currentText()) + matches = ThemeConfig.validate(brand, theme, animation, version=self.syncversion.currentText()) + + message = "No themes found matching configuration!" if len(matches) == 0 else matches[0] if len(matches) == 1 else "Found %d themes: %s" % (len(matches), "".join(matches)) + self.statusBar.showMessage(message) + #print(matches) + #f = ThemeConfig.validate() + + def launch_qt(self): self.app = QApplication([]) self.app.setStyle('Fusion') @@ -263,6 +285,7 @@ def launch_qt(self): self.button_exit = QPushButton("Exit") self.button_exit.clicked.connect(sys.exit) + self.main_layout.addWidget(self.button_open) self.main_layout.addWidget(self.button_exit) diff --git a/src/encoder.py b/src/encoder.py index 1ce5daf..97d0a73 100644 --- a/src/encoder.py +++ b/src/encoder.py @@ -450,7 +450,7 @@ def byte_loc_string(self, i, bits): def __init__(self): self.items = [Fields.block(block) for block in range(1, 10)] - def QtItemList(self, block, asbuilt, bitfields): + def QtItemList(self, block, asbuilt, bitfields, themechange): qtitems = [] prevbyte = -1 for item in Fields.block(block): @@ -507,6 +507,8 @@ def QtItemList(self, block, asbuilt, bitfields): option.setMaximumWidth(400) option.setCurrentIndex(value) option.currentIndexChanged.connect(partial(combo_change, option, item, bitfields[item['byte']])) + if 'theme' in item: + option.currentIndexChanged.connect(partial(themechange)) layout.addWidget(label) layout.addWidget(option) if unit is not None: diff --git a/src/statics.py b/src/statics.py index a2b219c..ee54cdc 100644 --- a/src/statics.py +++ b/src/statics.py @@ -658,9 +658,10 @@ def block(cls, block): 'items': 4 , 'type': 'mask', '0': 'Ford', - '1': 'Reserved (not used in 3.4)', + '1': 'Ford Timeless / Reserved (3.4)', '2': 'Lincoln', '3': 'Configurable Splash Screen (not used in 3.4)', + 'theme': True, }, { 'name': 'Hybrid (HEV)', @@ -1048,13 +1049,14 @@ def block(cls, block): 'type': 'ascii', }, { - 'name': 'Splash Screen, also sets some themes', + 'name': 'Splash Screen / Startup Animation', 'index': 72, 'byte': 2, 'bit': 0, 'size': 8, 'type': 'table', 'table': '__SS', + 'theme': True, }, { 'name': 'Vehicle Style', @@ -1710,13 +1712,14 @@ def block(cls, block): 'table': '___V', }, { - 'name': 'Visual Design Variants', + 'name': 'Visual Design Variants / Sync visual Theme', 'index': 131, 'byte': 2, 'bit': 0, 'size': 8, 'type': 'table', 'table': '_VDV', + 'theme': True }, { 'name': 'Drive Type', @@ -3775,6 +3778,230 @@ def block(cls, block): }, ] +class ThemeConfig(): + # checks themeconfig + themes = [ + "Ford Classic", #0 + "Ford Timeless", #1 + "Lincoln Classic", #2 + "Lincoln Timeless", #3 + "Ford GT (no longer used in 3.4)" #4 + "?", #5 + "?", + "10L Theme", #7 + "10P Theme" #8 + ] + + config_3_4 = { + "ford-my20": + { + "brand": 0, + "theme": 0, + "animation": -1, + "comment": "Maps to Classic theme but animation might not work" + }, + "ford-my20-2": + { + "brand": 0, + "theme": 0, + "animation": 8, + "comment": "Maps to Classic theme but animation is Vignale Classis" + }, + "ford-my20-3": + { + "brand": 0, + "theme": 1, + "animation": -1, + "comment": "Maps to Classic theme but animation might not work" + }, + "ford-raptor": + { + "brand": 0, + "theme": 1, + "animation": 5, + "comment": None + }, + "ford-mustang": + { + "brand": 0, + "theme": 1, + "animation": 6, + "comment": "Usethemeid is set to 0" + }, + "ford-evo": + { + "brand": 0, + "theme": 0, + "animation": 16, + "comment": None + }, + "ford-shelby": + { + "brand": 0, + "theme": 1, + "animation": 7, + "comment": "Usethemeid is set to 0" + }, + "ford-vignale": + { + "brand": 0, + "theme": 1, + "animation": 8, + "comment": "Usethemeid is set to 0" + }, + "ford-shelbyR": + { + "brand": 0, + "theme": 1, + "animation": 9, + "comment": "Usethemeid is set to 0" + }, + "ford-st": + { + "brand": 0, + "theme": 1, + "animation": 11, + }, + "ford-rs": + { + "brand": 0, + "theme": 1, + "animation": 12, + "comment": "Usethemeid is set to 0" + }, + "ford-my20-former-gt-theme": + { + "brand": 0, + "theme": 4, + "animation": 13, + "comment": "Some versions do not function with this theme!", + "warning": True + }, + "lincoln-U520": + { + "brand": 2, + "theme": 2, + "animation": 20, + "comment": "Marked as obsolete" + }, + "ford-10p-my20": + { + "brand": 0, + "theme": 8, + "animation": -1, + "comment": "Animation change might not work" + }, + "lincoln-my20": + { + "brand": 2, + "theme": 2, + "animation": -1, + "comment": "Marked as obsolete, animation might not work" + }, + "lincoln-blacklabel": + { + "brand": 2, + "theme": 2, + "animation": 3, + "comment": "Usethemeid is set to 3" + }, + "lincoln-presidential": + { + "brand": 2, + "theme": 2, + "animation": 4, + "comment": "Usethemeid is set to 3" + }, + "lincoln-my20": + { + "brand": 2, + "theme": 3, + "animation": -1, + "comment": "Animation might not work, used to be lincoln-next" + }, + "lincoln-my20-2": + { + "brand": 2, + "theme": 3, + "animation": 3, + "comment": "Obsolete is set used to be D544-blacklabel" + }, + "lincoln-continental": + { + "brand": 2, + "theme": 3, + "animation": 14, + "comment": None + }, + "lincoln-10L-my20": + { + "brand": 2, + "theme": 7, + "animation": -1, + "comment": "Animation might not work" + }, + "lincoln-U611": + { + "brand": 2, + "theme": 7, + "animation": 17, + "comment": None + }, + "ford-10P-st": + { + "brand": 0, + "theme": 8, + "animation": 11, + "comment": None + }, + "ford-U625": + { + "brand": 0, + "theme": 0, + "animation": 18, + "comment": None + }, + "ford-10P-U625": + { + "brand": 0, + "theme": 8, + "animation": 18, + "comment": None + }, + "lincoln-CX483": + { + "brand": 2, + "theme": 3, + "animation": 19, + "comment": None + }, + "lincoln-U540": + { + "brand": 2, + "theme": 3, + "animation": 20, + "comment": None + }, + "ford-CX430": + { + "brand": 0, + "theme": 0, + "animation": 23, + "comment": None + }, + } + + @classmethod + def validate(cls, brand, theme, animation, version="3.4"): + matches = [] + if version == "3.4": + for k,v in cls.config_3_4.items(): + if (v['brand'] == brand and v['theme'] == theme and v['animation'] == -1) or (v['brand'] == brand and v['theme'] == theme and v['animation'] == animation): + matches.append("Found theme '%s'. %s" % (k, "" if v['comment'] is None else v['comment'])) + else: + pass + return matches + class CCTypes(): ENUM = 1 FLAG = 2