diff --git a/dist/ladb_opencutlist-dev.rbz b/dist/ladb_opencutlist-dev.rbz index 9a62845fc..9925dde1f 100644 Binary files a/dist/ladb_opencutlist-dev.rbz and b/dist/ladb_opencutlist-dev.rbz differ diff --git a/src/ladb_opencutlist/js/plugins/jquery.ladb.dialog.js b/src/ladb_opencutlist/js/plugins/jquery.ladb.dialog.js index 414f2dfb8..d66b8bae5 100644 --- a/src/ladb_opencutlist/js/plugins/jquery.ladb.dialog.js +++ b/src/ladb_opencutlist/js/plugins/jquery.ladb.dialog.js @@ -246,6 +246,14 @@ return n; }; + LadbDialog.prototype.notifyErrors = function(errors) { + if (Array.isArray(errors)) { + for (var i = 0; i < errors.length; i++) { + this.notify(' ' + i18next.t(errors[i]), 'error'); + } + } + }; + LadbDialog.prototype.setupTooltips = function() { $('[data-toggle="tooltip"]').tooltip({ container: 'body' diff --git a/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-cutlist.js b/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-cutlist.js index 6475a5d89..044cd6820 100644 --- a/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-cutlist.js +++ b/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-cutlist.js @@ -344,12 +344,10 @@ rubyCallCommand('cutlist_part_highlight', part, function (response) { - var success = response['success']; - - if (success) { - that.opencutlist.minimize(); - } else { + if (response['errors']) { that.opencutlist.notify(' ' + i18next.t('tab.cutlist.highlight_error', {'name': part.name}), 'error'); + } else { + that.opencutlist.minimize(); } }); @@ -414,10 +412,30 @@ that.editedPart.cumulable = $selectCumulable.val(); that.editedPart.orientation_locked_on_axis = $inputOrientationLockedOnAxis.is(':checked'); - rubyCallCommand('cutlist_part_update', that.editedPart, function() { + rubyCallCommand('cutlist_part_update', that.editedPart, function(response) { + + if (response['errors']) { + + that.opencutlist.notifyErrors(response['errors']); + + } else { + + var partId = that.editedPart.id; + var wTop = $('#ladb_part_' + partId).offset().top - $(window).scrollTop(); + + // Refresh the list + that.generateCutlist(function() { + + // Try to scroll to the edited part's row + var $part = $('#ladb_part_' + partId); + if ($part.length > 0) { + $part.effect("highlight", {}, 1500); + $('html, body').animate({ scrollTop: $part.offset().top - wTop }, 0); + } + + }); - var partId = that.editedPart.id; - var wTop = $('#ladb_part_' + partId).offset().top - $(window).scrollTop(); + } // Reset edited part that.editedPart = null; @@ -425,18 +443,6 @@ // Hide modal $modal.modal('hide'); - // Refresh the list - that.generateCutlist(function() { - - // Try to scroll to the edited part's row - var $part = $('#ladb_part_' + partId); - if ($part.length > 0) { - $part.effect("highlight", {}, 1500); - $('html, body').animate({ scrollTop: $part.offset().top - wTop }, 0); - } - - }); - }); }); @@ -492,7 +498,18 @@ // Fetch form values that.editedGroup.material_name = $selectMaterialName.val(); - rubyCallCommand('cutlist_group_update', that.editedGroup, function() { + rubyCallCommand('cutlist_group_update', that.editedGroup, function(response) { + + if (response['errors']) { + + that.opencutlist.notifyErrors(response['errors']); + + } else { + + // Refresh the list + that.generateCutlist(); + + } // Reset edited group that.editedGroup = null; @@ -500,9 +517,6 @@ // Hide modal $modal.modal('hide'); - // Refresh the list - that.generateCutlist(); - }); }); diff --git a/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-materials.js b/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-materials.js index 465e12f79..e024da4ce 100644 --- a/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-materials.js +++ b/src/ladb_opencutlist/js/plugins/jquery.ladb.tab-materials.js @@ -73,7 +73,7 @@ })); // Update items state - that.$itemPurgeUnused.closest('li').toggleClass('disabled', materials.length == 0); + that.$itemPurgeUnused.closest('li').toggleClass('disabled', materials == null || materials.length == 0); // Update page that.$page.empty(); @@ -416,7 +416,18 @@ // Flag to ignore next material change event that.ignoreNextMaterialChangeEvent = true; - rubyCallCommand('materials_update', that.editedMaterial, function() { + rubyCallCommand('materials_update', that.editedMaterial, function(response) { + + if (response['errors']) { + + that.opencutlist.notifyErrors(response['errors']); + + } else { + + // Refresh the list + that.loadList(); + + } // Reset edited material that.editedMaterial = null; @@ -424,9 +435,6 @@ // Hide modal $modal.modal('hide'); - // Refresh the list - that.loadList(); - }); }); diff --git a/src/ladb_opencutlist/ruby/controller/cutlist_controller.rb b/src/ladb_opencutlist/ruby/controller/cutlist_controller.rb index a816454e6..fde6484ba 100644 --- a/src/ladb_opencutlist/ruby/controller/cutlist_controller.rb +++ b/src/ladb_opencutlist/ruby/controller/cutlist_controller.rb @@ -356,17 +356,17 @@ def _get_inherited_material(path) if @instance_infos_cache.length == 0 if model if entities.length == 0 - cutlist_def.add_error("tab.cutlist.error.no_entities") + cutlist_def.add_error('tab.cutlist.error.no_entities') else if use_selection - cutlist_def.add_error("tab.cutlist.error.no_component_in_selection") + cutlist_def.add_error('tab.cutlist.error.no_component_in_selection') else - cutlist_def.add_error("tab.cutlist.error.no_component_in_model") + cutlist_def.add_error('tab.cutlist.error.no_component_in_model') end - cutlist_def.add_tip("tab.cutlist.tip.no_component") + cutlist_def.add_tip('tab.cutlist.tip.no_component') end else - cutlist_def.add_error("tab.cutlist.error.no_model") + cutlist_def.add_error('tab.cutlist.error.no_model') end end @@ -819,7 +819,7 @@ def numbers_command(settings, reset) group_id = settings['group_id'] model = Sketchup.active_model - definitions = model.definitions + definitions = model ? model.definitions : [] @cutlist[:groups].each { |group| @@ -849,10 +849,12 @@ def part_get_thumbnail_command(part_data) :thumbnail_file => '' } + model = Sketchup.active_model + return response unless model + # Extract parameters definition_id = part_data['definition_id'] - model = Sketchup.active_model definitions = model.definitions definition = definitions[definition_id] if definition @@ -876,13 +878,8 @@ def part_get_thumbnail_command(part_data) def part_highlight_command(part_data) - response = { - :success => false - } - model = Sketchup.active_model - - return response unless model + return { :errors => [ 'tab.cutlist.error.no_model' ] } unless model # Extract parameters name = part_data['name'] @@ -892,7 +889,6 @@ def part_highlight_command(part_data) material_name = part_data['material_name'] entity_serialized_paths = part_data['entity_serialized_paths'] - # Populate instance defs entity_infos = [] entity_serialized_paths.each { |entity_serialized_path| @@ -914,15 +910,15 @@ def part_highlight_command(part_data) highlight_tool = HighlightPartTool.new(text_line_1, text_line_2, entity_infos) model.select_tool(highlight_tool) - response[:success] = true - end - response end def part_update_command(part_data) + model = Sketchup.active_model + return { :errors => [ 'tab.cutlist.error.no_model' ] } unless model + # Extract parameters definition_id = part_data['definition_id'] name = part_data['name'] @@ -931,36 +927,40 @@ def part_update_command(part_data) orientation_locked_on_axis = part_data['orientation_locked_on_axis'] entity_ids = part_data['entity_ids'] - model = Sketchup.active_model - - # Update definition's name definitions = model.definitions definition = definitions[definition_id] - if definition and definition.name != name - definition.name = name - end - definition_attributes = DefinitionAttributes.new(definition) - if cumulable != definition_attributes.cumulable or orientation_locked_on_axis != definition_attributes.orientation_locked_on_axis - definition_attributes.cumulable = cumulable - definition_attributes.orientation_locked_on_axis = orientation_locked_on_axis - definition_attributes.write_to_attributes - end + if definition - # Update component instance material - materials = model.materials - if material_name.nil? or material_name.empty? or (material = materials[material_name]) + # Update definition's name + if definition.name != name + definition.name = name + end + + # Update definition's attributes + definition_attributes = DefinitionAttributes.new(definition) + if cumulable != definition_attributes.cumulable or orientation_locked_on_axis != definition_attributes.orientation_locked_on_axis + definition_attributes.cumulable = cumulable + definition_attributes.orientation_locked_on_axis = orientation_locked_on_axis + definition_attributes.write_to_attributes + end + + # Update component instance material + materials = model.materials + if material_name.nil? or material_name.empty? or (material = materials[material_name]) - entity_ids.each { |entity_id| - entity = ModelUtils::find_entity_by_id(model, entity_id) - if entity - if material_name.nil? or material_name.empty? - entity.material = nil - elsif entity.material != material - entity.material = material + entity_ids.each { |entity_id| + entity = ModelUtils::find_entity_by_id(model, entity_id) + if entity + if material_name.nil? or material_name.empty? + entity.material = nil + elsif entity.material != material + entity.material = material + end end - end - } + } + + end end @@ -968,15 +968,16 @@ def part_update_command(part_data) def group_update_command(group_data) + model = Sketchup.active_model + return { :errors => [ 'tab.cutlist.error.no_model' ] } unless model + # Extract parameters - id = group_data['id'] material_name = group_data['material_name'] parts = group_data['parts'] - model = Sketchup.active_model + materials = model.materials # Update component instance material - materials = model.materials if material_name.nil? or material_name.empty? or (material = materials[material_name]) parts.each { |part_data| diff --git a/src/ladb_opencutlist/ruby/controller/materials_controller.rb b/src/ladb_opencutlist/ruby/controller/materials_controller.rb index 7e934becd..f654b3de2 100644 --- a/src/ladb_opencutlist/ruby/controller/materials_controller.rb +++ b/src/ladb_opencutlist/ruby/controller/materials_controller.rb @@ -102,7 +102,7 @@ def list_command() response[:errors].push('tab.materials.error.no_materials') end else - response[:errors].push("tab.materials.error.no_model") + response[:errors].push('tab.materials.error.no_model') end # Sort materials by type ASC, display_name ASC @@ -113,13 +113,19 @@ def list_command() def purge_unused_command() - materials = Sketchup.active_model.materials + model = Sketchup.active_model + return { :errors => [ 'tab.materials.error.no_model' ] } unless model + + materials = model.materials materials.purge_unused end def update_command(material_data) + model = Sketchup.active_model + return { :errors => [ 'tab.materials.error.no_model' ] } unless model + name = material_data['name'] display_name = material_data['display_name'] attributes = material_data['attributes'] @@ -131,7 +137,6 @@ def update_command(material_data) std_sections = attributes['std_sections'] # Fetch material - model = Sketchup.active_model materials = model.materials material = materials[name] @@ -158,18 +163,19 @@ def update_command(material_data) def remove_command(material_data) + model = Sketchup.active_model + return { :errors => [ 'tab.materials.error.no_model' ] } unless model + name = material_data['name'] - display_name = material_data['display_name'] + + response = { + :errors => [] + } # Fetch material - model = Sketchup.active_model materials = model.materials material = materials[name] - response = { - :errors => [], - } - if material begin @@ -178,6 +184,8 @@ def remove_command(material_data) response[:errors].push('tab.materials.error.failed_removing_material') end + else + response[:errors].push('tab.materials.error.failed_removing_material') end response @@ -185,17 +193,20 @@ def remove_command(material_data) def import_from_skm_command - # Fetch material model = Sketchup.active_model - materials = model.materials + return { :errors => [ 'tab.materials.error.no_model' ] } unless model response = { - :errors => [], + :errors => [] } - dir, filename = File.split(model ? model.path : '') + # Fetch material + materials = model.materials + + dir, filename = File.split(model.path) path = UI.openpanel(Plugin.get_i18n_string('tab.materials.import_from_skm.title'), dir, "Material Files|*.skm;||") if path + begin materials.load(path) rescue @@ -209,31 +220,31 @@ def import_from_skm_command def export_to_skm_command(material_data) + model = Sketchup.active_model + return { :errors => [ 'tab.materials.error.no_model' ] } unless model + name = material_data['name'] display_name = material_data['display_name'] # Fetch material - model = Sketchup.active_model materials = model.materials material = materials[name] - response = { - :errors => [], - } - if material - dir, filename = File.split(model ? model.path : '') + dir, filename = File.split(model.path) path = UI.savepanel(Plugin.get_i18n_string('tab.materials.export_to_skm.title'), dir, display_name + '.skm') if path begin material.save_as(path) - response[:export_path] = path; + response[:export_path] = path rescue response[:errors].push('tab.materials.error.failed_export_skm_file') end end + else + response[:errors].push('tab.materials.error.failed_export_skm_file') end response diff --git a/src/ladb_opencutlist/ruby/plugin.rb b/src/ladb_opencutlist/ruby/plugin.rb index 266728dbe..ab51cd14a 100644 --- a/src/ladb_opencutlist/ruby/plugin.rb +++ b/src/ladb_opencutlist/ruby/plugin.rb @@ -13,7 +13,7 @@ class Plugin NAME = 'OpenCutList'.freeze VERSION = '1.4.1-dev'.freeze - BUILD = '201804061110'.freeze + BUILD = '201804091154'.freeze DEFAULT_SECTION = ATTRIBUTE_DICTIONARY = 'ladb_opencutlist'.freeze BC_DEFAULT_SECTION = BC_ATTRIBUTE_DICTIONARY = 'ladb_toolbox'.freeze