BERATools 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. beratools/__init__.py +9 -0
  2. beratools/core/__init__.py +0 -0
  3. beratools/core/algo_centerline.py +351 -0
  4. beratools/core/constants.py +86 -0
  5. beratools/core/dijkstra_algorithm.py +460 -0
  6. beratools/core/logger.py +85 -0
  7. beratools/core/tool_base.py +133 -0
  8. beratools/gui/__init__.py +15 -0
  9. beratools/gui/batch_processing_dlg.py +463 -0
  10. beratools/gui/beratools.json +2300 -0
  11. beratools/gui/bt_data.py +487 -0
  12. beratools/gui/bt_gui_main.py +691 -0
  13. beratools/gui/cli.py +18 -0
  14. beratools/gui/gui.json +8 -0
  15. beratools/gui/img/BERALogo.png +0 -0
  16. beratools/gui/img/closed.gif +0 -0
  17. beratools/gui/img/closed.png +0 -0
  18. beratools/gui/img/open.gif +0 -0
  19. beratools/gui/img/open.png +0 -0
  20. beratools/gui/img/tool.gif +0 -0
  21. beratools/gui/img/tool.png +0 -0
  22. beratools/gui/map_window.py +146 -0
  23. beratools/gui/tool_widgets.py +493 -0
  24. beratools/gui_tk/ASCII Banners.txt +248 -0
  25. beratools/gui_tk/__init__.py +20 -0
  26. beratools/gui_tk/beratools_main.py +515 -0
  27. beratools/gui_tk/bt_widgets.py +442 -0
  28. beratools/gui_tk/cli.py +18 -0
  29. beratools/gui_tk/gui.json +8 -0
  30. beratools/gui_tk/img/BERALogo.png +0 -0
  31. beratools/gui_tk/img/closed.gif +0 -0
  32. beratools/gui_tk/img/closed.png +0 -0
  33. beratools/gui_tk/img/open.gif +0 -0
  34. beratools/gui_tk/img/open.png +0 -0
  35. beratools/gui_tk/img/tool.gif +0 -0
  36. beratools/gui_tk/img/tool.png +0 -0
  37. beratools/gui_tk/main.py +14 -0
  38. beratools/gui_tk/map_window.py +144 -0
  39. beratools/gui_tk/runner.py +1481 -0
  40. beratools/gui_tk/tooltip.py +55 -0
  41. beratools/third_party/pyqtlet2/__init__.py +9 -0
  42. beratools/third_party/pyqtlet2/leaflet/__init__.py +26 -0
  43. beratools/third_party/pyqtlet2/leaflet/control/__init__.py +6 -0
  44. beratools/third_party/pyqtlet2/leaflet/control/control.py +59 -0
  45. beratools/third_party/pyqtlet2/leaflet/control/draw.py +52 -0
  46. beratools/third_party/pyqtlet2/leaflet/control/layers.py +20 -0
  47. beratools/third_party/pyqtlet2/leaflet/core/Parser.py +24 -0
  48. beratools/third_party/pyqtlet2/leaflet/core/__init__.py +2 -0
  49. beratools/third_party/pyqtlet2/leaflet/core/evented.py +180 -0
  50. beratools/third_party/pyqtlet2/leaflet/layer/__init__.py +5 -0
  51. beratools/third_party/pyqtlet2/leaflet/layer/featuregroup.py +34 -0
  52. beratools/third_party/pyqtlet2/leaflet/layer/icon/__init__.py +1 -0
  53. beratools/third_party/pyqtlet2/leaflet/layer/icon/icon.py +30 -0
  54. beratools/third_party/pyqtlet2/leaflet/layer/imageoverlay.py +18 -0
  55. beratools/third_party/pyqtlet2/leaflet/layer/layer.py +105 -0
  56. beratools/third_party/pyqtlet2/leaflet/layer/layergroup.py +45 -0
  57. beratools/third_party/pyqtlet2/leaflet/layer/marker/__init__.py +1 -0
  58. beratools/third_party/pyqtlet2/leaflet/layer/marker/marker.py +91 -0
  59. beratools/third_party/pyqtlet2/leaflet/layer/tile/__init__.py +2 -0
  60. beratools/third_party/pyqtlet2/leaflet/layer/tile/gridlayer.py +4 -0
  61. beratools/third_party/pyqtlet2/leaflet/layer/tile/tilelayer.py +16 -0
  62. beratools/third_party/pyqtlet2/leaflet/layer/vector/__init__.py +5 -0
  63. beratools/third_party/pyqtlet2/leaflet/layer/vector/circle.py +15 -0
  64. beratools/third_party/pyqtlet2/leaflet/layer/vector/circlemarker.py +18 -0
  65. beratools/third_party/pyqtlet2/leaflet/layer/vector/path.py +5 -0
  66. beratools/third_party/pyqtlet2/leaflet/layer/vector/polygon.py +14 -0
  67. beratools/third_party/pyqtlet2/leaflet/layer/vector/polyline.py +18 -0
  68. beratools/third_party/pyqtlet2/leaflet/layer/vector/rectangle.py +14 -0
  69. beratools/third_party/pyqtlet2/leaflet/map/__init__.py +1 -0
  70. beratools/third_party/pyqtlet2/leaflet/map/map.py +220 -0
  71. beratools/third_party/pyqtlet2/mapwidget.py +45 -0
  72. beratools/third_party/pyqtlet2/web/custom.js +43 -0
  73. beratools/third_party/pyqtlet2/web/map.html +23 -0
  74. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers-2x.png +0 -0
  75. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers.png +0 -0
  76. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon-2x.png +0 -0
  77. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon.png +0 -0
  78. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-shadow.png +0 -0
  79. beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.css +656 -0
  80. beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.js +6 -0
  81. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.codeclimate.yml +14 -0
  82. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.editorconfig +4 -0
  83. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.gitattributes +22 -0
  84. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.travis.yml +43 -0
  85. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/LICENSE +20 -0
  86. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers-2x.png +0 -0
  87. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers.png +0 -0
  88. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon-2x.png +0 -0
  89. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon.png +0 -0
  90. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-shadow.png +0 -0
  91. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet-2x.png +0 -0
  92. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.png +0 -0
  93. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.svg +156 -0
  94. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.css +10 -0
  95. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.js +10 -0
  96. beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/LICENSE +22 -0
  97. beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/leaflet.rotatedMarker.js +57 -0
  98. beratools/tools/Beratools_r_script.r +1120 -0
  99. beratools/tools/Ht_metrics.py +116 -0
  100. beratools/tools/__init__.py +7 -0
  101. beratools/tools/batch_processing.py +132 -0
  102. beratools/tools/canopy_threshold_relative.py +670 -0
  103. beratools/tools/canopycostraster.py +222 -0
  104. beratools/tools/centerline.py +176 -0
  105. beratools/tools/common.py +885 -0
  106. beratools/tools/fl_regen_csf.py +428 -0
  107. beratools/tools/forest_line_attributes.py +408 -0
  108. beratools/tools/forest_line_ecosite.py +216 -0
  109. beratools/tools/lapis_all.py +103 -0
  110. beratools/tools/least_cost_path_from_chm.py +152 -0
  111. beratools/tools/line_footprint_absolute.py +363 -0
  112. beratools/tools/line_footprint_fixed.py +282 -0
  113. beratools/tools/line_footprint_functions.py +720 -0
  114. beratools/tools/line_footprint_relative.py +64 -0
  115. beratools/tools/ln_relative_metrics.py +615 -0
  116. beratools/tools/r_cal_lpi_elai.r +25 -0
  117. beratools/tools/r_generate_pd_focalraster.r +101 -0
  118. beratools/tools/r_interface.py +80 -0
  119. beratools/tools/r_point_density.r +9 -0
  120. beratools/tools/rpy_chm2trees.py +86 -0
  121. beratools/tools/rpy_dsm_chm_by.py +81 -0
  122. beratools/tools/rpy_dtm_by.py +63 -0
  123. beratools/tools/rpy_find_cellsize.py +43 -0
  124. beratools/tools/rpy_gnd_csf.py +74 -0
  125. beratools/tools/rpy_hummock_hollow.py +85 -0
  126. beratools/tools/rpy_hummock_hollow_raster.py +71 -0
  127. beratools/tools/rpy_las_info.py +51 -0
  128. beratools/tools/rpy_laz2las.py +40 -0
  129. beratools/tools/rpy_lpi_elai_lascat.py +466 -0
  130. beratools/tools/rpy_normalized_lidar_by.py +56 -0
  131. beratools/tools/rpy_percent_above_dbh.py +80 -0
  132. beratools/tools/rpy_points2trees.py +88 -0
  133. beratools/tools/rpy_vegcoverage.py +94 -0
  134. beratools/tools/tiler.py +206 -0
  135. beratools/tools/tool_template.py +54 -0
  136. beratools/tools/vertex_optimization.py +620 -0
  137. beratools/tools/zonal_threshold.py +144 -0
  138. beratools-0.2.0.dist-info/METADATA +63 -0
  139. beratools-0.2.0.dist-info/RECORD +142 -0
  140. beratools-0.2.0.dist-info/WHEEL +4 -0
  141. beratools-0.2.0.dist-info/entry_points.txt +2 -0
  142. beratools-0.2.0.dist-info/licenses/LICENSE +22 -0
