1+ import os
2+
3+ from PyQt5 .QtWidgets import QDialog , QDialogButtonBox
4+ from PyQt5 .uic import loadUi
5+
6+ from .layer_selection_table import LayerSelectionTable
7+
8+
9+ class AddFoliationDialog (QDialog ):
10+ def __init__ (self , parent = None , * , data_manager = None , model_manager = None ):
11+ super ().__init__ (parent )
12+ self .data_manager = data_manager
13+ self .model_manager = model_manager
14+ ui_path = os .path .join (os .path .dirname (__file__ ), 'add_foliation_dialog.ui' )
15+ loadUi (ui_path , self )
16+ self .setWindowTitle ('Add Foliation' )
17+
18+ # Create the layer selection table widget
19+ self .layer_table = LayerSelectionTable (
20+ data_manager = self .data_manager ,
21+ feature_name_provider = lambda : self .name ,
22+ name_validator = lambda : (self .name_valid , self .name_error )
23+ )
24+
25+ # Replace or integrate with existing UI
26+ self ._integrate_layer_table ()
27+
28+ self .buttonBox .accepted .connect (self .add_foliation )
29+ self .buttonBox .rejected .connect (self .cancel )
30+
31+ self .modelFeatureComboBox .addItems (
32+ [f .name for f in self .model_manager .features () if not f .name .startswith ("__" )]
33+ )
34+ self .name_valid = False
35+ self .name_error = ""
36+
37+ def validate_name_field (text ):
38+ """Validate the feature name field."""
39+ valid = True
40+ old_name = self .name
41+ new_name = text .strip ()
42+
43+ if not new_name :
44+ valid = False
45+ self .name_error = "Feature name cannot be empty."
46+ elif new_name in [f .name for f in self .model_manager .features ()]:
47+ valid = False
48+ self .name_error = "Feature name must be unique."
49+ elif new_name in self .data_manager .feature_data :
50+ valid = False
51+ self .name_error = "Layer already exists in the data manager."
52+
53+ if not valid :
54+ self .name_valid = False
55+ self .feature_name_input .setStyleSheet ("border: 1px solid red;" )
56+ else :
57+ self .feature_name_input .setStyleSheet ("" )
58+ self .name_valid = True
59+
60+ # Enable/disable the OK button based on validation
61+ self .buttonBox .button (QDialogButtonBox .Ok ).setEnabled (self .name_valid )
62+
63+ # If the name changes, update the data manager key and reinitialize table
64+ if old_name != new_name and old_name in self .data_manager .feature_data :
65+ # Save current table data
66+ old_data = self .layer_table .get_table_data ()
67+
68+ # Remove old key and set new key
69+ self .data_manager .feature_data .pop (old_name , None )
70+ if new_name and valid :
71+ self .data_manager .feature_data [new_name ] = old_data
72+
73+ # Update table to reflect new feature name
74+ self .layer_table .initialize_feature_data ()
75+ self .layer_table .restore_table_state ()
76+
77+ self .feature_name_input .textChanged .connect (validate_name_field )
78+
79+ @property
80+ def name (self ):
81+ return self .feature_name_input .text ().strip ()
82+
83+ def add_foliation (self ):
84+ if not self .name_valid :
85+ self .data_manager .logger (f'Name is invalid: { self .name_error } ' , log_level = 2 )
86+ return
87+
88+ # Ensure table state is synchronized with data manager
89+ self .layer_table .sync_table_with_data ()
90+
91+ # Check if we have any layers selected
92+ if not self .layer_table .has_layers ():
93+ self .data_manager .logger ("No layers selected for the foliation." , log_level = 2 )
94+ return
95+
96+ folded_feature_name = None
97+ if self .modelFeatureComboBox .currentText () != "" :
98+ folded_feature_name = self .modelFeatureComboBox .currentText ()
99+
100+ self .data_manager .add_foliation_to_model (self .name , folded_feature_name = folded_feature_name )
101+ self .accept () # Close the dialog
102+
103+ def cancel (self ):
104+ # Clean up any temporary data if necessary
105+ if self .name in self .data_manager .feature_data :
106+ self .data_manager .feature_data .pop (self .name , None )
107+ self .reject ()
108+
109+ def _integrate_layer_table (self ):
110+ """Integrate the layer table widget with the existing UI."""
111+ # Try to replace existing table widget if it exists
112+ if hasattr (self , 'items_table' ):
113+ table_parent = self .items_table .parent ()
114+
115+ # Get the position of the original table
116+ if hasattr (table_parent , 'layout' ) and table_parent .layout ():
117+ layout = table_parent .layout ()
118+
119+ # Find the index of the original table in the layout
120+ table_index = - 1
121+ for i in range (layout .count ()):
122+ item = layout .itemAt (i )
123+ if item and item .widget () == self .items_table :
124+ table_index = i
125+ break
126+
127+ # Remove original widgets
128+ if hasattr (self , 'items_table' ):
129+ self .items_table .setParent (None )
130+ if hasattr (self , 'add_item_button' ):
131+ self .add_item_button .setParent (None )
132+
133+ # Insert new widget at the same position
134+ if table_index >= 0 :
135+ layout .insertWidget (table_index , self .layer_table )
136+ else :
137+ layout .addWidget (self .layer_table )
138+ else :
139+ # Fallback: add to parent widget directly
140+ if hasattr (table_parent , 'layout' ) and not table_parent .layout ():
141+ from PyQt5 .QtWidgets import QVBoxLayout
142+ layout = QVBoxLayout (table_parent )
143+ table_parent .setLayout (layout )
144+ layout .addWidget (self .layer_table )
145+
146+ # If no existing table found, try to add to main layout
147+ elif hasattr (self , 'layout' ) and self .layout ():
148+ self .layout ().addWidget (self .layer_table )
0 commit comments