adjustments.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. """
  2. 手动调整功能
  3. """
  4. from .state_manager import save_state_for_undo
  5. from .drawing import clear_table_image_cache
  6. def create_adjustment_section(structure):
  7. """
  8. 创建手动调整区域
  9. """
  10. import streamlit as st
  11. st.divider()
  12. st.header("🛠️ 手动调整")
  13. horizontal_lines = structure.get('horizontal_lines', [])
  14. vertical_lines = structure.get('vertical_lines', [])
  15. adjusted = False
  16. # 行操作, 列操作
  17. adjustment_action = st.radio(
  18. "行&列操作",
  19. ["调整横线", "添加横线", "删除横线", "调整竖线", "添加竖线", "删除竖线"],
  20. horizontal=True,
  21. index=None,
  22. label_visibility="collapsed",
  23. key="adjustment_action_radio"
  24. )
  25. if adjustment_action == "调整横线" and horizontal_lines:
  26. line_index = st.selectbox(
  27. "选择横线",
  28. range(len(horizontal_lines)),
  29. format_func=lambda i: f"R{i+1} (Y={horizontal_lines[i]})",
  30. key="adjust_h_select"
  31. )
  32. new_y = st.number_input(
  33. "新的Y坐标",
  34. min_value=0,
  35. value=horizontal_lines[line_index],
  36. step=1,
  37. key="adjust_h_value"
  38. )
  39. if st.button("✅ 应用横线调整"):
  40. if new_y != horizontal_lines[line_index]:
  41. save_state_for_undo(structure)
  42. structure['horizontal_lines'][line_index] = new_y
  43. structure.setdefault('modified_h_lines', set()).add(line_index)
  44. _update_row_intervals(structure)
  45. clear_table_image_cache()
  46. adjusted = True
  47. st.success(f"✅ R{line_index+1} 已更新")
  48. elif adjustment_action == "添加横线":
  49. new_h_y = st.number_input(
  50. "新横线的Y坐标",
  51. min_value=0,
  52. value=horizontal_lines[-1] + 50 if horizontal_lines else 100,
  53. step=1,
  54. key="add_h_value"
  55. )
  56. if st.button("➕ 确认添加横线"):
  57. save_state_for_undo(structure)
  58. structure['horizontal_lines'].append(new_h_y)
  59. structure['horizontal_lines'].sort()
  60. idx = structure['horizontal_lines'].index(new_h_y)
  61. structure.setdefault('modified_h_lines', set()).add(idx)
  62. _update_row_intervals(structure)
  63. clear_table_image_cache()
  64. adjusted = True
  65. st.success(f"✅ 新增横线 Y={new_h_y}")
  66. elif adjustment_action == "删除横线" and len(horizontal_lines) > 2:
  67. to_delete = st.multiselect(
  68. "选择要删除的横线",
  69. range(len(horizontal_lines)),
  70. format_func=lambda i: f"R{i+1} (Y={horizontal_lines[i]})",
  71. key="del_h_select"
  72. )
  73. if to_delete and st.button("🗑️ 确认删除横线"):
  74. save_state_for_undo(structure)
  75. for idx in sorted(to_delete, reverse=True):
  76. del structure['horizontal_lines'][idx]
  77. structure['modified_h_lines'] = set()
  78. _update_row_intervals(structure)
  79. clear_table_image_cache()
  80. adjusted = True
  81. st.success(f"✅ 已删除 {len(to_delete)} 条横线")
  82. elif adjustment_action == "调整竖线" and vertical_lines:
  83. line_index = st.selectbox(
  84. "选择竖线",
  85. range(len(vertical_lines)),
  86. format_func=lambda i: f"C{i+1} (X={vertical_lines[i]})",
  87. key="adjust_v_select"
  88. )
  89. new_x = st.number_input(
  90. "新的X坐标",
  91. min_value=0,
  92. value=vertical_lines[line_index],
  93. step=1,
  94. key="adjust_v_value"
  95. )
  96. if st.button("✅ 应用竖线调整"):
  97. if new_x != vertical_lines[line_index]:
  98. save_state_for_undo(structure)
  99. structure['vertical_lines'][line_index] = new_x
  100. structure.setdefault('modified_v_lines', set()).add(line_index)
  101. _update_column_intervals(structure)
  102. clear_table_image_cache()
  103. adjusted = True
  104. st.success(f"✅ C{line_index+1} 已更新")
  105. elif adjustment_action == "添加竖线":
  106. new_v_x = st.number_input(
  107. "新竖线的X坐标",
  108. min_value=0,
  109. value=vertical_lines[-1] + 100 if vertical_lines else 100,
  110. step=1,
  111. key="add_v_value"
  112. )
  113. if st.button("➕ 确认添加竖线"):
  114. save_state_for_undo(structure)
  115. structure['vertical_lines'].append(new_v_x)
  116. structure['vertical_lines'].sort()
  117. idx = structure['vertical_lines'].index(new_v_x)
  118. structure.setdefault('modified_v_lines', set()).add(idx)
  119. _update_column_intervals(structure)
  120. clear_table_image_cache()
  121. adjusted = True
  122. st.success(f"✅ 新增竖线 X={new_v_x}")
  123. elif adjustment_action == "删除竖线" and len(vertical_lines) > 2:
  124. to_delete = st.multiselect(
  125. "选择要删除的竖线",
  126. range(len(vertical_lines)),
  127. format_func=lambda i: f"C{i+1} (X={vertical_lines[i]})",
  128. key="del_v_select"
  129. )
  130. if to_delete and st.button("🗑️ 确认删除竖线"):
  131. save_state_for_undo(structure)
  132. for idx in sorted(to_delete, reverse=True):
  133. del structure['vertical_lines'][idx]
  134. structure['modified_v_lines'] = set()
  135. _update_column_intervals(structure)
  136. clear_table_image_cache()
  137. adjusted = True
  138. st.success(f"✅ 已删除 {len(to_delete)} 条竖线")
  139. return adjusted
  140. def _update_row_intervals(structure):
  141. """根据横线坐标更新行区间"""
  142. horizontal_lines = structure.get('horizontal_lines', [])
  143. rows = []
  144. for i in range(len(horizontal_lines) - 1):
  145. rows.append({
  146. 'y_start': horizontal_lines[i],
  147. 'y_end': horizontal_lines[i + 1],
  148. 'bboxes': []
  149. })
  150. structure['rows'] = rows
  151. # 更新表格边界框
  152. if 'table_bbox' in structure:
  153. vertical_lines = structure.get('vertical_lines', [])
  154. structure['table_bbox'] = [
  155. vertical_lines[0] if vertical_lines else 0,
  156. horizontal_lines[0],
  157. vertical_lines[-1] if vertical_lines else 0,
  158. horizontal_lines[-1]
  159. ]
  160. def _update_column_intervals(structure):
  161. """根据竖线坐标更新列区间"""
  162. vertical_lines = structure.get('vertical_lines', [])
  163. columns = []
  164. for i in range(len(vertical_lines) - 1):
  165. columns.append({
  166. 'x_start': vertical_lines[i],
  167. 'x_end': vertical_lines[i + 1]
  168. })
  169. structure['columns'] = columns
  170. # 更新列宽
  171. col_widths = [col['x_end'] - col['x_start'] for col in columns]
  172. structure['col_widths'] = col_widths
  173. # 更新表格边界框
  174. if 'table_bbox' in structure:
  175. horizontal_lines = structure.get('horizontal_lines', [])
  176. structure['table_bbox'] = [
  177. vertical_lines[0],
  178. horizontal_lines[0] if horizontal_lines else 0,
  179. vertical_lines[-1],
  180. horizontal_lines[-1] if horizontal_lines else 0
  181. ]