Skip to content

Commit ee2c1c2

Browse files
Merge pull request #4
add_object_and_reorder_tree
2 parents b1c8413 + a7d0ce9 commit ee2c1c2

19 files changed

+1729
-456
lines changed

src/error_handler.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,10 @@ def raise_error(file_path, line_number, line_content, error_message, error_level
4242
else:
4343
# Log the error without affecting the flow
4444
log_manager.log(f"Logged Error: {error_details}", level="INFO")
45+
46+
class InvalidValuesError(Exception):
47+
"""Exception raised when the values are invalid."""
48+
49+
def __init__(self, message="Invalid values provided"):
50+
self.message = message
51+
super().__init__(self.message)

src/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ def load_object_property(self):
342342
if self.selected_object:
343343
try:
344344
# Load the windows into the object tree
345-
self.property_editor.load_property(self.selected_object.properties)
345+
self.property_editor.load_property(self.selected_object)
346346
self.log_manager.log(f"Loaded properties from object {self.selected_object.properties.get('WINDOWTYPE')} - {self.selected_object.properties.get('NAME', 'Unnamed')}", level="INFO")
347347

348348
except ValueError as e:

src/object_tree.py

Lines changed: 327 additions & 11 deletions
Large diffs are not rendered by default.

src/properties/control_properties.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class ControlForm(QWidget):
1111
def __init__(self, parent=None, control_attributes=None):
1212
super().__init__(parent)
1313
self.control_attributes = control_attributes
14+
self.update_modified_state = None
1415

1516
# Layout for the control-specific attributes
1617
self.layout = QVBoxLayout(self)
@@ -53,24 +54,24 @@ def create_pushbutton_attributes(self, properties):
5354
self.create_default_textures(properties)
5455

5556
def create_radiobutton_attributes(self, properties):
56-
self.create_attributes_for_control(properties.attributes['RADIOBUTTONDATA'][0])
57+
self.create_attributes_for_control(properties['attributes']['RADIOBUTTONDATA'][0])
5758
self.create_default_textures(properties)
5859

5960
def create_entryfield_attributes(self, properties):
60-
entryfield_data = normalize_boolean_values(properties.attributes['ENTRYFIELDDATA'],
61+
entryfield_data = normalize_boolean_values(properties['attributes']['TEXTENTRYDATA'],
6162
['SECRETTEXT', 'NUMERICALONLY', 'ALPHANUMERICALONLY', 'ASCIIONLY'])
6263
self.create_attributes_for_control(entryfield_data)
6364
self.create_default_textures(properties)
6465

6566
def create_statictext_attributes(self, properties):
66-
self.create_attributes_for_control(properties.attributes['STATICTEXTDATA'][0])
67+
self.create_attributes_for_control(properties['attributes']['STATICTEXTDATA'][0])
6768
self.create_default_textures(properties)
6869

6970
def create_progressbar_attributes(self, properties):
7071
self.create_default_textures(properties)
7172

7273
def create_scrolllistbox_attributes(self, properties):
73-
listbox_data = normalize_boolean_values(properties.attributes['LISTBOXDATA'],
74+
listbox_data = normalize_boolean_values(properties['attributes']['LISTBOXDATA'],
7475
['AUTOSCROLL', 'AUTOPURGE', 'SCROLLBAR', 'MULTISELECT', 'FORCESELECT'])
7576

7677
self.create_attributes_for_control(listbox_data)
@@ -85,7 +86,7 @@ def create_scrolllistbox_attributes(self, properties):
8586
self.create_textures_for_control(textures)
8687

8788
def create_combobox_attributes(self, properties):
88-
combobox_data = normalize_boolean_values(properties.attributes['COMBOBOXDATA'],
89+
combobox_data = normalize_boolean_values(properties['attributes']['COMBOBOXDATA'],
8990
['ISEDITABLE', 'ASCIIONLY', 'LETTERSANDNUMBERS'])
9091
self.create_attributes_for_control(combobox_data)
9192

@@ -100,24 +101,24 @@ def create_combobox_attributes(self, properties):
100101
'SLIDERTHUMBENABLEDDRAWDATA', 'SLIDERTHUMBDISABLEDDRAWDATA', 'SLIDERTHUMBHILITEDRAWDATA'
101102
]
102103

103-
textures = {key: filter_empty_properties(properties.textures[key]) for key in texture_keys}
104+
textures = {key: filter_empty_properties(properties['textures'][key]) for key in texture_keys}
104105
self.create_textures_for_control(textures)
105106

106107
def create_checkbox_attributes(self, properties):
107108
self.create_default_textures(properties)
108109

109110
def create_slider_attributes(self, properties):
110-
slider_data = normalize_boolean_values(properties.attributes['SLIDERDATA'], [])
111+
slider_data = normalize_boolean_values(properties['attributes']['SLIDERDATA'], [])
111112
self.create_attributes_for_control(slider_data)
112113
texture_keys = ['ENABLEDDRAWDATA', 'DISABLEDDRAWDATA', 'HILITEDRAWDATA', 'SLIDERTHUMBENABLEDDRAWDATA',
113114
'SLIDERTHUMBDISABLEDDRAWDATA', 'SLIDERTHUMBHILITEDRAWDATA']
114-
textures = {key: filter_empty_properties(properties.textures[key]) for key in texture_keys}
115+
textures = {key: filter_empty_properties(properties['textures'][key]) for key in texture_keys}
115116
self.create_textures_for_control(textures)
116117

117118

118119
def create_default_textures(self, properties):
119120
texture_keys = ['ENABLEDDRAWDATA', 'DISABLEDDRAWDATA', 'HILITEDRAWDATA']
120-
textures = {key: filter_empty_properties(properties.textures[key]) for key in texture_keys}
121+
textures = {key: filter_empty_properties(properties['textures'][key]) for key in texture_keys}
121122
self.create_textures_for_control(textures)
122123

123124
def create_attributes_for_control(self, attributes):
@@ -170,7 +171,7 @@ def update_texture_color(texture_type, image, color_picker_app):
170171
color = color_picker_app.color_data['texture_layout']['color']
171172
border = color_picker_app.color_data['texture_layout']['shadow']
172173

173-
self.update_texture_property(texture_type, 'color', image, (
174+
self.update_texture_property(texture_type, 'COLOR', image, (
174175
color.red(), color.green(), color.blue(), color.alpha()))
175176
self.update_texture_property(texture_type, 'BORDERCOLOR', image, (
176177
border.red(), border.green(), border.blue(), border.alpha()))
@@ -181,14 +182,14 @@ def update_texture_color(texture_type, image, color_picker_app):
181182
section = CollapsibleSection(title=texture_type_name, parent=self,
182183
section_manager=outer_section_manager)
183184
for texture in texture_data:
184-
inner_section_title = texture.get('image', 'No Image')
185+
inner_section_title = texture.get('IMAGE', 'No Image')
185186
inner_section = create_inner_section(inner_section_title, section, inner_section_manager,
186187
"InnerSection")
187188

188189
color_picker_app = ColorPickerApp(
189190
color_data={'texture_layout': {
190-
"color": QColor(texture.get('color')[0], texture.get('color')[1], texture.get('color')[2],
191-
texture.get('color')[3]),
191+
"color": QColor(texture.get('COLOR')[0], texture.get('COLOR')[1], texture.get('COLOR')[2],
192+
texture.get('COLOR')[3]),
192193
"shadow": QColor(texture.get('BORDERCOLOR')[0], texture.get('BORDERCOLOR')[1],
193194
texture.get('BORDERCOLOR')[2], texture.get('BORDERCOLOR')[3])
194195
}}
@@ -210,25 +211,28 @@ def update_texture_color(texture_type, image, color_picker_app):
210211
self.layout.addWidget(section)
211212

212213
def update_sub_property(self, main_key, sub_key, value=None):
213-
list_dict = self.control_attributes.textures \
214-
if main_key in self.control_attributes.textures \
215-
else self.control_attributes.attributes
214+
list_dict = self.control_attributes['textures'] \
215+
if main_key in self.control_attributes['textures'] \
216+
else self.control_attributes['attributes']
216217

217218
if main_key.endswith("SLIDERDATA"):
218219
main_key = "SLIDERDATA"
220+
if main_key == "ENTRYFIELDDATA":
221+
main_key = "TEXTENTRYDATA"
219222

220223
for d in list_dict[main_key]:
221224
if sub_key in d and d[sub_key] != value:
222225
d[sub_key] = value
223-
# self.main_window.update_modified_state(True)
226+
self.update_modified_state(True)
227+
224228

225229
def update_texture_property(self, main_key, sub_key, image, value=None):
226-
list_dict = self.control_attributes.textures
230+
list_dict = self.control_attributes['textures']
227231

228232
for d in list_dict[main_key]:
229-
if 'image' in d and d['image'] == image and sub_key in d and d[sub_key] != value:
233+
if 'IMAGE' in d and d['IMAGE'] == image and sub_key in d and d[sub_key] != value:
230234
d[sub_key] = value
231-
# self.main_window.update_modified_state(True)
235+
self.update_modified_state(True)
232236

233237
def clear(self):
234238
"""Clear all widgets from the layout."""
@@ -291,8 +295,8 @@ def create_inner_section(title, parent, section_manager, object_name):
291295
def filter_empty_properties(properties_list):
292296
return [
293297
prop for prop in properties_list if not (
294-
'image' in prop and prop['image'] == 'NoImage'
295-
and 'color' in prop and prop['color'] == (255, 255, 255, 0)
298+
'IMAGE' in prop and prop['IMAGE'] == 'NoImage'
299+
and 'COLOR' in prop and prop['COLOR'] == (255, 255, 255, 0)
296300
and 'BORDERCOLOR' in prop and prop['BORDERCOLOR'] == (255, 255, 255, 0)
297301
)
298302
]

src/properties/general_properties.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,13 @@ def update_resolution(self, width, height):
278278
self.bottom_right_y_spinbox.setMaximum(self.creation_resolution_height)
279279

280280
def update_key_property(self, main_key, value=None):
281-
old_value = getattr(self.general_data, main_key, None)
281+
old_value = self.general_data[main_key]
282282
if old_value != value:
283-
setattr(self.general_data, main_key, value)
283+
self.general_data[main_key] = value
284284
self.main_window.update_modified_state(True)
285285

286286
def update_sub_property(self, main_key, sub_key, value=None):
287-
attr = getattr(self.general_data, main_key)
287+
attr = self.general_data[main_key]
288288
if isinstance(attr, dict):
289289
if sub_key in attr:
290290
old_value = attr[sub_key]

src/property_editor.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from src.properties.control_properties import ControlForm
77
from src.window.line_iterator import LineIterator
8-
from src.window.window_properties import parse_window_properties, Window
8+
from src.window.window_properties import parse_window_properties
99
from src.properties.general_properties import GeneralForm
1010

1111
class PropertyEditor(QWidget):
@@ -17,6 +17,7 @@ def __init__(self, parent=None, main_window=None):
1717
super().__init__(parent)
1818
self.main_window = main_window
1919
self.properties = {}
20+
self.control_object = None
2021

2122
# Create tabs
2223
self.tabs = QTabWidget(self)
@@ -97,17 +98,18 @@ def create_raw_tab(self):
9798
# Set layout for raw_tab
9899
self.raw_tab.setLayout(raw_layout)
99100

100-
def load_property(self, properties):
101+
def load_property(self, control):
101102
"""Loads the properties of a selected object into the editor."""
102103
status = self.main_window.is_modified
103104
self.clear() # Clear any previous data
104-
105+
properties = control.properties
105106
if not properties:
106107
self.empty_label.setVisible(True) # Show the empty label if no properties
107108
return
108109

109110
self.original_properties = copy.deepcopy(properties)
110-
self.properties = properties
111+
self.properties = control.properties
112+
self.control_object = control
111113
self.empty_label.setVisible(False)
112114
self.tabs.setVisible(True)
113115

@@ -135,6 +137,7 @@ def load_control_properties(self, properties=None):
135137

136138
self.control_properties = ControlForm(self, control_attributes=properties)
137139
self.control_tab.layout().addWidget(self.control_properties)
140+
self.control_properties.update_modified_state = self.main_window.update_modified_state
138141

139142
# self.control_properties.type = properties.get('WINDOWTYPE', 'No type')
140143
# self.control_properties.type_label.setText(f"Type: {self.control_properties.type}")
@@ -234,7 +237,7 @@ def load_general_properties(self, properties=None):
234237

235238
def load_raw_properties(self):
236239
"""Loads the raw properties into the raw editor."""
237-
self.raw_edit.setPlainText(repr(self.properties))
240+
self.raw_edit.setPlainText(repr(self.control_object))
238241

239242
def display_error(self, error_message):
240243
"""Displays an error message in the property editor."""
@@ -258,9 +261,12 @@ def save_raw_properties(self):
258261
raw = self.raw_edit.toPlainText()
259262

260263
try:
261-
self.properties = parse_window_properties(LineIterator(raw.splitlines()))
264+
self.control_object = parse_window_properties(LineIterator(raw.splitlines()),
265+
window_uuid=self.control_object.window_uuid,
266+
file_name=self.control_object.file_name)
262267

263268
# If no error occurs, update the properties
269+
self.properties = self.control_object.properties
264270
self.error_label.setText("")
265271
self.main_window.selected_object.properties = self.properties
266272
self.load_general_properties()

src/window/controls/checkbox.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from src.window.controls.user import UserControl
2+
3+
4+
class CheckBoxControl(UserControl):
5+
def __init__(self, window_uuid, properties=None, children=None, file_name=None):
6+
super().__init__(window_uuid, properties, children, file_name)
7+
# Assign default values for CheckBoxControl
8+
if properties:
9+
self.properties.update(properties)
10+
else:
11+
self.properties['WINDOWTYPE'] = 'CHECKBOX'
12+
self.properties['NAME'] = 'CheckBox'
13+
self.properties['STYLE'] = ['CHECKBOX', 'MOUSETRACK']
14+
self.properties['STATUS'] = ['ENABLED', 'IMAGE', 'BORDER']
15+
self.properties['HEADERTEMPLATE'] = 'LabelRegular'
16+
self.properties['TEXT'] = 'CheckBox'
17+
self.properties['textures'] = {
18+
'ENABLEDDRAWDATA': [
19+
{'IMAGE': 'NoImage', 'COLOR': (255, 0, 0, 255), 'BORDERCOLOR': (255, 128, 128, 255)},
20+
{'IMAGE': 'Active-Unchecked', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (128, 128, 255, 255)},
21+
{'IMAGE': 'Active-Checked', 'COLOR': (0, 0, 255, 255), 'BORDERCOLOR': (128, 128, 255, 255)},
22+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
23+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
24+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
25+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
26+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
27+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)}
28+
],
29+
'DISABLEDDRAWDATA': [
30+
{'IMAGE': 'NoImage', 'COLOR': (128, 128, 128, 255), 'BORDERCOLOR': (192, 192, 192, 255)},
31+
{'IMAGE': 'Disabled-Unchecked', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (192, 192, 192, 255)},
32+
{'IMAGE': 'Disabled-Checked', 'COLOR': (64, 64, 64, 255), 'BORDERCOLOR': (254, 254, 254, 255)},
33+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
34+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
35+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
36+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
37+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
38+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)}
39+
],
40+
'HILITEDRAWDATA': [
41+
{'IMAGE': 'NoImage', 'COLOR': (0, 255, 0, 255), 'BORDERCOLOR': (128, 255, 128, 255)},
42+
{'IMAGE': 'Active-HiLighted', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (128, 128, 255, 255)},
43+
{'IMAGE': 'Active-Checked', 'COLOR': (255, 255, 0, 255), 'BORDERCOLOR': (254, 254, 254, 255)},
44+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
45+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
46+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
47+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
48+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
49+
{'IMAGE': 'NoImage', 'COLOR': (255, 255, 255, 0), 'BORDERCOLOR': (255, 255, 255, 0)},
50+
]
51+
}

0 commit comments

Comments
 (0)