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