Warning before overwriting. More flexible Excellon parser (tool numbers). Other small fixes.

This commit is contained in:
Juan Pablo Caram 2014-04-05 00:36:23 -04:00
parent 9740739f05
commit 6c13b7dc59
16 changed files with 519 additions and 315 deletions

View File

@ -36,6 +36,7 @@ from camlib import *
from FlatCAMObj import *
from FlatCAMWorker import Worker
########################################
## App ##
########################################
@ -149,13 +150,9 @@ class App:
# self.radios_inv.update({obj.kind + "_" + option: obj.radios_inv[option]})
## Event subscriptions ##
# TODO: Move to plotcanvas
self.plot_click_subscribers = {}
self.plot_mousemove_subscribers = {}
## Tools ##
self.measure = Measurement(self.builder.get_object("box39"), self.plotcanvas.axes,
self.plot_click_subscribers, self.plot_mousemove_subscribers)
self.measure = Measurement(self.builder.get_object("box39"), self.plotcanvas)
# Toolbar icon
# TODO: Where should I put this? Tool should have a method to add to toolbar?
meas_ico = Gtk.Image.new_from_file('share/measure32.png')
@ -188,10 +185,13 @@ class App:
def somethreadfunc(app_obj):
print "Hello World!"
self.message_dialog("Starting", "The best program is starting")
t = threading.Thread(target=somethreadfunc, args=(self,))
t.daemon = True
t.start()
########################################
## START ##
########################################
@ -203,6 +203,30 @@ class App:
self.window.set_default_size(900, 600)
self.window.show_all()
def message_dialog(self, title, message, type="info"):
types = {"info": Gtk.MessageType.INFO,
"warn": Gtk.MessageType.WARNING,
"error": Gtk.MessageType.ERROR}
dlg = Gtk.MessageDialog(self.window, 0, types[type], Gtk.ButtonsType.OK, title)
dlg.format_secondary_text(message)
dlg.run()
dlg.destroy()
def question_dialog(self, title, message):
label = Gtk.Label(message)
dialog = Gtk.Dialog(title, self.window, 0,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK))
dialog.set_default_size(150, 100)
dialog.set_modal(True)
box = dialog.get_content_area()
box.set_border_width(10)
box.add(label)
dialog.show_all()
response = dialog.run()
dialog.destroy()
return response
def setup_toolbar(self):
# Zoom fit
@ -255,48 +279,6 @@ class App:
"""
FlatCAMObj.app = self
# def setup_project_list(self):
# """
# Sets up list or Tree where whatever has been loaded or created is
# displayed.
#
# :return: None
# """
#
# # Model
# self.store = Gtk.ListStore(GdkPixbuf.Pixbuf, str)
# #self.store = Gtk.ListStore(str, str)
#
# # View
# self.tree = Gtk.TreeView(model=self.store)
#
# # Renderers
# renderer_pixbuf = Gtk.CellRendererPixbuf()
# column_pixbuf = Gtk.TreeViewColumn("Type", renderer_pixbuf, pixbuf=0)
# # column_pixbuf = Gtk.TreeViewColumn("Type")
# # column_pixbuf.pack_start(renderer_pixbuf, False)
# # column_pixbuf.add_attribute(renderer_pixbuf, "pixbuf", 1)
# self.tree.append_column(column_pixbuf)
#
# # renderer1 = Gtk.CellRendererText()
# # column1 = Gtk.TreeViewColumn("Type", renderer1, text=0)
# # self.tree.append_column(column1)
#
# renderer = Gtk.CellRendererText()
# column = Gtk.TreeViewColumn("Object name", renderer, text=1)
# self.tree.append_column(column)
#
# self.tree_select = self.tree.get_selection()
#
#
# self.builder.get_object("box_project").pack_start(self.tree, False, False, 1)
#
# # Double-click or Enter takes you to the object's options
# self.tree.connect("row_activated", self.on_row_activated)
#
# # Changes the selected item and populates the object options form
# self.signal_id = self.tree_select.connect("changed", self.on_tree_selection_changed)
def setup_component_editor(self):
"""
Initial configuration of the component editor. Creates
@ -335,7 +317,7 @@ class App:
'gerber': self.open_gerber,
'excellon': self.open_excellon,
'cncjob': self.open_gcode,
'project': lambda x: ""
'project': self.open_project
}
# Closure needed to create callbacks in a loop.
@ -378,39 +360,13 @@ class App:
def info(self, text):
"""
Show text on the status bar.
Show text on the status bar. This method is thread safe.
:param text: Text to display.
:type text: str
:return: None
"""
self.info_label.set_text(text)
# def build_list(self):
# """
# Clears and re-populates the list of objects in currently
# in the project.
#
# :return: None
# """
# icons = {
# "gerber": "share/flatcam_icon16.png",
# "excellon": "share/drill16.png",
# "cncjob": "share/cnc16.png",
# "geometry": "share/geometry16.png"
# }
#
#
# print "build_list(): clearing"
# self.tree_select.unselect_all()
# self.store.clear()
# print "repopulating...",
# for key in self.stuff:
# print key,
# obj = self.stuff[key]
# icon = GdkPixbuf.Pixbuf.new_from_file(icons[obj.kind])
# self.store.append([icon, key])
# print
GLib.idle_add(lambda: self.info_label.set_text(text))
def get_radio_value(self, radio_set):
"""
@ -474,31 +430,11 @@ class App:
self.info("Could not evaluate: " + value)
return None
# def set_list_selection(self, name):
# """
# Marks a given object as selected in the list ob objects
# in the GUI. This selection will in turn trigger
# ``self.on_tree_selection_changed()``.
#
# :param name: Name of the object.
# :type name: str
# :return: None
# """
#
# iter = self.store.get_iter_first()
# while iter is not None and self.store[iter][1] != name:
# iter = self.store.iter_next(iter)
# self.tree_select.unselect_all()
# self.tree_select.select_iter(iter)
#
# # Need to return False such that GLib.idle_add
# # or .timeout_add do not repeat.
# return False
def new_object(self, kind, name, initialize):
"""
Creates a new specalized FlatCAMObj and attaches it to the application,
this is, updates the GUI accordingly, any other records and plots it.
This method is thread-safe.
:param kind: The kind of object to create. One of 'gerber',
'excellon', 'cncjob' and 'geometry'.
@ -513,6 +449,8 @@ class App:
:rtype: None
"""
print "new_object()"
### Check for existing name
if name in self.collection.get_names():
## Create a new name
@ -553,18 +491,17 @@ class App:
obj.convert_units(self.options["units"])
# Add to our records
# TODO: Perhaps make collection thread safe instead?
GLib.idle_add(lambda: self.collection.append(obj, active=True))
self.collection.append(obj, active=True)
# Show object details now.
GLib.timeout_add(100, lambda: self.notebook.set_current_page(1))
GLib.idle_add(lambda: self.notebook.set_current_page(1))
# Plot
# TODO: (Thread-safe?)
obj.plot()
# TODO: Threading dissaster!
GLib.idle_add(lambda: self.on_zoom_fit(None))
#self.on_zoom_fit(None)
return obj
@ -582,23 +519,6 @@ class App:
self.progress_bar.set_fraction(percentage)
return False
# def get_current(self):
# """
# Returns the currently selected FlatCAMObj in the application.
#
# :return: Currently selected FlatCAMObj in the application.
# :rtype: FlatCAMObj or None
# """
#
# # TODO: Could possibly read the form into the object here.
# # But there are some cases when the form for the object
# # is not up yet. See on_tree_selection_changed.
#
# try:
# return self.stuff[self.selected_item_name]
# except:
# return None
def load_defaults(self):
"""
Loads the aplication's default settings from defaults.json into
@ -738,6 +658,7 @@ class App:
except:
pass
# Serialize the whole project
d = {"objs": [obj.to_dict() for obj in self.collection.get_list()],
"options": self.options}
@ -786,7 +707,7 @@ class App:
# Project options
self.options.update(d['options'])
self.project_filename = filename
self.units_label.set_text(self.options["units"])
GLib.idle_add(lambda: self.units_label.set_text(self.options["units"]))
# Re create objects
for obj in d['objs']:
@ -961,6 +882,9 @@ class App:
########################################
## EVENT HANDLERS ##
########################################
def on_debug_printlist(self, *args):
self.collection.print_list()
def on_disable_all_plots(self, widget):
self.disable_plots()
@ -997,8 +921,6 @@ class App:
:return: None
"""
# self.get_current().read_form()
# self.get_current().plot()
self.collection.get_active().read_form()
self.collection.get_active().plot()
@ -1012,7 +934,6 @@ class App:
about = self.builder.get_object("aboutdialog")
response = about.run()
#about.destroy()
about.hide()
def on_create_mirror(self, widget):
@ -1299,6 +1220,18 @@ class App:
def on_success(app_obj, filename):
assert isinstance(app_obj, App)
try:
f = open(filename, 'r')
f.close()
exists = True
except IOError:
exists = False
msg = "File exists. Overwrite?"
if exists and self.question_dialog("File exists", msg) == Gtk.ResponseType.CANCEL:
return
app_obj.save_project(filename)
self.project_filename = filename
self.register_recent("project", filename)
@ -1319,6 +1252,18 @@ class App:
def on_success(app_obj, filename):
assert isinstance(app_obj, App)
try:
f = open(filename, 'r')
f.close()
exists = True
except IOError:
exists = False
msg = "File exists. Overwrite?"
if exists and self.question_dialog("File exists", msg) == Gtk.ResponseType.CANCEL:
return
app_obj.save_project(filename)
self.register_recent("project", filename)
app_obj.info("Project copy saved to: " + filename)
@ -1578,9 +1523,7 @@ class App:
obj.plot()
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, "Idle"))
# t = threading.Thread(target=thread_func, args=(self,))
# t.daemon = True
# t.start()
# Send to worker
self.worker.add_task(thread_func, [self])
def on_generate_excellon_cncjob(self, widget):
@ -1625,10 +1568,7 @@ class App:
GLib.idle_add(lambda: app_obj.set_progress_bar(1.0, "Done!"))
GLib.timeout_add_seconds(1, lambda: app_obj.set_progress_bar(0.0, ""))
# Start the thread
# t = threading.Thread(target=job_thread, args=(self,))
# t.daemon = True
# t.start()
# Send to worker
self.worker.add_task(job_thread, [self])
def on_excellon_tool_choose(self, widget):
@ -1818,10 +1758,7 @@ class App:
GLib.idle_add(lambda: app_obj.set_progress_bar(1.0, "Done!"))
GLib.timeout_add_seconds(1, lambda: app_obj.set_progress_bar(0.0, ""))
# Start the thread
# t = threading.Thread(target=job_thread, args=(self,))
# t.daemon = True
# t.start()
# Send to worker
self.worker.add_task(job_thread, [self])
def on_generate_paintarea(self, widget):
@ -1843,10 +1780,14 @@ class App:
tooldia = geo.options["painttooldia"]
overlap = geo.options["paintoverlap"]
# Connection ID for the click event
subscription = None
# To be called after clicking on the plot.
def doit(event):
self.plot_click_subscribers.pop("generate_paintarea")
self.info("")
#self.plot_click_subscribers.pop("generate_paintarea")
self.plotcanvas.mpl_disconnect(subscription)
self.info("Painting")
point = [event.xdata, event.ydata]
poly = find_polygon(geo.solid_geometry, point)
@ -1858,10 +1799,12 @@ class App:
geo_obj.solid_geometry = cp
geo_obj.options["cnctooldia"] = tooldia
name = self.selected_item_name + "_paint"
#name = self.selected_item_name + "_paint"
name = geo.options["name"] + "_paint"
self.new_object("geometry", name, gen_paintarea)
self.plot_click_subscribers["generate_paintarea"] = doit
#self.plot_click_subscribers["generate_paintarea"] = doit
subscription = self.plotcanvas.mpl_connect('button_press_event', doit)
def on_cncjob_exportgcode(self, widget):
"""
@ -1940,23 +1883,25 @@ class App:
def on_file_new(self, param):
"""
Callback for menu item File->New. Returns the application to its
startup state.
startup state. This method is thread-safe.
:param param: Whatever is passed by the event. Ignore.
:return: None
"""
# Remove everything from memory
# Clear plot
self.plotcanvas.clear()
# Delete data
self.collection.delete_all()
# GUI things
def task():
# Clear plot
self.plotcanvas.clear()
# Clear object editor
self.setup_component_editor()
# Delete data
self.collection.delete_all()
# Clear list
#self.collection.build_list()
# Clear object editor
self.setup_component_editor()
GLib.idle_add(task)
# Clear project filename
self.project_filename = None
@ -2006,13 +1951,10 @@ class App:
if response == Gtk.ResponseType.OK:
filename = dialog.get_filename()
dialog.destroy()
# t = threading.Thread(target=on_success, args=(self, filename))
# t.daemon = True
# t.start()
# Send to worker.
self.worker.add_task(on_success, [self, filename])
#on_success(self, filename)
elif response == Gtk.ResponseType.CANCEL:
self.info("Open cancelled.") # print("Cancel clicked")
self.info("Open cancelled.")
dialog.destroy()
def file_chooser_save_action(self, on_success):
@ -2043,8 +1985,12 @@ class App:
def obj_init(gerber_obj, app_obj):
assert isinstance(gerber_obj, FlatCAMGerber)
# Opening the file happens here
GLib.idle_add(lambda: app_obj.set_progress_bar(0.2, "Parsing ..."))
gerber_obj.parse_file(filename)
# Further parsing
GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Creating Geometry ..."))
gerber_obj.create_geometry()
GLib.idle_add(lambda: app_obj.set_progress_bar(0.6, "Plotting ..."))
@ -2053,8 +1999,9 @@ class App:
self.new_object("gerber", name, obj_init)
self.register_recent("gerber", filename)
self.info("Opened: " + filename)
GLib.idle_add(lambda: self.set_progress_bar(1.0, "Done!"))
GLib.timeout_add_seconds(1, lambda: self.set_progress_bar(0.0, ""))
GLib.timeout_add_seconds(1, lambda: self.set_progress_bar(0.0, "Idle"))
def on_fileopengerber(self, param):
"""
@ -2065,30 +2012,7 @@ class App:
:param param: Ignore
:return: None
"""
# IMPORTANT: on_success will run on a separate thread. Use
# GLib.idle_add(function, **kwargs) to launch actions that will
# updata the GUI.
# def on_success(app_obj, filename):
# assert isinstance(app_obj, App)
# GLib.idle_add(lambda: app_obj.set_progress_bar(0.1, "Opening Gerber ..."))
#
# def obj_init(gerber_obj, app_obj):
# assert isinstance(gerber_obj, FlatCAMGerber)
# GLib.idle_add(lambda: app_obj.set_progress_bar(0.2, "Parsing ..."))
# gerber_obj.parse_file(filename)
# GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Creating Geometry ..."))
# gerber_obj.create_geometry()
# GLib.idle_add(lambda: app_obj.set_progress_bar(0.6, "Plotting ..."))
#
# name = filename.split('/')[-1].split('\\')[-1]
# app_obj.new_object("gerber", name, obj_init)
# app_obj.register_recent("gerber", filename)
#
# GLib.idle_add(lambda: app_obj.set_progress_bar(1.0, "Done!"))
# GLib.timeout_add_seconds(1, lambda: app_obj.set_progress_bar(0.0, ""))
# on_success gets run on a separate thread
# self.file_chooser_action(on_success)
self.file_chooser_action(lambda ao, filename: self.open_gerber(filename))
def open_excellon(self, filename):
@ -2104,6 +2028,7 @@ class App:
self.new_object("excellon", name, obj_init)
self.register_recent("excellon", filename)
self.info("Opened: " + filename)
GLib.idle_add(lambda: self.set_progress_bar(1.0, "Done!"))
GLib.timeout_add_seconds(1, lambda: self.set_progress_bar(0.0, ""))
@ -2116,28 +2041,7 @@ class App:
:param param: Ignore
:return: None
"""
# IMPORTANT: on_success will run on a separate thread. Use
# GLib.idle_add(function, **kwargs) to launch actions that will
# updata the GUI.
# def on_success(app_obj, filename):
# assert isinstance(app_obj, App)
# GLib.idle_add(lambda: app_obj.set_progress_bar(0.1, "Opening Excellon ..."))
#
# def obj_init(excellon_obj, app_obj):
# GLib.idle_add(lambda: app_obj.set_progress_bar(0.2, "Parsing ..."))
# excellon_obj.parse_file(filename)
# excellon_obj.create_geometry()
# GLib.idle_add(lambda: app_obj.set_progress_bar(0.6, "Plotting ..."))
#
# name = filename.split('/')[-1].split('\\')[-1]
# app_obj.new_object("excellon", name, obj_init)
# self.register_recent("excellon", filename)
#
# GLib.idle_add(lambda: app_obj.set_progress_bar(1.0, "Done!"))
# GLib.timeout_add_seconds(1, lambda: app_obj.set_progress_bar(0.0, ""))
# on_success gets run on a separate thread
# self.file_chooser_action(on_success)
self.file_chooser_action(lambda ao, filename: self.open_excellon(filename))
def open_gcode(self, filename):
@ -2168,6 +2072,7 @@ class App:
self.new_object("cncjob", name, obj_init)
self.register_recent("cncjob", filename)
self.info("Opened: " + filename)
GLib.idle_add(lambda: self.set_progress_bar(1.0, "Done!"))
GLib.timeout_add_seconds(1, lambda: self.set_progress_bar(0.0, ""))
@ -2180,43 +2085,7 @@ class App:
:param param: Ignore
:return: None
"""
# IMPORTANT: on_success will run on a separate thread. Use
# GLib.idle_add(function, **kwargs) to launch actions that will
# updata the GUI.
# def on_success(app_obj, filename):
# assert isinstance(app_obj, App)
#
# def obj_init(job_obj, app_obj_):
# """
#
# :type app_obj_: App
# """
# assert isinstance(app_obj_, App)
# GLib.idle_add(lambda: app_obj_.set_progress_bar(0.1, "Opening G-Code ..."))
#
# f = open(filename)
# gcode = f.read()
# f.close()
#
# job_obj.gcode = gcode
#
# GLib.idle_add(lambda: app_obj_.set_progress_bar(0.2, "Parsing ..."))
# job_obj.gcode_parse()
#
# GLib.idle_add(lambda: app_obj_.set_progress_bar(0.6, "Creating geometry ..."))
# job_obj.create_geometry()
#
# GLib.idle_add(lambda: app_obj_.set_progress_bar(0.6, "Plotting ..."))
#
# name = filename.split('/')[-1].split('\\')[-1]
# app_obj.new_object("cncjob", name, obj_init)
# self.register_recent("cncjob", filename)
#
# GLib.idle_add(lambda: app_obj.set_progress_bar(1.0, "Done!"))
# GLib.timeout_add_seconds(1, lambda: app_obj.set_progress_bar(0.0, ""))
# on_success gets run on a separate thread
# self.file_chooser_action(on_success)
self.file_chooser_action(lambda ao, filename: self.open_gcode(filename))
def on_mouse_move_over_plot(self, event):
@ -2234,8 +2103,8 @@ class App:
event.xdata, event.ydata))
self.mouse = [event.xdata, event.ydata]
for subscriber in self.plot_mousemove_subscribers:
self.plot_mousemove_subscribers[subscriber](event)
# for subscriber in self.plot_mousemove_subscribers:
# self.plot_mousemove_subscribers[subscriber](event)
except:
self.position_label.set_label("")
@ -2256,7 +2125,7 @@ class App:
:return: None
"""
# For key presses
# So it can receive key presses
self.plotcanvas.canvas.grab_focus()
try:
@ -2264,8 +2133,8 @@ class App:
event.button, event.x, event.y, event.xdata, event.ydata)
# TODO: This custom subscription mechanism is probably not necessary.
for subscriber in self.plot_click_subscribers:
self.plot_click_subscribers[subscriber](event)
# for subscriber in self.plot_click_subscribers:
# self.plot_click_subscribers[subscriber](event)
self.clipboard.set_text("(%.4f, %.4f)" % (event.xdata, event.ydata), -1)
@ -2403,31 +2272,32 @@ class DrawingPoint(DrawingObject):
class Measurement:
def __init__(self, container, axes, click_subscibers, move_subscribers, update=None):
def __init__(self, container, plotcanvas, update=None):
self.update = update
self.container = container
self.frame = None
self.label = None
self.click_subscribers = click_subscibers
self.move_subscribers = move_subscribers
self.point1 = None
self.point2 = None
self.active = False
self.plotcanvas = plotcanvas
self.click_subscription = None
self.move_subscription = None
def toggle_active(self, *args):
if self.active: # Deactivate
self.active = False
self.move_subscribers.pop("meas")
self.click_subscribers.pop("meas")
self.container.remove(self.frame)
if self.update is not None:
self.update()
self.plotcanvas.mpl_disconnect(self.click_subscription)
self.plotcanvas.mpl_disconnect(self.move_subscription)
return False
else: # Activate
print "DEBUG: Activating Measurement Tool..."
self.active = True
self.click_subscribers["meas"] = self.on_click
self.move_subscribers["meas"] = self.on_move
self.click_subscription = self.plotcanvas.mpl_connect("button_press_event", self.on_click)
self.move_subscription = self.plotcanvas.mpl_connect('motion_notify_event', self.on_move)
self.frame = Gtk.Frame()
self.frame.set_margin_right(5)
self.frame.set_margin_top(3)
@ -2449,10 +2319,13 @@ class Measurement:
if self.point1 is None:
self.label.set_label("Click on a reference point...")
else:
dx = event.xdata - self.point1[0]
dy = event.ydata - self.point1[1]
d = sqrt(dx**2 + dy**2)
self.label.set_label("D = %.4f D(x) = %.4f D(y) = %.4f" % (d, dx, dy))
try:
dx = event.xdata - self.point1[0]
dy = event.ydata - self.point1[1]
d = sqrt(dx**2 + dy**2)
self.label.set_label("D = %.4f D(x) = %.4f D(y) = %.4f" % (d, dx, dy))
except TypeError:
pass
if self.update is not None:
self.update()
@ -2540,9 +2413,18 @@ class PlotCanvas:
:type event_name: str
:param callback: Function to call
:type callback: func
:return: Nothing
:return: Connection id
:rtype: int
"""
self.canvas.mpl_connect(event_name, callback)
return self.canvas.mpl_connect(event_name, callback)
def mpl_disconnect(self, cid):
"""
Disconnect callback with the give id.
:param cid: Callback id.
:return: None
"""
self.canvas.mpl_disconnect(cid)
def connect(self, event_name, callback):
"""
@ -2592,6 +2474,8 @@ class PlotCanvas:
:return: None
"""
print "PC.adjust_axes()"
width = xmax - xmin
height = ymax - ymin
try:
@ -2707,21 +2591,6 @@ class PlotCanvas:
return self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label=name)
# def plot_axes(self, axes):
#
# if axes not in self.figure.axes:
# self.figure.add_axes(axes)
#
# # Basic configuration
# axes.set_frame_on(False) # No frame
# axes.set_xticks([]) # No tick
# axes.set_yticks([]) # No ticks
# axes.patch.set_visible(False) # No background
# axes.set_aspect(1)
#
# # Adjust limits
# self.auto_adjust_axes()
def on_scroll(self, canvas, event):
"""
Scroll event handler.
@ -2730,6 +2599,11 @@ class PlotCanvas:
:param event: Event object containing the event information.
:return: None
"""
# So it can receive key presses
self.canvas.grab_focus()
# Event info
z, direction = event.get_scroll_direction()
if self.key is None:
@ -2758,7 +2632,7 @@ class PlotCanvas:
def on_mouse_move(self, event):
"""
Mouse movement event hadler.
Mouse movement event hadler. Stores the coordinates.
:param event: Contains information about the event.
:return: None
@ -2822,6 +2696,13 @@ class ObjectCollection:
column_text.set_cell_data_func(renderer_text, _set_cell_text)
self.view.append_column(column_text)
def print_list(self):
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]
print obj
iterat = self.store.iter_next(iterat)
def delete_all(self):
print "OC.delete_all()"
# self.collection = []
@ -2837,10 +2718,22 @@ class ObjectCollection:
pass
def on_row_activated(self, *args):
"""
Does nothing right now.
:param args: Ignored.
:return: None
"""
print "OC.on_row_activated()"
return
def on_list_selection_change(self, selection):
"""
Callback for change in selection on the objects' list.
Instructs the new selection to build the UI for its options.
:param selection: Ignored.
:return: None
"""
print "OC.on_list_selection_change()"
try:
self.get_active().build_ui()
@ -2851,6 +2744,14 @@ class ObjectCollection:
# TODO: active, so cannot read form.
def set_active(self, name):
"""
Sets an object as the active object in the program. Same
as `set_list_selection()`.
:param name: Name of the object.
:type name: str
:return: None
"""
print "OC.set_active()"
self.set_list_selection(name)
@ -2863,6 +2764,13 @@ class ObjectCollection:
return None
def set_list_selection(self, name):
"""
Sets which object should be selected in the list.
:param name: Name of the object.
:rtype name: str
:return: None
"""
print "OC.set_list_selection()"
iterat = self.store.get_iter_first()
while iterat is not None and self.store[iterat][0].options["name"] != name:
@ -2870,13 +2778,30 @@ class ObjectCollection:
self.tree_selection.select_iter(iterat)
def append(self, obj, active=False):
"""
Add a FlatCAMObj the the collection. This method is thread-safe.
:param obj: FlatCAMObj to append
:type obj: FlatCAMObj
:param active: If it is to become the active object after appending
:type active: bool
:return: None
"""
print "OC.append()"
self.store.append([obj])
if active:
self.set_list_selection(obj.options["name"])
def guitask():
self.store.append([obj])
if active:
self.set_list_selection(obj.options["name"])
GLib.idle_add(guitask)
def get_names(self):
"""
Gets a list of the names of all objects in the collection.
:return: List of names.
:rtype: list
"""
print "OC.get_names()"
names = []
iterat = self.store.get_iter_first()
@ -2887,6 +2812,12 @@ class ObjectCollection:
return names
def get_bounds(self):
"""
Finds coordinates bounding all objects in the collection.
:return: [xmin, ymin, xmax, ymax]
:rtype: list
"""
print "OC.get_bounds()"
# TODO: Move the operation out of here.
@ -2911,6 +2842,12 @@ class ObjectCollection:
return [xmin, ymin, xmax, ymax]
def get_list(self):
"""
Returns a list with all FlatCAMObj.
:return: List with all FlatCAMObj.
:rtype: list
"""
collection_list = []
iterat = self.store.get_iter_first()
while iterat is not None:
@ -2920,6 +2857,14 @@ class ObjectCollection:
return collection_list
def get_by_name(self, name):
"""
Fetches the FlatCAMObj with the given `name`.
:param name: The name of the object.
:type name: str
:return: The requested object or None if no such object.
:rtype: FlatCAMObj or None
"""
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]
@ -2929,6 +2874,17 @@ class ObjectCollection:
return None
def change_name(self, old_name, new_name):
"""
Changes the name of `FlatCAMObj` named `old_name` to `new_name`.
:param old_name: Name of the object to change.
:type old_name: str
:param new_name: New name.
:type new_name: str
:return: True if name change succeeded, False otherwise. Will fail
if no object with `old_name` is found.
:rtype: bool
"""
iterat = self.store.get_iter_first()
while iterat is not None:
obj = self.store[iterat][0]

View File

@ -97,6 +97,11 @@ THE SOFTWARE.</property>
<property name="can_focus">False</property>
<property name="stock">gtk-open</property>
</object>
<object class="GtkImage" id="image21">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixbuf">share/bug16.png</property>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
@ -132,6 +137,77 @@ THE SOFTWARE.</property>
<property name="can_focus">False</property>
<property name="stock">gtk-open</property>
</object>
<object class="GtkDialog" id="question_dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="question_box">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box40">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImage" id="image22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="pixbuf">share/warning.png</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_warning">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">12</property>
<property name="margin_right">12</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkOffscreenWindow" id="offscreenwindow_dblsided">
<property name="can_focus">False</property>
<child>
@ -3488,6 +3564,22 @@ to application defaults.</property>
<signal name="activate" handler="on_tools_doublesided" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem7">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem17">
<property name="label" translatable="yes">List objects</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image21</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_debug_printlist" swapped="no"/>
</object>
</child>
</object>
</child>
</object>

View File

@ -38,6 +38,9 @@ class FlatCAMObj(GObject.GObject, object):
self.axes = None # Matplotlib axes
self.kind = None # Override with proper name
def __str__(self):
return "<FlatCAMObj({:12s}): {:20s}>".format(self.kind, self.options["name"])
def setup_axes(self, figure):
"""
1) Creates axes if they don't exist. 2) Clears axes. 3) Attaches

