Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
4be876a1
Commit
4be876a1
authored
Apr 30, 2015
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Expandable CONTEXT_MENUs (GAL). Minor CONTEXT_MENU
parent
946b9d19
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
114 additions
and
86 deletions
+114
-86
context_menu.cpp
common/tool/context_menu.cpp
+83
-56
context_menu.h
include/tool/context_menu.h
+19
-22
router_tool.cpp
pcbnew/router/router_tool.cpp
+2
-2
selection_tool.cpp
pcbnew/tools/selection_tool.cpp
+7
-5
selection_tool.h
pcbnew/tools/selection_tool.h
+3
-1
No files found.
common/tool/context_menu.cpp
View file @
4be876a1
...
@@ -33,14 +33,11 @@
...
@@ -33,14 +33,11 @@
CONTEXT_MENU
::
CONTEXT_MENU
()
:
CONTEXT_MENU
::
CONTEXT_MENU
()
:
m_titleSet
(
false
),
m_selected
(
-
1
),
m_tool
(
NULL
),
m_icon
(
NULL
)
m_titleSet
(
false
),
m_selected
(
-
1
),
m_tool
(
NULL
),
m_icon
(
NULL
)
{
{
setCustomEventHandler
(
boost
::
bind
(
&
CONTEXT_MENU
::
handleCustomEvent
,
this
,
_1
)
);
setupEvents
();
setupEvents
();
}
}
CONTEXT_MENU
::
CONTEXT_MENU
(
const
CONTEXT_MENU
&
aMenu
)
:
CONTEXT_MENU
::
CONTEXT_MENU
(
const
CONTEXT_MENU
&
aMenu
)
m_titleSet
(
aMenu
.
m_titleSet
),
m_selected
(
-
1
),
m_tool
(
aMenu
.
m_tool
),
m_toolActions
(
aMenu
.
m_toolActions
),
m_customHandler
(
aMenu
.
m_customHandler
)
{
{
copyFrom
(
aMenu
);
copyFrom
(
aMenu
);
setupEvents
();
setupEvents
();
...
@@ -51,12 +48,6 @@ CONTEXT_MENU& CONTEXT_MENU::operator=( const CONTEXT_MENU& aMenu )
...
@@ -51,12 +48,6 @@ CONTEXT_MENU& CONTEXT_MENU::operator=( const CONTEXT_MENU& aMenu )
{
{
Clear
();
Clear
();
m_titleSet
=
aMenu
.
m_titleSet
;
m_selected
=
aMenu
.
m_selected
;
m_tool
=
aMenu
.
m_tool
;
m_toolActions
=
aMenu
.
m_toolActions
;
m_customHandler
=
aMenu
.
m_customHandler
;
copyFrom
(
aMenu
);
copyFrom
(
aMenu
);
setupEvents
();
setupEvents
();
...
@@ -90,7 +81,7 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
...
@@ -90,7 +81,7 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
}
}
void
CONTEXT_MENU
::
Add
(
const
wxString
&
aLabel
,
int
aId
,
const
BITMAP_OPAQUE
*
aIcon
)
wxMenuItem
*
CONTEXT_MENU
::
Add
(
const
wxString
&
aLabel
,
int
aId
,
const
BITMAP_OPAQUE
*
aIcon
)
{
{
#ifdef DEBUG
#ifdef DEBUG
...
@@ -103,18 +94,18 @@ void CONTEXT_MENU::Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aI
...
@@ -103,18 +94,18 @@ void CONTEXT_MENU::Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aI
if
(
aIcon
)
if
(
aIcon
)
item
->
SetBitmap
(
KiBitmap
(
aIcon
)
);
item
->
SetBitmap
(
KiBitmap
(
aIcon
)
);
Append
(
item
);
return
Append
(
item
);
}
}
void
CONTEXT_MENU
::
Add
(
const
TOOL_ACTION
&
aAction
)
wxMenuItem
*
CONTEXT_MENU
::
Add
(
const
TOOL_ACTION
&
aAction
)
{
{
/// ID numbers for tool actions need to have a value higher than
m_actionId
/// ID numbers for tool actions need to have a value higher than
ACTION_ID
int
id
=
m_actionId
+
aAction
.
GetId
();
int
id
=
ACTION_ID
+
aAction
.
GetId
();
const
BITMAP_OPAQUE
*
icon
=
aAction
.
GetIcon
();
const
BITMAP_OPAQUE
*
icon
=
aAction
.
GetIcon
();
wxMenuItem
*
item
=
new
wxMenuItem
(
this
,
id
,
wxMenuItem
*
item
=
new
wxMenuItem
(
this
,
id
,
aAction
.
GetMenuItem
(),
aAction
.
GetMenuItem
(),
aAction
.
GetDescription
(),
wxITEM_NORMAL
);
aAction
.
GetDescription
(),
wxITEM_NORMAL
);
if
(
icon
)
if
(
icon
)
item
->
SetBitmap
(
KiBitmap
(
icon
)
);
item
->
SetBitmap
(
KiBitmap
(
icon
)
);
...
@@ -136,24 +127,45 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
...
@@ -136,24 +127,45 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
item
->
SetAccel
(
&
accel
);
item
->
SetAccel
(
&
accel
);
}
}
Append
(
item
);
m_toolActions
[
id
]
=
&
aAction
;
m_toolActions
[
id
]
=
&
aAction
;
return
Append
(
item
);
}
}
void
CONTEXT_MENU
::
Add
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
)
std
::
list
<
wxMenuItem
*>
CONTEXT_MENU
::
Add
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
,
bool
aExpand
)
{
{
if
(
aMenu
->
m_icon
)
std
::
list
<
wxMenuItem
*>
items
;
if
(
aExpand
)
{
{
wxMenuItem
*
newItem
=
new
wxMenuItem
(
this
,
-
1
,
aLabel
,
wxEmptyString
,
wxITEM_NORMAL
);
unsigned
int
i
=
0
;
newItem
->
SetBitmap
(
KiBitmap
(
aMenu
->
m_icon
)
);
newItem
->
SetSubMenu
(
aMenu
);
for
(
i
=
0
;
i
<
aMenu
->
GetMenuItemCount
();
++
i
)
Append
(
newItem
);
{
wxMenuItem
*
item
=
aMenu
->
FindItemByPosition
(
i
);
items
.
push_back
(
appendCopy
(
item
)
);
}
}
}
else
else
{
{
AppendSubMenu
(
aMenu
,
aLabel
);
if
(
aMenu
->
m_icon
)
{
wxMenuItem
*
newItem
=
new
wxMenuItem
(
this
,
-
1
,
aLabel
,
wxEmptyString
,
wxITEM_NORMAL
);
newItem
->
SetBitmap
(
KiBitmap
(
aMenu
->
m_icon
)
);
newItem
->
SetSubMenu
(
aMenu
);
items
.
push_back
(
Append
(
newItem
)
);
}
else
{
items
.
push_back
(
AppendSubMenu
(
aMenu
,
aLabel
)
);
}
}
}
m_toolActions
.
insert
(
aMenu
->
m_toolActions
.
begin
(),
aMenu
->
m_toolActions
.
end
()
);
m_handlers
.
insert
(
m_handlers
.
end
(),
aMenu
->
m_handlers
.
begin
(),
aMenu
->
m_handlers
.
end
()
);
return
items
;
}
}
...
@@ -164,6 +176,7 @@ void CONTEXT_MENU::Clear()
...
@@ -164,6 +176,7 @@ void CONTEXT_MENU::Clear()
GetMenuItems
().
DeleteContents
(
true
);
GetMenuItems
().
DeleteContents
(
true
);
GetMenuItems
().
Clear
();
GetMenuItems
().
Clear
();
m_toolActions
.
clear
();
m_toolActions
.
clear
();
m_handlers
.
clear
();
GetMenuItems
().
DeleteContents
(
false
);
// restore the default so destructor does not go wild
GetMenuItems
().
DeleteContents
(
false
);
// restore the default so destructor does not go wild
assert
(
GetMenuItemCount
()
==
0
);
assert
(
GetMenuItemCount
()
==
0
);
...
@@ -211,7 +224,14 @@ void CONTEXT_MENU::onMenuEvent( wxMenuEvent& aEvent )
...
@@ -211,7 +224,14 @@ void CONTEXT_MENU::onMenuEvent( wxMenuEvent& aEvent )
}
}
}
}
#endif
#endif
evt
=
m_customHandler
(
aEvent
);
for
(
std
::
list
<
CUSTOM_MENU_HANDLER
>::
iterator
it
=
m_handlers
.
begin
();
it
!=
m_handlers
.
end
();
++
it
)
{
evt
=
(
*
it
)(
aEvent
);
if
(
evt
)
break
;
}
// Handling non-action menu entries (e.g. items in clarification list)
// Handling non-action menu entries (e.g. items in clarification list)
if
(
!
evt
)
if
(
!
evt
)
...
@@ -244,49 +264,56 @@ void CONTEXT_MENU::setTool( TOOL_INTERACTIVE* aTool )
...
@@ -244,49 +264,56 @@ void CONTEXT_MENU::setTool( TOOL_INTERACTIVE* aTool )
}
}
void
CONTEXT_MENU
::
copyItem
(
const
wxMenuItem
*
aSource
,
wxMenuItem
*
aDest
)
const
wxMenuItem
*
CONTEXT_MENU
::
appendCopy
(
const
wxMenuItem
*
aSource
)
{
{
assert
(
!
aSource
->
IsSubMenu
()
);
// it does not transfer submenus
wxMenuItem
*
newItem
=
new
wxMenuItem
(
this
,
aSource
->
GetId
(),
aSource
->
GetItemLabel
(),
aSource
->
GetHelp
(),
aSource
->
GetKind
()
);
if
(
aSource
->
GetKind
()
==
wxITEM_NORMAL
)
newItem
->
SetBitmap
(
aSource
->
GetBitmap
()
);
if
(
aSource
->
IsSubMenu
()
)
{
#ifdef DEBUG
// Submenus of a CONTEXT_MENU are supposed to be CONTEXT_MENUs as well
assert
(
dynamic_cast
<
CONTEXT_MENU
*>
(
aSource
->
GetSubMenu
()
)
);
#endif
CONTEXT_MENU
*
menu
=
new
CONTEXT_MENU
(
static_cast
<
const
CONTEXT_MENU
&>
(
*
aSource
->
GetSubMenu
()
)
);
newItem
->
SetSubMenu
(
menu
);
Append
(
newItem
);
m_toolActions
.
insert
(
menu
->
m_toolActions
.
begin
(),
menu
->
m_toolActions
.
end
()
);
m_handlers
.
insert
(
m_handlers
.
end
(),
menu
->
m_handlers
.
begin
(),
menu
->
m_handlers
.
end
()
);
}
else
{
Append
(
newItem
);
newItem
->
SetKind
(
aSource
->
GetKind
()
);
newItem
->
SetHelp
(
aSource
->
GetHelp
()
);
newItem
->
Enable
(
aSource
->
IsEnabled
()
);
aDest
->
SetKind
(
aSource
->
GetKind
()
);
if
(
aSource
->
IsCheckable
()
)
aDest
->
SetHelp
(
aSource
->
GetHelp
()
);
newItem
->
Check
(
aSource
->
IsChecked
()
);
aDest
->
Enable
(
aSource
->
IsEnabled
()
);
}
if
(
aSource
->
IsCheckable
()
)
return
newItem
;
aDest
->
Check
(
aSource
->
IsChecked
()
);
}
}
void
CONTEXT_MENU
::
copyFrom
(
const
CONTEXT_MENU
&
aMenu
)
void
CONTEXT_MENU
::
copyFrom
(
const
CONTEXT_MENU
&
aMenu
)
{
{
m_icon
=
aMenu
.
m_icon
;
m_icon
=
aMenu
.
m_icon
;
m_titleSet
=
aMenu
.
m_titleSet
;
m_selected
=
-
1
;
// aMenu.m_selected;
m_tool
=
aMenu
.
m_tool
;
m_toolActions
=
aMenu
.
m_toolActions
;
m_handlers
=
aMenu
.
m_handlers
;
// Copy all the menu entries
// Copy all the menu entries
for
(
unsigned
i
=
0
;
i
<
aMenu
.
GetMenuItemCount
();
++
i
)
for
(
unsigned
i
=
0
;
i
<
aMenu
.
GetMenuItemCount
();
++
i
)
{
{
wxMenuItem
*
item
=
aMenu
.
FindItemByPosition
(
i
);
wxMenuItem
*
item
=
aMenu
.
FindItemByPosition
(
i
);
appendCopy
(
item
);
wxMenuItem
*
newItem
=
new
wxMenuItem
(
this
,
item
->
GetId
(),
item
->
GetItemLabel
(),
item
->
GetHelp
(),
item
->
GetKind
()
);
if
(
item
->
GetKind
()
==
wxITEM_NORMAL
)
newItem
->
SetBitmap
(
item
->
GetBitmap
()
);
if
(
item
->
IsSubMenu
()
)
{
#ifdef DEBUG
// Submenus of a CONTEXT_MENU are supposed to be CONTEXT_MENUs as well
assert
(
dynamic_cast
<
CONTEXT_MENU
*>
(
item
->
GetSubMenu
()
)
);
#endif
CONTEXT_MENU
*
menu
=
new
CONTEXT_MENU
(
static_cast
<
const
CONTEXT_MENU
&>
(
*
item
->
GetSubMenu
()
)
);
newItem
->
SetSubMenu
(
menu
);
Append
(
newItem
);
}
else
{
Append
(
newItem
);
copyItem
(
item
,
newItem
);
}
}
}
}
}
include/tool/context_menu.h
View file @
4be876a1
...
@@ -77,7 +77,7 @@ public:
...
@@ -77,7 +77,7 @@ public:
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
* @param aIcon is an optional icon.
* @param aIcon is an optional icon.
*/
*/
void
Add
(
const
wxString
&
aLabel
,
int
aId
,
const
BITMAP_OPAQUE
*
aIcon
=
NULL
);
wxMenuItem
*
Add
(
const
wxString
&
aLabel
,
int
aId
,
const
BITMAP_OPAQUE
*
aIcon
=
NULL
);
/**
/**
* Function Add()
* Function Add()
...
@@ -85,7 +85,7 @@ public:
...
@@ -85,7 +85,7 @@ public:
* a TOOL_EVENT command containing name of the action is sent.
* a TOOL_EVENT command containing name of the action is sent.
* @param aAction is the action to be added to menu entry.
* @param aAction is the action to be added to menu entry.
*/
*/
void
Add
(
const
TOOL_ACTION
&
aAction
);
wxMenuItem
*
Add
(
const
TOOL_ACTION
&
aAction
);
/**
/**
* Function Add()
* Function Add()
...
@@ -93,8 +93,10 @@ public:
...
@@ -93,8 +93,10 @@ public:
* is the capability to handle icons.
* is the capability to handle icons.
* @param aMenu is the submenu to be added.
* @param aMenu is the submenu to be added.
* @param aLabel is the caption displayed for the menu entry.
* @param aLabel is the caption displayed for the menu entry.
* @param aExpand allows to add all entries from the menu as individual entries rather than
* add everything as a submenu.
*/
*/
void
Add
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
);
std
::
list
<
wxMenuItem
*>
Add
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
,
bool
aExpand
=
false
);
/**
/**
* Function Clear()
* Function Clear()
...
@@ -114,23 +116,21 @@ public:
...
@@ -114,23 +116,21 @@ public:
return
m_selected
;
return
m_selected
;
}
}
protected
:
///> Function type to handle menu events in a custom way.
void
setCustomEventHandler
(
boost
::
function
<
OPT_TOOL_EVENT
(
const
wxMenuEvent
&
)
>
aHandler
)
typedef
boost
::
function
<
OPT_TOOL_EVENT
(
const
wxMenuEvent
&
)
>
CUSTOM_MENU_HANDLER
;
{
m_customHandler
=
aHandler
;
}
virtual
OPT_TOOL_EVENT
handleCustomEvent
(
const
wxMenuEvent
&
aEvent
)
///> Adds an event handler to the custom menu event handlers chain.
void
AppendCustomEventHandler
(
CUSTOM_MENU_HANDLER
aHandler
)
{
{
return
OPT_TOOL_EVENT
(
);
m_handlers
.
push_back
(
aHandler
);
}
}
private
:
private
:
/**
/**
* Function
copyItem
* Function
appendCopy
*
Copies all properties of a menu entry to another
.
*
Appends a copy of wxMenuItem
.
*/
*/
void
copyItem
(
const
wxMenuItem
*
aSource
,
wxMenuItem
*
aDest
)
const
;
wxMenuItem
*
appendCopy
(
const
wxMenuItem
*
aSource
)
;
///> Common part of copy constructor and assignment operator.
///> Common part of copy constructor and assignment operator.
void
copyFrom
(
const
CONTEXT_MENU
&
aMenu
);
void
copyFrom
(
const
CONTEXT_MENU
&
aMenu
);
...
@@ -154,22 +154,19 @@ private:
...
@@ -154,22 +154,19 @@ private:
///> Stores the id number of selected item.
///> Stores the id number of selected item.
int
m_selected
;
int
m_selected
;
///> Instance of menu event handler.
//CMEventHandler m_handler;
///> Creator of the menu
///> Creator of the menu
TOOL_INTERACTIVE
*
m_tool
;
TOOL_INTERACTIVE
*
m_tool
;
/// Menu items with ID higher than that are considered TOOL_ACTIONs
///
>
Menu items with ID higher than that are considered TOOL_ACTIONs
static
const
int
m_actionId
=
1
0000
;
static
const
int
ACTION_ID
=
3
0000
;
/// Associates tool actions with menu item IDs. Non-owning.
///
>
Associates tool actions with menu item IDs. Non-owning.
std
::
map
<
int
,
const
TOOL_ACTION
*>
m_toolActions
;
std
::
map
<
int
,
const
TOOL_ACTION
*>
m_toolActions
;
///
Custom events handler, allows to translate wxEvents to TOOL_EVENT
s.
///
> Chain of custom menu event handler
s.
boost
::
function
<
OPT_TOOL_EVENT
(
const
wxMenuEvent
&
aEvent
)
>
m_customHandler
;
std
::
list
<
CUSTOM_MENU_HANDLER
>
m_handlers
;
/// Optional icon
///
>
Optional icon
const
BITMAP_OPAQUE
*
m_icon
;
const
BITMAP_OPAQUE
*
m_icon
;
friend
class
TOOL_INTERACTIVE
;
friend
class
TOOL_INTERACTIVE
;
...
...
pcbnew/router/router_tool.cpp
View file @
4be876a1
...
@@ -96,8 +96,8 @@ public:
...
@@ -96,8 +96,8 @@ public:
{
{
m_board
=
NULL
;
m_board
=
NULL
;
SetIcon
(
width_track_via_xpm
);
SetIcon
(
width_track_via_xpm
);
set
CustomEventHandler
(
boost
::
bind
(
&
CONTEXT_TRACK_WIDTH_MENU
::
handleCustomEvent
,
Append
CustomEventHandler
(
boost
::
bind
(
&
CONTEXT_TRACK_WIDTH_MENU
::
handleCustomEvent
,
this
,
_1
)
);
this
,
_1
)
);
}
}
void
SetBoard
(
BOARD
*
aBoard
)
void
SetBoard
(
BOARD
*
aBoard
)
...
...
pcbnew/tools/selection_tool.cpp
View file @
4be876a1
...
@@ -242,7 +242,7 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
...
@@ -242,7 +242,7 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
void
SELECTION_TOOL
::
AddMenuItem
(
const
TOOL_ACTION
&
aAction
,
const
SELECTION_CONDITION
&
aCondition
)
void
SELECTION_TOOL
::
AddMenuItem
(
const
TOOL_ACTION
&
aAction
,
const
SELECTION_CONDITION
&
aCondition
)
{
{
assert
(
aAction
.
GetId
()
>
0
);
// Check if the action was registered before
in ACTION_MANAGER
assert
(
aAction
.
GetId
()
>
0
);
// Check if action was previously registered
in ACTION_MANAGER
m_menu
.
Add
(
aAction
);
m_menu
.
Add
(
aAction
);
m_menuConditions
.
push_back
(
aCondition
);
m_menuConditions
.
push_back
(
aCondition
);
...
@@ -250,10 +250,12 @@ void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction, const SELECTION_CO
...
@@ -250,10 +250,12 @@ void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction, const SELECTION_CO
void
SELECTION_TOOL
::
AddSubMenu
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
,
void
SELECTION_TOOL
::
AddSubMenu
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
,
const
SELECTION_CONDITION
&
aCondition
)
const
SELECTION_CONDITION
&
aCondition
,
bool
aExpand
)
{
{
m_menu
.
Add
(
aMenu
,
aLabel
);
std
::
list
<
wxMenuItem
*>
items
=
m_menu
.
Add
(
aMenu
,
aLabel
,
aExpand
);
m_menuConditions
.
push_back
(
aCondition
);
for
(
unsigned
int
i
=
0
;
i
<
items
.
size
();
++
i
)
m_menuConditions
.
push_back
(
aCondition
);
}
}
...
@@ -1285,7 +1287,7 @@ void SELECTION_TOOL::generateMenu()
...
@@ -1285,7 +1287,7 @@ void SELECTION_TOOL::generateMenu()
assert
(
m_menuCopy
.
GetMenuItemCount
()
==
m_menuConditions
.
size
()
);
assert
(
m_menuCopy
.
GetMenuItemCount
()
==
m_menuConditions
.
size
()
);
// Filter out entries that do
es not apply to
the current selection
// Filter out entries that do
not comply with
the current selection
for
(
int
i
=
m_menuCopy
.
GetMenuItemCount
()
-
1
;
i
>=
0
;
--
i
)
for
(
int
i
=
m_menuCopy
.
GetMenuItemCount
()
-
1
;
i
>=
0
;
--
i
)
{
{
try
try
...
...
pcbnew/tools/selection_tool.h
View file @
4be876a1
...
@@ -141,9 +141,11 @@ public:
...
@@ -141,9 +141,11 @@ public:
* @param aMenu is the submenu to be added.
* @param aMenu is the submenu to be added.
* @param aLabel is the label of added submenu.
* @param aLabel is the label of added submenu.
* @param aCondition is a condition that has to be fulfilled to enable the submenu entry.
* @param aCondition is a condition that has to be fulfilled to enable the submenu entry.
* @param aExpand determines if the added submenu items should be added as individual items.
*/
*/
void
AddSubMenu
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
,
void
AddSubMenu
(
CONTEXT_MENU
*
aMenu
,
const
wxString
&
aLabel
,
const
SELECTION_CONDITION
&
aCondition
=
SELECTION_CONDITIONS
::
ShowAlways
);
const
SELECTION_CONDITION
&
aCondition
=
SELECTION_CONDITIONS
::
ShowAlways
,
bool
aExpand
=
false
);
/**
/**
* Function EditModules()
* Function EditModules()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment