■変更前
```csharp
#region 追加関数等
private AbstractData convert_from_layer_type(AbstractVoid baseObj, string layerType)
{
// 塗り図形、領域オブジェクトの変換処理
// 省略
}
private void _set_layer_and_layer_type(Quadcept.Interface.Manager.IPCBDataCore window, int layer, string layerType, int[] ids, bool isMoveLayerType)
{
// 層間移動処理
// 省略
}
#endregion
/// <summary>
/// 層間移動モードへ切り替え
/// </summary>
/// <param name="window">対象DataCore</param>
/// <param name="layer">層</param>
/// <param name="layerType">層種類</param>
/// <param name="isCopy">コピー</param>
/// <param name="mgr">モードマネージャ</param>
/// <returns>結果</returns>
public OperationResult Execute(Quadcept.Interface.Manager.IPCBDataCore window, int layer, string layerType, bool isCopy, Quadcept.Command.PCB.CommandMode.DetailCommandModeManager mgr)
{
#region
if (window.TempDataManager.SelectedObjects.Keys.Count == 0 || window.TempDataManager.Objects.Keys.Count() != 0)
return OperationResult.Invalid;
var targets = new List<Data.PCB.AbstractData>();
var isMoveLayerType = true;
var selectCannotMoveItemTypeList = new HashSet<PCBItemType>();
// 層間移動チェックと移動 or コピー対象(clone)を抽出する。
foreach (var id in window.TempDataManager.SelectedObjects.Keys.ToArray())
{
var tmp = window.TempDataManager.SelectedObjects[id];
if (tmp.ItemType.EqualsAny(PCBItemType.FootPrint, PCBItemType.Cutout, PCBItemType.Rat, PCBItemType.PadStack, PCBItemType.ViaStack, PCBItemType.Panel))
{
selectCannotMoveItemTypeList.Add(tmp.ItemType); // 層間移動できないオブジェクトリスト
continue;
}
if (!window.DataManager.Objects.AllObjectsContainsKey(id))
continue;
var obj = window.DataManager.Objects[id];
if (obj.SharedLayer < 0) // システム層オブジェクトは他の層(物理層)に移動しない。
continue;
// コピーモード で コピー不可なら対象にしない。
if (isCopy && !CopySelectedObjectsCommand.IsCanCopy(window, obj))
continue;
if (window.TempDataManager.Objects.NetObjects.ContainsKey(obj.SharedNetName) && window.TempDataManager.Objects.NetObjects[obj.SharedNetName].Contains(obj))
isMoveLayerType = false; // 層種類変更フラグを落とす
if (obj.ItemType.EqualsAny(PCBItemType.ArcRoute, PCBItemType.PolyRoute, PCBItemType.Route, PCBItemType.ConnectionPoint,
PCBItemType.DynamicCopper, PCBItemType.StaticCopper, PCBItemType.FillingShape, PCBItemType.ThermalLine,
PCBItemType.AssemblyArea))
isMoveLayerType = false; // 層種類変更フラグを落とす
if (isCopy)
targets.Add(obj.Clone(true));
else
targets.Add(obj);
}
if (targets.Count != window.TempDataManager.SelectedObjects.Keys.Count)
{
// 移動(コピー)できないオブジェクトがあれば再選択メッセージ表示
var itemtypeMessage = new StringBuilder();
foreach (var type in selectCannotMoveItemTypeList)
{
itemtypeMessage.AppendLine(type.ToDescription());
}
Quadcept.Interface.QuadceptModule.UIDialog.MessageDialog_Show(LM.GetResource(LM.Message.Mes_SelectedFailedToLayerMoveObject).F(itemtypeMessage.ToString()), Quadcept.Interface.UI.Dialog.Type.MessageDialog_CaptionType.Error);
return OperationResult.Invalid;
}
using (Data.PCB.AbstractVoid.GeometriesCaches.Instance.CreateSection_Cache())
using (window.CreateSection_SheetMultiEntryCommand())
{
var newDummyNet = OptimizeDummyNetCommand.GetNewDummyNet(window);
var layerSetting = window.Environment.LayerSetting;
if (!isCopy)
{
var targetIDs = new List<int>();
// 作業層変更
foreach (var obj in targets)
targetIDs.Add(obj.ID);
OptimizeDummyNetCommand.SetDummyNetToFixedMoveObjects(window.Environment.IsFixNet, newDummyNet, targets);
_set_layer_and_layer_type(window, layer, layerType, targetIDs.ToArray(), isMoveLayerType);
}
else
{
var layerMovedIds = new HashSet<int>(); // 層移動、再選択するオブジェクトのID
var clones = new List<Data.PCB.AbstractData>();
var newCopperIDs = new List<int>();
window.TempDataManager.Clear();
// cloneしたコピー対象オブジェクトの作業層、層種類更新する
foreach (var obj in targets)
{
var cloneLayerType = isMoveLayerType ? layerType : obj.SharedLayerType;
obj.SharedLayer = layer;
switch (obj.ItemTypeBit)
{
// #14753 塗りオブジェクトの変換機能のミニマムとして実装(ベタ、部品領域には非対応)
case PCBItemType.BitType.Polygon:
case PCBItemType.BitType.PatternRestrictedArea:
case PCBItemType.BitType.DrillRestrictedArea:
case PCBItemType.BitType.ComponentRestrictedArea:
case PCBItemType.BitType.HeightLimitArea:
case PCBItemType.BitType.DesignRuleArea:
clones.Add(convert_from_layer_type(obj as AbstractVoid, cloneLayerType));
break;
default:
obj.SharedLayerType = cloneLayerType;
// 作業層、層種類が変更できないオブジェクトなら対象から除く(フェールセーフ)
if (window.Environment.LayerSetting.GetLayer(obj.SharedLayer, obj.SharedLayerType) == null)
continue;
clones.Add(obj);
break;
}
}
// 層間移動のコピーは元オブジェクトと接触しない&フットプリント、パッドは移動対象外なので元と同じダミーネットが渡されても問題なかった。
// 「ネット固定しない」設定の対象となったので、相対移動、回転移動と同じチェックを追加(
OptimizeDummyNetCommand.SetDummyNetToFixedCopyObjects(window.Environment.IsFixNet, newDummyNet, clones);
foreach (var obj in clones)
{
if (obj.ItemType.Equals(PCBItemType.PadStack))
{
obj.SharedPinNo = GetIncrementedUniqePadNumberCommand.Instance.Execute(window, obj.SharedPinNo, 1);
}
var fixedId = FixTempObjectsCommand.Instance.FixObject(window, -1, obj);
layerMovedIds.Add(fixedId);
//ベタ更新リストに追加
if (obj.ItemTypeBit == PCBItemType.BitType.DynamicCopper)
{
newCopperIDs.Add(fixedId);
}
}
using (DetailCommand.DummyNet.Section.CreateSectionOldNetMerge(window)) // 旧ネットマージ
// ダミーネット更新、ベタ更新、ラッツ更新
NetLogic.Instance.OptimizeCopperObject(window, newCopperIDs);
// 移動(コピー)後のオブジェクトを最選択(複数コピーできないので「最後の」を考慮する必要なし)
window.CommandManager.Commands.SelectObjects.Exucecute(layerMovedIds.ToArray());
}
}
window.CommandManager.Commands.Refresh.Exucecute();
return OperationResult.Invalid;
#endregion
}
```
■変更後
```csharp
#region 追加関数等
PCBItemType[] _cant_move_layer_list = new PCBItemType[]
{
PCBItemType.FootPrint,
PCBItemType.Cutout,
PCBItemType.Rat,
PCBItemType.PadStack,
PCBItemType.ViaStack,
PCBItemType.Panel
};
PCBItemType[] _cant_move_layerType_list = new PCBItemType[]
{
PCBItemType.ArcRoute,
PCBItemType.PolyRoute,
PCBItemType.Route,
PCBItemType.ConnectionPoint,
PCBItemType.DynamicCopper,
PCBItemType.StaticCopper,
PCBItemType.FillingShape,
PCBItemType.ThermalLine,
PCBItemType.AssemblyArea
};
PCBItemType[] _is_convert_ItemType = new PCBItemType[]
{
PCBItemType.Polygon,
PCBItemType.PatternRestrictedArea,
PCBItemType.DrillRestrictedArea,
PCBItemType.ComponentRestrictedArea,
PCBItemType.HeightLimitArea,
PCBItemType.DesignRuleArea,
};
private AbstractData convert_from_layer_type(AbstractVoid baseObj, string layerType)
{
// 塗り図形、領域オブジェクトの変換処理
// 省略
}
private void _set_layer_and_layer_type(Quadcept.Interface.Manager.IPCBDataCore window, int layer, string layerType, int[] ids, bool isMoveLayerType)
{
// 層間移動処理
// 省略
}
private static void _set_layer_and_layer_type(IPCBDataCore window, List<AbstractData> clones)
{
// パッドに新しい番号をセット
_set_number_pad(window, clones);
var layerMovedIds = new HashSet<int>(); // 層移動、再選択するオブジェクトのID
var newCopperIDs = new List<int>();
foreach (var obj in clones)
{
var fixedId = FixTempObjectsCommand.Instance.FixObject(window, -1, obj);
layerMovedIds.Add(fixedId);
//ベタ更新リストに追加
if (obj.ItemTypeBit == PCBItemType.BitType.DynamicCopper)
{
newCopperIDs.Add(fixedId);
}
}
using (DetailCommand.DummyNet.Section.CreateSectionOldNetMerge(window)) // 旧ネットマージ
// ダミーネット更新、ベタ更新、ラッツ更新
NetLogic.Instance.OptimizeCopperObject(window, newCopperIDs);
// 移動(コピー)後のオブジェクトを最選択(複数コピーできないので「最後の」を考慮する必要なし)
window.CommandManager.Commands.SelectObjects.Exucecute(layerMovedIds.ToArray());
}
private static void _set_number_pad(IPCBDataCore window, List<AbstractData> clones)
{
foreach (var obj in clones.Where(obj => obj.ItemType.Equals(PCBItemType.PadStack)))
{
obj.SharedPinNo = GetIncrementedUniqePadNumberCommand.Instance.Execute(window, obj.SharedPinNo, 1);
}
}
private List<AbstractData> _create_clones(IPCBDataCore window, int layer, string layerType, List<AbstractData> targets, bool isMoveLayerType)
{
var clones = new List<Data.PCB.AbstractData>();
foreach (var obj in targets)
{
var clone = obj.Clone(true);
var cloneLayerType = isMoveLayerType ? layerType : clone.SharedLayerType;
clone.SharedLayer = layer;
if (_is_convert_ItemType.Contains(clone.ItemType))
{
clones.Add(_convert_from_layer_type(clone as AbstractVoid, cloneLayerType));
}
else
{
clone.SharedLayerType = cloneLayerType;
// 作業層、層種類が変更できないオブジェクトなら対象から除く(フェールセーフ)
if (window.Environment.LayerSetting.GetLayer(clone.SharedLayer, clone.SharedLayerType) != null)
clones.Add(clone);
}
}
return clones;
}
private bool _checkMoveLayerType(IPCBDataCore window, List<AbstractData> targets)
{
foreach (var obj in targets)
{
if (window.TempDataManager.Objects.NetObjects.ContainsKey(obj.SharedNetName) && window.TempDataManager.Objects.NetObjects[obj.SharedNetName].Contains(obj))
return false; // 層種類変更フラグを落とす
if (_cant_move_layerType_list.Contains(obj.ItemType))
return false; // 層種類変更フラグを落とす
}
return true;
}
private List<AbstractData> _create_copy_targetList(IPCBDataCore window)
{
var targets = new List<Data.PCB.AbstractData>();
foreach (var id in window.TempDataManager.SelectedObjects.Keys)
{
var tmp = window.TempDataManager.SelectedObjects[id];
if (!_cant_move_layer_list.Contains(tmp.ItemType))
{
if (window.DataManager.Objects.AllObjectsContainsKey(id))
{
var obj = window.DataManager.Objects[id];
if (obj.SharedLayer >= 0) // システム層オブジェクトは他の層(物理層)に移動しない。
{
// コピー不可なら対象にしない。
if (CopySelectedObjectsCommand.IsCanCopy(window, obj))
targets.Add(obj);
}
}
}
}
return targets;
}
private List<AbstractData> _create_move_targetList(IPCBDataCore window)
{
var targets = new List<Data.PCB.AbstractData>();
foreach (var id in window.TempDataManager.SelectedObjects.Keys)
{
var tmp = window.TempDataManager.SelectedObjects[id];
if (!_cant_move_layer_list.Contains(tmp.ItemType))
{
if (window.DataManager.Objects.AllObjectsContainsKey(id))
{
var obj = window.DataManager.Objects[id];
if (obj.SharedLayer >= 0) // システム層オブジェクトは他の層(物理層)に移動しない。
{
targets.Add(obj);
}
}
}
}
return targets;
}
private HashSet<PCBItemType> _create_selectCannotMoveItemTypeList(IPCBDataCore window)
{
var selectCannotMoveItemTypeList = new HashSet<PCBItemType>();
foreach (var id in window.TempDataManager.SelectedObjects.Keys)
{
var tmp = window.TempDataManager.SelectedObjects[id];
if (_cant_move_layer_list.Contains(tmp.ItemType))
selectCannotMoveItemTypeList.Add(tmp.ItemType);
}
return selectCannotMoveItemTypeList;
}
#endregion
public OperationResult Execute(Quadcept.Interface.Manager.IPCBDataCore window, int layer, string layerType, bool isCopy, Quadcept.Command.PCB.CommandMode.DetailCommandModeManager mgr)
{
#region
if (window.TempDataManager.SelectedObjects.Keys.Count == 0 || window.TempDataManager.Objects.Keys.Count() != 0)
return OperationResult.Invalid;
// 層間移動できないオブジェクト種類リスト
HashSet<PCBItemType> selectCannotMoveItemTypeList = _create_selectCannotMoveItemTypeList(window);
// 移動 or コピー対象(clone)となるオブジェクトリスト
List<AbstractData> targets = isCopy?
_create_copy_targetList(window):
_create_move_targetList(window);
// 層間移動チェック
bool isMoveLayerType = _checkMoveLayerType(window, targets);
if (targets.Count != window.TempDataManager.SelectedObjects.Keys.Count)
{
// 移動(コピー)できないオブジェクトがあれば再選択メッセージ表示
var itemtypeMessage = new StringBuilder();
foreach (var type in selectCannotMoveItemTypeList)
{
itemtypeMessage.AppendLine(type.ToDescription());
}
Quadcept.Interface.QuadceptModule.UIDialog.MessageDialog_Show(LM.GetResource(LM.Message.Mes_SelectedFailedToLayerMoveObject).F(itemtypeMessage.ToString()), Quadcept.Interface.UI.Dialog.Type.MessageDialog_CaptionType.Error);
return OperationResult.Invalid;
}
using (Data.PCB.AbstractVoid.GeometriesCaches.Instance.CreateSection_Cache())
using (window.CreateSection_SheetMultiEntryCommand())
{
var newDummyNet = OptimizeDummyNetCommand.GetNewDummyNet(window);
var layerSetting = window.Environment.LayerSetting;
if (!isCopy)
{
var targetIDs = new List<int>();
// 作業層変更
foreach (var obj in targets)
targetIDs.Add(obj.ID);
OptimizeDummyNetCommand.SetDummyNetToFixedMoveObjects(window.Environment.IsFixNet, newDummyNet, targets);
_set_layer_and_layer_type(window, layer, layerType, targetIDs.ToArray(), isMoveLayerType);
}
else
{
window.TempDataManager.Clear();
// cloneしたコピー対象オブジェクトの作業層、層種類更新する
List<AbstractData> clones = _create_clones(window, layer, layerType, targets, isMoveLayerType);
// 層間移動のコピーは元オブジェクトと接触しない&フットプリント、パッドは移動対象外なので元と同じダミーネットが渡されても問題なかった。
// 「ネット固定しない」設定の対象となったので、相対移動、回転移動と同じチェックを追加(
OptimizeDummyNetCommand.SetDummyNetToFixedCopyObjects(window.Environment.IsFixNet, newDummyNet, clones);
_set_layer_and_layer_type(window, clones);
}
}
window.CommandManager.Commands.Refresh.Exucecute();
return OperationResult.Invalid;
#endregion
}
```