Skip to content

Commit 45d6bbf

Browse files
committed
Dev : add_table function modified and fixed
1 parent 71262b7 commit 45d6bbf

File tree

7 files changed

+118
-77
lines changed

7 files changed

+118
-77
lines changed

AutoCAD/AutoCAD_Module.py

Lines changed: 112 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -145,33 +145,31 @@ def __repr__(self):
145145

146146

147147
class Table:
148-
"""Represents a full-featured AutoCAD table."""
149-
def __init__(self, insertion_point: APoint, data: list[list[str]], headers: list[str] = None, title: str = None,
150-
col_widths: list[float] = None, row_height: float = 8.0, text_height: float = 2.5,
151-
alignment: Alignment = Alignment.CENTER):
148+
"""Represents a data table to be drawn in AutoCAD."""
149+
150+
def __init__(self, insertion_point: APoint, data: list[list[str]], headers: list[str] = None,
151+
col_widths: list[float] = None, row_height: float = 8.0, text_height: float = 2.5, text_style: str = None):
152152
"""
153153
Initializes a table data object.
154154
Args:
155155
insertion_point (APoint): The top-left insertion point for the table.
156156
data (list[list[str]]): A list of lists representing the table's body data.
157157
headers (list[str], optional): A list of strings for the header row. Defaults to None.
158-
title (str, optional): A title for the table. Defaults to None.
159-
col_widths (list[float], optional): A list of widths for each column. If None, widths are automatic.
158+
col_widths (list[float], optional): A list of widths for each column.
160159
row_height (float): The height for each row.
161160
text_height (float): The default text height for cells.
162-
alignment (Alignment): The alignment for cell content. Defaults to Alignment.CENTER.
161+
text_style (str, optional): The text style to use. Defaults to None (use default).
163162
"""
164163
self.insertion_point = insertion_point
165164
self.data = data
166165
self.headers = headers
167-
self.title = title
168166
self.col_widths = col_widths
169167
self.row_height = row_height
170168
self.text_height = text_height
171-
self.alignment = alignment
169+
self.text_style = text_style
172170

173171
def __repr__(self):
174-
return f"Table(title='{self.title}', rows={len(self.data)}, cols={len(self.data[0]) if self.data else 0})"
172+
return f"Table(rows={len(self.data)}, cols={len(self.data[0]) if self.data else 0}, text_style={self.text_style})"
175173

176174

177175
class Text:
@@ -1188,23 +1186,51 @@ def select_group(self, group_name):
11881186
except Exception as e:
11891187
raise CADException(f"Error selecting group '{group_name}': {e}")
11901188

1191-
def add_mtext(self, content: str, insertion_point: APoint, width: float, height: float):
1189+
def add_mtext(self, content: str, insertion_point: APoint, width: float, height: float, text_style: str = None,
1190+
attachment_point: int = 1):
11921191
"""
1193-
Adds a multiline text (MText) object to the model space.
1192+
Adds a multiline text (MText) object to the model space with specified alignment.
1193+
11941194
Args:
11951195
content (str): The text string to display. Can include newlines.
1196-
insertion_point (APoint): The insertion point for the top-left corner of the text box.
1196+
insertion_point (APoint): The insertion point for the text, relative to the alignment.
11971197
width (float): The width of the MText bounding box.
11981198
height (float): The height of the text characters.
1199+
text_style (str, optional): The name of the text style to use. Defaults to None (use default).
1200+
attachment_point (int): The COM constant for the attachment point (e.g., 1 for TopLeft, 5 for MiddleCenter).
1201+
11991202
Returns:
12001203
The created MText object.
12011204
12021205
Raises:
12031206
CADException: If the MText object cannot be added.
12041207
"""
12051208
try:
1206-
mtext_obj = self.modelspace.AddMText(insertion_point.to_variant(), width, content)
1209+
temp_point = APoint(0, 0, 0)
1210+
mtext_obj = self.modelspace.AddMText(temp_point.to_variant(), width, content)
12071211
mtext_obj.Height = height
1212+
1213+
mtext_obj.AttachmentPoint = attachment_point
1214+
if text_style:
1215+
text_styles = self.doc.TextStyles
1216+
style_exists = False
1217+
for style in text_styles:
1218+
if style.Name.lower() == text_style.lower():
1219+
style_exists = True
1220+
break
1221+
1222+
if style_exists:
1223+
try:
1224+
mtext_obj.StyleName = text_style
1225+
except Exception as e:
1226+
print(f"Error setting TextStyle '{text_style}': {e}. Using default.")
1227+
mtext_obj.StyleName = "Standard"
1228+
else:
1229+
print(f"Warning: TextStyle '{text_style}' not found in drawing. Using 'Standard' style.")
1230+
mtext_obj.StyleName = "Standard"
1231+
1232+
mtext_obj.InsertionPoint = insertion_point.to_variant()
1233+
12081234
return mtext_obj
12091235
except Exception as e:
12101236
raise CADException(f"Error adding MText: {e}")
@@ -1240,78 +1266,93 @@ def zoom_to_object(self, obj):
12401266

