447 lines
13 KiB
C++
447 lines
13 KiB
C++
/***************/
|
|
/* hotkeys.cpp */
|
|
/***************/
|
|
|
|
#include "fctsys.h"
|
|
|
|
#include "gr_basic.h"
|
|
|
|
#include "common.h"
|
|
#include "program.h"
|
|
#include "libcmp.h"
|
|
#include "general.h"
|
|
|
|
#include "id.h"
|
|
|
|
#include "protos.h"
|
|
|
|
enum hotkey_id_commnand {
|
|
HK_NOT_FOUND = 0,
|
|
HK_RESET_LOCAL_COORD,
|
|
HK_HELP,
|
|
HK_ZOOM_IN,
|
|
HK_ZOOM_OUT,
|
|
HK_ZOOM_REDRAW,
|
|
HK_ZOOM_CENTER,
|
|
HK_NEXT_SEARCH,
|
|
HK_DELETE,
|
|
HK_REPEAT_LAST,
|
|
HK_MOVEBLOCK_TO_DRAGBLOCK,
|
|
HK_ROTATE_COMPONENT,
|
|
HK_MIRROR_X_COMPONENT,
|
|
HK_MIRROR_Y_COMPONENT,
|
|
HK_ORIENT_NORMAL_COMPONENT,
|
|
HK_MOVE_COMPONENT,
|
|
HK_ADD_NEW_COMPONENT,
|
|
HK_BEGIN_WIRE
|
|
};
|
|
|
|
/* Class to handle hotkey commnands. hotkeys have a default value
|
|
This class allows (for the future..) the real key code changed by user(from a key code list file, TODO)
|
|
*/
|
|
class Ki_HotkeyInfo
|
|
{
|
|
public:
|
|
int m_KeyCode; // Key code (ascii value for ascii keys or wxWidgets code for function key
|
|
wxString m_InfoMsg; // info message.
|
|
hotkey_id_commnand m_Idcommand; // internal id for the corresponding command (see hotkey_id_commnand list)
|
|
|
|
public:
|
|
Ki_HotkeyInfo(const wxChar * infomsg, hotkey_id_commnand idcommand, int keycode);
|
|
};
|
|
|
|
Ki_HotkeyInfo::Ki_HotkeyInfo(const wxChar * infomsg, hotkey_id_commnand idcommand, int keycode)
|
|
{
|
|
m_KeyCode = keycode; // Key code (ascii value for ascii keys or wxWidgets code for function key
|
|
m_InfoMsg = infomsg; // info message.
|
|
m_Idcommand = idcommand; // internal id for the corresponding command (see hotkey_id_commnand list)
|
|
}
|
|
|
|
/* local variables */
|
|
/* Hotkey list: */
|
|
static Ki_HotkeyInfo HkBeginWire(wxT("begin Wire"), HK_BEGIN_WIRE, 'W');
|
|
static Ki_HotkeyInfo HkAddComponent(wxT("Add Component"), HK_ADD_NEW_COMPONENT, 'A');
|
|
static Ki_HotkeyInfo HkMirrorYComponent(wxT("Mirror Y Component"), HK_MIRROR_Y_COMPONENT, 'Y');
|
|
static Ki_HotkeyInfo HkMirrorXComponent(wxT("Mirror X Component"), HK_MIRROR_X_COMPONENT, 'X');
|
|
static Ki_HotkeyInfo HkOrientNormalComponent(wxT("Orient Normal Component"), HK_ORIENT_NORMAL_COMPONENT, 'N');
|
|
static Ki_HotkeyInfo HkRotateComponent(wxT("Rotate Component"), HK_ROTATE_COMPONENT, 'R');
|
|
static Ki_HotkeyInfo HkMoveComponent(wxT("Move Component"), HK_MOVE_COMPONENT, 'M');
|
|
static Ki_HotkeyInfo HkMove2Drag(wxT("Switch move block to drag block"), HK_MOVEBLOCK_TO_DRAGBLOCK, '\t');
|
|
static Ki_HotkeyInfo HkInsert(wxT("Repeat Last Item"), HK_REPEAT_LAST, WXK_INSERT);
|
|
static Ki_HotkeyInfo HkDelete(wxT("Delete Item"), HK_DELETE, WXK_DELETE);
|
|
static Ki_HotkeyInfo HkResetLocalCoord(wxT("Reset local coord."), HK_RESET_LOCAL_COORD, ' ');
|
|
static Ki_HotkeyInfo HkNextSearch(wxT("Next Search"), HK_NEXT_SEARCH, WXK_F5);
|
|
static Ki_HotkeyInfo HkZoomCenter(wxT("Zoom Center"), HK_ZOOM_CENTER, WXK_F4);
|
|
static Ki_HotkeyInfo HkZoomRedraw(wxT("Zoom Redraw"), HK_ZOOM_REDRAW, WXK_F3);
|
|
static Ki_HotkeyInfo HkZoomOut(wxT("Zoom Out"), HK_ZOOM_OUT, WXK_F2);
|
|
static Ki_HotkeyInfo HkZoomIn(wxT("Zoom In"), HK_ZOOM_IN, WXK_F1);
|
|
static Ki_HotkeyInfo HkHelp(wxT("Help: this message"), HK_HELP, '?');
|
|
|
|
// List of hotkey descriptors for schematic
|
|
static Ki_HotkeyInfo *s_Schematic_Hotkey_List[] = {
|
|
&HkHelp,
|
|
&HkZoomIn, &HkZoomOut, &HkZoomRedraw, &HkZoomCenter,
|
|
&HkNextSearch, &HkResetLocalCoord,
|
|
&HkDelete, &HkInsert, &HkMove2Drag,
|
|
&HkMoveComponent, &HkAddComponent,
|
|
&HkRotateComponent, &HkMirrorXComponent, &HkMirrorYComponent, & HkOrientNormalComponent,
|
|
&HkBeginWire,
|
|
NULL
|
|
};
|
|
|
|
|
|
// Library editor:
|
|
static Ki_HotkeyInfo HkInsertPin(wxT("Repeat Pin"), HK_REPEAT_LAST, WXK_INSERT);
|
|
|
|
// List of hotkey descriptors for libray editor
|
|
static Ki_HotkeyInfo *s_LibEdit_Hotkey_List[] =
|
|
{
|
|
&HkHelp,
|
|
&HkZoomIn, &HkZoomOut, &HkZoomRedraw, &HkZoomCenter,
|
|
&HkResetLocalCoord,
|
|
&HkInsertPin,
|
|
NULL
|
|
};
|
|
|
|
|
|
/****************************************************/
|
|
static wxString ReturnKeyNameFromKeyCode(int keycode)
|
|
/****************************************************/
|
|
/*
|
|
* return the key name from the key code
|
|
* Only some wxWidgets key values are handled for function key
|
|
* @param key = key code (ascii value, or wxWidgets value for function keys)
|
|
* @return the key name wxString
|
|
*/
|
|
{
|
|
wxString keyname, modifier, fullkeyname;
|
|
|
|
if ( keycode & GR_KB_CTRL) modifier << wxT("Ctrl ");
|
|
if ( keycode & GR_KB_ALT) modifier << wxT("Alt ");
|
|
if ( keycode & GR_KB_SHIFT) modifier << wxT("Shift ");
|
|
keycode &= ~(GR_KB_CTRL|GR_KB_ALT|GR_KB_SHIFT);
|
|
|
|
switch ( keycode )
|
|
{
|
|
default:
|
|
keyname.Printf(wxT("%c"), keycode);
|
|
break;
|
|
|
|
case WXK_F1:
|
|
case WXK_F2:
|
|
case WXK_F3:
|
|
case WXK_F4:
|
|
case WXK_F5:
|
|
case WXK_F6:
|
|
case WXK_F7:
|
|
case WXK_F8:
|
|
case WXK_F9:
|
|
case WXK_F10:
|
|
case WXK_F11:
|
|
case WXK_F12:
|
|
keyname.Printf(wxT("F%d"), keycode - WXK_F1 + 1);
|
|
break;
|
|
|
|
case ' ':
|
|
keyname = wxT("space");
|
|
break;
|
|
|
|
case '\t':
|
|
keyname = wxT("Tab");
|
|
break;
|
|
|
|
case WXK_DELETE:
|
|
keyname = wxT("Delete");
|
|
break;
|
|
|
|
case WXK_INSERT:
|
|
keyname = wxT("Insert");
|
|
break;
|
|
}
|
|
|
|
fullkeyname = modifier + keyname;
|
|
return keyname;
|
|
}
|
|
|
|
/****************************************************************************/
|
|
static void DisplayHotkeyList(WinEDA_DrawFrame * frame, Ki_HotkeyInfo ** List)
|
|
/*****************************************************************************/
|
|
/*
|
|
* Displays the current hotkey list
|
|
* @param frame = current open frame
|
|
* @param List = pointer to a Ki_HotkeyInfo list of commands
|
|
* @return none
|
|
*/
|
|
{
|
|
wxString keyname;
|
|
|
|
wxString msg = _("Current hotkey list:\n\n");
|
|
for ( ; * List != NULL; List++ )
|
|
{
|
|
Ki_HotkeyInfo * hk_decr = * List;
|
|
if ( hk_decr->m_InfoMsg.IsEmpty() ) break;
|
|
msg += _("key ");
|
|
keyname = ReturnKeyNameFromKeyCode(hk_decr->m_KeyCode);
|
|
msg += keyname + wxT(": ") + hk_decr->m_InfoMsg + wxT("\n");
|
|
}
|
|
DisplayInfo(frame, msg);
|
|
}
|
|
|
|
/******************************************************************/
|
|
static int GetCommandCodeFromHotkey(int key, Ki_HotkeyInfo ** List)
|
|
/******************************************************************/
|
|
/*
|
|
* Return an id identifier fron a key code for OnHotKey() function
|
|
* @param key = key code (ascii value, or wxWidgets value for function keys
|
|
* @param List = pointer to a Ki_HotkeyInfo list of commands
|
|
* @return the corresponding function identifier from the Ki_HotkeyInfo List
|
|
*/
|
|
{
|
|
for ( ; * List != NULL; List++ )
|
|
{
|
|
Ki_HotkeyInfo * hk_decr = * List;
|
|
if ( hk_decr->m_KeyCode == key ) return hk_decr->m_Idcommand;
|
|
}
|
|
|
|
return HK_NOT_FOUND;
|
|
}
|
|
|
|
/***********************************************************/
|
|
void WinEDA_SchematicFrame::OnHotKey(wxDC * DC, int hotkey,
|
|
EDA_BaseStruct * DrawStruct)
|
|
/***********************************************************/
|
|
/* Hot keys. Some commands are relatives to the item under the mouse cursor
|
|
Commands are case insensitive
|
|
Zoom commands are not managed here
|
|
*/
|
|
{
|
|
bool PopupOn = m_CurrentScreen->m_CurrentItem &&
|
|
m_CurrentScreen->m_CurrentItem->m_Flags;
|
|
bool RefreshToolBar = FALSE; // We must refresh tool bar when the undo/redo tool state is modified
|
|
|
|
if ( hotkey == 0 ) return;
|
|
|
|
wxPoint MousePos = m_CurrentScreen->m_MousePosition;
|
|
|
|
/* Convert lower to upper case (the usual toupper function has problem with non ascii codes like function keys */
|
|
if( (hotkey >= 'a') && (hotkey <= 'z') ) hotkey += 'A' - 'a';
|
|
|
|
// Search commnd from key :
|
|
switch ( GetCommandCodeFromHotkey(hotkey, s_Schematic_Hotkey_List) )
|
|
{
|
|
default:
|
|
case HK_NOT_FOUND:
|
|
return;
|
|
break;
|
|
|
|
case HK_HELP: // Display Current hotkey list
|
|
DisplayHotkeyList(this, s_Schematic_Hotkey_List);
|
|
break;
|
|
|
|
case HK_ZOOM_IN:
|
|
case HK_ZOOM_OUT:
|
|
case HK_ZOOM_REDRAW:
|
|
case HK_ZOOM_CENTER:
|
|
case HK_RESET_LOCAL_COORD:
|
|
break;
|
|
|
|
case HK_MOVEBLOCK_TO_DRAGBLOCK: // Switch to drag mode, when block moving
|
|
HandleBlockEndByPopUp(BLOCK_DRAG, DC);
|
|
break;
|
|
|
|
case HK_DELETE:
|
|
if ( PopupOn ) break;
|
|
RefreshToolBar = LocateAndDeleteItem(this, DC);
|
|
m_CurrentScreen->SetModify();
|
|
m_CurrentScreen->m_CurrentItem = NULL;
|
|
TestDanglingEnds(m_CurrentScreen->EEDrawList, DC);
|
|
break;
|
|
|
|
case HK_REPEAT_LAST:
|
|
if ( g_ItemToRepeat && (g_ItemToRepeat->m_Flags == 0) )
|
|
{
|
|
RepeatDrawItem(DC);
|
|
}
|
|
else wxBell();
|
|
break;
|
|
|
|
case HK_NEXT_SEARCH :
|
|
if ( g_LastSearchIsMarker ) WinEDA_SchematicFrame::FindMarker(1);
|
|
else FindSchematicItem(wxEmptyString, 2);
|
|
break;
|
|
|
|
case HK_ADD_NEW_COMPONENT: // Add component
|
|
if ( DrawStruct && DrawStruct->m_Flags ) break;
|
|
// switch to m_ID_current_state = ID_COMPONENT_BUTT;
|
|
if ( m_ID_current_state != ID_COMPONENT_BUTT ) SetToolID( ID_COMPONENT_BUTT, wxCURSOR_PENCIL, _("Add Component"));
|
|
OnLeftClick(DC, MousePos);
|
|
break;
|
|
|
|
case HK_BEGIN_WIRE: // Add wire
|
|
if ( DrawStruct ) // An item is selected. If edited and not a wire, a new command is not possible
|
|
{
|
|
if ( DrawStruct->m_Flags ) // Item selected and edition in progress
|
|
{
|
|
if (DrawStruct->m_StructType == DRAW_SEGMENT_STRUCT_TYPE )
|
|
{
|
|
EDA_DrawLineStruct * segment = (EDA_DrawLineStruct *)DrawStruct;
|
|
if ( segment->m_Layer != LAYER_WIRE ) break;
|
|
}
|
|
else break;
|
|
}
|
|
}
|
|
// switch to m_ID_current_state = ID_WIRE_BUTT;
|
|
if ( m_ID_current_state != ID_WIRE_BUTT ) SetToolID( ID_WIRE_BUTT, wxCURSOR_PENCIL, _("Add Wire"));
|
|
OnLeftClick(DC, MousePos);
|
|
break;
|
|
|
|
case HK_ROTATE_COMPONENT: // Component Rotation
|
|
if ( DrawStruct == NULL )
|
|
{
|
|
DrawStruct = PickStruct( GetScreen()->m_Curseur,
|
|
GetScreen()->EEDrawList, LIBITEM|TEXTITEM|LABELITEM );
|
|
if ( DrawStruct == NULL ) break;
|
|
if ( DrawStruct->m_StructType == DRAW_LIB_ITEM_STRUCT_TYPE )
|
|
DrawStruct = LocateSmallestComponent( GetScreen() );
|
|
if ( DrawStruct == NULL ) break;
|
|
}
|
|
switch (DrawStruct->m_StructType)
|
|
{
|
|
case DRAW_LIB_ITEM_STRUCT_TYPE:
|
|
if ( DrawStruct->m_Flags == 0 )
|
|
{
|
|
SaveCopyInUndoList(DrawStruct, IS_CHANGED);
|
|
RefreshToolBar = TRUE;
|
|
}
|
|
|
|
CmpRotationMiroir(
|
|
(EDA_SchComponentStruct *) DrawStruct, DC, CMP_ROTATE_COUNTERCLOCKWISE );
|
|
break;
|
|
|
|
case DRAW_TEXT_STRUCT_TYPE:
|
|
case DRAW_LABEL_STRUCT_TYPE:
|
|
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
|
|
if ( DrawStruct->m_Flags == 0 )
|
|
{
|
|
SaveCopyInUndoList(DrawStruct, IS_CHANGED);
|
|
RefreshToolBar = TRUE;
|
|
}
|
|
ChangeTextOrient( (DrawTextStruct*)DrawStruct, DC);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case HK_MIRROR_Y_COMPONENT: // Mirror Y (Component)
|
|
if ( DrawStruct == NULL )
|
|
DrawStruct = LocateSmallestComponent( GetScreen() );
|
|
if ( DrawStruct )
|
|
{
|
|
if ( DrawStruct->m_Flags == 0 )
|
|
{
|
|
SaveCopyInUndoList(DrawStruct, IS_CHANGED);
|
|
RefreshToolBar = TRUE;
|
|
}
|
|
CmpRotationMiroir(
|
|
(EDA_SchComponentStruct *) DrawStruct, DC, CMP_MIROIR_Y );
|
|
}
|
|
break;
|
|
|
|
case HK_MIRROR_X_COMPONENT: // Mirror X (Component)
|
|
if ( DrawStruct == NULL )
|
|
DrawStruct = LocateSmallestComponent( GetScreen() );
|
|
if ( DrawStruct )
|
|
{
|
|
if ( DrawStruct->m_Flags == 0 )
|
|
{
|
|
SaveCopyInUndoList(DrawStruct, IS_CHANGED);
|
|
RefreshToolBar = TRUE;
|
|
}
|
|
CmpRotationMiroir(
|
|
(EDA_SchComponentStruct *) DrawStruct, DC, CMP_MIROIR_X );
|
|
}
|
|
break;
|
|
|
|
case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component)
|
|
if ( DrawStruct == NULL )
|
|
DrawStruct = LocateSmallestComponent( GetScreen() );
|
|
if ( DrawStruct )
|
|
{
|
|
if ( DrawStruct->m_Flags == 0 )
|
|
{
|
|
SaveCopyInUndoList(DrawStruct, IS_CHANGED);
|
|
RefreshToolBar = TRUE;
|
|
}
|
|
CmpRotationMiroir(
|
|
(EDA_SchComponentStruct *) DrawStruct, DC, CMP_NORMAL );
|
|
TestDanglingEnds(m_CurrentScreen->EEDrawList, DC);
|
|
}
|
|
break;
|
|
|
|
case HK_MOVE_COMPONENT: // Start move Component
|
|
if ( PopupOn ) break;
|
|
if ( DrawStruct == NULL )
|
|
DrawStruct = LocateSmallestComponent( GetScreen() );
|
|
if ( DrawStruct && (DrawStruct->m_Flags ==0) )
|
|
{
|
|
m_CurrentScreen->m_CurrentItem = DrawStruct;
|
|
Process_Move_Item(m_CurrentScreen->m_CurrentItem, DC);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ( RefreshToolBar ) SetToolbars();
|
|
}
|
|
|
|
|
|
/***********************************************************/
|
|
void WinEDA_LibeditFrame::OnHotKey(wxDC * DC, int hotkey,
|
|
EDA_BaseStruct * DrawStruct)
|
|
/***********************************************************/
|
|
/* Hot keys for the component editot. Some commands are relatives to the item under the mouse cursor
|
|
Commands are case insensitive
|
|
Zoom commands are not managed here
|
|
*/
|
|
{
|
|
bool PopupOn = m_CurrentScreen->m_CurrentItem &&
|
|
m_CurrentScreen->m_CurrentItem->m_Flags;
|
|
|
|
bool RefreshToolBar = FALSE; // We must refresh tool bar when the undo/redo tool state is modified
|
|
|
|
if ( hotkey == 0 ) return;
|
|
|
|
wxPoint MousePos = m_CurrentScreen->m_MousePosition;
|
|
|
|
/* Convert lower to upper case (the usual toupper function has problem with non ascii codes like function keys */
|
|
if( (hotkey >= 'a') && (hotkey <= 'z') ) hotkey += 'A' - 'a';
|
|
switch ( GetCommandCodeFromHotkey(hotkey, s_LibEdit_Hotkey_List) )
|
|
{
|
|
default:
|
|
case HK_NOT_FOUND:
|
|
return;
|
|
break;
|
|
|
|
case HK_HELP: // Display Current hotkey list
|
|
DisplayHotkeyList(this, s_LibEdit_Hotkey_List);
|
|
break;
|
|
|
|
case HK_ZOOM_IN:
|
|
case HK_ZOOM_OUT:
|
|
case HK_ZOOM_REDRAW:
|
|
case HK_ZOOM_CENTER:
|
|
case HK_RESET_LOCAL_COORD:
|
|
break;
|
|
|
|
case HK_REPEAT_LAST:
|
|
if ( LibItemToRepeat && (LibItemToRepeat->m_Flags == 0) &&
|
|
(LibItemToRepeat->m_StructType == COMPONENT_PIN_DRAW_TYPE) )
|
|
{
|
|
RepeatPinItem(DC, (LibDrawPin*) LibItemToRepeat);
|
|
}
|
|
else wxBell();
|
|
break;
|
|
}
|
|
|
|
if ( RefreshToolBar ) SetToolbars();
|
|
}
|
|
|