1
////////////////////////////////////////////////////////////////////////////
2
// NoteCase notes manager project <http://notecase.sf.net>
4
// This code is licensed under BSD license.See "license.txt" for more details.
6
// File: Implements list of keyboard shortcuts for program actions
7
////////////////////////////////////////////////////////////////////////////
9
#include "ShortcutsList.h"
10
#include "lib/IniFile.h"
12
#include <gdk/gdkkeysyms.h>
13
#include "lib/debug.h"
15
extern IniFile g_objIni;
17
bool g_bListInited = false;
18
ShortcutsList g_lstDefAction;
20
std::string ShortcutDef::GetDisplayString()
24
//format modifier keys
28
strMsg += _("Shift+");
33
guint32 cLetter = gdk_keyval_to_unicode (m_nKey);
39
strMsg += g_ascii_toupper(cLetter);
41
else if(m_nKey != GDK_Control_L &&
42
m_nKey != GDK_Control_R &&
43
m_nKey != GDK_Shift_L &&
44
m_nKey != GDK_Shift_R &&
45
m_nKey != GDK_Alt_L &&
48
if(gdk_keyval_name(m_nKey))
49
strMsg += gdk_keyval_name(m_nKey);
55
int ShortcutDef::GetModifierFlags()
59
nRes |= GDK_CONTROL_MASK;
61
nRes |= GDK_SHIFT_MASK;
63
nRes |= GDK_MOD1_MASK;
68
bool ShortcutDef::Match(GdkEventKey *evnt)
71
if(evnt->keyval == (unsigned int)m_nKey){
72
unsigned int nFlags = GetModifierFlags();
73
if(nFlags == (evnt->state & nFlags))
80
bool ShortcutDef::IsValid(int nContext)
82
//key must be valid - non-modifier code
84
m_nKey == GDK_Control_L ||
85
m_nKey == GDK_Control_R ||
86
m_nKey == GDK_Shift_L ||
87
m_nKey == GDK_Shift_R ||
88
m_nKey == GDK_Alt_L ||
92
//at least one modifier required (global shortcuts only)
93
if(SH_CTX_GLOBAL == nContext)
94
if(!m_bModCtrl && !m_bModShift && !m_bModAlt)
100
bool ShortcutDef::operator ==(const ShortcutDef &other)
102
return (m_nKey == other.m_nKey &&
103
m_bModShift == other.m_bModShift &&
104
m_bModCtrl == other.m_bModCtrl &&
105
m_bModAlt == other.m_bModAlt);
108
ShortcutsList::ShortcutsList()
112
//g_bListInited = true;
113
g_lstDefAction.clear();
114
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_DOC_NEW, _("New Document"), 'N', false, true, false));
115
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_DOC_OPEN, _("Open Document"), 'O', false, true, false));
116
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_DOC_SAVE, _("Save Document"), 'S', false, true, false));
117
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_DOC_SAVE_AS, _("Save As Document"), 0, false, false, false));
118
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_DOC_RELOAD, _("Reload Document"), 'R', false, true, false));
119
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_DOC_IMPORT, _("Import"), 0, false, false, false));
120
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_DOC_EXPORT, _("Export"), 'E', false, true, false));
121
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_APP_NEW, _("New Notecase"), 0, false, false, false));
122
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_APP_QUIT, _("Quit Notecase"), 'Q', false, true, false));
123
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_NEW, _("New Node"), 0, false, false, false));
124
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_NEW_CHILD, _("New Child Node"), 0, false, false, false));
125
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_DELETE, _("Delete Node"), 0, false, false, false));
126
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_RENAME, _("Rename Node"), 'M', false, true, false));
127
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_MOVE_UP, _("Move Node Up"), 0, false, false, false));
128
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_MOVE_DOWN, _("Move Node Down"), 0, false, false, false));
129
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_MOVE_LEFT, _("Move Node Left"), 0, false, false, false));
130
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_MOVE_RIGHT, _("Move Node Right"), 0, false, false, false));
131
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_PROPERTIES, _("Show Node Properties"), 0, false, false, false));
132
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_DELETE_FINISHED, _("Delete Finished Nodes"), 0, false, false, false));
133
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_NODE_TOGGLE_FINISHED, _("Toggle Finished Status"), 0, false, false, false));
134
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_SORT_CHILDREN_ASC, _("Sort Children Ascending"), 0, false, false, false));
135
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_SORT_CHILDREN_DESC, _("Sort Children Descending"), 0, false, false, false));
136
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_SORT_ROOT_ASC, _("Sort Tree Ascending"), 0, false, false, false));
137
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_SORT_ROOT_DESC, _("Sort Tree Descending"), 0, false, false, false));
138
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_EXPAND_ALL, _("Expand All"), 0, false, false, false));
139
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_TREE_COLAPSE_ALL, _("Colapse All"), 0, false, false, false));
140
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_UNDO, _("Undo"), 'Z', false, true, false));
141
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_REDO, _("Redo"), 'Y', false, true, false));
142
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_CUT, _("Cut"), 'X', false, true, false));
143
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_COPY, _("Copy"), 'C', false, true, false));
144
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_PASTE, _("Paste"), 'V', false, true, false));
145
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_DELETE, _("Delete"), 0, false, false, false));
146
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_COPY_BR_STRUCT, _("Copy Branch Structure"), 0, false, false, false));
147
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_PASTE_BR_ROOT, _("Paste Branch Root"), 0, false, false, false));
148
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_INSERT_DATETIME, _("Insert date/time"), 'T', true, true, false));
149
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_FIND, _("Find"), 'F', false, true, false));
150
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_FIND_NEXT, _("Find Next"), GDK_F3, false, false, false));
151
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_REPLACE, _("Replace"), 'H', false, true, false));
152
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_LINK_WIZARD, _("Link Wizard"), 'L', false, true, false));
153
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_INSERT_PICTURE, _("Insert Picture"), 0, false, false, false));
154
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_ATTACHMENTS, _("Attachments"), 0, false, false, false));
155
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_SHORTCUTS, _("Shortcuts"), 'K', true, false, false));
156
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_EDIT_OPTIONS, _("Options"), GDK_F7, false, false, false));
157
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_FORMAT_BOLD, _("Bold"), 'B', false, true, false));
158
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_FORMAT_ITALIC, _("Italic"), 'I', false, true, false));
159
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_FORMAT_UNDERLINE, _("Underline"), 'U', false, true, false));
160
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_FORMAT_STRIKETHROUGH, _("Strikethrough"), 0, false, false, false));
161
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_FORMAT_COLOR, _("Color"), 0, false, false, false));
162
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_FORMAT_REMOVE, _("Remove Formatting"), 0, false, false, false));
163
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_VIEW_TOOLBAR, _("View Toolbar"), 0, false, false, false));
164
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_VIEW_NODE_TITLEBAR, _("View Node Title Bar"), 0, false, false, false));
165
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_VIEW_STATUS_BAR, _("View Status Bar"), 0, false, false, false));
166
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_VIEW_WRAP, _("Word Wrap"), 'W', false, true, false));
167
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_VIEW_CHANGE_MODE, _("Change View Mode"), 'T', false, true, false));
168
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_VIEW_WORD_COUNT, _("Calculate Word Count"), 'K', false, true, false));
169
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_HELP_INDEX, _("Show help"), GDK_F1, false, false, false));
170
g_lstDefAction.push_back(ShortcutDef(SH_CTX_GLOBAL, NC_ACTION_HELP_ABOUT, _("About"), 0, false, false, false));
173
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_NEW, _("New Node"), GDK_Insert, false, false, false));
174
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_NEW_CHILD, _("New Child Node"), GDK_Insert, true, false, false));
175
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_DELETE, _("Delete Node"), GDK_Delete, false, false, false));
176
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_RENAME, _("Rename Node"), GDK_F2, false, false, false));
177
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_MOVE_UP, _("Move Node Up"), GDK_Up, true, false, false));
178
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_MOVE_DOWN, _("Move Node Down"), GDK_Down, true, false, false));
179
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_MOVE_LEFT, _("Move Node Left"), GDK_Left, true, false, false));
180
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_MOVE_RIGHT, _("Move Node Right"), GDK_Right, true, false, false));
181
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_PROPERTIES, _("Show Node Properties"), GDK_Return, false, true, false));
182
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_DELETE_FINISHED, _("Delete Finished Nodes"), 0, false, false, false));
183
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_NODE_TOGGLE_FINISHED, _("Toggle Finished Status"), ' ', false, false, false));
184
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_SORT_CHILDREN_ASC, _("Sort Children Ascending"), 0, false, false, false));
185
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_SORT_CHILDREN_DESC, _("Sort Children Descending"), 0, false, false, false));
186
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_SORT_ROOT_ASC, _("Sort Tree Ascending"), 0, false, false, false));
187
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_SORT_ROOT_DESC, _("Sort Tree Descending"), 0, false, false, false));
188
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_EXPAND_ALL, _("Expand All"), 0, false, false, false));
189
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_TREE_COLAPSE_ALL, _("Colapse All"), 0, false, false, false));
190
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_EDIT_COPY_BR_STRUCT, _("Copy Branch Structure"), 0, false, false, false));
191
g_lstDefAction.push_back(ShortcutDef(SH_CTX_TREE_WIDGET, NC_ACTION_EDIT_PASTE_BR_ROOT, _("Paste Branch Root"), 0, false, false, false));
195
ShortcutsList::~ShortcutsList()
199
bool ShortcutsList::Load()
205
g_objIni.GetValue("Shortcuts", "NumEntries", nEntries);
207
for(int i=0; i<nEntries; i++)
213
sprintf(szKey, "ModShift_%d", i+1);
214
g_objIni.GetValue("Shortcuts", szKey, bValue);
215
info.m_bModShift = bValue; //FIX: VS2005 complains when using directly without temp variable
216
sprintf(szKey, "ModCtrl_%d", i+1);
217
g_objIni.GetValue("Shortcuts", szKey, bValue);
218
info.m_bModCtrl = bValue;
219
sprintf(szKey, "ModAlt_%d", i+1);
220
g_objIni.GetValue("Shortcuts", szKey, bValue);
221
info.m_bModAlt = bValue;
222
sprintf(szKey, "Key_%d", i+1);
223
g_objIni.GetValue("Shortcuts", szKey, info.m_nKey, 0);
224
sprintf(szKey, "ActionID_%d", i+1);
225
g_objIni.GetValue("Shortcuts", szKey, info.m_nActionID, 0);
226
sprintf(szKey, "Context_%d", i+1);
227
g_objIni.GetValue("Shortcuts", szKey, info.m_nCtx, 0);
229
//forbid invalid and duplicate shortcuts
230
if( info.IsValid(info.m_nCtx) /*&&
231
FindByKey(info) < 0*/)
240
bool ShortcutsList::Save()
242
int nEntries = size();
243
g_objIni.SetValue("Shortcuts", "NumEntries", nEntries);
245
for(int i=0; i<nEntries; i++)
248
ShortcutDef &info = operator[](i);
250
sprintf(szKey, "ModShift_%d", i+1);
251
g_objIni.SetValue("Shortcuts", szKey, info.m_bModShift);
252
sprintf(szKey, "ModCtrl_%d", i+1);
253
g_objIni.SetValue("Shortcuts", szKey, info.m_bModCtrl);
254
sprintf(szKey, "ModAlt_%d", i+1);
255
g_objIni.SetValue("Shortcuts", szKey, info.m_bModAlt);
256
sprintf(szKey, "Key_%d", i+1);
257
g_objIni.SetValue("Shortcuts", szKey, info.m_nKey);
258
sprintf(szKey, "ActionID_%d", i+1);
259
g_objIni.SetValue("Shortcuts", szKey, info.m_nActionID);
260
sprintf(szKey, "Context_%d", i+1);
261
g_objIni.SetValue("Shortcuts", szKey, info.m_nCtx);
267
int ShortcutsList::FindByKey(ShortcutDef &key, int nSkipLine, int nActionID)
270
for(int i=0; i<nMax; i++)
272
if(i != nSkipLine && operator[](i) == key)
274
//check if action matches (if required)
275
if(nActionID >= 0 && operator[](i).m_nActionID != key.m_nActionID)
283
int ShortcutsList::FindByAction(int nActionID, int nCtx)
286
for(int i=0; i<nMax; i++)
287
if( operator[](i).m_nActionID == nActionID &&
288
operator[](i).m_nCtx == nCtx)
293
void ShortcutsList::UpdateAction(ShortcutDef &key)
295
int nPos = FindByAction(key.m_nActionID, key.m_nCtx);
297
operator[](nPos) = key;
302
void ShortcutsList::ClearAction(int nActionID, int nCtx)
304
int nPos = FindByAction(nActionID, nCtx);
306
erase(begin() + nPos);
309
int ShortcutsList::FindByContext(int nCtx, int nIdx)
312
for(int i=0; i<nMax; i++)
313
if(operator[](i).m_nCtx == nCtx) //return on first proper context (guess the index)