Commit 26f20fbb authored by Maciej Suminski's avatar Maciej Suminski

Moved "Place Target" and "Place Module" tools from DRAWING_TOOL to...

Moved "Place Target" and "Place Module" tools from DRAWING_TOOL to PCB_EDITOR_CONTROL (to avoid placing modules in the footprint editor).
parent 721949b5
...@@ -153,14 +153,6 @@ TOOL_ACTION COMMON_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout", ...@@ -153,14 +153,6 @@ TOOL_ACTION COMMON_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout",
AS_GLOBAL, 0, AS_GLOBAL, 0,
"Add a keepout area", "Add a keepout area", AF_ACTIVATE ); "Add a keepout area", "Add a keepout area", AF_ACTIVATE );
TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget",
AS_GLOBAL, 0,
"Add layer alignment target", "Add layer alignment target", AF_ACTIVATE );
TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule",
AS_GLOBAL, 'O',
"Add modules", "Add modules", AF_ACTIVATE );
TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF", TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF",
AS_GLOBAL, 0, AS_GLOBAL, 0,
"", "", AF_ACTIVATE ); "", "", AF_ACTIVATE );
...@@ -363,6 +355,15 @@ TOOL_ACTION COMMON_ACTIONS::zoneUnfillAll( "pcbnew.EditorControl.zoneUnfillAll", ...@@ -363,6 +355,15 @@ TOOL_ACTION COMMON_ACTIONS::zoneUnfillAll( "pcbnew.EditorControl.zoneUnfillAll",
"Unfill all", "Unfill all zones" ); "Unfill all", "Unfill all zones" );
TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.EditorControl.placeTarget",
AS_GLOBAL, 0,
"Add layer alignment target", "Add layer alignment target", AF_ACTIVATE );
TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.EditorControl.placeModule",
AS_GLOBAL, 'O',
"Add modules", "Add modules", AF_ACTIVATE );
// Module editor tools // Module editor tools
TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.ModuleEditor.placePad", TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.ModuleEditor.placePad",
AS_GLOBAL, 0, AS_GLOBAL, 0,
......
...@@ -22,9 +22,6 @@ ...@@ -22,9 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <boost/bind.hpp>
#include <cstdio>
#include "drawing_tool.h" #include "drawing_tool.h"
#include "common_actions.h" #include "common_actions.h"
...@@ -47,7 +44,6 @@ ...@@ -47,7 +44,6 @@
#include <class_edge_mod.h> #include <class_edge_mod.h>
#include <class_pcb_text.h> #include <class_pcb_text.h>
#include <class_dimension.h> #include <class_dimension.h>
#include <class_mire.h>
#include <class_zone.h> #include <class_zone.h>
#include <class_module.h> #include <class_module.h>
...@@ -438,208 +434,6 @@ int DRAWING_TOOL::DrawKeepout( const TOOL_EVENT& aEvent ) ...@@ -438,208 +434,6 @@ int DRAWING_TOOL::DrawKeepout( const TOOL_EVENT& aEvent )
} }
int DRAWING_TOOL::PlaceTarget( const TOOL_EVENT& aEvent )
{
PCB_TARGET* target = new PCB_TARGET( m_board );
// Init the new item attributes
target->SetLayer( Edge_Cuts );
target->SetWidth( m_board->GetDesignSettings().m_EdgeSegmentWidth );
target->SetSize( Millimeter2iu( 5 ) );
VECTOR2I cursorPos = m_controls->GetCursorPosition();
target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
preview.Add( target );
m_view->Add( &preview );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_controls->SetSnapping( true );
m_controls->SetAutoPan( true );
m_controls->CaptureCursor( true );
Activate();
m_frame->SetToolID( ID_PCB_MIRE_BUTT, wxCURSOR_PENCIL, _( "Add layer alignment target" ) );
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
cursorPos = m_controls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
break;
else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) )
{
target->SetWidth( target->GetWidth() + WIDTH_STEP );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) )
{
int width = target->GetWidth();
if( width > WIDTH_STEP )
{
target->SetWidth( width - WIDTH_STEP );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
assert( target->GetSize() > 0 );
assert( target->GetWidth() > 0 );
m_view->Add( target );
m_board->Add( target );
target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( target, UR_NEW );
preview.Remove( target );
// Create next PCB_TARGET
target = new PCB_TARGET( *target );
preview.Add( target );
}
else if( evt->IsMotion() )
{
target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
delete target;
m_controls->SetSnapping( false );
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_view->Remove( &preview );
setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
int DRAWING_TOOL::PlaceModule( const TOOL_EVENT& aEvent )
{
MODULE* module = NULL;
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
m_view->Add( &preview );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
m_controls->SetAutoPan( true );
m_controls->CaptureCursor( true );
Activate();
m_frame->SetToolID( ID_PCB_MODULE_BUTT, wxCURSOR_HAND, _( "Add module" ) );
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
VECTOR2I cursorPos = m_controls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
{
if( module )
{
m_board->Delete( module ); // it was added by LoadModuleFromLibrary()
module = NULL;
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_controls->ShowCursor( true );
}
else
break;
if( evt->IsActivate() ) // now finish unconditionally
break;
}
else if( module && evt->Category() == TC_COMMAND )
{
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
module->Rotate( module->GetPosition(), m_frame->GetRotationAngle() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
{
module->Flip( module->GetPosition() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !module )
{
// Init the new item attributes
module = m_frame->LoadModuleFromLibrary( wxEmptyString,
m_frame->Prj().PcbFootprintLibs(),
true, NULL );
if( module == NULL )
continue;
m_controls->ShowCursor( false );
module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Add all the drawable parts to preview
preview.Add( module );
module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else
{
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, m_view, _1 ) );
m_view->Add( module );
module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( module, UR_NEW );
// Remove from preview
preview.Remove( module );
module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Remove, &preview, _1 ) );
module = NULL; // to indicate that there is no module that we currently modify
m_controls->ShowCursor( true );
}
}
else if( module && evt->IsMotion() )
{
module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
m_controls->ShowCursor( false );
m_controls->SetSnapping( false );
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_view->Remove( &preview );
setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
{ {
DIALOG_DXF_IMPORT dlg( m_frame ); DIALOG_DXF_IMPORT dlg( m_frame );
...@@ -1705,8 +1499,6 @@ void DRAWING_TOOL::setTransitions() ...@@ -1705,8 +1499,6 @@ void DRAWING_TOOL::setTransitions()
Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() );
Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() ); Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() );
Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() ); Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() );
Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() );
Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() );
Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() ); Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() );
Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() ); Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() );
} }
...@@ -1724,3 +1516,5 @@ int DRAWING_TOOL::getSegmentWidth( unsigned int aLayer ) const ...@@ -1724,3 +1516,5 @@ int DRAWING_TOOL::getSegmentWidth( unsigned int aLayer ) const
return m_board->GetDesignSettings().m_DrawSegmentWidth; return m_board->GetDesignSettings().m_DrawSegmentWidth;
} }
const int DRAWING_TOOL::WIDTH_STEP = 100000;
...@@ -109,18 +109,6 @@ public: ...@@ -109,18 +109,6 @@ public:
*/ */
int DrawKeepout( const TOOL_EVENT& aEvent ); int DrawKeepout( const TOOL_EVENT& aEvent );
/**
* Function PlaceTarget()
* Allows user to place a layer alignment target.
*/
int PlaceTarget( const TOOL_EVENT& aEvent );
/**
* Function PlaceModule()
* Displays a dialog to select a module to be added and allows the user to set its position.
*/
int PlaceModule( const TOOL_EVENT& aEvent );
/** /**
* Function PlaceDXF() * Function PlaceDXF()
* Places a drawing imported from a DXF file in module editor. * Places a drawing imported from a DXF file in module editor.
...@@ -206,7 +194,7 @@ private: ...@@ -206,7 +194,7 @@ private:
unsigned int m_lineWidth; unsigned int m_lineWidth;
// How does line width change after one -/+ key press. // How does line width change after one -/+ key press.
static const int WIDTH_STEP = 100000; static const int WIDTH_STEP;
}; };
#endif /* __DRAWING_TOOL_H */ #endif /* __DRAWING_TOOL_H */
...@@ -22,15 +22,24 @@ ...@@ -22,15 +22,24 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <boost/bind.hpp>
#include "pcb_editor_control.h" #include "pcb_editor_control.h"
#include "common_actions.h" #include "common_actions.h"
#include "selection_tool.h" #include "selection_tool.h"
#include <project.h>
#include <pcbnew_id.h>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <class_board.h> #include <class_board.h>
#include <class_zone.h> #include <class_zone.h>
#include <class_draw_panel_gal.h> #include <class_draw_panel_gal.h>
#include <class_module.h>
#include <class_mire.h>
#include <view/view_group.h>
#include <view/view_controls.h>
class ZONE_CONTEXT_MENU : public CONTEXT_MENU class ZONE_CONTEXT_MENU : public CONTEXT_MENU
...@@ -159,6 +168,214 @@ int PCB_EDITOR_CONTROL::ViaSizeDec( const TOOL_EVENT& aEvent ) ...@@ -159,6 +168,214 @@ int PCB_EDITOR_CONTROL::ViaSizeDec( const TOOL_EVENT& aEvent )
} }
int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
{
MODULE* module = NULL;
KIGFX::VIEW* view = getView();
KIGFX::VIEW_CONTROLS* controls = getViewControls();
BOARD* board = getModel<BOARD>();
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( view );
view->Add( &preview );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
controls->ShowCursor( true );
controls->SetSnapping( true );
controls->SetAutoPan( true );
controls->CaptureCursor( true );
Activate();
m_frame->SetToolID( ID_PCB_MODULE_BUTT, wxCURSOR_HAND, _( "Add module" ) );
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
VECTOR2I cursorPos = controls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
{
if( module )
{
board->Delete( module ); // it was added by LoadModuleFromLibrary()
module = NULL;
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
controls->ShowCursor( true );
}
else
break;
if( evt->IsActivate() ) // now finish unconditionally
break;
}
else if( module && evt->Category() == TC_COMMAND )
{
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
module->Rotate( module->GetPosition(), m_frame->GetRotationAngle() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
{
module->Flip( module->GetPosition() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !module )
{
// Init the new item attributes
module = m_frame->LoadModuleFromLibrary( wxEmptyString,
m_frame->Prj().PcbFootprintLibs(),
true, NULL );
if( module == NULL )
continue;
controls->ShowCursor( false );
module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Add all the drawable parts to preview
preview.Add( module );
module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else
{
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
view->Add( module );
module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( module, UR_NEW );
// Remove from preview
preview.Remove( module );
module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Remove, &preview, _1 ) );
module = NULL; // to indicate that there is no module that we currently modify
controls->ShowCursor( true );
}
}
else if( module && evt->IsMotion() )
{
module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
controls->ShowCursor( false );
controls->SetSnapping( false );
controls->SetAutoPan( false );
controls->CaptureCursor( false );
view->Remove( &preview );
setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
{
KIGFX::VIEW* view = getView();
KIGFX::VIEW_CONTROLS* controls = getViewControls();
BOARD* board = getModel<BOARD>();
PCB_TARGET* target = new PCB_TARGET( board );
// Init the new item attributes
target->SetLayer( Edge_Cuts );
target->SetWidth( board->GetDesignSettings().m_EdgeSegmentWidth );
target->SetSize( Millimeter2iu( 5 ) );
VECTOR2I cursorPos = controls->GetCursorPosition();
target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( view );
preview.Add( target );
view->Add( &preview );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
controls->SetSnapping( true );
controls->SetAutoPan( true );
controls->CaptureCursor( true );
Activate();
m_frame->SetToolID( ID_PCB_MIRE_BUTT, wxCURSOR_PENCIL, _( "Add layer alignment target" ) );
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
cursorPos = controls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
break;
else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) )
{
target->SetWidth( target->GetWidth() + WIDTH_STEP );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) )
{
int width = target->GetWidth();
if( width > WIDTH_STEP )
{
target->SetWidth( width - WIDTH_STEP );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
assert( target->GetSize() > 0 );
assert( target->GetWidth() > 0 );
view->Add( target );
board->Add( target );
target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( target, UR_NEW );
preview.Remove( target );
// Create next PCB_TARGET
target = new PCB_TARGET( *target );
preview.Add( target );
}
else if( evt->IsMotion() )
{
target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
delete target;
controls->SetSnapping( false );
controls->SetAutoPan( false );
controls->CaptureCursor( false );
view->Remove( &preview );
setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
// Zone actions // Zone actions
int PCB_EDITOR_CONTROL::ZoneFill( const TOOL_EVENT& aEvent ) int PCB_EDITOR_CONTROL::ZoneFill( const TOOL_EVENT& aEvent )
{ {
...@@ -266,5 +483,12 @@ void PCB_EDITOR_CONTROL::setTransitions() ...@@ -266,5 +483,12 @@ void PCB_EDITOR_CONTROL::setTransitions()
Go( &PCB_EDITOR_CONTROL::ZoneUnfill, COMMON_ACTIONS::zoneUnfill.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::ZoneUnfill, COMMON_ACTIONS::zoneUnfill.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::ZoneUnfillAll, COMMON_ACTIONS::zoneUnfillAll.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::ZoneUnfillAll, COMMON_ACTIONS::zoneUnfillAll.MakeEvent() );
// Placing tools
Go( &PCB_EDITOR_CONTROL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::SelectionCrossProbe, SELECTION_TOOL::SelectedEvent ); Go( &PCB_EDITOR_CONTROL::SelectionCrossProbe, SELECTION_TOOL::SelectedEvent );
} }
const int PCB_EDITOR_CONTROL::WIDTH_STEP = 100000;
...@@ -57,6 +57,18 @@ public: ...@@ -57,6 +57,18 @@ public:
int ZoneUnfill( const TOOL_EVENT& aEvent ); int ZoneUnfill( const TOOL_EVENT& aEvent );
int ZoneUnfillAll( const TOOL_EVENT& aEvent ); int ZoneUnfillAll( const TOOL_EVENT& aEvent );
/**
* Function PlaceTarget()
* Allows user to place a layer alignment target.
*/
int PlaceTarget( const TOOL_EVENT& aEvent );
/**
* Function PlaceModule()
* Displays a dialog to select a module to be added and allows the user to set its position.
*/
int PlaceModule( const TOOL_EVENT& aEvent );
///> Notifies eeschema about the selected item. ///> Notifies eeschema about the selected item.
int SelectionCrossProbe( const TOOL_EVENT& aEvent ); int SelectionCrossProbe( const TOOL_EVENT& aEvent );
...@@ -66,6 +78,9 @@ private: ...@@ -66,6 +78,9 @@ private:
///> Pointer to the currently used edit frame. ///> Pointer to the currently used edit frame.
PCB_EDIT_FRAME* m_frame; PCB_EDIT_FRAME* m_frame;
// How does line width change after one -/+ key press.
static const int WIDTH_STEP;
}; };
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment