Преглед изворни кода

Patched Gerber parsing to support some non-compliant instructions.

Juan Pablo Caram пре 12 година
родитељ
комит
b6497b2edb

+ 19 - 5
FlatCAM.py

@@ -1,7 +1,9 @@
 ############################################################
-# Author: Juan Pablo Caram                                 #
+# FlatCAM: 2D Post-processing for Manufacturing            #
+# http://caram.cl/software/flatcam                         #
+# Author: Juan Pablo Caram (c)                             #
 # Date: 2/5/2014                                           #
-# caram.cl                                                 #
+# MIT Licence                                              #
 ############################################################
 
 import threading
@@ -553,7 +555,7 @@ class App:
         self.builder = Gtk.Builder()
         self.builder.add_from_file(self.gladefile)
         self.window = self.builder.get_object("window1")
-        self.window.set_title("FlatCAM")
+        self.window.set_title("FlatCAM - Alpha 1 UNSTABLE - Check for updates!")
         self.position_label = self.builder.get_object("label3")
         self.grid = self.builder.get_object("grid1")
         self.notebook = self.builder.get_object("notebook1")
@@ -969,9 +971,9 @@ class App:
 
     def set_progress_bar(self, percentage, text=""):
         """
-        Sets the application's progress bar to a given fraction and text.
+        Sets the application's progress bar to a given frac_digits and text.
 
-        :param percentage: The fraction (0.0-1.0) of the progress.
+        :param percentage: The frac_digits (0.0-1.0) of the progress.
         :type percentage: float
         :param text: Text to display on the progress bar.
         :type text: str
@@ -1260,6 +1262,18 @@ class App:
     ########################################
     ##         EVENT HANDLERS             ##
     ########################################
+    def on_about(self, widget):
+        """
+        Opens the 'About' dialog box.
+
+        :param widget: Ignored.
+        :return: None
+        """
+        about = self.builder.get_object("aboutdialog")
+        response = about.run()
+        about.destroy()
+
+
     def on_create_mirror(self, widget):
         """
         Creates a mirror image of a Gerber object to be used as a bottom

+ 56 - 0
FlatCAM.ui

@@ -1,6 +1,61 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkAboutDialog" id="aboutdialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="type_hint">dialog</property>
+    <property name="program_name">FlatCAM</property>
+    <property name="version">Version Alpha 1 (2014/02) - UNSTABLE</property>
+    <property name="copyright" translatable="yes">(c) 2014 Juan Pablo Caram</property>
+    <property name="comments" translatable="yes">2D Post-processing for Manufacturing specialized in 
+Printed Circuit Boards</property>
+    <property name="website">http://caram.cl/software/flatcam/</property>
+    <property name="website_label" translatable="yes">Caram.cl/software/flatcam</property>
+    <property name="license" translatable="yes">The MIT License (MIT)
+
+Copyright (c) 2014 Juan Pablo Caram
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="aboutdialog-vbox1">
+        <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="aboutdialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+          </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>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+  </object>
   <object class="GtkImage" id="image1">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -2673,6 +2728,7 @@ to application defaults.</property>
                         <property name="can_focus">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
+                        <signal name="activate" handler="on_about" swapped="no"/>
                       </object>
                     </child>
                   </object>

+ 257 - 75
camlib.py

@@ -1,7 +1,9 @@
 ############################################################
-# Author: Juan Pablo Caram                                 #
+# FlatCAM: 2D Post-processing for Manufacturing            #
+# http://caram.cl/software/flatcam                         #
+# Author: Juan Pablo Caram (c)                             #
 # Date: 2/5/2014                                           #
-# caram.cl                                                 #
+# MIT Licence                                              #
 ############################################################
 
 from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos
@@ -25,6 +27,7 @@ import simplejson as json
 # TODO: Commented for FlatCAM packaging with cx_freeze
 #from matplotlib.pyplot import plot
 
+
 class Geometry:
     def __init__(self):
         # Units (in or mm)
