class Microstation::App
Constants
- IsProcessLocked
- Visible
- X
- Y
- Z
Attributes
Public Class Methods
Constructor for app @param [Boolean] visible @param event_handler [EventHandler]
# File lib/microstation/app.rb, line 145 def initialize(visible: false, event_handler: default_event_handler) @visible = visible @event_handler = event_handler @ole_obj, @app_event = init_ole_and_app_event(visible: @visible, event_handler: @event_handler, tries: 5, sleep_duration: 0.5) @run_loop = true @windows = Windows::FileSystem.new # make_visible(visible) @scanners = {} rescue StandardError => e binding.pry end
Calls run to get an app instance then call open drawing with that app (see open_drawing
) @yield Drawing
@return [void]
# File lib/microstation/app.rb, line 89 def open_drawing(drawing, app_options: {}, options: {}, &block) run(**app_options) do |app| app.open_drawing(drawing, **options, &block) end end
Initialize an instance of app with the options @param [Hash] options the options to create the app with @option options [Boolean] :visible Is the app visible
- source
App.run
do |app|drawing = app.open_drawing('test.dgn') drawing.scan_all_text do |model,text| puts "#{model} #{text}" end
end
@yield [App] the_app yields the instanciated app @return [void]
# File lib/microstation/app.rb, line 68 def run(options = {}) opts = self.default_app_options.merge(options) begin the_app = new(**opts) binding.pry if the_app.nil? yield the_app rescue StandardError binding.pry ensure the_app.quit if the_app.respond_to? :quit the_app = nil GC.start nil end end
Runs the app, opening the filenames and yielding each open drawing to the supplied block it automatically closes the drawing and the app when done
- source
-
dir = Pathname('C:/templates') drawings =
Pathname.glob
(dir + '/*/.dgn')App.with_drawings(drawings)
do |drawing|drawing.save_as_pdf(dir: 'c:/output/')
end
@param files [Array<String,Pathname>] @param visible [Boolean] @param readonly [Boolean] @param error_proc [Proc] @yield [Drawing] @return [void]
# File lib/microstation/app.rb, line 114 def with_drawings(*files, visible: true, readonly: false, error_proc: ::Microstation.default_error_proc, &block) # drawing_options = default_drawing_options.merge(options) # app_options = default_app_options errors = [] files = files[0] if files[0].is_a? Array begin the_app = new(visible: visible) files_enum = files.each loop do file = files_enum.next puts "opening #{file}.." begin the_app.open_drawing(file, readonly: readonly, error_proc: error_proc, &block) the_app.ole_obj.ole_methods # check if server still open rescue StandardError => e error_proc.call(e, file) the_app = new(app_options) end end ensure the_app&.quit the_app = nil end end
Public Instance Methods
the active design file @return [Drawing]
# File lib/microstation/app.rb, line 486 def active_design_file if active_design_file? ole = ole_obj.ActiveDesignFile drawing_from_ole(ole) end end
@return [Boolean] true if app has an active design file open
# File lib/microstation/app.rb, line 512 def active_design_file? ole_obj.HasActiveDesignFile end
# File lib/microstation/app.rb, line 616 def active_model_reference DefaultModel.new(self, ole_obj.ActiveModelReference) rescue StandardError nil end
# File lib/microstation/app.rb, line 357 def active_workspace ole_obj.ActiveWorkspace end
# File lib/microstation/app.rb, line 267 def base_dir project_dir || Pathname.getwd end
lets you interact with the cad_input_queue
@yield [CadInputQueue] @return [void]
# File lib/microstation/app.rb, line 566 def cad_input_queue queue = init_cad_input_queue return queue unless block_given? begin yield queue rescue StandardError ensure queue.close queue = nil @cad_input_queue = nil end end
# File lib/microstation/app.rb, line 611 def can_open?(filename) ext = File.extname(filename) (ext == '.dwg') || (ext == '.dgn') end
# File lib/microstation/configuration.rb, line 175 def capabilities(mode = :all) case mode when :all configuration.capabilities_all when :dwg configuration.capabilites_dwg when :v7 configuration.capabilities_v7 else configuration_capabilities_all end end
# File lib/microstation/app.rb, line 165 def change_drawing(dgn, output_dir: nil, name: nil, options: {}, &block) changer = Changer.new(dgn, name: name, output_dir: output_dir, app: self) changer.run(&block) end
close the active_design_file
@return [void]
# File lib/microstation/app.rb, line 501 def close_active_drawing active_design_file.close if active_design_file? end
@return the [Configuration]
# File lib/microstation/app.rb, line 362 def configuration @config ||= ::Microstation::Configuration.new(self) end
@return [String] the configuration variable MS_SEEDFILES
# File lib/microstation/app.rb, line 437 def configured_seed_paths configuration['MS_SEEDFILES'] end
Create an WIN32OLE_RECORD of type Point3d
@param [Numeric] x coordinate in x axis @param [Numeric] y coordinate in y axis @param [Numeric] z coordinate in z direction (0.0)
@return [WIN32OLE_RECORD] record of type Point3d
# File lib/microstation/app.rb, line 649 def create_ole_point(x, y, z = 0) ole = ole_point ole.X = x ole.Y = y ole.Z = z ole end
# File lib/microstation/scan/criteria.rb, line 14 def create_ole_scan_criteria ole_obj.CreateObjectInMicroStation("MicroStationDGN.ElementScanCriteria") end
# File lib/microstation/app.rb, line 541 def create_scan_criteria(name = nil, &block) ::Microstation::Scan::Criteria.create_scanner(name, self, &block) end
# File lib/microstation/app.rb, line 529 def create_scanner(name = nil, &block) ::Microstation::Scan::Criteria.create_scanner(name, self, &block) end
# File lib/microstation/app.rb, line 696 def create_text_node(origin, rotation, temp = nil) ole_origin = to_ole_point3d(origin) ole_rotation = to_ole_matrix3d(rotation) temp ||= WIN32OLE_VARIANT::Nothing ole = ole_obj.CreateTextNodeElement1(temp, ole_origin, ole_rotation) rescue Exception => e puts e.message nil end
the default EventHandler
@return [EventHandler] returns the default EventHandler
# File lib/microstation/app.rb, line 180 def default_event_handler event_handler = EventHandler.new event_handler.add_handler('OnDesignFileOpened') do |*_args| puts 'drawing opened' @drawing_opened = true end event_handler.add_handler('OnDesignFileClosed') do |*_args| @drawing_opened = false puts 'drawing closed' end event_handler end
# File lib/microstation/app.rb, line 622 def default_model DefaultModel.new(self, ole_obj.DefaultModelReference) rescue StandardError nil end
# File lib/microstation/app.rb, line 427 def determine_seed(seedfile) return configuration['MS_DESIGNSEED'] unless seedfile seed = find_seed(seedfile) return seed.to_s if seed raise "Seedfile #{seedfile} not found in #{configured_seed_paths}" end
# File lib/microstation/app.rb, line 423 def drawing_from_ole(ole) Drawing.new(self, ole) end
# File lib/microstation/app.rb, line 349 def drawing_opened? @drawing_opened end
# File lib/microstation/app.rb, line 465 def eval_cexpression(string) ole_obj.GetCExpressionValue(string) end
# File lib/microstation/app.rb, line 216 def exit_message_looop puts 'Microstation exiting...' @run_loop = false end
<Description>
@param [String,Pathname] file name of file to search for
@return [Boolean] true if file exists
# File lib/microstation/app.rb, line 525 def file_exists?(file) Pathname(file).expand_path.file? end
find the seedfile @param [String,Pathname] seedfile
-
If the seed file is absolute and found the return the
seedfile.
-
If the seed file is not found search MS_SEEDFILES
@return [Pathname] seedfile the found seedfile
# File lib/microstation/app.rb, line 448 def find_seed(seedfile) seed = Pathname(seedfile).expand_path.sub_ext('.dgn') return seed if seed.file? find_seed_in_seed_dirs(seed.basename) end
# File lib/microstation/app.rb, line 455 def find_seed_in_seed_dirs(seedfile) seed_dir = seed_paths.find { |p| (p + seedfile).file? } return (seed_dir + seedfile) if seed_dir end
return a Handler
@param [String,Symbol] event the event key
@return [Proc] returns the Proc given by event name
# File lib/microstation/app.rb, line 212 def get_handler(event) @event_handler.get_handler(event) end
# File lib/microstation/app.rb, line 555 def get_ole_element_enumerator(model:, criteria: nil) criteria ||= create_scan_criteria criteria.resolve model.scan(criteria.ole_obj) rescue Exception # binding.pry end
# File lib/microstation/app.rb, line 413 def has_current_drawing? ole_obj.HasActiveDesignFile end
# File lib/microstation/app.rb, line 230 def init_ole_and_app_event(visible: @visible, event_handler: @event_handler, tries: 5, sleep_duration: 1) ole = WIN32OLE.new('MicrostationDGN.Application') sleep(sleep_duration) ole.Visible = visible ole.IsProcessLocked = true load_constants(ole) app_event = WIN32OLE_EVENT.new(ole) app_event.handler = event_handler [ole, app_event] rescue StandardError => e tries -= 1 sleep_duration += 1.5 puts "Error: #{e}. #{tries} tries left." retry if tries.positive? raise e, 'unable to init ole app' end
# File lib/microstation/app.rb, line 281 def make_visible(visible) @visible = visible begin ole_obj.Visible = @visible true rescue Exception => e false end end
# File lib/microstation/app.rb, line 740 def method_missing(meth, *args, &block) if meth.to_s =~ /^[A-Z]/ require 'pry'; binding.pry result = ole_obj.send(meth, *args, &block) else super(meth, *args, &block) end rescue StandardError => e binding.pry end
# File lib/microstation/app.rb, line 735 def my_place_line require_relative 'primitive_command_interface' start_primitive LineCreation end
create a new drawing @param filename [String,Pathname] the name of the file @param seedfile [String] The name of the seed file.
should not include a path. The default extension is ".dgn". Typical values are "seed2d" or "seed3d".
@param open [Boolean] .If the open argument is True,
CreateDesignFile returns the newly-opened DesignFile object; this is the same value as ActiveDesignFile. If the Open argument is False, CreateDesignFile returns Nothing.
@return [Drawing]
# File lib/microstation/app.rb, line 381 def new_drawing(filename, seedfile: nil, open: true, wait_time: 500, wait_interval: 1, &block) file_path = Pathname(filename).expand_path raise ExistingFile, file_path if file_path.exist? # drawing_name = normalize_name(filename) seedfile = determine_seed(seedfile) binding.pry unless seedfile windows_name = windows_path(filename) ole = new_ole_drawing(seedfile, windows_name, open: open, wait_time: wait_time, wait_interval: wait_interval) drawing = drawing_from_ole(ole) return drawing unless block_given? begin yield drawing rescue StandardError => e 'puts error in new drawing' raise e ensure drawing.close end end
# File lib/microstation/app.rb, line 403 def new_ole_drawing(seedfile, new_design_file_name, open: true, wait_time: 500, wait_interval: 0.5) ole = ole_obj.CreateDesignFile(seedfile, new_design_file_name, open) wait_drawing_opened(wait_time, wait_interval) raise "drawing not opened in #{wait_time}" unless drawing_opened? ole rescue StandardError => e raise e end
# File lib/microstation/app.rb, line 275 def normalize_name(name) name = Pathname.new(name) unless name.is_a? Pathname name = name.ext('.dgn') unless name.extname.to_s == /\.(dgn|dwg)$/ (base_dir + name).expand_path end
# File lib/microstation/app.rb, line 636 def ole_matrix ::WIN32OLE_RECORD.new('Matrix', ole_obj) end
# File lib/microstation/app.rb, line 291 def ole_obj is_ok = true begin @ole_obj.Visible rescue StandardError => e is_ok = false end @ole_obj, @app_event = init_ole_and_app_event(tries: 3) unless is_ok @ole_obj end
# File lib/microstation/app.rb, line 628 def ole_point ::WIN32OLE_RECORD.new('Point3d', ole_obj) end
<Description>
@param [Object] pt pt object to test if it is a WIN32OLE_RECORD of 'Point3d'
@return [Boolean] true if pt is WIN32OLE_RECORD of 'Point3d'
# File lib/microstation/app.rb, line 692 def ole_point3d?(pt) pt.instance_of?(WIN32OLE_RECORD) && pt.typename == 'Point3d' end
# File lib/microstation/app.rb, line 632 def ole_rotation ::WIN32OLE_RECORD.new('Rotation', ole_obj) end
# File lib/microstation/element.rb, line 283 def ole_to_ruby(ole) Element.convert_item(ole,self) end
open the drawing @param filename [String] the name of the file to open @param [Boolean] :readonly (false) @param [Proc] :error_proc (raise) a proc to run @param wait_time [Integer] the total amount of time to wait to open file (500) @param wait_interval [Float] the amount of time in seconds to wait before retry (0.5) @yield [Drawing] drawing @return [void]
# File lib/microstation/app.rb, line 324 def open_drawing(filename, readonly: false, error_proc: nil, wait_time: 500, wait_interval: 0.5) filename = Pathname(filename) raise FileNotFound unless filename.file? begin ole = ole_open_drawing(windows_path(filename), readonly: readonly, wait_time: wait_time, wait_interval: wait_interval) rescue StandardError => e if error_proc error_proc.call(filename) return else raise e end end drawing = drawing_from_ole(ole) return drawing unless block_given? begin yield drawing ensure drawing.close end end
prepend a dir to the MS_SEEDFILES configuration @param dir [String,Pathname]
# File lib/microstation/app.rb, line 419 def prepend_seed_path(dir) configuration.prepend('MS_SEEDFILES', windows_path(dir)) end
# File lib/microstation/app.rb, line 263 def project_dir=(dir) @project_dir = dir ? Pathname.new(dir) : dir end
quit the app
@return [void]
# File lib/microstation/app.rb, line 474 def quit close_active_drawing @scanners.each { |_name, sc| sc.close } begin ole_obj.Quit rescue StandardError nil end end
register an handler
@param [String] event key for handler @param [<Type>] &block <description>
@return [<Type>] <description>
# File lib/microstation/app.rb, line 201 def register_handler(event, &block) @event_handler.add_handler(event, &block) unless event == 'OnQuit' end
# File lib/microstation/app.rb, line 170 def render_template(drawing, output_dir: nil, locals: {}, name: nil) temp = Template.new(drawing, output_dir: output_dir, app: self, name: name) temp.render(output_dir: output_dir, locals: locals) end
# File lib/microstation/app.rb, line 158 def run_templates_in_dir(dir, options = {}) yaml_files = Pathname.glob("#{Pathname(dir).expand_path}*.yaml") yaml_files.each do |f| TemplateRunner.new(f).run_with_app(self, options) end end
def find_by_id(id)
active_design_file.find_by_id(id) wrap(model) if el
end
# File lib/microstation/app.rb, line 550 def scan_model(criteria = nil, model = nil) model ||= active_model_reference model.scan(criteria) end
@return [Array] returns the MS_SEEDFILES as Pathnames Array
# File lib/microstation/app.rb, line 461 def seed_paths configured_seed_paths.split(';').map { |d| Pathname(d) } end
# File lib/microstation/app.rb, line 580 def show_command(text) ole_obj.ShowCommand(text) end
# File lib/microstation/app.rb, line 588 def show_message(text) ole_obj.ShowMessage(text) end
# File lib/microstation/app.rb, line 584 def show_prompt(text) ole_obj.ShowPrompt(text) end
@param [String] text text to show @param [Symbol] location (one of :left, :middle)
@return [void]
# File lib/microstation/app.rb, line 599 def show_temp_message(text, location: nil) loc = case location when :left MSD::MsdStatusBarAreaLeft when :middle MSD::MsdStatusBarAreaMiddle else MSD::MsdStatusBarAreaLeft end ole_obj.ShowTempMessage(loc, text) end
# File lib/microstation/app.rb, line 731 def start_primitive(klass) ole_obj.CommandState.StartPrimitive klass.new(self) end
# File lib/microstation/app.rb, line 533 def text_criteria scanners[:textual] || create_scanner(:textual) { include_textual } end
# File lib/microstation/app.rb, line 657 def to_ole_matrix3d(vec) if vec.instance_of?(WIN32OLE_RECORD) && vec.typename == 'Matrix3d' vec else binding.pry end end
Conversion to WIN32OLE_RECORD of type Point3d
@param [WIN32OLE_RECORD, Point3d
, Array<Numeric>] pt Point to normalize to ole point @return [WIN32OLE_RECORD] 'Point3d' WIN32OLE_RECORD
# File lib/microstation/app.rb, line 671 def to_ole_point3d(pt) case pt when ole_point3d?(pt) pt when Point3d create_ole_point(pt.x, pt.y, pt.z) when Array pt1 = pt.map(&:to_f) x, y, z = pt1 z ||= 0.0 create_ole_point(x, y, z) end end
# File lib/microstation/app.rb, line 727 def to_point(pt) to_point3d(pt) end
convert pt to Point3d
@param [Array<Numeric,Numeric,Numeric>, Point3d
, WIN32OLE_RECORD] pt Point to convert
@return [Point3d]
# File lib/microstation/app.rb, line 713 def to_point3d(pt) case pt when Array pt_a = pt.map(&:to_f) x, y, z = pt_a z ||= 0.0 Point3d.new(x, y, z) when Point3d pt when WIN32OLE_RECORD Point3d.from_ole(pt) if pt.typename == 'Point3d' end end
@return [String] the configuration variable USERNAME
# File lib/microstation/app.rb, line 367 def username configuration['USERNAME'] end
Change the visible attribute
@param [Boolean] bool true or false to make it visible
@return [void]
# File lib/microstation/app.rb, line 259 def visible=(bool) ole_obj.Visible = bool end
@return [Boolean] whether the app is visible
# File lib/microstation/app.rb, line 248 def visible? @visible end
# File lib/microstation/app.rb, line 221 def wait_drawing_opened(secs, interval = 1) elapsed = 0 while !drawing_opened? && elapsed <= secs elapsed += interval sleep(interval) WIN32OLE_EVENT.message_loop end end
# File lib/microstation/app.rb, line 353 def windows_path(path) @windows.windows_path(path) end
# File lib/microstation/configuration.rb, line 85 def with_config end
# File lib/microstation/app.rb, line 304 def with_drawing(drawing) yield drawing ensure drawing.close end
# File lib/microstation/app.rb, line 310 def with_template(template) template = Template.new(template, self) yield template template = nil end
# File lib/microstation/app.rb, line 271 def wrap(item, cell = nil) Element.convert_item(item, self, cell) end
Protected Instance Methods
# File lib/microstation/app.rb, line 763 def load_constants(ole_obj) WIN32OLE.const_load(ole_obj, MSD) unless MSD.constants.size.positive? end
# File lib/microstation/app.rb, line 753 def ole_open_drawing(path, readonly: false, wait_time: 500, wait_interval: 0.5) ole = ole_obj.OpenDesignFile(windows_path(path), 'ReadOnly' => readonly) wait_drawing_opened(wait_time, wait_interval) raise "drawing not opened in #{wait_time}" unless drawing_opened? ole rescue StandardError => e raise e end
# File lib/microstation/app.rb, line 767 def run_loop WIN32OLE_EVENT.message_loop while @run_loop end
# File lib/microstation/app.rb, line 771 def stop_loop @run_loop = false end
Private Instance Methods
# File lib/microstation/app.rb, line 777 def init_cad_input_queue ::Microstation::CadInputQueue.new(ole_obj.CadInputQueue, self) end