From 58f24cbb37a242af389887618a9b109459261756 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 27 Nov 2019 03:44:28 +0200 Subject: [PATCH] - in Tool Film added the page size and page orientation in case of saving the film as PDF file - the application workspace has now a lot more options selectable in the Edit -> Preferences -> General -> GUI Preferences --- FlatCAMApp.py | 16 +++- README.md | 5 + flatcamGUI/PlotCanvas.py | 144 +++++++++++++++++++++++------ flatcamGUI/PreferencesUI.py | 165 +++++++++++++++++++++++++++++++-- flatcamTools/ToolFilm.py | 179 ++++++++++++++++++++++++++++++------ flatcamTools/ToolMove.py | 22 ++--- flatcamTools/ToolPaint.py | 6 +- 7 files changed, 453 insertions(+), 84 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index bbf73c4a..7b4380fa 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -427,7 +427,8 @@ class App(QtCore.QObject): "global_gridy": 0.0393701, "global_snap_max": 0.001968504, "global_workspace": False, - "global_workspaceT": "A4P", + "global_workspaceT": "A4", + "global_workspace_orientation": 'p', "global_grid_context_menu": { 'in': [0.01, 0.02, 0.025, 0.05, 0.1], @@ -766,6 +767,8 @@ class App(QtCore.QObject): "tools_film_mirror_cb": False, "tools_film_mirror_axis_radio": 'none', "tools_film_file_type_radio": 'svg', + "tools_film_orientation": 'p', + "tools_film_pagesize": 'A4', # Panel Tool "tools_panelize_spacing_columns": 0, @@ -1039,6 +1042,7 @@ class App(QtCore.QObject): "global_snap_max": self.ui.general_defaults_form.general_gui_group.snap_max_dist_entry, "global_workspace": self.ui.general_defaults_form.general_gui_group.workspace_cb, "global_workspaceT": self.ui.general_defaults_form.general_gui_group.wk_cb, + "global_workspace_orientation": self.ui.general_defaults_form.general_gui_group.wk_orientation_radio, "global_plot_fill": self.ui.general_defaults_form.general_gui_group.pf_color_entry, "global_plot_line": self.ui.general_defaults_form.general_gui_group.pl_color_entry, @@ -1324,6 +1328,8 @@ class App(QtCore.QObject): "tools_film_mirror_cb": self.ui.tools_defaults_form.tools_film_group.film_mirror_cb, "tools_film_mirror_axis_radio": self.ui.tools_defaults_form.tools_film_group.film_mirror_axis, "tools_film_file_type_radio": self.ui.tools_defaults_form.tools_film_group.file_type_radio, + "tools_film_orientation": self.ui.tools_defaults_form.tools_film_group.orientation_radio, + "tools_film_pagesize": self.ui.tools_defaults_form.tools_film_group.pagesize_combo, # Panelize Tool "tools_panelize_spacing_columns": self.ui.tools_defaults_form.tools_panelize_group.pspacing_columns, @@ -1932,6 +1938,10 @@ class App(QtCore.QObject): # ############################# workspace setting signals ##################### self.ui.general_defaults_form.general_gui_group.wk_cb.currentIndexChanged.connect(self.on_workspace_modified) + self.ui.general_defaults_form.general_gui_group.wk_orientation_radio.activated_custom.connect( + self.on_workspace_modified + ) + self.ui.general_defaults_form.general_gui_group.workspace_cb.stateChanged.connect(self.on_workspace) self.ui.general_defaults_form.general_gui_set_group.layout_combo.activated.connect(self.on_layout) @@ -5729,7 +5739,7 @@ class App(QtCore.QObject): # change this only if the workspace is active if self.defaults['global_workspace'] is True: - self.plotcanvas.draw_workspace() + self.plotcanvas.draw_workspace(pagesize=self.defaults['global_workspaceT']) # adjust the grid values on the main toolbar dec = 6 if new_units == 'IN'else 4 @@ -6660,7 +6670,7 @@ class App(QtCore.QObject): def on_workspace_modified(self): self.save_defaults(silent=True) - self.plotcanvas.draw_workspace() + self.plotcanvas.draw_workspace(pagesize=self.defaults['global_workspaceT']) def on_workspace(self): self.report_usage("on_workspace()") diff --git a/README.md b/README.md index 05058899..14af4a59 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +27.11.2019 + +- in Tool Film added the page size and page orientation in case of saving the film as PDF file +- the application workspace has now a lot more options selectable in the Edit -> Preferences -> General -> GUI Preferences + 26.11.2019 - updated the Film Tool to allow exporting PDF and PNG file (besides the SVG file) diff --git a/flatcamGUI/PlotCanvas.py b/flatcamGUI/PlotCanvas.py index 9ef813b5..3cc95d93 100644 --- a/flatcamGUI/PlotCanvas.py +++ b/flatcamGUI/PlotCanvas.py @@ -76,7 +76,7 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas): # draw a rectangle made out of 4 lines on the canvas to serve as a hint for the work area # all CNC have a limited workspace - self.draw_workspace() + self.draw_workspace(pagesize=self.fcapp.defaults["global_workspaceT"]) self.line_parent = None self.cursor_v_line = InfiniteLine(pos=None, color=self.line_color, vertical=True, @@ -107,37 +107,122 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas): # draw a rectangle made out of 4 lines on the canvas to serve as a hint for the work area # all CNC have a limited workspace - def draw_workspace(self): - a = np.empty((0, 0)) + # def draw_workspace(self): + # a = np.empty((0, 0)) + # + # a4p_in = np.array([(0, 0), (8.3, 0), (8.3, 11.7), (0, 11.7)]) + # a4l_in = np.array([(0, 0), (11.7, 0), (11.7, 8.3), (0, 8.3)]) + # a3p_in = np.array([(0, 0), (11.7, 0), (11.7, 16.5), (0, 16.5)]) + # a3l_in = np.array([(0, 0), (16.5, 0), (16.5, 11.7), (0, 11.7)]) + # + # a4p_mm = np.array([(0, 0), (210, 0), (210, 297), (0, 297)]) + # a4l_mm = np.array([(0, 0), (297, 0), (297, 210), (0, 210)]) + # a3p_mm = np.array([(0, 0), (297, 0), (297, 420), (0, 420)]) + # a3l_mm = np.array([(0, 0), (420, 0), (420, 297), (0, 297)]) + # + # if self.fcapp.defaults['units'].upper() == 'MM': + # if self.fcapp.defaults['global_workspaceT'] == 'A4P': + # a = a4p_mm + # elif self.fcapp.defaults['global_workspaceT'] == 'A4L': + # a = a4l_mm + # elif self.fcapp.defaults['global_workspaceT'] == 'A3P': + # a = a3p_mm + # elif self.fcapp.defaults['global_workspaceT'] == 'A3L': + # a = a3l_mm + # else: + # if self.fcapp.defaults['global_workspaceT'] == 'A4P': + # a = a4p_in + # elif self.fcapp.defaults['global_workspaceT'] == 'A4L': + # a = a4l_in + # elif self.fcapp.defaults['global_workspaceT'] == 'A3P': + # a = a3p_in + # elif self.fcapp.defaults['global_workspaceT'] == 'A3L': + # a = a3l_in + # + # self.delete_workspace() + # + # self.b_line = Line(pos=a[0:2], color=(0.70, 0.3, 0.3, 1.0), + # antialias=True, method='agg', parent=self.view.scene) + # self.r_line = Line(pos=a[1:3], color=(0.70, 0.3, 0.3, 1.0), + # antialias=True, method='agg', parent=self.view.scene) + # + # self.t_line = Line(pos=a[2:4], color=(0.70, 0.3, 0.3, 1.0), + # antialias=True, method='agg', parent=self.view.scene) + # self.l_line = Line(pos=np.array((a[0], a[3])), color=(0.70, 0.3, 0.3, 1.0), + # antialias=True, method='agg', parent=self.view.scene) + # + # if self.fcapp.defaults['global_workspace'] is False: + # self.delete_workspace() - a4p_in = np.array([(0, 0), (8.3, 0), (8.3, 11.7), (0, 11.7)]) - a4l_in = np.array([(0, 0), (11.7, 0), (11.7, 8.3), (0, 8.3)]) - a3p_in = np.array([(0, 0), (11.7, 0), (11.7, 16.5), (0, 16.5)]) - a3l_in = np.array([(0, 0), (16.5, 0), (16.5, 11.7), (0, 11.7)]) + # delete the workspace lines from the plot by removing the parent - a4p_mm = np.array([(0, 0), (210, 0), (210, 297), (0, 297)]) - a4l_mm = np.array([(0, 0), (297, 0), (297, 210), (0, 210)]) - a3p_mm = np.array([(0, 0), (297, 0), (297, 420), (0, 420)]) - a3l_mm = np.array([(0, 0), (420, 0), (420, 297), (0, 297)]) + def draw_workspace(self, pagesize): + pagesize_dict = dict() + pagesize_dict.update( + { + 'A0': (841, 1189), + 'A1': (594, 841), + 'A2': (420, 594), + 'A3': (297, 420), + 'A4': (210, 297), + 'A5': (148, 210), + 'A6': (105, 148), + 'A7': (74, 105), + 'A8': (52, 74), + 'A9': (37, 52), + 'A10': (26, 37), - if self.fcapp.defaults['units'].upper() == 'MM': - if self.fcapp.defaults['global_workspaceT'] == 'A4P': - a = a4p_mm - elif self.fcapp.defaults['global_workspaceT'] == 'A4L': - a = a4l_mm - elif self.fcapp.defaults['global_workspaceT'] == 'A3P': - a = a3p_mm - elif self.fcapp.defaults['global_workspaceT'] == 'A3L': - a = a3l_mm - else: - if self.fcapp.defaults['global_workspaceT'] == 'A4P': - a = a4p_in - elif self.fcapp.defaults['global_workspaceT'] == 'A4L': - a = a4l_in - elif self.fcapp.defaults['global_workspaceT'] == 'A3P': - a = a3p_in - elif self.fcapp.defaults['global_workspaceT'] == 'A3L': - a = a3l_in + 'B0': (1000, 1414), + 'B1': (707, 1000), + 'B2': (500, 707), + 'B3': (353, 500), + 'B4': (250, 353), + 'B5': (176, 250), + 'B6': (125, 176), + 'B7': (88, 125), + 'B8': (62, 88), + 'B9': (44, 62), + 'B10': (31, 44), + + 'C0': (917, 1297), + 'C1': (648, 917), + 'C2': (458, 648), + 'C3': (324, 458), + 'C4': (229, 324), + 'C5': (162, 229), + 'C6': (114, 162), + 'C7': (81, 114), + 'C8': (57, 81), + 'C9': (40, 57), + 'C10': (28, 40), + + # American paper sizes + 'LETTER': (8.5*25.4, 11*25.4), + 'LEGAL': (8.5*25.4, 14*25.4), + 'ELEVENSEVENTEEN': (11*25.4, 17*25.4), + + # From https://en.wikipedia.org/wiki/Paper_size + 'JUNIOR_LEGAL': (5*25.4, 8*25.4), + 'HALF_LETTER': (5.5*25.4, 8*25.4), + 'GOV_LETTER': (8*25.4, 10.5*25.4), + 'GOV_LEGAL': (8.5*25.4, 13*25.4), + 'LEDGER': (17*25.4, 11*25.4), + } + ) + + try: + if self.fcapp.defaults['units'].upper() == 'MM': + dims = pagesize_dict[pagesize] + else: + dims = (pagesize_dict[pagesize][0]/25.4, pagesize_dict[pagesize][1]/25.4) + except Exception as e: + log.debug("PlotCanvas.draw_workspace() --> %s" % str(e)) + return + + if self.fcapp.defaults['global_workspace_orientation'] == 'l': + dims = (dims[1], dims[0]) + + a = np.array([(0, 0), (dims[0], 0), (dims[0], dims[1]), (0, dims[1])]) self.delete_workspace() @@ -154,7 +239,6 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas): if self.fcapp.defaults['global_workspace'] is False: self.delete_workspace() - # delete the workspace lines from the plot by removing the parent def delete_workspace(self): try: self.b_line.parent = None diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 0f18610f..44e5a028 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -343,19 +343,92 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): _("Draw a delimiting rectangle on canvas.\n" "The purpose is to illustrate the limits for our work.") ) - self.workspace_type_lbl = QtWidgets.QLabel('%s:' % _('Wk. format')) + self.workspace_type_lbl = QtWidgets.QLabel('%s:' % _('Wk. size')) self.workspace_type_lbl.setToolTip( _("Select the type of rectangle to be used on canvas,\n" "as valid workspace.") ) self.workspace_cb = FCCheckBox() self.wk_cb = FCComboBox() - self.wk_cb.addItem('A4P') - self.wk_cb.addItem('A4L') - self.wk_cb.addItem('A3P') - self.wk_cb.addItem('A3L') - self.wks = OptionalInputSection(self.workspace_cb, [self.workspace_type_lbl, self.wk_cb]) + self.pagesize = dict() + self.pagesize.update( + { + 'A0': (841, 1189), + 'A1': (594, 841), + 'A2': (420, 594), + 'A3': (297, 420), + 'A4': (210, 297), + 'A5': (148, 210), + 'A6': (105, 148), + 'A7': (74, 105), + 'A8': (52, 74), + 'A9': (37, 52), + 'A10': (26, 37), + + 'B0': (1000, 1414), + 'B1': (707, 1000), + 'B2': (500, 707), + 'B3': (353, 500), + 'B4': (250, 353), + 'B5': (176, 250), + 'B6': (125, 176), + 'B7': (88, 125), + 'B8': (62, 88), + 'B9': (44, 62), + 'B10': (31, 44), + + 'C0': (917, 1297), + 'C1': (648, 917), + 'C2': (458, 648), + 'C3': (324, 458), + 'C4': (229, 324), + 'C5': (162, 229), + 'C6': (114, 162), + 'C7': (81, 114), + 'C8': (57, 81), + 'C9': (40, 57), + 'C10': (28, 40), + + # American paper sizes + 'LETTER': (8.5, 11), + 'LEGAL': (8.5, 14), + 'ELEVENSEVENTEEN': (11, 17), + + # From https://en.wikipedia.org/wiki/Paper_size + 'JUNIOR_LEGAL': (5, 8), + 'HALF_LETTER': (5.5, 8), + 'GOV_LETTER': (8, 10.5), + 'GOV_LEGAL': (8.5, 13), + 'LEDGER': (17, 11), + } + ) + + page_size_list = list(self.pagesize.keys()) + + self.wk_cb.addItems(page_size_list) + # self.wk_cb.addItem('A4P') + # self.wk_cb.addItem('A4L') + # self.wk_cb.addItem('A3P') + # self.wk_cb.addItem('A3L') + + # Page orientation + self.wk_orientation_label = QtWidgets.QLabel('%s:' % _("Wk. Orientation")) + self.wk_orientation_label.setToolTip(_("Can be:\n" + "- Portrait\n" + "- Landscape")) + + self.wk_orientation_radio = RadioSet([{'label': _('Portrait'), 'value': 'p'}, + {'label': _('Landscape'), 'value': 'l'}, + ], stretch=False) + + self.wks = OptionalInputSection(self.workspace_cb, + [ + self.workspace_type_lbl, + self.wk_cb, + self.wk_orientation_label, + self.wk_orientation_radio + ]) # Plot Fill Color self.pf_color_label = QtWidgets.QLabel('%s:' % _('Plot Fill')) @@ -579,6 +652,8 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): self.form_box.addRow(self.workspace_lbl, self.workspace_cb) self.form_box.addRow(self.workspace_type_lbl, self.wk_cb) + self.form_box.addRow(self.wk_orientation_label, self.wk_orientation_radio) + self.form_box.addRow(self.spacelabel, self.spacelabel) self.form_box.addRow(self.pf_color_label, self.form_box_child_1) self.form_box.addRow(self.pf_alpha_label, self.form_box_child_2) @@ -4654,6 +4729,84 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.file_type_label, 15, 0) grid0.addWidget(self.file_type_radio, 15, 1) + # Page orientation + self.orientation_label = QtWidgets.QLabel('%s:' % _("Page Orientation")) + self.orientation_label.setToolTip(_("Can be:\n" + "- Portrait\n" + "- Lanscape")) + + self.orientation_radio = RadioSet([{'label': _('Portrait'), 'value': 'p'}, + {'label': _('Landscape'), 'value': 'l'}, + ], stretch=False) + + grid0.addWidget(self.orientation_label, 16, 0) + grid0.addWidget(self.orientation_radio, 16, 1) + + # Page Size + self.pagesize_label = QtWidgets.QLabel('%s:' % _("Page Size")) + self.pagesize_label.setToolTip(_("A selection of standard ISO 216 page sizes.")) + + self.pagesize_combo = FCComboBox() + + self.pagesize = dict() + self.pagesize.update( + { + 'Bounds': None, + 'A0': (841, 1189), + 'A1': (594, 841), + 'A2': (420, 594), + 'A3': (297, 420), + 'A4': (210, 297), + 'A5': (148, 210), + 'A6': (105, 148), + 'A7': (74, 105), + 'A8': (52, 74), + 'A9': (37, 52), + 'A10': (26, 37), + + 'B0': (1000, 1414), + 'B1': (707, 1000), + 'B2': (500, 707), + 'B3': (353, 500), + 'B4': (250, 353), + 'B5': (176, 250), + 'B6': (125, 176), + 'B7': (88, 125), + 'B8': (62, 88), + 'B9': (44, 62), + 'B10': (31, 44), + + 'C0': (917, 1297), + 'C1': (648, 917), + 'C2': (458, 648), + 'C3': (324, 458), + 'C4': (229, 324), + 'C5': (162, 229), + 'C6': (114, 162), + 'C7': (81, 114), + 'C8': (57, 81), + 'C9': (40, 57), + 'C10': (28, 40), + + # American paper sizes + 'LETTER': (8.5, 11), + 'LEGAL': (8.5, 14), + 'ELEVENSEVENTEEN': (11, 17), + + # From https://en.wikipedia.org/wiki/Paper_size + 'JUNIOR_LEGAL': (5, 8), + 'HALF_LETTER': (5.5, 8), + 'GOV_LETTER': (8, 10.5), + 'GOV_LEGAL': (8.5, 13), + 'LEDGER': (17, 11), + } + ) + + page_size_list = list(self.pagesize.keys()) + self.pagesize_combo.addItems(page_size_list) + + grid0.addWidget(self.pagesize_label, 17, 0) + grid0.addWidget(self.pagesize_combo, 17, 1) self.layout.addStretch() diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index 608ca359..8acab8d7 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -9,15 +9,17 @@ from PyQt5 import QtGui, QtCore, QtWidgets from FlatCAMTool import FlatCAMTool from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \ - OptionalHideInputSection, OptionalInputSection + OptionalHideInputSection, OptionalInputSection, FCComboBox from copy import deepcopy import logging from shapely.geometry import Polygon, MultiPolygon, Point -from reportlab.graphics import renderPDF, renderPM +from reportlab.graphics import renderPDF from reportlab.pdfgen import canvas -from reportlab.lib.pagesizes import letter, A0, A1, A2, A3, A4, A5 +from reportlab.graphics import renderPM +from reportlab.lib.units import inch, mm +from reportlab.lib.pagesizes import landscape, portrait, A4 from svglib.svglib import svg2rlg from xml.dom.minidom import parseString as parse_xml_string @@ -268,6 +270,10 @@ class Film(FlatCAMTool): separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken) grid0.addWidget(separator_line2, 17, 0, 1, 2) + self.film_param_label = QtWidgets.QLabel('%s' % _("Film Parameters")) + + grid0.addWidget(self.film_param_label, 18, 0, 1, 2) + # Scale Stroke size self.film_scale_stroke_entry = FCDoubleSpinner() self.film_scale_stroke_entry.set_range(-999.9999, 999.9999) @@ -280,10 +286,10 @@ class Film(FlatCAMTool): "It means that the line that envelope each SVG feature will be thicker or thinner,\n" "therefore the fine features may be more affected by this parameter.") ) - grid0.addWidget(self.film_scale_stroke_label, 18, 0) - grid0.addWidget(self.film_scale_stroke_entry, 18, 1) + grid0.addWidget(self.film_scale_stroke_label, 19, 0) + grid0.addWidget(self.film_scale_stroke_entry, 19, 1) - grid0.addWidget(QtWidgets.QLabel(''), 19, 0) + grid0.addWidget(QtWidgets.QLabel(''), 20, 0) # Film Type self.film_type = RadioSet([{'label': _('Positive'), 'value': 'pos'}, @@ -298,8 +304,8 @@ class Film(FlatCAMTool): "with white on a black canvas.\n" "The Film format is SVG.") ) - grid0.addWidget(self.film_type_label, 20, 0) - grid0.addWidget(self.film_type, 20, 1) + grid0.addWidget(self.film_type_label, 21, 0) + grid0.addWidget(self.film_type, 21, 1) # Boundary for negative film generation self.boundary_entry = FCDoubleSpinner() @@ -318,8 +324,8 @@ class Film(FlatCAMTool): "white color like the rest and which may confound with the\n" "surroundings if not for this border.") ) - grid0.addWidget(self.boundary_label, 21, 0) - grid0.addWidget(self.boundary_entry, 21, 1) + grid0.addWidget(self.boundary_label, 22, 0) + grid0.addWidget(self.boundary_entry, 22, 1) self.boundary_label.hide() self.boundary_entry.hide() @@ -329,7 +335,7 @@ class Film(FlatCAMTool): self.punch_cb.setToolTip(_("When checked the generated film will have holes in pads when\n" "the generated film is positive. This is done to help drilling,\n" "when done manually.")) - grid0.addWidget(self.punch_cb, 22, 0, 1, 2) + grid0.addWidget(self.punch_cb, 23, 0, 1, 2) # this way I can hide/show the frame self.punch_frame = QtWidgets.QFrame() @@ -393,6 +399,7 @@ class Film(FlatCAMTool): separator_line3.setFrameShadow(QtWidgets.QFrame.Sunken) grid1.addWidget(separator_line3, 0, 0, 1, 2) + # File type self.file_type_radio = RadioSet([{'label': _('SVG'), 'value': 'svg'}, {'label': _('PNG'), 'value': 'png'}, {'label': _('PDF'), 'value': 'pdf'} @@ -408,15 +415,96 @@ class Film(FlatCAMTool): grid1.addWidget(self.file_type_label, 1, 0) grid1.addWidget(self.file_type_radio, 1, 1) + # Page orientation + self.orientation_label = QtWidgets.QLabel('%s:' % _("Page Orientation")) + self.orientation_label.setToolTip(_("Can be:\n" + "- Portrait\n" + "- Landscape")) + + self.orientation_radio = RadioSet([{'label': _('Portrait'), 'value': 'p'}, + {'label': _('Landscape'), 'value': 'l'}, + ], stretch=False) + + grid1.addWidget(self.orientation_label, 2, 0) + grid1.addWidget(self.orientation_radio, 2, 1) + + # Page Size + self.pagesize_label = QtWidgets.QLabel('%s:' % _("Page Size")) + self.pagesize_label.setToolTip(_("A selection of standard ISO 216 page sizes.")) + + self.pagesize_combo = FCComboBox() + + self.pagesize = dict() + self.pagesize.update( + { + 'Bounds': None, + 'A0': (841*mm, 1189*mm), + 'A1': (594*mm, 841*mm), + 'A2': (420*mm, 594*mm), + 'A3': (297*mm, 420*mm), + 'A4': (210*mm, 297*mm), + 'A5': (148*mm, 210*mm), + 'A6': (105*mm, 148*mm), + 'A7': (74*mm, 105*mm), + 'A8': (52*mm, 74*mm), + 'A9': (37*mm, 52*mm), + 'A10': (26*mm, 37*mm), + + 'B0': (1000*mm, 1414*mm), + 'B1': (707*mm, 1000*mm), + 'B2': (500*mm, 707*mm), + 'B3': (353*mm, 500*mm), + 'B4': (250*mm, 353*mm), + 'B5': (176*mm, 250*mm), + 'B6': (125*mm, 176*mm), + 'B7': (88*mm, 125*mm), + 'B8': (62*mm, 88*mm), + 'B9': (44*mm, 62*mm), + 'B10': (31*mm, 44*mm), + + 'C0': (917*mm, 1297*mm), + 'C1': (648*mm, 917*mm), + 'C2': (458*mm, 648*mm), + 'C3': (324*mm, 458*mm), + 'C4': (229*mm, 324*mm), + 'C5': (162*mm, 229*mm), + 'C6': (114*mm, 162*mm), + 'C7': (81*mm, 114*mm), + 'C8': (57*mm, 81*mm), + 'C9': (40*mm, 57*mm), + 'C10': (28*mm, 40*mm), + + # American paper sizes + 'LETTER': (8.5*inch, 11*inch), + 'LEGAL': (8.5*inch, 14*inch), + 'ELEVENSEVENTEEN': (11*inch, 17*inch), + + # From https://en.wikipedia.org/wiki/Paper_size + 'JUNIOR_LEGAL': (5*inch, 8*inch), + 'HALF_LETTER': (5.5*inch, 8*inch), + 'GOV_LETTER': (8*inch, 10.5*inch), + 'GOV_LEGAL': (8.5*inch, 13*inch), + 'LEDGER': (17*inch, 11*inch), + } + ) + + page_size_list = list(self.pagesize.keys()) + self.pagesize_combo.addItems(page_size_list) + + grid1.addWidget(self.pagesize_label, 3, 0) + grid1.addWidget(self.pagesize_combo, 3, 1) + + self.on_film_type(val='hide') + # Buttons self.film_object_button = QtWidgets.QPushButton(_("Save Film")) self.film_object_button.setToolTip( _("Create a Film for the selected object, within\n" "the specified box. Does not create a new \n " - "FlatCAM object, but directly save it in SVG format\n" - "which can be opened with Inkscape.") + "FlatCAM object, but directly save it in the\n" + "selected format.") ) - grid1.addWidget(self.film_object_button, 2, 0, 1, 2) + grid1.addWidget(self.film_object_button, 4, 0, 1, 2) self.layout.addStretch() @@ -429,6 +517,7 @@ class Film(FlatCAMTool): self.film_type.activated_custom.connect(self.on_film_type) self.source_punch.activated_custom.connect(self.on_punch_source) + self.file_type_radio.activated_custom.connect(self.on_file_type) def on_type_obj_index_changed(self, index): obj_type = self.tf_type_obj_combo.currentIndex() @@ -498,6 +587,8 @@ class Film(FlatCAMTool): self.film_mirror_cb.set_value(self.app.defaults["tools_film_mirror_cb"]) self.film_mirror_axis.set_value(self.app.defaults["tools_film_mirror_axis_radio"]) self.file_type_radio.set_value(self.app.defaults["tools_film_file_type_radio"]) + self.orientation_radio.set_value(self.app.defaults["tools_film_orientation"]) + self.pagesize_combo.set_value(self.app.defaults["tools_film_pagesize"]) def on_film_type(self, val): type_of_film = val @@ -512,6 +603,18 @@ class Film(FlatCAMTool): self.boundary_entry.hide() self.punch_cb.show() + def on_file_type(self, val): + if val == 'pdf': + self.orientation_label.show() + self.orientation_radio.show() + self.pagesize_label.show() + self.pagesize_combo.show() + else: + self.orientation_label.hide() + self.orientation_radio.hide() + self.pagesize_label.hide() + self.pagesize_combo.hide() + def on_punch_source(self, val): if val == 'pad' and self.punch_cb.get_value(): self.punch_size_label.show() @@ -604,7 +707,7 @@ class Film(FlatCAMTool): try: filename, _f = QtWidgets.QFileDialog.getSaveFileName( caption=_("Export positive film"), - directory=self.app.get_last_save_folder() + '/' + name, + directory=self.app.get_last_save_folder() + '/' + name + '_film', filter=filter_ext) except TypeError: filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export positive film")) @@ -647,7 +750,7 @@ class Film(FlatCAMTool): outname = name + "_punched" self.app.new_object('gerber', outname, init_func) - self.generate_positive_normal_film(outname, boxname, factor=factor) + self.generate_positive_normal_film(outname, boxname, factor=factor, ftype=ftype) else: log.debug("ToolFilm.Film.generate_positive_punched_film() with Pad center source started ...") @@ -698,7 +801,7 @@ class Film(FlatCAMTool): outname = name + "_punched" self.app.new_object('gerber', outname, init_func) - self.generate_positive_normal_film(outname, boxname, factor=factor) + self.generate_positive_normal_film(outname, boxname, factor=factor, ftype=ftype) def generate_negative_film(self, name, boxname, factor, ftype='svg'): log.debug("ToolFilm.Film.generate_negative_film() started ...") @@ -744,7 +847,7 @@ class Film(FlatCAMTool): try: filename, _f = QtWidgets.QFileDialog.getSaveFileName( caption=_("Export negative film"), - directory=self.app.get_last_save_folder() + '/' + name, + directory=self.app.get_last_save_folder() + '/' + name + '_film', filter=filter_ext) except TypeError: filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export negative film")) @@ -785,6 +888,7 @@ class Film(FlatCAMTool): those are the 4 points of the bounding box of the geometry to be skewed. :param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry :param use_thread: if to be run in a separate thread; boolean + :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf' :return: """ self.app.report_usage("export_negative()") @@ -896,19 +1000,26 @@ class Film(FlatCAMTool): else: try: if self.units == 'INCH': - from reportlab.lib.units import inch unit = inch else: - from reportlab.lib.units import mm unit = mm doc_final = StringIO(doc_final) - my_canvas = canvas.Canvas(filename, pagesize=A4) drawing = svg2rlg(doc_final) - my_canvas.translate(bounds[0] * unit, bounds[1] * unit) - renderPDF.draw(drawing, my_canvas, 0, 0) - my_canvas.save() + p_size = self.pagesize_combo.get_value() + if p_size == 'Bounds': + renderPDF.drawToFile(drawing, filename) + else: + if self.orientation_radio.get_value() == 'p': + page_size = portrait(self.pagesize[p_size]) + else: + page_size = landscape(self.pagesize[p_size]) + + my_canvas = canvas.Canvas(filename, pagesize=page_size) + my_canvas.translate(bounds[0] * unit, bounds[1] * unit) + renderPDF.draw(drawing, my_canvas, 0, 0) + my_canvas.save() except Exception as e: log.debug("FilmTool.export_negative() --> PDF output --> %s" % str(e)) return 'fail' @@ -955,6 +1066,7 @@ class Film(FlatCAMTool): :param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry :param use_thread: if to be run in a separate thread; boolean + :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf' :return: """ self.app.report_usage("export_positive()") @@ -1059,19 +1171,26 @@ class Film(FlatCAMTool): else: try: if self.units == 'INCH': - from reportlab.lib.units import inch unit = inch else: - from reportlab.lib.units import mm unit = mm doc_final = StringIO(doc_final) - my_canvas = canvas.Canvas(filename, pagesize=A4) drawing = svg2rlg(doc_final) - my_canvas.translate(bounds[0]*unit, bounds[1]*unit) - renderPDF.draw(drawing, my_canvas, 0, 0) - my_canvas.save() + p_size = self.pagesize_combo.get_value() + if p_size == 'Bounds': + renderPDF.drawToFile(drawing, filename) + else: + if self.orientation_radio.get_value() == 'p': + page_size = portrait(self.pagesize[p_size]) + else: + page_size = landscape(self.pagesize[p_size]) + + my_canvas = canvas.Canvas(filename, pagesize=page_size) + my_canvas.translate(bounds[0] * unit, bounds[1] * unit) + renderPDF.draw(drawing, my_canvas, 0, 0) + my_canvas.save() except Exception as e: log.debug("FilmTool.export_positive() --> PDF output --> %s" % str(e)) return 'fail' diff --git a/flatcamTools/ToolMove.py b/flatcamTools/ToolMove.py index 398933ff..e46c1b36 100644 --- a/flatcamTools/ToolMove.py +++ b/flatcamTools/ToolMove.py @@ -160,11 +160,12 @@ class ToolMove(FlatCAMTool): def job_move(app_obj): with self.app.proc_container.new(_("Moving...")) as proc: - try: - if not obj_list: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("No object(s) selected.")) - return "fail" + if not obj_list: + app_obj.app.inform.emit('[WARNING_NOTCL] %s' % _("No object(s) selected.")) + return "fail" + + try: # remove any mark aperture shape that may be displayed for sel_obj in obj_list: # if the Gerber mark shapes are enabled they need to be disabled before move @@ -173,10 +174,9 @@ class ToolMove(FlatCAMTool): try: sel_obj.replotApertures.emit() - except Exception as e: + except Exception: pass - for sel_obj in obj_list: # offset solid_geometry sel_obj.offset((dx, dy)) @@ -186,15 +186,13 @@ class ToolMove(FlatCAMTool): sel_obj.options['ymin'] = b sel_obj.options['xmax'] = c sel_obj.options['ymax'] = d - - # time to plot the moved objects - self.replot_signal.emit(obj_list) except Exception as e: - proc.done() - self.app.inform.emit('[ERROR_NOTCL] %s --> %s' % ('ToolMove.on_left_click()', str(e))) + log.debug('[ERROR_NOTCL] %s --> %s' % ('ToolMove.on_left_click()', str(e))) return "fail" - proc.done() + # time to plot the moved objects + app_obj.replot_signal.emit(obj_list) + # delete the selection bounding box self.delete_shape() self.app.inform.emit('[success] %s %s' % diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 2c92c3bc..0a9799a0 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -381,6 +381,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.overlap = None self.connect = None self.contour = None + self.select_method = None self.units = '' self.paint_tools = {} @@ -966,7 +967,6 @@ class ToolPaint(FlatCAMTool, Gerber): self.connect = self.pathconnect_cb.get_value() self.contour = self.paintcontour_cb.get_value() self.select_method = self.selectmethod_combo.get_value() - self.obj_name = self.obj_combo.currentText() # Get source object. @@ -2018,7 +2018,7 @@ class ToolPaint(FlatCAMTool, Gerber): except FlatCAMApp.GracefulException: proc.done() return - except Exception as e: + except Exception: proc.done() traceback.print_stack() return @@ -2493,7 +2493,7 @@ class ToolPaint(FlatCAMTool, Gerber): except FlatCAMApp.GracefulException: proc.done() return - except Exception as e: + except Exception: proc.done() traceback.print_stack() return