@@ -232,10 +235,10 @@ class Gerber (Geometry):
         Geometry.__init__(self)        
         
         # Number format
-        self.digits = 3
+        self.int_digits = 3
         """Number of integer digits in Gerber numbers. Used during parsing."""
 
-        self.fraction = 4
+        self.frac_digits = 4
         """Number of fraction digits in Gerber numbers. Used during parsing."""
         
         ## Gerber elements ##
@@ -264,10 +267,72 @@ class Gerber (Geometry):
         # Attributes to be included in serialization
         # Always append to it because it carries contents
         # from Geometry.
-        self.ser_attrs += ['digits', 'fraction', 'apertures', 'paths',
+        self.ser_attrs += ['int_digits', 'frac_digits', 'apertures', 'paths',
                            'buffered_paths', 'regions', 'flashes',
                            'flash_geometry']
 
+        #### Parser patterns ####
+        # FS - Format Specification
+        # The format of X and Y must be the same!
+        # L-omit leading zeros, T-omit trailing zeros
+        # A-absolute notation, I-incremental notation
+        self.fmt_re = re.compile(r'%FS([LT])([AI])X(\d)(\d)Y\d\d\*%$')
+
+        # Mode (IN/MM)
+        self.mode_re = re.compile(r'^%MO(IN|MM)\*%$')
+
+        # Comment G04|G4
+        self.comm_re = re.compile(r'^G0?4(.*)$')
+
+        # AD - Aperture definition
+        self.ad_re = re.compile(r'^%ADD(\d\d+)([a-zA-Z0-9]*),(.*)\*%$')
+
+        # AM - Aperture Macro
+        # Beginning of macro (Ends with *%):
+        self.am_re = re.compile(r'^%AM([a-zA-Z0-9]*)\*')
+
+        # Tool change
+        # May begin with G54 but that is deprecated
+        self.tool_re = re.compile(r'^(?:G54)?D(\d\d+)\*$')
+
+        # G01 - Linear interpolation plus flashes
+        # Operation code (D0x) missing is deprecated... oh well I will support it.
+        self.lin_re = re.compile(r'^(?:G0?(1))?(?:X(-?\d+))?(?:Y(-?\d+))?(?:D0([123]))?\*$')
+
+        self.setlin_re = re.compile(r'^(?:G0?1)\*')
+
+        # G02/3 - Circular interpolation
+        # 2-clockwise, 3-counterclockwise
+        self.circ_re = re.compile(r'^(?:G0?([23]))?(?:X(-?\d+))?(?:Y(-?\d+))' +
+                                  '?(?:I(-?\d+))?(?:J(-?\d+))?D0([12])\*$')
+
+        # G01/2/3 Occurring without coordinates
+        self.interp_re = re.compile(r'^(?:G0?([123]))\*')
+
+        # Single D74 or multi D75 quadrant for circular interpolation
+        self.quad_re = re.compile(r'^G7([45])\*$')
+
+        # Region mode on
+        # In region mode, D01 starts a region
+        # and D02 ends it. A new region can be started again
+        # with D01. All contours must be closed before
+        # D02 or G37.
+        self.regionon_re = re.compile(r'^G36\*$')
+
+        # Region mode off
+        # Will end a region and come off region mode.
+        # All contours must be closed before D02 or G37.
+        self.regionoff_re = re.compile(r'^G37\*$')
+
+        # End of file
+        self.eof_re = re.compile(r'^M02\*')
+
+        # IP - Image polarity
+        self.pol_re = re.compile(r'^%IP(POS|NEG)\*%$')
+
+        # LP - Level polarity
+        self.lpol_re = re.compile(r'^%LP([DC])\*%$')
+
     def scale(self, factor):
         """
         Scales the objects' geometry on the XY plane by a given factor.
@@ -343,16 +408,20 @@ class Gerber (Geometry):
         :return: Identifier of the aperture.
         :rtype: str
         """
+
         indexstar = gline.find("*")
         indexc = gline.find("C,")
         if indexc != -1:  # Circle, example: %ADD11C,0.1*%
-            apid = gline[4:indexc]
+            # Found some Gerber with a leading zero in the aperture id and the
+            # referenced it without the zero, so this is a hack to handle that.
+            apid = str(int(gline[4:indexc]))
             self.apertures[apid] = {"type": "C",
                                     "size": float(gline[indexc+2:indexstar])}
             return apid
         indexr = gline.find("R,")
         if indexr != -1:  # Rectangle, example: %ADD15R,0.05X0.12*%
-            apid = gline[4:indexr]
+            # Hack explained above
+            apid = str(int(gline[4:indexr]))
             indexx = gline.find("X")
             self.apertures[apid] = {"type": "R",
                                     "width": float(gline[indexr+2:indexx]),
@@ -360,7 +429,8 @@ class Gerber (Geometry):
             return apid
         indexo = gline.find("O,")
         if indexo != -1:  # Obround
-            apid = gline[4:indexo]
+            # Hack explained above
+            apid = str(int(gline[4:indexo]))
             indexx = gline.find("X")
             self.apertures[apid] = {"type": "O",
                                     "width": float(gline[indexo+2:indexx]),
@@ -381,67 +451,148 @@ class Gerber (Geometry):
         
     def parse_lines(self, glines):
         """
-        Main Gerber parser.
-        """
+        Main Gerber parser. Reads Gerber and populates ``self.paths``, ``self.apertures``,
+        ``self.flashes``, ``self.regions`` and ``self.units``.
 
-        # Mode (IN/MM)
-        mode_re = re.compile(r'^%MO(IN|MM)\*%$')
+        :param glines: Gerber code as list of strings, each
+        element being one line of the source file.
+        :type glines: list
+        :return: None
+        :rtype: None
+        """
 
         path = []  # Coordinates of the current path
+
         last_path_aperture = None
         current_aperture = None
-        
+
+        # 1,2 or 3 from "G01", "G02" or "G03"
+        current_interpolation_mode = None
+
+        # 1 or 2 from "D01" or "D02"
+        # Note this is to support deprecated Gerber not putting
+        # an operation code at the end of every coordinate line.
+        current_operation_code = None
+
+        # Current coordinates
+        current_x = None
+        current_y = None
+
         for gline in glines:
-            
-            if gline.find("D01*") != -1:  # pen down
-                path.append(coord(gline, self.digits, self.fraction))
-                last_path_aperture = current_aperture
-                continue
-        
-            if gline.find("D02*") != -1:  # pen up
-                if len(path) > 1:
-                    # Path completed, create shapely LineString
-                    self.paths.append({"linestring": LineString(path),
-                                       "aperture": last_path_aperture})
-                path = [coord(gline, self.digits, self.fraction)]
-                continue
-            
-            indexd3 = gline.find("D03*")
-            if indexd3 > 0:  # Flash
-                self.flashes.append({"loc": coord(gline, self.digits, self.fraction),
-                                     "aperture": current_aperture})
-                continue
-            if indexd3 == 0:  # Flash?
-                print "WARNING: Uninplemented flash style:", gline
+
+            # Linear interpolation plus flashes
+            match = self.lin_re.search(gline)
+            if match:
+                # Parse coordinates
+                if match.group(2) is not None:
+                    current_x = parse_gerber_number(match.group(2), self.frac_digits)
+                if match.group(3) is not None:
+                    current_y = parse_gerber_number(match.group(3), self.frac_digits)
+
+                # Parse operation code
+                if match.group(4) is not None:
+                    current_operation_code = match.group(4)
+
+                # Pen down: add segment
+                if current_operation_code == '1':
+                    path.append([current_x, current_y])
+                    last_path_aperture = current_aperture
+
+                # Pen up: finish path
+                elif current_operation_code == '2':
+                    if len(path) > 1:
+                        self.paths.append({"linestring": LineString(path),
+                                           "aperture": last_path_aperture})
+                    path = [[current_x, current_y]]
+
+                # Flash
+                elif current_operation_code == '3':
+                    self.flashes.append({"loc": [current_x, current_y],
+                                         "aperture": current_aperture})
+
                 continue
-            
-            if gline.find("G37*") != -1:  # end region
+
+            # if gline.find("D01*") != -1:  # pen down
+            #     path.append(parse_gerber_coords(gline, self.int_digits, self.frac_digits))
+            #     last_path_aperture = current_aperture
+            #     continue
+            #
+            # if gline.find("D02*") != -1:  # pen up
+            #     if len(path) > 1:
+            #         # Path completed, create shapely LineString
+            #         self.paths.append({"linestring": LineString(path),
+            #                            "aperture": last_path_aperture})
+            #     path = [parse_gerber_coords(gline, self.int_digits, self.frac_digits)]
+            #     continue
+            #
+            # indexd3 = gline.find("D03*")
+            # if indexd3 > 0:  # Flash
+            #     self.flashes.append({"loc": parse_gerber_coords(gline, self.int_digits, self.frac_digits),
+            #                          "aperture": current_aperture})
+            #     continue
+            # if indexd3 == 0:  # Flash?
+            #     print "WARNING: Uninplemented flash style:", gline
+            #     continue
+
+            # End region
+            if self.regionoff_re.search(gline):
                 # Only one path defines region?
                 self.regions.append({"polygon": Polygon(path),
                                      "aperture": last_path_aperture})
                 path = []
                 continue
+
+            # if gline.find("G37*") != -1:  # end region
+            #     # Only one path defines region?
+            #     self.regions.append({"polygon": Polygon(path),
+            #                          "aperture": last_path_aperture})
+            #     path = []
+            #     continue
             
             if gline.find("%ADD") != -1:  # aperture definition
                 self.aperture_parse(gline)  # adds element to apertures
                 continue
-            
-            indexstar = gline.find("*")
-            if gline.find("D") == 0:  # Aperture change
-                current_aperture = gline[1:indexstar]
+
+            # Interpolation mode change
+            # Can occur along with coordinates and operation code but
+            # sometimes by itself (handled here).
+            # Example: G01*
+            match = self.interp_re.search(gline)
+            if match:
+                current_interpolation_mode = int(match.group(1))
                 continue
-            if gline.find("G54D") == 0:  # Aperture change (deprecated)
-                current_aperture = gline[4:indexstar]
+
+            # Tool/aperture change
+            # Example: D12*
+            match = self.tool_re.search(gline)
+            if match:
+                current_aperture = match.group(1)
                 continue
-            
-            if gline.find("%FS") != -1:  # Format statement
-                indexx = gline.find("X")
-                self.digits = int(gline[indexx + 1])
-                self.fraction = int(gline[indexx + 2])
+
+            # indexstar = gline.find("*")
+            # if gline.find("D") == 0:  # Aperture change
+            #     current_aperture = gline[1:indexstar]
+            #     continue
+            # if gline.find("G54D") == 0:  # Aperture change (deprecated)
+            #     current_aperture = gline[4:indexstar]
+            #     continue
+
+            # Number format
+            # TODO: This is ignoring most of the format. Implement the rest.
+            match = self.fmt_re.search(gline)
+            if match:
+                self.int_digits = int(match.group(3))
+                self.frac_digits = int(match.group(4))
                 continue
 
+            # if gline.find("%FS") != -1:  # Format statement
+            #     indexx = gline.find("X")
+            #     self.int_digits = int(gline[indexx + 1])
+            #     self.frac_digits = int(gline[indexx + 2])
+            #     continue
+
             # Mode (IN/MM)
-            match = mode_re.search(gline)
+            match = self.mode_re.search(gline)
             if match:
                 self.units = match.group(1)
                 continue
@@ -452,7 +603,12 @@ class Gerber (Geometry):
             # EOF, create shapely LineString if something still in path
             self.paths.append({"linestring": LineString(path),
                                "aperture": last_path_aperture})
-    
+
+        # if len(path) > 1:
+        #     # EOF, create shapely LineString if something still in path
+        #     self.paths.append({"linestring": LineString(path),
+        #                        "aperture": current_aperture})
+
     def do_flashes(self):
         """
         Creates geometry for Gerber flashes (aperture on a single point).
@@ -1133,19 +1289,22 @@ def get_bounds(geometry_set):
 def arc(center, radius, start, stop, direction, steps_per_circ):
     """
     Creates a Shapely.LineString for the specified arc.
-    @param center: Coordinates of the center [x, y]
-    @type center: list
-    @param radius: Radius of the arc.
-    @type radius: float
-    @param start: Starting angle in radians
-    @type start: float
-    @param stop: End angle in radians
-    @type stop: float
-    @param direction: Orientation of the arc, "CW" or "CCW"
-    @type direction: string
-    @param steps_per_circ: Number of straight line segments to
+
+    :param center: Coordinates of the center [x, y]
+    :type center: list
+    :param radius: Radius of the arc.
+    :type radius: float
+    :param start: Starting angle in radians
+    :type start: float
+    :param stop: End angle in radians
+    :type stop: float
+    :param direction: Orientation of the arc, "CW" or "CCW"
+    :type direction: string
+    :param steps_per_circ: Number of straight line segments to
         represent a circle.
-    @type steps_per_circ: int
+    :type steps_per_circ: int
+    :return: The desired arc.
+    :rtype: Shapely.LineString
     """
     da_sign = {"cw": -1.0, "ccw": 1.0}
     points = []
@@ -1170,14 +1329,16 @@ def clear_poly(poly, tooldia, overlap=0.1):
     Creates a list of Shapely geometry objects covering the inside
     of a Shapely.Polygon. Use for removing all the copper in a region
     or bed flattening.
-    @param poly: Target polygon
-    @type poly: Shapely.Polygon
-    @param tooldia: Diameter of the tool
-    @type tooldia: float
-    @param overlap: Fraction of the tool diameter to overlap
+
+    :param poly: Target polygon
+    :type poly: Shapely.Polygon
+    :param tooldia: Diameter of the tool
+    :type tooldia: float
+    :param overlap: Fraction of the tool diameter to overlap
         in each pass.
-    @type overlap: float
-    @return list of Shapely.Polygon
+    :type overlap: float
+    :return: list of Shapely.Polygon
+    :rtype: list
     """
     poly_cuts = [poly.buffer(-tooldia/2.0)]
     while True:
@@ -1251,11 +1412,33 @@ def plotg(geo):
             print "Cannot plot:", str(type(g))
             continue
 
+def parse_gerber_number(strnumber, frac_digits):
+    """
+    Parse a single number of Gerber coordinates.
+
+    :param strnumber: String containing a number in decimal digits
+    from a coordinate data block, possibly with a leading sign.
+    :type strnumber: str
+    :param frac_digits: Number of digits used for the fractional
+    part of the number
+    :type frac_digits: int
+    :return: The number in floating point.
+    :rtype: float
+    """
+    return int(strnumber)*(10**(-frac_digits))
 
-############### cam.py ####################
-def coord(gstr, digits, fraction):
+def parse_gerber_coords(gstr, int_digits, frac_digits):
     """
     Parse Gerber coordinates
+
+    :param gstr: Line of G-Code containing coordinates.
+    :type gstr: str
+    :param int_digits: Number of digits in integer part of a number.
+    :type int_digits: int
+    :param frac_digits: Number of digits in frac_digits part of a number.
+    :type frac_digits: int
+    :return: [x, y] coordinates.
+    :rtype: list
     """
     global gerbx, gerby
     xindex = gstr.find("X")
@@ -1263,14 +1446,13 @@ def coord(gstr, digits, fraction):
     index = gstr.find("D")
     if xindex == -1:
         x = gerbx
-        y = int(gstr[(yindex+1):index])*(10**(-fraction))
+        y = int(gstr[(yindex+1):index])*(10**(-frac_digits))
     elif yindex == -1:
         y = gerby
-        x = int(gstr[(xindex+1):index])*(10**(-fraction))
+        x = int(gstr[(xindex+1):index])*(10**(-frac_digits))
     else:
-        x = int(gstr[(xindex+1):yindex])*(10**(-fraction))
-        y = int(gstr[(yindex+1):index])*(10**(-fraction))
+        x = int(gstr[(xindex+1):yindex])*(10**(-frac_digits))
+        y = int(gstr[(yindex+1):index])*(10**(-frac_digits))
     gerbx = x
     gerby = y
     return [x, y]
-################ end of cam.py #############

BIN
doc/build/.doctrees/environment.pickle


BIN
doc/build/.doctrees/index.doctree


+ 1 - 1
doc/build/_sources/index.txt

@@ -5,7 +5,7 @@
 
 
 
-Welcome to Cirkuix's documentation!
+Welcome to FlatCAM's documentation!
 ===================================
 
 Contents:

+ 4 - 0
doc/build/genindex.html

@@ -382,6 +382,10 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
+  <dt><a href="index.html#FlatCAM.App.on_about">on_about() (FlatCAM.App method)</a>
+  </dt>
+
+      
   <dt><a href="index.html#FlatCAM.App.on_activate_name">on_activate_name() (FlatCAM.App method)</a>
   </dt>
 

+ 20 - 4
doc/build/index.html

@@ -7,7 +7,7 @@
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Welcome to Cirkuix’s documentation! &mdash; Cirkuix 0.5 documentation</title>
+  <title>Welcome to FlatCAM’s documentation! &mdash; Cirkuix 0.5 documentation</title>
   
 
   
@@ -102,7 +102,7 @@
   <ul class="wy-breadcrumbs">
     <li><a href="#">Docs</a> &raquo;</li>
       
-    <li>Welcome to Cirkuix&#8217;s documentation!</li>
+    <li>Welcome to FlatCAM&#8217;s documentation!</li>
       <li class="wy-breadcrumbs-aside">
         
           <a href="_sources/index.txt" rel="nofollow"> View page source</a>
@@ -113,8 +113,8 @@
 </div>
           <div role="main">
             
-  <div class="section" id="welcome-to-cirkuix-s-documentation">
-<h1>Welcome to Cirkuix&#8217;s documentation!<a class="headerlink" href="#welcome-to-cirkuix-s-documentation" title="Permalink to this headline">¶</a></h1>
+  <div class="section" id="welcome-to-flatcam-s-documentation">
+<h1>Welcome to FlatCAM&#8217;s documentation!<a class="headerlink" href="#welcome-to-flatcam-s-documentation" title="Permalink to this headline">¶</a></h1>
 <p>Contents:</p>
 <div class="toctree-wrapper compound">
 <ul class="simple">
@@ -326,6 +326,22 @@ called with 2 parameters: the new object and the App instance.</li>
 </table>
 </dd></dl>
 
+<dl class="method">
+<dt id="FlatCAM.App.on_about">
+<tt class="descname">on_about</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_about" title="Permalink to this definition">¶</a></dt>
+<dd><p>Opens the &#8216;About&#8217; dialog box.</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>widget</strong> &#8211; Ignored.</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="method">
 <dt id="FlatCAM.App.on_activate_name">
 <tt class="descname">on_activate_name</tt><big>(</big><em>entry</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_activate_name" title="Permalink to this definition">¶</a></dt>

BIN
doc/build/objects.inv


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
doc/build/searchindex.js


+ 0 - 0
doc/source/test


Неке датотеке нису приказане због велике количине промена