def run_drc_5_1(cfg): logger.info('Open Inspect->DRC') wait_point(cfg) xdotool(['key', 'alt+i', 'd']) wait_for_window('DRC modal window', 'DRC Control') # Note: Refill zones on DRC gets saved in ~/.config/kicad/pcbnew as RefillZonesBeforeDrc # The space here is to enable the report of all errors for tracks logger.info('Enable reporting all errors for tracks') wait_point(cfg) xdotool([ 'key', 'Tab', 'Tab', 'Tab', 'Tab', 'space', 'Tab', 'Tab', 'Tab', 'Tab' ]) logger.info('Pasting output dir') wait_point(cfg) text_replace(cfg.output_file) xdotool(['key', 'Return']) wait_for_window('Report completed dialog', 'Disk File Report Completed') wait_point(cfg) xdotool(['key', 'Return']) wait_for_window('DRC modal window', 'DRC Control') logger.info('Closing the DRC dialog') wait_point(cfg) xdotool(['key', 'shift+Tab', 'Return']) wait_pcbnew()
def open_3d_view(cfg): # Open the KiCad Print dialog logger.info('Open View->3D Viewer') wait_point(cfg) sleep(1 * cfg.time_out_scale) xdotool(['key', 'alt+3']) try: id = wait_for_window('3D Viewer', '3D Viewer') except RuntimeError: # pragma: no cover return None sleep(1 * cfg.time_out_scale) width = cfg.rec_width height = cfg.rec_height logger.debug("Moving 3D viewer window...") xdotool(['search', '--name', '3D Viewer', 'windowmove', '0', '0']) sleep(1 * cfg.time_out_scale) logger.debug("Resizing 3D viewer window...") xdotool([ 'search', '--name', '3D Viewer', 'windowsize', str(width), str(height) ]) sleep(1 * cfg.time_out_scale) logger.debug("Waiting for render (sleep 1s)...") sleep(1 * cfg.time_out_scale) return id[0] if id else None
def wait_pcbew_start(cfg): failed_focuse = False other = None try: wait_pcbnew(args.wait_start, [TITLE_CONFIRMATION, TITLE_WARNING, TITLE_ERROR], cfg.popen_obj) except RuntimeError: # pragma: no cover logger.debug('Time-out waiting for pcbnew, will retry') failed_focuse = True except ValueError as err: other = str(err) logger.debug('Found "' + other + '" window instead of pcbnew') failed_focuse = True except subprocess.CalledProcessError: logger.debug('Pcbnew is no longer running (returned {})'.format( cfg.popen_obj.poll())) if failed_focuse: wait_point(cfg) if other == TITLE_ERROR: dismiss_error() logger.error('pcbnew reported an error') exit(PCBNEW_ERROR) if other == TITLE_CONFIRMATION: dismiss_already_running() if other == TITLE_WARNING: # pragma: no cover dismiss_warning() try: wait_pcbnew(5) except RuntimeError: # pragma: no cover logger.error('Time-out waiting for pcbnew, giving up') exit(PCBNEW_ERROR)
def run_drc(cfg): if cfg.kicad_version >= KICAD_VERSION_5_99: run_drc_6_0(cfg) else: run_drc_5_1(cfg) # Save the PCB if cfg.save: logger.info('Saving PCB') wait_point(cfg) os.rename(cfg.input_file, cfg.input_file + '-bak') xdotool(['key', 'ctrl+s']) logger.info('Wait for PCB file creation') wait_point(cfg) wait_for_file_created_by_process(cfg.pcbnew_pid, os.path.realpath(cfg.input_file)) # Exit exit_pcbnew(cfg)
def open_print_dialog(cfg, print_dialog_keys): # Open the KiCad Print dialog logger.info('Open File->Print') wait_point(cfg) xdotool(['key'] + print_dialog_keys) retry = False try: id = wait_for_window('Print dialog', 'Print') except RuntimeError: # pragma: no cover # Perhaps the fill took too muchm try again retry = True # Retry the open dialog if retry: # pragma: no cover # Excluded from coverage, only happends under conditions hard to reproduce logger.info('Open File->Print (retrying)') wait_point(cfg) xdotool(['key'] + print_dialog_keys) id = wait_for_window('Print dialog', 'Print') return id
def exit_pcbnew(cfg): # Wait until the dialog is closed, useful when more than one file are created id = wait_pcbnew(10) logger.info('Exiting pcbnew') wait_point(cfg) xdotool(['key', 'ctrl+q']) try: wait_not_focused(id[0], 5) except RuntimeError: # pragma: no cover logger.debug('PCBnew not exiting, will retry') pass # Dismiss any dialog. I.e. failed to write the project # Note: if we modified the PCB KiCad will ask for save using a broken dialog. # It doesn't have a name and only gets focus with a WM. logger.info('Retry pcbnew exit') wait_point(cfg) xdotool(['key', 'Return', 'ctrl+q']) try: wait_not_focused(id[0], 5) except RuntimeError: # pragma: no cover logger.debug('PCBnew not exiting, will kill') pass # If we failed to exit we will kill it anyways wait_point(cfg)
def run_drc_6_0(cfg): logger.info('Open Inspect->DRC') wait_point(cfg) xdotool(['key', 'ctrl+shift+i']) # Wait dialog wait_for_window('DRC modal window', 'DRC Control') # Run the DRC logger.info('Run DRC') wait_point(cfg) xdotool(['key', 'Return']) # # To know when KiCad finished we try this: # - Currently I can see a way, just wait some time # sleep(12 * cfg.time_out_scale) # Save the DRC logger.info('Open the save dialog') wait_point(cfg) logger.info('Save DRC') wait_point(cfg) xdotool([ 'key', 'shift+Tab', 'shift+Tab', 'shift+Tab', 'shift+Tab', 'shift+Tab', 'Return' ]) # Wait for the save dialog wait_for_window('DRC File save dialog', 'Save Report to File') # Paste the name logger.info('Pasting output file') wait_point(cfg) text_replace(cfg.output_file) # Wait for report created logger.info('Wait for DRC file creation') wait_point(cfg) xdotool(['key', 'Return']) wait_for_file_created_by_process(cfg.pcbnew_pid, cfg.output_file) # Close the dialog logger.info('Closing the DRC dialog') wait_point(cfg) xdotool(['key', 'Escape']) wait_pcbnew()
def print_layers(cfg): if cfg.kicad_version >= KICAD_VERSION_5_99: print_dialog_keys = ['ctrl+p'] else: # We should be able to use Ctrl+P, unless the user configured it # otherwise. We aren't configuring hotkeys for 5.1 so is better # to just use the menu accelerators (removed on KiCad 6) print_dialog_keys = ['alt+f', 'p'] # Fill zones if the user asked for it if cfg.fill_zones: logger.info('Fill zones') wait_point(cfg) # Make sure KiCad is responding # We open the dialog and then we close it id = open_print_dialog(cfg, print_dialog_keys) xdotool(['key', 'Escape']) wait_not_focused(id[0]) wait_pcbnew() # Now we fill the zones xdotool(['key', 'b']) # Wait for complation sleep(1) wait_pcbnew() id = open_print_dialog(cfg, print_dialog_keys) # Open the gtk print dialog wait_point(cfg) # Two possible options here: # 1) With WM we usually get "Exclude PCB edge ..." selected # 2) Without WM we usually get "Color" selected # In both cases sending 4 Shit+Tab moves us to one of the layer columns. # From there Return prints and Escape closes the window. xdotool( ['key', 'shift+Tab', 'shift+Tab', 'shift+Tab', 'shift+Tab', 'Return']) # Check it is open id2 = wait_for_window('Printer dialog', '^(Print|%s)$' % cfg.print_dlg_name, skip_id=id[0]) wait_point(cfg) # List of printers xdotool([ 'key', 'Tab', # Go up to the top 'Home', # Output file name 'Tab', # Open dialog 'Return' ]) id_sel_f = wait_for_window( 'Select a filename', '(Select a filename|%s)' % cfg.select_a_filename, 2) logger.info('Pasting output dir') wait_point(cfg) text_replace(cfg.output_file) xdotool([ 'key', # Select this name 'Return' ]) # Back to print wait_not_focused(id_sel_f[0]) wait_for_window('Printer dialog', '^(Print|%s)$' % cfg.print_dlg_name, skip_id=id[0]) wait_point(cfg) xdotool([ 'key', # Format options 'Tab', # Be sure we are at left (PDF) 'Left', 'Left', 'Left', # Print it 'Return' ]) # Wait until the file is created wait_for_file_created_by_process(cfg.pcbnew_pid, cfg.output_file) wait_not_focused(id2[1]) # Now we should be in the KiCad Print dialog again id = wait_for_window('Print dialog', 'Print') wait_point(cfg) # Close the dialog # We are in one of the layer columns, here Escape works xdotool(['key', 'Escape']) wait_not_focused(id2[0]) # Exit exit_pcbnew(cfg)