View File

@ -1485,7 +1485,11 @@ class Excellon(Geometry):
# Tool definition/parameters (?= is look-ahead
# NOTE: This might be an overkill!
self.toolset_re = re.compile(r'^T(0?\d|\d\d)(?=.*C(\d*\.?\d*))?' +
# self.toolset_re = re.compile(r'^T(0?\d|\d\d)(?=.*C(\d*\.?\d*))?' +
# r'(?=.*F(\d*\.?\d*))?(?=.*S(\d*\.?\d*))?' +
# r'(?=.*B(\d*\.?\d*))?(?=.*H(\d*\.?\d*))?' +
# r'(?=.*Z([-\+]?\d*\.?\d*))?[CFSBHT]')
self.toolset_re = re.compile(r'^T(\d+)(?=.*C(\d*\.?\d*))?' +
r'(?=.*F(\d*\.?\d*))?(?=.*S(\d*\.?\d*))?' +
r'(?=.*B(\d*\.?\d*))?(?=.*H(\d*\.?\d*))?' +
r'(?=.*Z([-\+]?\d*\.?\d*))?[CFSBHT]')
@ -1494,7 +1498,8 @@ class Excellon(Geometry):
# Can have additional data after tool number but
# is ignored if present in the header.
# Warning: This will match toolset_re too.
self.toolsel_re = re.compile(r'^T((?:\d\d)|(?:\d))')
# self.toolsel_re = re.compile(r'^T((?:\d\d)|(?:\d))')
self.toolsel_re = re.compile(r'^T(\d+)')
# Comment
self.comm_re = re.compile(r'^;(.*)$')

View File

@ -1 +1 @@
{"gerber_noncopperrounded": false, "geometry_paintoverlap": 0.15, "geometry_plot": true, "excellon_feedrate": 5.0, "gerber_plot": true, "gerber_mergepolys": true, "excellon_drillz": -0.1, "geometry_feedrate": 3.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "gerber_isopasses": 1, "excellon_plot": true, "gerber_isotooldia": 0.016, "gerber_bboxmargin": 0.0, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "geometry_cnctooldia": 0.016, "gerber_cutouttooldia": 0.07, "gerber_gaps": "4", "geometry_painttooldia": 0.0625, "cncjob_plot": true, "gerber_cutoutgapsize": 0.15, "gerber_isooverlap": 0.15, "gerber_bboxrounded": false, "geometry_multicolored": false, "gerber_noncoppermargin": 0.0, "geometry_solid": false}
{"gerber_noncopperrounded": false, "geometry_paintoverlap": 0.15, "geometry_plot": true, "excellon_feedrate": 5.0, "gerber_plot": true, "gerber_mergepolys": true, "excellon_drillz": -0.1, "geometry_feedrate": 3.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "gerber_isopasses": 1, "excellon_plot": true, "gerber_isotooldia": 0.016, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "geometry_cnctooldia": 0.016, "gerber_cutouttooldia": 0.07, "geometry_painttooldia": 0.0625, "gerber_gaps": "4", "gerber_bboxmargin": 0.0, "cncjob_plot": true, "gerber_cutoutgapsize": 0.15, "gerber_isooverlap": 0.15, "gerber_bboxrounded": false, "geometry_multicolored": false, "gerber_noncoppermargin": 0.0, "geometry_solid": false}

Binary file not shown.

Binary file not shown.

87
doc/build/camlib.html vendored
View File

@ -100,10 +100,14 @@
<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a><ul>
<li class="toctree-l2"><a class="reference internal" href="app.html#app">App</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#plotcanvas">PlotCanvas</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#objectcollection">ObjectCollection</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#measurement">Measurement</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="devman.html">FlatCAM Developer Manual</a><ul>
<li class="toctree-l2"><a class="reference internal" href="devman.html#options">Options</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#serialization">Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#geometry-processing">Geometry Processing</a></li>
</ul>
</li>
</ul>
@ -523,7 +527,19 @@ box in both positive and negative, x and y axes.</li>
<dl class="method">
<dt id="camlib.Gerber.mirror">
<tt class="descname">mirror</tt><big>(</big><em>axis</em>, <em>point</em><big>)</big><a class="headerlink" href="#camlib.Gerber.mirror" title="Permalink to this definition"></a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<dd><p>Mirrors the object around a specified axis passign through
the given point. What is affected:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">buffered_paths</span></tt></li>
<li><tt class="docutils literal"><span class="pre">flash_geometry</span></tt></li>
<li><tt class="docutils literal"><span class="pre">solid_geometry</span></tt></li>
<li><tt class="docutils literal"><span class="pre">regions</span></tt></li>
</ul>
<p>NOTE:
Does not modify the data used to create these elements. If these
are recreated, the scaling will be lost. This behavior was modified
because of the complexity reached in this class.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
@ -546,12 +562,15 @@ box in both positive and negative, x and y axes.</li>
<dd><p>Offsets the objects&#8217; geometry on the XY plane by a given vector.
These are:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">paths</span></tt></li>
<li><tt class="docutils literal"><span class="pre">buffered_paths</span></tt></li>
<li><tt class="docutils literal"><span class="pre">flash_geometry</span></tt></li>
<li><tt class="docutils literal"><span class="pre">solid_geometry</span></tt></li>
<li><tt class="docutils literal"><span class="pre">regions</span></tt></li>
<li><tt class="docutils literal"><span class="pre">flashes</span></tt></li>
</ul>
<p>Then <tt class="docutils literal"><span class="pre">buffered_paths</span></tt>, <tt class="docutils literal"><span class="pre">flash_geometry</span></tt> and <tt class="docutils literal"><span class="pre">solid_geometry</span></tt>
are re-created with <tt class="docutils literal"><span class="pre">self.create_geometry()</span></tt>.</p>
<p>NOTE:
Does not modify the data used to create these elements. If these
are recreated, the scaling will be lost. This behavior was modified
because of the complexity reached in this class.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
@ -607,16 +626,24 @@ one line of the source file.</td>
<dd><p>Scales the objects&#8217; geometry on the XY plane by a given factor.
These are:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">apertures</span></tt></li>
<li><tt class="docutils literal"><span class="pre">paths</span></tt></li>
<li><tt class="docutils literal"><span class="pre">buffered_paths</span></tt></li>
<li><tt class="docutils literal"><span class="pre">flash_geometry</span></tt></li>
<li><tt class="docutils literal"><span class="pre">solid_geometry</span></tt></li>
<li><tt class="docutils literal"><span class="pre">regions</span></tt></li>
<li><tt class="docutils literal"><span class="pre">flashes</span></tt></li>
</ul>
<p>Then <tt class="docutils literal"><span class="pre">buffered_paths</span></tt>, <tt class="docutils literal"><span class="pre">flash_geometry</span></tt> and <tt class="docutils literal"><span class="pre">solid_geometry</span></tt>
are re-created with <tt class="docutils literal"><span class="pre">self.create_geometry()</span></tt>.
:param factor: Number by which to scale.
:type factor: float
:rtype : None</p>
<p>NOTE:
Does not modify the data used to create these elements. If these
are recreated, the scaling will be lost. This behavior was modified
because of the complexity reached in this class.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>factor</strong> (<em>float</em>) &#8211; Number by which to scale.</td>
</tr>
</tbody>
</table>
<p>:rtype : None</p>
</dd></dl>
</dd></dl>
@ -668,6 +695,23 @@ list of length n.</p>
</table>
</dd></dl>
<dl class="method">
<dt id="camlib.ApertureMacro.from_dict">
<tt class="descname">from_dict</tt><big>(</big><em>d</em><big>)</big><a class="headerlink" href="#camlib.ApertureMacro.from_dict" title="Permalink to this definition"></a></dt>
<dd><p>Populates the object from a serial representation created
with <tt class="docutils literal"><span class="pre">self.to_dict()</span></tt>.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>d</strong> &#8211; Serial representation of an ApertureMacro object.</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="staticmethod">
<dt id="camlib.ApertureMacro.make_centerline">
<em class="property">static </em><tt class="descname">make_centerline</tt><big>(</big><em>mods</em><big>)</big><a class="headerlink" href="#camlib.ApertureMacro.make_centerline" title="Permalink to this definition"></a></dt>
@ -833,6 +877,23 @@ are stored in <tt class="docutils literal"><span class="pre">self.primitives</sp
</table>
</dd></dl>
<dl class="method">
<dt id="camlib.ApertureMacro.to_dict">
<tt class="descname">to_dict</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.ApertureMacro.to_dict" title="Permalink to this definition"></a></dt>
<dd><p>Returns the object in a serializable form. Only the name and
raw are required.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">Dictionary representing the object. JSON ready.</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">dict</td>
</tr>
</tbody>
</table>
</dd></dl>
</dd></dl>
</div>

View File

@ -99,11 +99,14 @@
<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a><ul>
<li class="toctree-l2"><a class="reference internal" href="app.html#app">App</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#plotcanvas">PlotCanvas</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#objectcollection">ObjectCollection</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#measurement">Measurement</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="devman.html">FlatCAM Developer Manual</a><ul>
<li class="toctree-l2"><a class="reference internal" href="devman.html#options">Options</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#serialization">Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#geometry-processing">Geometry Processing</a></li>
</ul>
</li>
</ul>
@ -187,6 +190,12 @@
<dt><a href="camlib.html#camlib.ApertureMacro.append">append() (camlib.ApertureMacro method)</a>
</dt>
<dd><dl>
<dt><a href="app.html#FlatCAM.ObjectCollection.append">(FlatCAM.ObjectCollection method)</a>
</dt>
</dl></dd>
<dt><a href="app.html#FlatCAM.PlotCanvas.auto_adjust_axes">auto_adjust_axes() (FlatCAM.PlotCanvas method)</a>
</dt>
@ -208,10 +217,6 @@
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.App.build_list">build_list() (FlatCAM.App method)</a>
</dt>
<dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.build_ui">build_ui() (FlatCAM.FlatCAMObj method)</a>
</dt>
@ -226,6 +231,10 @@
</dt>
<dt><a href="app.html#FlatCAM.ObjectCollection.change_name">change_name() (FlatCAM.ObjectCollection method)</a>
</dt>
<dt><a href="app.html#FlatCAM.PlotCanvas.clear">clear() (FlatCAM.PlotCanvas method)</a>
</dt>
@ -233,12 +242,12 @@
<dt><a href="camlib.html#camlib.Geometry.clear_polygon">clear_polygon() (camlib.Geometry method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="camlib.html#camlib.CNCjob">CNCjob (class in camlib)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.PlotCanvas.connect">connect() (FlatCAM.PlotCanvas method)</a>
</dt>
@ -280,6 +289,10 @@
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.App.disable_plots">disable_plots() (FlatCAM.App method)</a>
</dt>
<dt><a href="camlib.html#camlib.Gerber.do_flashes">do_flashes() (camlib.Gerber method)</a>
</dt>
@ -342,9 +355,15 @@
</dt>
<dt><a href="camlib.html#camlib.Geometry.from_dict">from_dict() (camlib.Geometry method)</a>
<dt><a href="camlib.html#camlib.ApertureMacro.from_dict">from_dict() (camlib.ApertureMacro method)</a>
</dt>
<dd><dl>
<dt><a href="camlib.html#camlib.Geometry.from_dict">(camlib.Geometry method)</a>
</dt>
</dl></dd>
</dl></td>
</tr></table>
@ -375,14 +394,18 @@
<dt><a href="camlib.html#camlib.Gerber">Gerber (class in camlib)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="camlib.html#camlib.Gerber.get_bounding_box">get_bounding_box() (camlib.Gerber method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.App.get_current">get_current() (FlatCAM.App method)</a>
<dt><a href="app.html#FlatCAM.ObjectCollection.get_bounds">get_bounds() (FlatCAM.ObjectCollection method)</a>
</dt>
<dt><a href="app.html#FlatCAM.ObjectCollection.get_by_name">get_by_name() (FlatCAM.ObjectCollection method)</a>
</dt>
@ -394,6 +417,14 @@
</dt>
<dt><a href="app.html#FlatCAM.ObjectCollection.get_list">get_list() (FlatCAM.ObjectCollection method)</a>
</dt>
<dt><a href="app.html#FlatCAM.ObjectCollection.get_names">get_names() (FlatCAM.ObjectCollection method)</a>
</dt>
<dt><a href="app.html#FlatCAM.App.get_radio_value">get_radio_value() (FlatCAM.App method)</a>
</dt>
@ -463,12 +494,12 @@
<dt><a href="camlib.html#camlib.ApertureMacro.make_outline">make_outline() (camlib.ApertureMacro static method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="camlib.html#camlib.ApertureMacro.make_polygon">make_polygon() (camlib.ApertureMacro static method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="camlib.html#camlib.ApertureMacro.make_thermal">make_thermal() (camlib.ApertureMacro static method)</a>
</dt>
@ -478,6 +509,10 @@
</dt>
<dt><a href="app.html#FlatCAM.Measurement">Measurement (class in FlatCAM)</a>
</dt>
<dt><a href="camlib.html#camlib.Excellon.mirror">mirror() (camlib.Excellon method)</a>
</dt>
@ -491,6 +526,10 @@
<dt><a href="app.html#FlatCAM.PlotCanvas.mpl_connect">mpl_connect() (FlatCAM.PlotCanvas method)</a>
</dt>
<dt><a href="app.html#FlatCAM.PlotCanvas.mpl_disconnect">mpl_disconnect() (FlatCAM.PlotCanvas method)</a>
</dt>
</dl></td>
</tr></table>
@ -514,6 +553,10 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.ObjectCollection">ObjectCollection (class in FlatCAM)</a>
</dt>
<dt><a href="camlib.html#camlib.CNCjob.offset">offset() (camlib.CNCjob method)</a>
</dt>
@ -647,12 +690,12 @@
<dt><a href="app.html#FlatCAM.App.on_generate_isolation">on_generate_isolation() (FlatCAM.App method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.App.on_generate_paintarea">on_generate_paintarea() (FlatCAM.App method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.App.on_gerber_generate_cutout">on_gerber_generate_cutout() (FlatCAM.App method)</a>
</dt>
@ -662,10 +705,22 @@
</dt>
<dt><a href="app.html#FlatCAM.PlotCanvas.on_key_down">on_key_down() (FlatCAM.PlotCanvas method)</a>
</dt>
<dt><a href="app.html#FlatCAM.App.on_key_over_plot">on_key_over_plot() (FlatCAM.App method)</a>
</dt>
<dt><a href="app.html#FlatCAM.PlotCanvas.on_key_up">on_key_up() (FlatCAM.PlotCanvas method)</a>
</dt>
<dt><a href="app.html#FlatCAM.ObjectCollection.on_list_selection_change">on_list_selection_change() (FlatCAM.ObjectCollection method)</a>
</dt>
<dt><a href="app.html#FlatCAM.PlotCanvas.on_mouse_move">on_mouse_move() (FlatCAM.PlotCanvas method)</a>
</dt>
@ -713,6 +768,12 @@
<dt><a href="app.html#FlatCAM.App.on_row_activated">on_row_activated() (FlatCAM.App method)</a>
</dt>
<dd><dl>
<dt><a href="app.html#FlatCAM.ObjectCollection.on_row_activated">(FlatCAM.ObjectCollection method)</a>
</dt>
</dl></dd>
<dt><a href="app.html#FlatCAM.App.on_scale_object">on_scale_object() (FlatCAM.App method)</a>
</dt>
@ -738,10 +799,6 @@
</dt>
<dt><a href="app.html#FlatCAM.App.on_tree_selection_changed">on_tree_selection_changed() (FlatCAM.App method)</a>
</dt>
<dt><a href="app.html#FlatCAM.App.on_update_plot">on_update_plot() (FlatCAM.App method)</a>
</dt>
@ -896,6 +953,10 @@
</dt>
<dt><a href="app.html#FlatCAM.ObjectCollection.set_active">set_active() (FlatCAM.ObjectCollection method)</a>
</dt>
<dt><a href="app.html#FlatCAM.App.set_form_item">set_form_item() (FlatCAM.App method)</a>
</dt>
@ -906,16 +967,16 @@
</dl></dd>
<dt><a href="app.html#FlatCAM.App.set_list_selection">set_list_selection() (FlatCAM.App method)</a>
</dt>
<dt><a href="app.html#FlatCAM.App.set_progress_bar">set_progress_bar() (FlatCAM.App method)</a>
<dt><a href="app.html#FlatCAM.ObjectCollection.set_list_selection">set_list_selection() (FlatCAM.ObjectCollection method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="app.html#FlatCAM.App.set_progress_bar">set_progress_bar() (FlatCAM.App method)</a>
</dt>
<dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.setup_axes">setup_axes() (FlatCAM.FlatCAMObj method)</a>
</dt>
@ -928,10 +989,6 @@
</dt>
<dt><a href="app.html#FlatCAM.App.setup_project_list">setup_project_list() (FlatCAM.App method)</a>
</dt>
<dt><a href="camlib.html#camlib.Geometry.size">size() (camlib.Geometry method)</a>
</dt>
@ -942,9 +999,15 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="camlib.html#camlib.Geometry.to_dict">to_dict() (camlib.Geometry method)</a>
<dt><a href="camlib.html#camlib.ApertureMacro.to_dict">to_dict() (camlib.ApertureMacro method)</a>
</dt>
<dd><dl>
<dt><a href="camlib.html#camlib.Geometry.to_dict">(camlib.Geometry method)</a>
</dt>
</dl></dd>
</dl></td>
<td style="width: 33%" valign="top"><dl>

View File

@ -99,11 +99,14 @@
<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a><ul>
<li class="toctree-l2"><a class="reference internal" href="app.html#app">App</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#plotcanvas">PlotCanvas</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#objectcollection">ObjectCollection</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#measurement">Measurement</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="devman.html">FlatCAM Developer Manual</a><ul>
<li class="toctree-l2"><a class="reference internal" href="devman.html#options">Options</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#serialization">Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#geometry-processing">Geometry Processing</a></li>
</ul>
</li>
</ul>
@ -164,11 +167,14 @@
<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a><ul>
<li class="toctree-l2"><a class="reference internal" href="app.html#app">App</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#plotcanvas">PlotCanvas</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#objectcollection">ObjectCollection</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#measurement">Measurement</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="devman.html">FlatCAM Developer Manual</a><ul>
<li class="toctree-l2"><a class="reference internal" href="devman.html#options">Options</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#serialization">Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#geometry-processing">Geometry Processing</a></li>
</ul>
</li>
</ul>

BIN
doc/build/objects.inv vendored

Binary file not shown.

View File

@ -105,11 +105,14 @@
<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a><ul>
<li class="toctree-l2"><a class="reference internal" href="app.html#app">App</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#plotcanvas">PlotCanvas</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#objectcollection">ObjectCollection</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#measurement">Measurement</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="devman.html">FlatCAM Developer Manual</a><ul>
<li class="toctree-l2"><a class="reference internal" href="devman.html#options">Options</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#serialization">Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#geometry-processing">Geometry Processing</a></li>
</ul>
</li>
</ul>

View File

@ -106,11 +106,14 @@
<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a><ul>
<li class="toctree-l2"><a class="reference internal" href="app.html#app">App</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#plotcanvas">PlotCanvas</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#objectcollection">ObjectCollection</a></li>
<li class="toctree-l2"><a class="reference internal" href="app.html#measurement">Measurement</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="devman.html">FlatCAM Developer Manual</a><ul>
<li class="toctree-l2"><a class="reference internal" href="devman.html#options">Options</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#serialization">Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="devman.html#geometry-processing">Geometry Processing</a></li>
</ul>
</li>
</ul>

File diff suppressed because one or more lines are too long

View File

@ -14,3 +14,15 @@ PlotCanvas
.. autoclass:: PlotCanvas
:members:
ObjectCollection
~~~~~~~~~~~~~~~~
.. autoclass:: ObjectCollection
:members:
Measurement
~~~~~~~~~~~
.. autoclass:: Measurement
:members:

View File

@ -1 +1 @@
[{"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.GBL"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\BLDC2003Through.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.GTL"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\BLDC_1303_Bottom.gbr"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles-F_Cu.gtl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\Example1_copper_bottom.gbr"}, {"kind": "cncjob", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\RTWO1_CNC\\cutout1.gcode"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\RTWO1.fcproj"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.TXT"}]
[{"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\TFTadapter.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles-F_Cu.gtl"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles.drl"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\BLDC2003Through.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.GTL"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\RTWO_fc5_3.fcproj"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\RTWO_fc5_2.fcproj"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\RTWO_fc5.fcproj"}, {"kind": "cncjob", "filename": "Z:\\CNC\\testpcb\\2\\noname-F_Cu_ISOLATION_GCODE3.ngc"}, {"kind": "cncjob", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\RTWO1_CNC\\iso_bottom1.gcode"}]