12411267
def add_table(self, table_obj: Table):
12421268
"""
1243-
Adds a fully-featured table to the model space from a Table object.
1269+
Adds a table to the model space by manually drawing lines and text.
1270+
This version is optimized for tables with headers and data only (no title)
1271+
and provides precise text alignment within each cell.
1272+
12441273
Args:
12451274
table_obj (Table): The Table data object to draw.
1246-
Returns:
1247-
The created AutoCAD table object.
12481275
Raises:
12491276
CADException: If the table cannot be created or data is inconsistent.
12501277
"""
12511278
try:
12521279
if not table_obj.data or not isinstance(table_obj.data[0], list):
12531280
raise ValueError("Input 'data' must be a non-empty list of lists.")
1254-
1255-
num_data_rows = len(table_obj.data)
12561281
num_cols = len(table_obj.data[0])
1257-
1282+
if num_cols == 0:
1283+
raise ValueError("Input 'data' must contain at least one column.")
12581284
if table_obj.headers and len(table_obj.headers) != num_cols:
12591285
raise ValueError("Number of headers must match the number of columns in data.")
1286+
if not table_obj.col_widths or len(table_obj.col_widths) != num_cols:
1287+
raise ValueError("A list of column widths matching the number of columns is required for manual creation.")
12601288

1261-
total_rows = num_data_rows
1262-
has_title = table_obj.title is not None
1263-
has_headers = table_obj.headers is not None
1264-
if has_title:
1265-
total_rows += 1
1266-
if has_headers:
1267-
total_rows += 1
1268-
1269-
default_col_width = 20.0
1270-
if table_obj.col_widths and table_obj.col_widths[0] > 0:
1271-
default_col_width = table_obj.col_widths[0]
1272-
1273-
table = self.modelspace.AddTable(table_obj.insertion_point.to_variant(), total_rows, num_cols,
1274-
table_obj.row_height, default_col_width)
1275-
1276-
alignment_map = {
1277-
Alignment.LEFT: 4,
1278-
Alignment.CENTER: 5,
1279-
Alignment.RIGHT: 6,
1280-
}
1281-
acad_alignment = alignment_map.get(table_obj.alignment, 5)
1282-
1283-
table.SetTextHeight(table_obj.text_height)
1284-
table.SetAlignment(acad_alignment)
1285-
1286-
current_row = 0
1287-
if has_title:
1288-
table.SetRowType(current_row, 1)
1289-
table.SetText(current_row, 0, table_obj.title)
1290-
table.MergeCells(current_row, 0, current_row, num_cols - 1)
1291-
current_row += 1
1292-
1293-
if has_headers:
1294-
table.SetRowType(current_row, 2)
1295-
for col_idx, header_text in enumerate(table_obj.headers):
1296-
table.SetText(current_row, col_idx, header_text)
1297-
current_row += 1
1289+
ip = table_obj.insertion_point
1290+
col_widths = table_obj.col_widths
1291+
row_height = table_obj.row_height
1292+
total_width = sum(col_widths)
12981293

1299-
for row_idx, data_row in enumerate(table_obj.data):
1300-
if len(data_row) != num_cols:
1301-
raise ValueError(f"Inconsistent number of columns in data row {row_idx}.")
1302-
for col_idx, cell_text in enumerate(data_row):
1303-
table.SetText(current_row + row_idx, col_idx, str(cell_text))
1294+
num_data_rows = len(table_obj.data)
1295+
num_header_rows = 1 if table_obj.headers else 0
1296+
num_total_rows = num_header_rows + num_data_rows
1297+
total_height = num_total_rows * row_height
1298+
1299+
current_y = ip.y
1300+
for _ in range(num_total_rows + 1):
1301+
self.add_line(APoint(ip.x, current_y), APoint(ip.x + total_width, current_y))
1302+
current_y -= row_height
13041303

1305-
if table_obj.col_widths:
1306-
if len(table_obj.col_widths) != num_cols:
1307-
raise ValueError("Number of column widths must match the number of columns.")
1308-
for i, width in enumerate(table_obj.col_widths):
1309-
table.SetColumnWidth(i, width)
1304+
current_x = ip.x
1305+
for width in col_widths:
1306+
self.add_line(APoint(current_x, ip.y), APoint(current_x, ip.y - total_height))
1307+
current_x += width
1308+
self.add_line(APoint(ip.x + total_width, ip.y), APoint(ip.x + total_width, ip.y - total_height))
13101309

