| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- """
- 手动调整功能
- """
- 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
- ]
|