- upgraded the punch Gerber Tool

- updated the Turkish translation strings (by Mehmet Kaya)
This commit is contained in:
Marius Stanciu
2020-10-28 19:12:15 +02:00
committed by Marius
parent d1368425f1
commit 735a20242a
5 changed files with 413 additions and 299 deletions

View File

@@ -27,12 +27,14 @@ CHANGELOG for FlatCAM beta
- fixed Tcl command Paint
- temporary fix for comboboxes not finding the the value in the items when setting themselves with a value by defaulting to the first item in the list
- fix in Tool Subtract where there was a typo
- upgraded the punch Gerber Tool
- updated the Turkish translation strings (by Mehmet Kaya)
27.10.2020
- created custom classes derived from TextEdit and from LineEdit where I overloaded the context menu and I made all the other classes that were inheriting from them to inherit from those new classes
- minor fix in ToolsDB2UI
- updated the Turkuish translation strings (by Mehmet Kaya)
- updated the Turkish translation strings (by Mehmet Kaya)
- fixed a bug in conversion of any to Gerber in the section of Excellon conversion
- some PEP8 fixes
- fixed a bug due of recent chagnes in FileMenuHandlers class

View File

@@ -212,7 +212,7 @@ class GerberObject(FlatCAMObj, Gerber):
self.apertures_row = 0
aper_no = self.apertures_row + 1
sort = []
for k, v in list(self.apertures.items()):
for k in list(self.apertures.keys()):
sort.append(int(k))
sorted_apertures = sorted(sort)

View File