@@ -0,0 +1,463 @@
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ import pandas as pd
5
+ from PyQt5.QtCore import (QDir, QItemSelectionModel, QAbstractTableModel, QModelIndex,
6
+ QVariant, QSettings)
7
+ from PyQt5.QtWidgets import (QTableView, QAbstractItemView, QShortcut, QDialog, QDialogButtonBox)
8
+ from PyQt5.QtGui import QKeySequence, QTextDocument, QTextCursor, QTextTableFormat
9
+ from PyQt5 import QtPrintSupport
10
+
11
+ from beratools.gui.tool_widgets import *
12
+ from bt_data import *
13
+ bt = BTData()
14
+
15
+
16
+ class PandasModel(QAbstractTableModel):
17
+ def __init__(self, df=pd.DataFrame(), parent=None):
18
+ QAbstractTableModel.__init__(self, parent=None)
19
+ self._df = df
20
+ self.setChanged = False
21
+ self.dataChanged.connect(self.setModified)
22
+
23
+ def setModified(self):
24
+ self.setChanged = True
25
+ print(self.setChanged)
26
+
27
+ def headerData(self, section, orientation, role=Qt.DisplayRole):
28
+ if role != Qt.DisplayRole:
29
+ return QVariant()
30
+ if orientation == Qt.Horizontal:
31
+ try:
32
+ return self._df.columns.tolist()[section]
33
+ except (IndexError,):
34
+ return QVariant()
35
+ elif orientation == Qt.Vertical:
36
+ try:
37
+ return self._df.index.tolist()[section]
38
+ except (IndexError,):
39
+ return QVariant()
40
+
41
+ def flags(self, index):
42
+ return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
43
+
44
+ def data(self, index, role=Qt.DisplayRole):
45
+ if index.isValid():
46
+ if role == Qt.EditRole:
47
+ return self._df.values[index.row()][index.column()]
48
+ elif role == Qt.DisplayRole:
49
+ return self._df.values[index.row()][index.column()]
50
+ return None
51
+
52
+ def data_row_dict(self, row):
53
+ return self._df.iloc[row].to_dict()
54
+
55
+ def setData(self, index, value, role):
56
+ row = self._df.index[index.row()]
57
+ col = self._df.columns[index.column()]
58
+ self._df.values[row][col] = value
59
+ self.dataChanged.emit(index, index)
60
+ return True
61
+
62
+ def rowCount(self, parent=QModelIndex()):
63
+ return len(self._df.index)
64
+
65
+ def columnCount(self, parent=QModelIndex()):
66
+ return len(self._df.columns)
67
+
68
+ def sort(self, column, order):
69
+ colname = self._df.columns.tolist()[column]
70
+ self.layoutAboutToBeChanged.emit()
71
+ self._df.sort_values(colname, ascending=order == Qt.AscendingOrder, inplace=True)
72
+ self._df.reset_index(inplace=True, drop=True)
73
+ self.layoutChanged.emit()
74
+
75
+ def insertRows(self, position, rows=1, index=QModelIndex()):
76
+ print("\n\t\t ...insertRows() Starting position: '%s'" % position, 'with the total rows to be inserted: ', rows)
77
+ self.beginInsertRows(QModelIndex(), position, position + rows - 1)
78
+ # del self._data[position]
79
+ default_row = []
80
+ for i in range(rows):
81
+ self._df.loc[len(self._df)] = self.default_record
82
+
83
+ self.endInsertRows()
84
+ return True
85
+
86
+ def removeRows(self, position, rows=1, index=QModelIndex()):
87
+ print("\n\t\t ...removeRows() Starting position: '%s'" % position, 'with the total rows to be removed: ', rows)
88
+ self.beginRemoveRows(QModelIndex(), position, position + rows - 1)
89
+ for i in range(rows):
90
+ self._df.drop(self._df.index[position + i], inplace=True)
91
+ print('removed: {}'.format(position + i))
92
+
93
+ self.endRemoveRows()
94
+ return True
95
+
96
+ def updateRow(self, row, row_data):
97
+ self._df.loc[row] = row_data
98
+ self.dataChanged(row, 0)
99
+
100
+ def save_csv(self, csv_file):
101
+ self._df.to_csv(csv_file, index=False)
102
+
103
+
104
+ class BPDialog(QDialog):
105
+ # signals
106
+ signal_update_tool_widgets = pyqtSignal(int)
107
+
108
+ def __init__(self, tool_name, parent=None):
109
+ super(BPDialog, self).__init__(parent)
110
+ self.setWindowTitle('Batch Processing')
111
+ self.MaxRecentFiles = 5
112
+ self.window_list = []
113
+ self.recent_files = []
114
+ self.settings = QSettings('Richard Zeng', 'Batch Processing')
115
+ self.filename = ""
116
+ self.setGeometry(0, 0, 800, 600)
117
+
118
+ # tableview
119
+ self.table_view = QTableView()
120
+ self.table_view.verticalHeader().setVisible(True)
121
+ self.model = PandasModel()
122
+ self.table_view.setModel(self.model)
123
+ self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
124
+ self.table_view.setSelectionBehavior(self.table_view.SelectRows)
125
+ self.table_view.setSelectionMode(self.table_view.ExtendedSelection)
126
+
127
+ self.table_view.clicked.connect(self.table_view_clicked)
128
+ self.table_view.verticalHeader().sectionClicked.connect(self.table_view_vertical_header_clicked)
129
+ QShortcut(Qt.Key_Up, self.table_view, activated=self.table_view_key_up)
130
+ QShortcut(Qt.Key_Down, self.table_view, activated=self.table_view_key_down)
131
+
132
+ # create form
133
+ self.tool_name = tool_name
134
+ tool_args = bt.get_bera_tool_args(self.tool_name)
135
+ self.tool_widgets = ToolWidgets(tool_name, tool_args, False)
136
+
137
+ # self.createToolBar()
138
+ hbox_widgets = QHBoxLayout()
139
+ hbox_widgets.addWidget(self.table_view, 2)
140
+ hbox_widgets.addWidget(self.tool_widgets, 1)
141
+
142
+ # Add project, record related button box
143
+ self.project_btns = QHBoxLayout()
144
+ open_button = QPushButton('Open')
145
+ save_button = QPushButton('Save')
146
+ save_as_button = QPushButton('Save as')
147
+ delete_button = QPushButton('Delete records')
148
+ add_button = QPushButton('Add record')
149
+ print_button = QPushButton('Print')
150
+
151
+ open_button.clicked.connect(self.load_csv)
152
+ save_button.setShortcut(QKeySequence.Open)
153
+ save_button.clicked.connect(self.write_csv_update)
154
+ save_button.setShortcut(QKeySequence.Save)
155
+ save_as_button.clicked.connect(self.write_csv)
156
+ save_as_button.setShortcut(QKeySequence.SaveAs)
157
+ delete_button.clicked.connect(self.table_view_delete_records)
158
+ delete_button.setShortcut(QKeySequence.Delete)
159
+
160
+ add_button.clicked.connect(self.table_view_add_records)
161
+
162
+ self.last_files = QComboBox()
163
+ self.last_files.setFixedWidth(300)
164
+ self.last_files.currentIndexChanged.connect(self.load_recent)
165
+
166
+ self.line_find = QLineEdit()
167
+ self.line_find.setPlaceholderText("find")
168
+ self.line_find.setClearButtonEnabled(True)
169
+ self.line_find.setFixedWidth(250)
170
+ self.line_find.returnPressed.connect(self.find_in_table)
171
+
172
+ print_button.clicked.connect(self.handle_preview)
173
+
174
+ self.project_btns.addWidget(open_button, QDialogButtonBox.ActionRole)
175
+ self.project_btns.addWidget(save_button, QDialogButtonBox.ActionRole)
176
+ self.project_btns.addWidget(save_as_button, QDialogButtonBox.ActionRole)
177
+ self.project_btns.addWidget(delete_button, QDialogButtonBox.ActionRole)
178
+ self.project_btns.addWidget(add_button, QDialogButtonBox.ActionRole)
179
+ self.project_btns.addWidget(self.line_find, QDialogButtonBox.ActionRole)
180
+ self.project_btns.addWidget(print_button, QDialogButtonBox.ActionRole)
181
+
182
+ # Add OK/cancel buttons
183
+ self.ok_btn_box = QDialogButtonBox()
184
+ self.ok_btn_box.addButton("Run", QDialogButtonBox.AcceptRole)
185
+ self.ok_btn_box.addButton("Cancel", QDialogButtonBox.RejectRole)
186
+ self.ok_btn_box.addButton("Help", QDialogButtonBox.HelpRole)
187
+
188
+ self.ok_btn_box.accepted.connect(self.run)
189
+ self.ok_btn_box.rejected.connect(self.reject)
190
+ self.ok_btn_box.helpRequested.connect(self.help)
191
+
192
+ hbox_btns = QHBoxLayout()
193
+ hbox_btns.addLayout(self.project_btns)
194
+ hbox_btns.addWidget(self.ok_btn_box)
195
+
196
+ vbox_main = QVBoxLayout()
197
+ vbox_main.addLayout(hbox_widgets)
198
+ vbox_main.addLayout(hbox_btns)
199
+ self.setLayout(vbox_main)
200
+
201
+ # delete dialog when close
202
+ self.setAttribute(Qt.WA_DeleteOnClose)
203
+
204
+ self.setContentsMargins(10, 10, 10, 10)
205
+ self.read_settings()
206
+ self.table_view.setFocus()
207
+ # self.statusBar().showMessage("Ready", 0)
208
+
209
+ # signals
210
+ self.tool_widgets.signal_save_tool_params.connect(self.table_view_update_record)
211
+ self.signal_update_tool_widgets.connect(self.update_tool_widgets)
212
+
213
+ def accept(self):
214
+ if self.line_find.hasFocus():
215
+ return
216
+
217
+ print("Run the batch processing.")
218
+ QDialog.accept(self)
219
+
220
+ def run(self):
221
+ self.model.save_csv(self.filename)
222
+ self.accept()
223
+
224
+ def reject(self):
225
+ print("Batch processing canceled.")
226
+ self.close()
227
+
228
+ def help(self):
229
+ print("Help requested.")
230
+
231
+ def table_view_clicked(self, item):
232
+ print('Row, column:{}, {}'.format(item.row(), item.column()))
233
+ self.signal_update_tool_widgets.emit(item.row())
234
+
235
+ def table_view_vertical_header_clicked(self, item):
236
+ print('Horizontal header clicked: {}'.format(item))
237
+ self.signal_update_tool_widgets.emit(item)
238
+
239
+ def table_view_key_up(self):
240
+ current_row = self.table_view.selectionModel().selectedRows()[-1].row()
241
+ if current_row >= 1:
242
+ self.table_view.selectRow(current_row - 1)
243
+ self.signal_update_tool_widgets.emit(current_row - 1)
244
+
245
+ def table_view_delete_records(self):
246
+ selected_index = self.table_view.selectionModel().selectedRows()
247
+ rows = [item.row() for item in selected_index]
248
+ rows.sort(reverse=True)
249
+
250
+ for i in rows:
251
+ self.model.removeRows(i)
252
+
253
+ current_row = i
254
+ if self.model.rowCount() > 0:
255
+ if current_row > self.model.rowCount() - 1:
256
+ current_row = self.model.rowCount() - 1
257
+
258
+ self.table_view.selectRow(current_row)
259
+ self.signal_update_tool_widgets.emit(current_row)
260
+
261
+ print('remove row {}'.format(i))
262
+
263
+ self.model.submit()
264
+
265
+ def table_view_add_records(self):
266
+ self.model.default_record = bt.get_bera_tool_parameters_list(self.tool_name)
267
+ ret = self.model.insertRow(self.model.rowCount())
268
+ if ret:
269
+ count = self.model.rowCount() - 1
270
+ self.table_view.selectRow(count)
271
+ self.signal_update_tool_widgets.emit(count)
272
+
273
+ print('Insert row in position {}'.format(count))
274
+ self.model.submit()
275
+
276
+ def table_view_update_record(self, row_data):
277
+ current_row = self.table_view.selectionModel().selectedRows()[-1].row()
278
+ self.model.updateRow(current_row, row_data)
279
+
280
+ def update_tool_widgets(self, row):
281
+ tool_paramas = self.model.data_row_dict(row)
282
+ self.tool_widgets.update_widgets(tool_paramas)
283
+ print('Update tool parameters for record {}'.format(tool_paramas))
284
+
285
+ def table_view_key_down(self):
286
+ current_row = self.table_view.selectionModel().selectedRows()[-1].row()
287
+ if current_row < self.model.rowCount() - 1:
288
+ self.table_view.selectRow(current_row + 1)
289
+ self.signal_update_tool_widgets.emit(current_row + 1)
290
+
291
+ def read_settings(self):
292
+ print("reading settings")
293
+ if self.settings.contains("geometry"):
294
+ self.setGeometry(self.settings.value('geometry'))
295
+ if self.settings.contains("recentFiles"):
296
+ self.recent_files = self.settings.value('recentFiles')
297
+ self.last_files.addItem("last Files")
298
+ self.last_files.addItems(self.recent_files[:15])
299
+
300
+ def save_settings(self):
301
+ print("saving settings")
302
+ self.settings.setValue('geometry', self.geometry())
303
+ self.settings.setValue('recentFiles', self.recent_files)
304
+
305
+ def closeEvent(self, event):
306
+ print(self.model.setChanged)
307
+ if self.model.setChanged:
308
+ print("is changed, saving?")
309
+ quit_msg = "<b>The document was changed.<br>Do you want to save the changes?</ b>"
310
+ reply = QMessageBox.question(self, 'Save Confirmation',
311
+ quit_msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
312
+ if reply == QMessageBox.Yes:
313
+ self.write_csv_update()
314
+ else:
315
+ print("Settings not saved.")
316
+ return
317
+ else:
318
+ print("nothing changed.")
319
+ self.save_settings()
320
+
321
+ def load_recent(self):
322
+ if self.last_files.currentIndex() > 0:
323
+ print(self.last_files.currentText())
324
+ print(self.model.setChanged)
325
+ if self.model.setChanged:
326
+ print("is changed, saving?")
327
+ quit_msg = "<b>The document was changed.<br>Do you want to save the changes?</ b>"
328
+ reply = QMessageBox.question(self, 'Save Confirmation',
329
+ quit_msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
330
+ if reply == QMessageBox.Yes:
331
+ self.open_csv(self.last_files.currentText())
332
+ else:
333
+ self.open_csv(self.last_files.currentText())
334
+ else:
335
+ self.open_csv(self.last_files.currentText())
336
+
337
+ def open_csv(self, path):
338
+ f = open(path, 'r+b')
339
+ with f:
340
+ df = pd.read_csv(f, sep='\t|;|,|\s+', keep_default_na=False, engine='python',
341
+ skipinitialspace=True, skip_blank_lines=True)
342
+ f.close()
343
+ self.filename = path
344
+
345
+ self.model = PandasModel(df)
346
+ self.table_view.setModel(self.model)
347
+ self.table_view.resizeColumnsToContents()
348
+ self.table_view.selectRow(0)
349
+ self.signal_update_tool_widgets.emit(0)
350
+ # self.statusBar().showMessage("%s %s" % (path, "loaded"), 0)
351
+
352
+ def find_in_table(self):
353
+ self.table_view.clearSelection()
354
+ text = self.line_find.text()
355
+ model = self.table_view.model()
356
+ for column in range(self.model.columnCount()):
357
+ start = model.index(0, column)
358
+ matches = model.match(start, Qt.DisplayRole, text, -1, Qt.MatchContains)
359
+ if matches:
360
+ for index in matches:
361
+ # print(index.row(), index.column())
362
+ self.table_view.selectionModel().select(index, QItemSelectionModel.Select)
363
+
364
+ def open_file(self, path=None):
365
+ print(self.model.setChanged)
366
+ if self.model.setChanged == True:
367
+ print("is changed, saving?")
368
+ quit_msg = "<b>The document was changed.<br>Do you want to save the changes?</ b>"
369
+ reply = QMessageBox.question(self, 'Save Confirmation',
370
+ quit_msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
371
+ if reply == QMessageBox.Yes:
372
+ self.write_csv_update()
373
+ else:
374
+ print("not saved, loading ...")
375
+ return
376
+ path, _ = QFileDialog.getOpenFileName(self, "Open File", QDir.homePath() + "/Dokumente/CSV/",
377
+ "CSV Files (*.csv)")
378
+ if path:
379
+ return path
380
+
381
+ def load_csv(self):
382
+ file_name = self.open_file()
383
+ if file_name:
384
+ print(file_name + " loaded")
385
+ f = open(file_name, 'r+b')
386
+ with f:
387
+ df = pd.read_csv(f, sep='\t|;|,|\s+', keep_default_na=False, engine='python',
388
+ skipinitialspace=True, skip_blank_lines=True)
389
+ f.close()
390
+ self.model = PandasModel(df)
391
+ self.table_view.setModel(self.model)
392
+ self.table_view.resizeColumnsToContents()
393
+ self.table_view.selectRow(0)
394
+ # self.statusBar().showMessage("%s %s" % (fileName, "loaded"), 0)
395
+ self.recent_files.insert(0, file_name)
396
+ self.last_files.insertItem(1, file_name)
397
+
398
+ def write_csv(self):
399
+ file_name, _ = QFileDialog.getSaveFileName(self, "Open File", self.filename, "CSV Files (*.csv)")
400
+ if file_name:
401
+ print(file_name + " saved")
402
+ f = open(file_name, 'w')
403
+ new_model = self.model
404
+ data_frame = new_model._df.copy()
405
+ data_frame.to_csv(f, sep=',', index=False, header=True, lineterminator='\n')
406
+
407
+ def write_csv_update(self):
408
+ if self.filename:
409
+ f = open(self.filename, 'w')
410
+ new_model = self.model
411
+ data_frame = new_model._df.copy()
412
+ data_frame.to_csv(f, sep='\t', index=False, header=False)
413
+ self.model.setChanged = False
414
+ print("%s %s" % (self.filename, "saved"))
415
+ # self.statusBar().showMessage("%s %s" % (self.filename, "saved"), 0)
416
+
417
+ def handle_preview(self):
418
+ if self.model.rowCount() == 0:
419
+ self.msg("no rows")
420
+ else:
421
+ dialog = QtPrintSupport.QPrintPreviewDialog()
422
+ dialog.setFixedSize(1000, 700)
423
+ dialog.paintRequested.connect(self.handle_paint_request)
424
+ dialog.exec_()
425
+ print("Print Preview closed")
426
+
427
+ def handle_paint_request(self, printer):
428
+ printer.setDocName(self.filename)
429
+ document = QTextDocument()
430
+ cursor = QTextCursor(document)
431
+ model = self.table_view.model()
432
+ table_format = QTextTableFormat()
433
+ table_format.setBorder(0.2)
434
+ table_format.setBorderStyle(3)
435
+ table_format.setCellSpacing(0);
436
+ table_format.setTopMargin(0);
437
+ table_format.setCellPadding(4)
438
+ table = cursor.insertTable(model.rowCount() + 1, model.columnCount(), table_format)
439
+ model = self.table_view.model()
440
+
441
+ # get headers
442
+ myheader = []
443
+ for i in range(0, model.columnCount()):
444
+ myheader = model.headerData(i, Qt.Horizontal)
445
+ cursor.insertText(str(myheader))
446
+ cursor.movePosition(QTextCursor.NextCell)
447
+ # get cells
448
+ for row in range(0, model.rowCount()):
449
+ for col in range(0, model.columnCount()):
450
+ index = model.index(row, col)
451
+ cursor.insertText(str(index.data()))
452
+ cursor.movePosition(QTextCursor.NextCell)
453
+ document.print_(printer)
454
+
455
+
456
+ if __name__ == "__main__":
457
+ app = QApplication(sys.argv)
458
+ main = BPDialog('Raster Line Attributes')
459
+ main.show()
460
+ if len(sys.argv) > 1:
461
+ main.open_csv(sys.argv[1])
462
+
463
+ sys.exit(app.exec_())