""" 手动调整功能 """ import streamlit as st from .state_manager import save_state_for_undo from .drawing import clear_table_image_cache def create_adjustment_section(structure): """ 创建手动调整区域 Args: structure: 表格结构字典 Returns: 是否进行了调整(用于判断是否需要重新渲染) """ st.divider() st.header("🛠️ 手动调整") adjusted = False # 横线调整 with st.expander("📏 调整横线位置", expanded=False): horizontal_lines = structure.get('horizontal_lines', []) if not horizontal_lines: st.warning("⚠️ 没有检测到横线") else: st.info(f"当前有 {len(horizontal_lines)} 条横线") # 选择要调整的横线 line_index = st.selectbox( "选择横线", range(len(horizontal_lines)), format_func=lambda i: f"R{i+1} (Y={horizontal_lines[i]})" ) # 显示当前Y坐标 current_y = horizontal_lines[line_index] st.text(f"当前Y坐标: {current_y}") # 输入新的Y坐标 col1, col2 = st.columns([3, 1]) with col1: new_y = st.number_input( "新的Y坐标", min_value=0, value=current_y, step=1, key=f"h_line_{line_index}" ) with col2: if st.button("✅ 应用", key=f"apply_h_{line_index}"): if new_y != current_y: # 保存状态 save_state_for_undo(structure) # 更新横线 structure['horizontal_lines'][line_index] = new_y # 标记为已修改 structure.setdefault('modified_h_lines', set()).add(line_index) # 重新计算行区间 _update_row_intervals(structure) clear_table_image_cache() adjusted = True st.success(f"✅ 已更新 R{line_index+1} 到 Y={new_y}") st.rerun() # 竖线调整 with st.expander("📏 调整竖线位置", expanded=False): vertical_lines = structure.get('vertical_lines', []) if not vertical_lines: st.warning("⚠️ 没有检测到竖线") else: st.info(f"当前有 {len(vertical_lines)} 条竖线") # 选择要调整的竖线 line_index = st.selectbox( "选择竖线", range(len(vertical_lines)), format_func=lambda i: f"C{i+1} (X={vertical_lines[i]})" ) # 显示当前X坐标 current_x = vertical_lines[line_index] st.text(f"当前X坐标: {current_x}") # 输入新的X坐标 col1, col2 = st.columns([3, 1]) with col1: new_x = st.number_input( "新的X坐标", min_value=0, value=current_x, step=1, key=f"v_line_{line_index}" ) with col2: if st.button("✅ 应用", key=f"apply_v_{line_index}"): if new_x != current_x: # 保存状态 save_state_for_undo(structure) # 更新竖线 structure['vertical_lines'][line_index] = new_x # 标记为已修改 structure.setdefault('modified_v_lines', set()).add(line_index) # 重新计算列区间 _update_column_intervals(structure) clear_table_image_cache() adjusted = True st.success(f"✅ 已更新 C{line_index+1} 到 X={new_x}") st.rerun() # 添加横线 with st.expander("➕ 添加横线", expanded=False): horizontal_lines = structure.get('horizontal_lines', []) col1, col2 = st.columns([3, 1]) with col1: new_h_y = st.number_input( "新横线的Y坐标", min_value=0, value=horizontal_lines[-1] + 50 if horizontal_lines else 100, step=1, key="new_h_line" ) with col2: if st.button("➕ 添加", key="add_h_line"): # 保存状态 save_state_for_undo(structure) # 插入新横线(保持排序) horizontal_lines.append(new_h_y) horizontal_lines.sort() # 找到新线的索引 new_index = horizontal_lines.index(new_h_y) # 标记为已修改 structure.setdefault('modified_h_lines', set()).add(new_index) # 重新计算行区间 _update_row_intervals(structure) clear_table_image_cache() adjusted = True st.success(f"✅ 已添加横线 Y={new_h_y}") st.rerun() # 删除横线 with st.expander("🗑️ 删除横线", expanded=False): horizontal_lines = structure.get('horizontal_lines', []) if len(horizontal_lines) <= 2: st.warning("⚠️ 至少需要保留2条横线(表格顶部和底部)") else: # 多选要删除的横线 to_delete = st.multiselect( "选择要删除的横线", range(len(horizontal_lines)), format_func=lambda i: f"R{i+1} (Y={horizontal_lines[i]})", key="delete_h_lines" ) if to_delete and st.button("🗑️ 删除选中", key="confirm_delete_h"): # 保存状态 save_state_for_undo(structure) # 删除选中的横线(从后往前删) for idx in sorted(to_delete, reverse=True): del horizontal_lines[idx] # 重新计算修改标记 structure['modified_h_lines'] = set() # 重新计算行区间 _update_row_intervals(structure) clear_table_image_cache() adjusted = True st.success(f"✅ 已删除 {len(to_delete)} 条横线") st.rerun() # 添加竖线 with st.expander("➕ 添加竖线", expanded=False): vertical_lines = structure.get('vertical_lines', []) col1, col2 = st.columns([3, 1]) with col1: new_v_x = st.number_input( "新竖线的X坐标", min_value=0, value=vertical_lines[-1] + 100 if vertical_lines else 100, step=1, key="new_v_line" ) with col2: if st.button("➕ 添加", key="add_v_line"): # 保存状态 save_state_for_undo(structure) # 插入新竖线(保持排序) vertical_lines.append(new_v_x) vertical_lines.sort() # 找到新线的索引 new_index = vertical_lines.index(new_v_x) # 标记为已修改 structure.setdefault('modified_v_lines', set()).add(new_index) # 重新计算列区间 _update_column_intervals(structure) clear_table_image_cache() adjusted = True st.success(f"✅ 已添加竖线 X={new_v_x}") st.rerun() # 删除竖线 with st.expander("🗑️ 删除竖线", expanded=False): vertical_lines = structure.get('vertical_lines', []) if len(vertical_lines) <= 2: st.warning("⚠️ 至少需要保留2条竖线(表格左侧和右侧)") else: # 多选要删除的竖线 to_delete = st.multiselect( "选择要删除的竖线", range(len(vertical_lines)), format_func=lambda i: f"C{i+1} (X={vertical_lines[i]})", key="delete_v_lines" ) if to_delete and st.button("🗑️ 删除选中", key="confirm_delete_v"): # 保存状态 save_state_for_undo(structure) # 删除选中的竖线(从后往前删) for idx in sorted(to_delete, reverse=True): del vertical_lines[idx] # 重新计算修改标记 structure['modified_v_lines'] = set() # 重新计算列区间 _update_column_intervals(structure) clear_table_image_cache() adjusted = True st.success(f"✅ 已删除 {len(to_delete)} 条竖线") st.rerun() return adjusted def _update_row_intervals(structure): """根据横线坐标更新行区间""" horizontal_lines = structure.get('horizontal_lines', []) rows = [] for i in range(len(horizontal_lines) - 1): rows.append({ 'y_start': horizontal_lines[i], 'y_end': horizontal_lines[i + 1], 'bboxes': [] }) structure['rows'] = rows # 更新表格边界框 if 'table_bbox' in structure: vertical_lines = structure.get('vertical_lines', []) structure['table_bbox'] = [ vertical_lines[0] if vertical_lines else 0, horizontal_lines[0], vertical_lines[-1] if vertical_lines else 0, horizontal_lines[-1] ] def _update_column_intervals(structure): """根据竖线坐标更新列区间""" vertical_lines = structure.get('vertical_lines', []) columns = [] for i in range(len(vertical_lines) - 1): columns.append({ 'x_start': vertical_lines[i], 'x_end': vertical_lines[i + 1] }) structure['columns'] = columns # 更新列宽 col_widths = [col['x_end'] - col['x_start'] for col in columns] structure['col_widths'] = col_widths # 更新表格边界框 if 'table_bbox' in structure: horizontal_lines = structure.get('horizontal_lines', []) structure['table_bbox'] = [ vertical_lines[0], horizontal_lines[0] if horizontal_lines else 0, vertical_lines[-1], horizontal_lines[-1] if horizontal_lines else 0 ]