@@ -8,7 +8,7 @@
from PyQt5 import QtCore, QtWidgets, QtGui
from appTool import AppTool
from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox
from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox, FCTable
from copy import deepcopy
import logging
@@ -45,6 +45,8 @@ class ToolPunchGerber(AppTool):
self.ui.reset_button.clicked.connect(self.set_tool_ui)
self.ui.punch_object_button.clicked.connect(self.on_generate_object)
self.ui.gerber_object_combo.currentIndexChanged.connect(self.build_tool_ui)
self.ui.circular_cb.stateChanged.connect(
lambda state:
self.ui.circular_ring_entry.setDisabled(False) if state else
@@ -97,6 +99,7 @@ class ToolPunchGerber(AppTool):
AppTool.run(self)
self.set_tool_ui()
self.build_tool_ui()
self.app.ui.notebook.setTabText(2, _("Punch Tool"))
@@ -106,6 +109,7 @@ class ToolPunchGerber(AppTool):
def set_tool_ui(self):
self.reset_fields()
self.ui_disconnect()
self.ui_connect()
self.ui.method_punch.set_value(self.app.defaults["tools_punch_hole_type"])
self.ui.select_all_cb.set_value(False)
@@ -126,6 +130,69 @@ class ToolPunchGerber(AppTool):
self.ui.factor_entry.set_value(float(self.app.defaults["tools_punch_hole_prop_factor"]))
def build_tool_ui(self):
# get the Gerber file who is the source of the punched Gerber
selection_index = self.ui.gerber_object_combo.currentIndex()
model_index = self.app.collection.index(selection_index, 0, self.ui.gerber_object_combo.rootModelIndex())
obj = None
try:
obj = model_index.internalPointer().obj
sort = [int(k) for k in obj.apertures.keys()]
sorted_apertures = sorted(sort)
except Exception:
# no object loaded
sorted_apertures = []
n = len(sorted_apertures)
self.ui.apertures_table.setRowCount(n)
row = 0
for ap_code in sorted_apertures:
ap_code = str(ap_code)
ap_code_item = QtWidgets.QTableWidgetItem(ap_code)
ap_code_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
ap_type_item = QtWidgets.QTableWidgetItem(str(obj.apertures[ap_code]['type']))
ap_type_item.setFlags(QtCore.Qt.ItemIsEnabled)
try:
if obj.apertures[ap_code]['size'] is not None:
size_val = self.app.dec_format(float(obj.apertures[ap_code]['size']), self.decimals)
ap_size_item = QtWidgets.QTableWidgetItem(str(size_val))
else:
ap_size_item = QtWidgets.QTableWidgetItem('')
except KeyError:
ap_size_item = QtWidgets.QTableWidgetItem('')
ap_size_item.setFlags(QtCore.Qt.ItemIsEnabled)
self.ui.apertures_table.setItem(row, 0, ap_code_item) # Aperture Code
self.ui.apertures_table.setItem(row, 1, ap_type_item) # Aperture Type
self.ui.apertures_table.setItem(row, 2, ap_size_item) # Aperture Dimensions
# increment row
row += 1
self.ui.apertures_table.resizeColumnsToContents()
self.ui.apertures_table.resizeRowsToContents()
vertical_header = self.ui.apertures_table.verticalHeader()
vertical_header.hide()
# self.ui.apertures_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
horizontal_header = self.ui.apertures_table.horizontalHeader()
horizontal_header.setMinimumSectionSize(10)
horizontal_header.setDefaultSectionSize(70)
horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
self.ui.apertures_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.ui.apertures_table.setSortingEnabled(False)
# self.ui.apertures_table.setMinimumHeight(self.ui.apertures_table.getHeight())
# self.ui.apertures_table.setMaximumHeight(self.ui.apertures_table.getHeight())
def on_select_all(self, state):
self.ui_disconnect()
if state:
@@ -143,29 +210,29 @@ class ToolPunchGerber(AppTool):
self.ui_connect()
def on_method(self, val):
self.ui.exc_label.setEnabled(False)
self.ui.exc_combo.setEnabled(False)
self.ui.fixed_label.setEnabled(False)
self.ui.dia_label.setEnabled(False)
self.ui.dia_entry.setEnabled(False)
self.ui.ring_frame.setEnabled(False)
self.ui.prop_label.setEnabled(False)
self.ui.factor_label.setEnabled(False)
self.ui.factor_entry.setEnabled(False)
self.ui.exc_label.hide()
self.ui.exc_combo.hide()
self.ui.fixed_label.hide()
self.ui.dia_label.hide()
self.ui.dia_entry.hide()
self.ui.ring_frame.hide()
self.ui.prop_label.hide()
self.ui.factor_label.hide()
self.ui.factor_entry.hide()
if val == 'exc':
self.ui.exc_label.setEnabled(True)
self.ui.exc_combo.setEnabled(True)
self.ui.exc_label.show()
self.ui.exc_combo.show()
elif val == 'fixed':
self.ui.fixed_label.setEnabled(True)
self.ui.dia_label.setEnabled(True)
self.ui.dia_entry.setEnabled(True)
self.ui.fixed_label.show()
self.ui.dia_label.show()
self.ui.dia_entry.show()
elif val == 'ring':
self.ui.ring_frame.setEnabled(True)
self.ui.ring_frame.show()
elif val == 'prop':
self.ui.prop_label.setEnabled(True)
self.ui.factor_label.setEnabled(True)
self.ui.factor_entry.setEnabled(True)
self.ui.prop_label.show()
self.ui.factor_label.show()
self.ui.factor_entry.show()
def ui_connect(self):
self.ui.select_all_cb.stateChanged.connect(self.on_select_all)
@@ -192,13 +259,16 @@ class ToolPunchGerber(AppTool):
outname = name + "_punched"
punch_method = self.ui.method_punch.get_value()
new_options = {}
for opt in grb_obj.options:
new_options[opt] = deepcopy(grb_obj.options[opt])
if punch_method == 'exc':
self.on_excellon_method(grb_obj, outname)
elif punch_method == 'fixed':
self.on_fixed_method(grb_obj, outname)
elif punch_method == 'ring':
self.on_ring_method(grb_obj, outname)
elif punch_method == 'prop':
self.on_proportional_method(grb_obj, outname)
def on_excellon_method(self, grb_obj, outname):
# get the Excellon file whose geometry will create the punch holes
selection_index = self.ui.exc_combo.currentIndex()
model_index = self.app.collection.index(selection_index, 0, self.ui.exc_combo.rootModelIndex())
@@ -209,6 +279,10 @@ class ToolPunchGerber(AppTool):
self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Excellon object loaded ..."))
return
new_options = {}
for opt in grb_obj.options:
new_options[opt] = deepcopy(grb_obj.options[opt])
# this is the punching geometry
exc_solid_geometry = MultiPolygon(exc_obj.solid_geometry)
if isinstance(grb_obj.solid_geometry, list):
@@ -271,9 +345,9 @@ class ToolPunchGerber(AppTool):
local_use=new_obj, use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func)
elif punch_method == 'fixed':
punch_size = float(self.ui.dia_entry.get_value())
def on_fixed_method(self, grb_obj, outname):
punch_size = float(self.ui.dia_entry.get_value())
if punch_size == 0.0:
self.app.inform.emit('[WARNING_NOTCL] %s' % _("The value of the fixed diameter is 0.0. Aborting."))
return 'fail'
@@ -281,8 +355,18 @@ class ToolPunchGerber(AppTool):
fail_msg = _("Could not generate punched hole Gerber because the punch hole size is bigger than"
" some of the apertures in the Gerber object.")
new_options = {}
for opt in grb_obj.options:
new_options[opt] = deepcopy(grb_obj.options[opt])
# selected codes in thre apertures UI table
sel_apid = []
for it in self.ui.apertures_table.selectedItems():
sel_apid.append(it.text())
punching_geo = []
for apid in grb_obj.apertures:
if apid in sel_apid:
if grb_obj.apertures[apid]['type'] == 'C' and self.ui.circular_cb.get_value():
for elem in grb_obj.apertures[apid]['geometry']:
if 'follow' in elem:
@@ -394,15 +478,19 @@ class ToolPunchGerber(AppTool):
local_use=new_obj, use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func)
elif punch_method == 'ring':
def on_ring_method(self, grb_obj, outname):
circ_r_val = self.ui.circular_ring_entry.get_value()
oblong_r_val = self.ui.oblong_ring_entry.get_value()
square_r_val = self.ui.square_ring_entry.get_value()
rect_r_val = self.ui.rectangular_ring_entry.get_value()
other_r_val = self.ui.other_ring_entry.get_value()
dia = None
new_options = {}
for opt in grb_obj.options:
new_options[opt] = deepcopy(grb_obj.options[opt])
if isinstance(grb_obj.solid_geometry, list):
temp_solid_geometry = MultiPolygon(grb_obj.solid_geometry)
else:
@@ -416,6 +504,11 @@ class ToolPunchGerber(AppTool):
# find maximum aperture id
new_apid = max([int(x) for x, __ in new_apertures_items])
# selected codes in the apertures UI table
sel_apid = []
for it in self.ui.apertures_table.selectedItems():
sel_apid.append(it.text())
# store here the clear geometry, the key is the new aperture size
holes_apertures = {}
@@ -423,12 +516,12 @@ class ToolPunchGerber(AppTool):
ap_type = apid_value['type']
punching_geo = []
if apid in sel_apid:
if ap_type == 'C' and self.ui.circular_cb.get_value():
dia = float(apid_value['size']) - (2 * circ_r_val)
for elem in apid_value['geometry']:
if 'follow' in elem and isinstance(elem['follow'], Point):
punching_geo.append(elem['follow'].buffer(dia / 2))
elif ap_type == 'O' and self.ui.oblong_cb.get_value():
width = float(apid_value['width'])
height = float(apid_value['height'])
@@ -442,7 +535,6 @@ class ToolPunchGerber(AppTool):
if 'follow' in elem:
if isinstance(elem['follow'], Point):
punching_geo.append(elem['follow'].buffer(dia / 2))
elif ap_type == 'R':
width = float(apid_value['width'])
height = float(apid_value['height'])
@@ -466,7 +558,6 @@ class ToolPunchGerber(AppTool):
if 'follow' in elem:
if isinstance(elem['follow'], Point):
punching_geo.append(elem['follow'].buffer(dia / 2))
elif self.ui.other_cb.get_value():
try:
dia = float(apid_value['size']) - (2 * other_r_val)
@@ -537,10 +628,12 @@ class ToolPunchGerber(AppTool):
self.app.app_obj.new_object('gerber', outname, init_func)
elif punch_method == 'prop':
def on_proportional_method(self, grb_obj, outname):
prop_factor = self.ui.factor_entry.get_value() / 100.0
dia = None
new_options = {}
for opt in grb_obj.options:
new_options[opt] = deepcopy(grb_obj.options[opt])
if isinstance(grb_obj.solid_geometry, list):
temp_solid_geometry = MultiPolygon(grb_obj.solid_geometry)
@@ -555,6 +648,11 @@ class ToolPunchGerber(AppTool):
# find maximum aperture id
new_apid = max([int(x) for x, __ in new_apertures_items])
# selected codes in the apertures UI table
sel_apid = []
for it in self.ui.apertures_table.selectedItems():
sel_apid.append(it.text())
# store here the clear geometry, the key is the new aperture size
holes_apertures = {}
@@ -562,12 +660,12 @@ class ToolPunchGerber(AppTool):
ap_type = apid_value['type']
punching_geo = []
if apid in sel_apid:
if ap_type == 'C' and self.ui.circular_cb.get_value():
dia = float(apid_value['size']) * prop_factor
for elem in apid_value['geometry']:
if 'follow' in elem and isinstance(elem['follow'], Point):
punching_geo.append(elem['follow'].buffer(dia / 2))
elif ap_type == 'O' and self.ui.oblong_cb.get_value():
width = float(apid_value['width'])
height = float(apid_value['height'])
@@ -581,7 +679,6 @@ class ToolPunchGerber(AppTool):
if 'follow' in elem:
if isinstance(elem['follow'], Point):
punching_geo.append(elem['follow'].buffer(dia / 2))
elif ap_type == 'R':
width = float(apid_value['width'])
height = float(apid_value['height'])
@@ -605,7 +702,6 @@ class ToolPunchGerber(AppTool):
if 'follow' in elem:
if isinstance(elem['follow'], Point):
punching_geo.append(elem['follow'].buffer(dia / 2))
elif self.ui.other_cb.get_value():
try:
dia = float(apid_value['size']) * prop_factor
@@ -738,9 +834,18 @@ class PunchUI:
grid_lay.addWidget(self.padt_label, 3, 0, 1, 2)
pad_all_grid = QtWidgets.QGridLayout()
pad_all_grid.setColumnStretch(0, 0)
pad_all_grid.setColumnStretch(1, 1)
grid_lay.addLayout(pad_all_grid, 5, 0, 1, 2)
pad_grid = QtWidgets.QGridLayout()
pad_grid.setColumnStretch(0, 0)
pad_all_grid.addLayout(pad_grid, 0, 0)
# Select all
self.select_all_cb = FCCheckBox('%s' % _("ALL"))
grid_lay.addWidget(self.select_all_cb)
pad_grid.addWidget(self.select_all_cb, 0, 0)
# Circular Aperture Selection
self.circular_cb = FCCheckBox('%s' % _("Circular"))
@@ -748,7 +853,7 @@ class PunchUI:
_("Process Circular Pads.")
)
grid_lay.addWidget(self.circular_cb, 5, 0, 1, 2)
pad_grid.addWidget(self.circular_cb, 1, 0)
# Oblong Aperture Selection
self.oblong_cb = FCCheckBox('%s' % _("Oblong"))
@@ -756,7 +861,7 @@ class PunchUI:
_("Process Oblong Pads.")
)
grid_lay.addWidget(self.oblong_cb, 6, 0, 1, 2)
pad_grid.addWidget(self.oblong_cb, 2, 0)
# Square Aperture Selection
self.square_cb = FCCheckBox('%s' % _("Square"))
@@ -764,7 +869,7 @@ class PunchUI:
_("Process Square Pads.")
)
grid_lay.addWidget(self.square_cb, 7, 0, 1, 2)
pad_grid.addWidget(self.square_cb, 3, 0)
# Rectangular Aperture Selection
self.rectangular_cb = FCCheckBox('%s' % _("Rectangular"))
@@ -772,7 +877,7 @@ class PunchUI:
_("Process Rectangular Pads.")
)
grid_lay.addWidget(self.rectangular_cb, 8, 0, 1, 2)
pad_grid.addWidget(self.rectangular_cb, 4, 0)
# Others type of Apertures Selection
self.other_cb = FCCheckBox('%s' % _("Others"))
@@ -780,7 +885,29 @@ class PunchUI:
_("Process pads not in the categories above.")
)
grid_lay.addWidget(self.other_cb, 9, 0, 1, 2)
pad_grid.addWidget(self.other_cb, 5, 0)
# Aperture Table
self.apertures_table = FCTable()
pad_all_grid.addWidget(self.apertures_table, 0, 1)
self.apertures_table.setColumnCount(3)
self.apertures_table.setHorizontalHeaderLabels([_('Code'), _('Type'), _('Size')])
self.apertures_table.setSortingEnabled(False)
self.apertures_table.setRowCount(0)
self.apertures_table.resizeColumnsToContents()
self.apertures_table.resizeRowsToContents()
self.apertures_table.horizontalHeaderItem(0).setToolTip(
_("Aperture Code"))
self.apertures_table.horizontalHeaderItem(1).setToolTip(
_("Type of aperture: circular, rectangle, macros etc"))
self.apertures_table.horizontalHeaderItem(2).setToolTip(
_("Aperture Size:"))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
self.apertures_table.setSizePolicy(sizePolicy)
self.apertures_table.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
@@ -832,11 +959,6 @@ class PunchUI:
grid0.addWidget(self.exc_label, 3, 0, 1, 2)
grid0.addWidget(self.exc_combo, 4, 0, 1, 2)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 5, 0, 1, 2)
# Fixed Dia
self.fixed_label = QtWidgets.QLabel('<b>%s</b>' % _("Fixed Diameter"))
grid0.addWidget(self.fixed_label, 6, 0, 1, 2)
@@ -854,11 +976,9 @@ class PunchUI:
grid0.addWidget(self.dia_label, 8, 0)
grid0.addWidget(self.dia_entry, 8, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 9, 0, 1, 2)
# #############################################################################################################
# RING FRAME
# #############################################################################################################
self.ring_frame = QtWidgets.QFrame()
self.ring_frame.setContentsMargins(0, 0, 0, 0)
grid0.addWidget(self.ring_frame, 10, 0, 1, 2)
@@ -946,11 +1066,7 @@ class PunchUI:
self.grid1.addWidget(self.other_ring_label, 7, 0)
self.grid1.addWidget(self.other_ring_entry, 7, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 11, 0, 1, 2)
# #############################################################################################################
# Proportional value
self.prop_label = QtWidgets.QLabel('<b>%s</b>' % _("Proportional Diameter"))
@@ -1012,10 +1128,10 @@ class PunchUI:
self.rectangular_ring_entry.setEnabled(False)
self.other_ring_entry.setEnabled(False)
self.dia_entry.setDisabled(True)
self.dia_label.setDisabled(True)
self.factor_label.setDisabled(True)
self.factor_entry.setDisabled(True)
self.dia_entry.hide()
self.dia_label.hide()
self.factor_label.hide()
self.factor_entry.hide()
# #################################### FINSIHED GUI ###########################
# #############################################################################