1311-
table.GenerateLayout()
1312-
return table
1310+
acAttachmentPointMiddleCenter = 5
1311+
1312+
current_y = ip.y
1313+
1314+
# Header Row
1315+
if table_obj.headers:
1316+
current_x = ip.x
1317+
for col_idx, header_text in enumerate(table_obj.headers):
1318+
cell_width = col_widths[col_idx]
1319+
1320+
cell_center_x = current_x + (cell_width / 2)
1321+
cell_center_y = current_y - (row_height / 2)
1322+
1323+
mtext_obj = self.add_mtext(
1324+
content=str(header_text),
1325+
insertion_point=APoint(cell_center_x, cell_center_y),
1326+
width=cell_width * 0.95,
1327+
height=table_obj.text_height,
1328+
text_style=table_obj.text_style,
1329+
attachment_point=acAttachmentPointMiddleCenter
1330+
)
1331+
mtext_obj.AttachmentPoint = acAttachmentPointMiddleCenter
1332+
current_x += cell_width
1333+
current_y -= row_height
1334+
1335+
for data_row in table_obj.data:
1336+
current_x = ip.x
1337+
for col_idx, cell_text in enumerate(data_row):
1338+
cell_width = col_widths[col_idx]
1339+
1340+
cell_center_x = current_x + (cell_width / 2)
1341+
cell_center_y = current_y - (row_height / 2)
1342+
1343+
mtext_obj = self.add_mtext(
1344+
content=str(cell_text),
1345+
insertion_point=APoint(cell_center_x, cell_center_y),
1346+
width=cell_width * 0.95,
1347+
height=table_obj.text_height,
1348+
text_style=table_obj.text_style,
1349+
attachment_point=acAttachmentPointMiddleCenter # Pass alignment directly
1350+
)
1351+
mtext_obj.AttachmentPoint = acAttachmentPointMiddleCenter
1352+
current_x += cell_width
1353+
current_y -= row_height
13131354

13141355
except ValueError as ve:
1315-
raise CADException(f"Invalid input for table creation: {ve}")
1356+
raise CADException(f"Invalid input for manual table creation: {ve}")
13161357
except Exception as e:
1317-
raise CADException(f"Error adding table: {e}")
1358+
raise CADException(f"Error during manual table creation: {e}")

AutoCAD/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
from .AutoCAD_Module import *
2-
__version__ = "0.1.8"
2+
__version__ = "0.1.9"

AutoCAD/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
print("| workflows,enabling efficient drawing manipulations, custom |")
55
print("| scripting, and automation of repetitive CAD tasks |")
66
print("| using Python. |")
7-
print("| version : 0.1.8 By - JonesPeter |")
7+
print("| version : 0.1.9 By - JonesPeter |")
88
print("| github : https://github.com/Jones-peter |")
99
print("| |")
1010
print("╚──────────────────────────Unlimited CAD Automation───────────────────────────╝")

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![acadlib.png](https://i.postimg.cc/xjBy2P1f/acadlib.png)](https://postimg.cc/5jqF5LzT)
22

3-
# AutoCAD - python library Latest Version 0.1.8
3+
# AutoCAD - python library Latest Version 0.1.9
44
[![GitHub](https://img.shields.io/badge/GitHub-Jones--peter-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/Jones-peter) [![Instagram](https://img.shields.io/badge/Instagram-jones__peter__-E4405F?style=for-the-badge&logo=instagram&logoColor=white)](https://www.instagram.com/jones_peter__/) [![LinkedIn](https://img.shields.io/badge/LinkedIn-Jones--Peter-0A66C2?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/jones-peter-121157221/) [![Website](https://img.shields.io/badge/Website-jonespeter.site-0078D4?style=for-the-badge&logo=google-chrome&logoColor=white)](https://jonespeter.site)
55

66
[![PyPI version](https://img.shields.io/pypi/v/AutoCAD)](https://pypi.org/project/AutoCAD/)

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
# The full version, including alpha/beta/rc tags
2727
# This should match the version in your README/pyproject.toml
28-
release = '0.1.8'
28+
release = '0.1.9'
2929

3030

3131
# -- General configuration ---------------------------------------------------

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setup(
1010
name="AutoCAD",
11-
version="0.1.8",
11+
version="0.1.9",
1212
packages=find_packages(),
1313
install_requires=requirements,
1414
entry_points={

tests/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
acad = AutoCAD()
66
time.sleep(1)
7-
acad.open_file("D:/jones/Jones/USTS_WHEELSENSOR_SHEET.DWG")
7+
acad.open_file("D:/jones/Jones/test.DWG")
88
time.sleep(1)
99
# Collect all block references
1010
blocks = list(acad.iter_objects("AcDbBlockReference"))

0 commit comments

Comments
 (0)