Skip to content

Commit 7eaa861

Browse files
authored
Don't allow certain blocks to be copied. Clear previous clipboard data. (#326)
1 parent 994c206 commit 7eaa861

File tree

8 files changed

+51
-1
lines changed

8 files changed

+51
-1
lines changed

src/blocks/mrc_class_method_def.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import * as toolboxItems from '../toolbox/items';
3535
import { getClassData } from './utils/python';
3636
import { FunctionData } from './utils/python_json_types';
3737
import { findConnectedBlocksOfType } from './utils/find_connected_blocks';
38+
import { NONCOPYABLE_BLOCK } from './noncopyable_block';
3839
import { BLOCK_NAME as MRC_GET_PARAMETER_BLOCK_NAME } from './mrc_get_parameter';
3940
import * as paramContainer from './mrc_param_container'
4041

@@ -122,6 +123,7 @@ const CLASS_METHOD_DEF = {
122123
this.setNextStatement(false);
123124
this.updateBlock_();
124125
},
126+
...NONCOPYABLE_BLOCK,
125127
/**
126128
* Returns the state of this block as a JSON serializable object.
127129
*/

src/blocks/mrc_component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { getAllowedTypesForSetCheck, getClassData, getSubclassNames } from './ut
3131
import * as toolboxItems from '../toolbox/items';
3232
import * as storageModule from '../storage/module';
3333
import * as storageModuleContent from '../storage/module_content';
34+
import { NONCOPYABLE_BLOCK } from './noncopyable_block';
3435
import {
3536
BLOCK_NAME as MRC_MECHANISM_COMPONENT_HOLDER,
3637
MechanismComponentHolderBlock,
@@ -100,6 +101,7 @@ const COMPONENT = {
100101
this.setPreviousStatement(true, OUTPUT_NAME);
101102
this.setNextStatement(true, OUTPUT_NAME);
102103
},
104+
...NONCOPYABLE_BLOCK,
103105

104106
/**
105107
* Returns the state of this block as a JSON serializable object.

src/blocks/mrc_event.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
2626
import { Parameter } from './mrc_class_method_def';
2727
import { Editor } from '../editor/editor';
2828
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
29+
import { NONCOPYABLE_BLOCK } from './noncopyable_block';
2930
import * as paramContainer from './mrc_param_container'
3031
import {
3132
BLOCK_NAME as MRC_MECHANISM_COMPONENT_HOLDER,
@@ -80,6 +81,7 @@ const EVENT = {
8081
this.setNextStatement(true, OUTPUT_NAME);
8182
this.updateBlock_();
8283
},
84+
...NONCOPYABLE_BLOCK,
8385

8486
/**
8587
* Returns the state of this block as a JSON serializable object.

src/blocks/mrc_mechanism.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import * as toolboxItems from '../toolbox/items';
3131
import * as storageModule from '../storage/module';
3232
import * as storageModuleContent from '../storage/module_content';
3333
import * as storageNames from '../storage/names';
34+
import { NONCOPYABLE_BLOCK } from './noncopyable_block';
3435
import {
3536
BLOCK_NAME as MRC_MECHANISM_COMPONENT_HOLDER,
3637
MechanismComponentHolderBlock,
@@ -96,6 +97,7 @@ const MECHANISM = {
9697
this.setPreviousStatement(true, OUTPUT_NAME);
9798
this.setNextStatement(true, OUTPUT_NAME);
9899
},
100+
...NONCOPYABLE_BLOCK,
99101

100102
/**
101103
* Returns the state of this block as a JSON serializable object.

src/blocks/mrc_mechanism_component_holder.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { Editor } from '../editor/editor';
2727
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
2828
import * as storageModule from '../storage/module';
2929
import * as storageModuleContent from '../storage/module_content';
30+
import { NONCOPYABLE_BLOCK } from './noncopyable_block';
3031
import { BLOCK_NAME as MRC_MECHANISM_NAME } from './mrc_mechanism';
3132
import { OUTPUT_NAME as MECHANISM_OUTPUT } from './mrc_mechanism';
3233
import { MechanismBlock } from './mrc_mechanism';
@@ -79,6 +80,7 @@ const MECHANISM_COMPONENT_HOLDER = {
7980
this.mrcEventBlockIds = '';
8081
this.mrcToolboxUpdateTimeout = null;
8182
},
83+
...NONCOPYABLE_BLOCK,
8284
saveExtraState: function (this: MechanismComponentHolderBlock): MechanismComponentHolderExtraState {
8385
const extraState: MechanismComponentHolderExtraState = {
8486
};

src/blocks/mrc_opmode_details.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { Editor } from '../editor/editor';
2727
import { ExtendedPythonGenerator, OpModeDetails } from '../editor/extended_python_generator';
2828
import { createFieldDropdown } from '../fields/FieldDropdown';
2929
import { MRC_STYLE_CLASS_BLOCKS } from '../themes/styles';
30+
import { NONCOPYABLE_BLOCK } from './noncopyable_block';
3031

3132
export const BLOCK_NAME = 'mrc_opmode_details';
3233

@@ -65,6 +66,7 @@ const OPMODE_DETAILS = {
6566
this.getField('NAME')?.setTooltip(Blockly.Msg.OPMODE_NAME_TOOLTIP);
6667
this.getField('GROUP')?.setTooltip(Blockly.Msg.OPMODE_GROUP_TOOLTIP);
6768
},
69+
...NONCOPYABLE_BLOCK,
6870
checkOpMode(this: OpmodeDetailsBlock, editor: Editor): void {
6971
if (editor.isStepsInWorkspace() ||
7072
editor.getMethodNamesAlreadyOverriddenInWorkspace().includes(PERIODIC_METHOD_NAME)) {

src/blocks/mrc_steps.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717

1818
/**
19-
* @fileoverview Blocks for class method definition
19+
* @fileoverview Block for defining steps.
2020
* @author [email protected] (Alan Smith)
2121
*/
2222
import * as Blockly from 'blockly';
@@ -25,6 +25,7 @@ import { Order } from 'blockly/python';
2525
import { MRC_STYLE_STEPS } from '../themes/styles';
2626
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
2727
import { createStepFieldFlydown } from '../fields/field_flydown';
28+
import { NONCOPYABLE_BLOCK } from './noncopyable_block';
2829
import { renameSteps as updateJumpToStepBlocks } from './mrc_jump_to_step';
2930
import * as stepContainer from './mrc_step_container'
3031
import { createBooleanShadowValue } from './utils/value';
@@ -63,6 +64,7 @@ const STEPS = {
6364
this.setStyle(MRC_STYLE_STEPS);
6465
this.setMutator(stepContainer.getMutatorIcon(this));
6566
},
67+
...NONCOPYABLE_BLOCK,
6668
saveExtraState: function (this: StepsBlock): StepsExtraState {
6769
return {
6870
stepNames: this.mrcStepNames,

src/blocks/noncopyable_block.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* @author [email protected] (Liz Looney)
20+
*/
21+
22+
import * as Blockly from 'blockly';
23+
24+
export const NONCOPYABLE_BLOCK = {
25+
isCopyable: function(this: Blockly.BlockSvg): boolean {
26+
// We don't allow copying, but we return true here so that toCopyData will
27+
// be called. The default in blockly is that a block is only copyable if it
28+
// is both deletable and movable.
29+
return true;
30+
},
31+
toCopyData: function(this: Blockly.BlockSvg, _addNextBlocks = false): Blockly.clipboard.BlockCopyData | null {
32+
// We don't allow copying, but we return null here so the previous contents
33+
// of the clipboard is cleared.
34+
return null;
35+
},
36+
}

0 commit comments

Comments
 (0)