Binary file not shown.

View File

@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2020-10-28 10:58+0200\n"
"PO-Revision-Date: 2020-10-28 10:58+0200\n"
"PO-Revision-Date: 2020-10-28 15:13+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: tr_TR\n"
@@ -89,10 +89,8 @@ msgid "Bookmark added."
msgstr "Yer işareti eklendi."
#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
#, fuzzy
#| msgid "Backup"
msgid "Backup Site"
msgstr "Yedekleme"
msgstr "Alternatif Web Sayfası"
#: Bookmark.py:244
msgid "This bookmark can not be removed"
@@ -4986,7 +4984,7 @@ msgstr "Gerber Özellikleri"
#: appGUI/MainGUI.py:610
msgid "Shortcuts List"
msgstr ""
msgstr "Klavye Kısayol Listesi"
#: appGUI/MainGUI.py:610 appGUI/MainGUI.py:4398
msgid "F3"
@@ -13722,11 +13720,11 @@ msgstr "Hatanın nedeni"
#: appObjects/ObjectCollection.py:1195
msgid "All objects are selected."
msgstr "Hatanın nedeni."
msgstr "Nesnelerin Tümü Seçildi."
#: appObjects/ObjectCollection.py:1205
msgid "Objects selection is cleared."
msgstr "Nesnelerin seçimi temizlendi."
msgstr "Nesnelerin seçimi kaldırıldı."
#: appParsers/ParseExcellon.py:292
msgid "This is GCODE mark"
@@ -18536,20 +18534,18 @@ msgid ""
"If you can't get any informations about the application\n"
"use the YouTube channel link from the Help menu."
msgstr ""
"Aşağıdaki durumlarda bu girişe başka bir\n"
"sitede izin verilecektir:\n"
"Bu giriş, aşağıdaki durumlarda başka bir web sayfasına yönlendirecektir:\n"
"\n"
"1. FlatCAM.org web sitesi çalışmıyor\n"
"2. Birisi FlatCAM projesini çatalladı ve \n"
"kendi web sitesine işaret etmek istiyor\n"
"1. FlatCAM.org sayfası kapandığında\n"
"2. Birisi FlatCAM projesini kopyaladığında ve sizi kendi web sayfasına \n"
"yönlendirmek istediğinde\n"
"\n"
"Uygulama'in beta sürümü hakkında herhangi\n"
"bir bilgi alamıyorsanız, Yardım menüsündeki\n"
"YouTube kanalı bağlantısını kullanın."
"Uygulama hakkında bilgi alamazsanız, Yardım menüsünden \n"
"\"YouTube Kanalı\" bağlantısını kullanın."
#: app_Main.py:3294
msgid "Alternative website"
msgstr "Alternatif web sitesi"
msgstr "Alternatif Web Sayfası"
#: app_Main.py:3636
msgid "Selected Excellon file extensions registered with FlatCAM."