Book a Demo

Author Topic: I can't control menu state in Python  (Read 8803 times)

goshawk

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
  • I love YaBB 1G - SP1!
    • View Profile
I can't control menu state in Python
« on: November 22, 2005, 09:52:05 pm »
Hi there :D

I'm writing add-in code for EA 4.50.744 (Unicode) in Python.

I want to control the menu state (selectable or not) by EA_GetMenuState, but I can't.
# I attach my code at the end of this mail

In this code, I define 1 parent menu "AAA" and 2 child  menus "BBB", "CCC". I expect that menu "AAA" and "BBB" are selectable, "CCC" is not.

But, all the menus are selectable. Why? ???

Is there any example that control menu state in Python?

My envirronment
OS  Windows XP SP1
Python 2.4.1
wxPython wx-2.5.5-msw-unicode

*****
import sys
from win32com.server.util import wrap, unwrap
import win32com.client
import wx

# For defaultencoding
if hasattr(sys,"setdefaultencoding"):
   sys.setdefaultencoding("shift_jis")

# For Late Bound
from win32com.client import dynamic

# For debug
debugging = 0

if debugging:
   from win32com.server.dispatcher import DefaultDebugDispatcher
   useDispatcher = DefaultDebugDispatcher
else:
   useDispatcher = None

#
class TestPlugIn(wx.App):
   #
   _public_methods_ = [ 'EA_MenuClick',
                        'EA_GetMenuItems',
                        'EA_GetMenuState',
                        ]
   #
   _reg_progid_ = "PythonUtil.TestPlugIn"
   #
   #
   # >>> import pythoncom
   # >>> print pythoncom.CreateGuid()
   #
   _reg_clsid_ = "{3DBD5A66-CCBC-4545-85FE-784F99A4CE94}"

   # Menu items
   def EA_GetMenuItems(self, Repository, MenuLocation, MenuName):
       if MenuName == "":
           menu = [
               u'-&AAA',                ]
       elif MenuName == u'-&AAA':
           menu = [
               u'&BBB',
               u'&CCC',
               ]
       return menu

   # Menu state control
   def EA_GetMenuState(self, Repository, MenuLocation, MenuName,
                       ItemName, IsEnabled, IsChecked):
##        print "EA_GetMenuState"
       if MenuLocation == "TreeView":
           IsEnabled = False
       elif MenuLocation == "Diagram":
           IsEnabled = False
       elif  MenuLocation == "MainMenu":
           if MenuName == u'-&AAA':
               IsEnabled = True
               if ItemName == u'&BBB':
                   IsEnabled = True
               else:
                   IsEnabled = False
       print MenuName, ItemName, IsEnabled

   def EA_MenuClick(self, Repository, MenuLocation, MenuName, ItemName):
       print "No choice"

def main():
   print "TestPlugin ver", version
   app = TestPlugIn(0)
   app.MainLoop()

if __name__ == '__main__':
   if len(sys.argv) < 2:
       main()
   else:
       import win32com.server.register
       if sys.argv[1] == "--register":
           print "regist COM server"
           print "TestPlugin ver", version
           win32com.server.register.UseCommandLine(TestPlugIn,
                                                   debug=debugging)
       elif sys.argv[1] == "--unregister":
           print "Unregist COM server"
           print "TestPlugin ver", version
           win32com.server.register.UseCommandLine(TestPlugIn)
       else:
           print "Usage: testplugin.py [--register|--unregister]"
*****


thomaskilian

  • Guest
Re: I can't control menu state in Python
« Reply #1 on: November 22, 2005, 11:44:36 pm »
Maybe because MenuLocation can take only "TreeView" and "Diagram"? I never came across "MainMenu" ???

Aaron B

  • EA Administrator
  • EA User
  • *****
  • Posts: 941
  • Karma: +18/-0
    • View Profile
Re: I can't control menu state in Python
« Reply #2 on: November 23, 2005, 04:41:17 pm »
"MainMenu" is indeed a valid location.
My only initial thought is to make sure your indentation/logic is correct.  It is a bit hard to tell from your pasted sample as the spacing seems to be out.

Just to try a different logic flow, perhaps try this:
Code: [Select]
elif MenuLocation == "MainMenu":
 IsEnabled = True
 if MenuName == u'-&AAA' and ItemName == u'&CCC':
   IsEnabled = False

Should result in all menu items except "CCC" being enabled.

goshawk

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
  • I love YaBB 1G - SP1!
    • View Profile
Re: I can't control menu state in Python
« Reply #3 on: November 23, 2005, 10:07:09 pm »
Hello! thomaskilian and AaronB.

Thank you for reply. :)

From Posted by: AaronB
Posted on: Today at 4:41pm
Quote
"MainMenu" is indeed a valid location.
My only initial thought is to make sure your indentation/logic is correct.  It is a bit hard to tell from your pasted sample as the spacing seems to be out.
 

Sorry, I should use a tag for code.
Quote
Just to try a different logic flow, perhaps try this:
Code:

elif MenuLocation == "MainMenu":
  IsEnabled = True
  if MenuName == u'-&AAA' and ItemName == u'&CCC':
    IsEnabled = False

I modified code as follows,
Code: [Select]

#!python
# -*- coding: shift_jis -*-
#
# testplugin.py
#

version = "0.01"

import sys
from win32com.server.util import wrap, unwrap
import win32com.client
import wx

# For defaultencoding
if hasattr(sys,"setdefaultencoding"):
 sys.setdefaultencoding("shift_jis")

# For Late Bound
from win32com.client import dynamic

# For debug
debugging = 0

if debugging:
 from win32com.server.dispatcher import DefaultDebugDispatcher
 useDispatcher = DefaultDebugDispatcher
else:
 useDispatcher = None

#
class TestPlugIn(wx.App):
 #
 _public_methods_ = [
   'EA_MenuClick',
   'EA_GetMenuItems',
   'EA_GetMenuState',
 ]
 #
 _reg_progid_ = "PythonUtil.TestPlugIn"
 #  
 #  
 # >>> import pythoncom
 # >>> print pythoncom.CreateGuid()
 #
 _reg_clsid_ = "{EE11FD80-F4D2-4DE1-9F9E-01838711405A}"

 # Menu items
 def EA_GetMenuItems(self, Repository, MenuLocation, MenuName):
   if MenuName == "":
     menu = [
       u'-&AAA',      ]
     elif MenuName == u'-&AAA':
       menu = [
         u'&BBB',          u'&CCC',
       ]
   return menu

 # Menu state control
 def EA_GetMenuState(self, Repository, MenuLocation, MenuName, ItemName, IsEnabled, IsChecked):
   ##   print "EA_GetMenuState"
   if MenuLocation == "TreeView":
     IsEnabled = False
   elif MenuLocation == "Diagram":
     IsEnabled = False
   elif  MenuLocation == "MainMenu":
     IsEnabled = True
     if (MenuName == u'-&AAA') and (ItemName == u'&CCC'):
       IsEnabled = False
   print MenuName, ItemName, IsEnabled

 def EA_MenuClick(self, Repository, MenuLocation, MenuName, ItemName):
   print "No choice"

def main():
 print "TestPlugin ver", version
 app = TestPlugIn(0)
 app.MainLoop()

if __name__ == '__main__':
 if len(sys.argv) < 2:
   main()
 else:
   import win32com.server.register
   if sys.argv[1] == "--register":
     print "regist COM server"
     print "TestPlugin ver", version
     win32com.server.register.UseCommandLine(TestPlugIn, debug=debugging)
   elif sys.argv[1] == "--unregister":
     print "Unregist COM server"
     print "TestPlugin ver", version
     win32com.server.register.UseCommandLine(TestPlugIn)
   else:
     print "Usage: testplugin.py [--register|--unregister]"

:-[ I can't control indentation.
Quote
Should result in all menu items except "CCC" being enabled.


I tried modified code, but still all the menu were selectable.
Then got debug print messages as follows,

Code: [Select]

-&AAA &BBB True
-&AAA &CCC False
-&AAA &BBB True
-&AAA &CCC False
-&AAA &BBB True
-&AAA &CCC False
-&AAA &BBB True
-&AAA &CCC False
-&AAA &BBB True
-&AAA &CCC False
...


valiable IsEnabled was actually set "False", but menu "CCC" was still selectable.

Did anyone control menu state in Python? :-[

Thank you.

thomaskilian

  • Guest
Re: I can't control menu state in Python
« Reply #4 on: November 24, 2005, 12:59:38 am »
Okay. So my suggestion would be to reduce the example to a single entry and trying to toggle that on/off. Having that working it should be possible to crawl back to your original code  :P

goshawk

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
  • I love YaBB 1G - SP1!
    • View Profile
Re: I can't control menu state in Python
« Reply #5 on: November 24, 2005, 04:11:35 am »
Hi  thomaskilian
Quote
Okay. So my suggestion would be to reduce the example to a single entry and trying to toggle that on/off. Having that working it should be possible to crawl back to your original code  

Thanks for your advice.
I minimized my code. It has only one menu "AAA".
Then menu "AAA" will be always unselectable(IsEnabled = False).
Code: [Select]

#!python
# -*- coding: shift_jis -*-
#
# testplugin2.py
#

version = "0.01"

import sys
from win32com.server.util import wrap, unwrap
import win32com.client
import wx

# For defaultencoding
if hasattr(sys,"setdefaultencoding"):
   sys.setdefaultencoding("shift_jis")

# For Late Bound
from win32com.client import dynamic

# For debug
debugging = 0

if debugging:
   from win32com.server.dispatcher import DefaultDebugDispatcher
   useDispatcher = DefaultDebugDispatcher
else:
   useDispatcher = None

#
class TestPlugIn(wx.App):
   #
   _public_methods_ = [
       'EA_MenuClick',
       'EA_GetMenuItems',
       'EA_GetMenuState',
    ]
   #
   _reg_progid_ = "PythonUtil.TestPlugIn"
   #  
   #  
   # >>> import pythoncom
   # >>> print pythoncom.CreateGuid()
   #
   _reg_clsid_ = "{EE11FD80-F4D2-4DE1-9F9E-01838711405A}"

   # Menu items
   def EA_GetMenuItems(self, Repository, MenuLocation, MenuName):
       if MenuName == "":
           menu = [
               u'&AAA',                ]
       elif MenuName == u'&AAA':
           menu = [                ]
       return menu

   # Menu state control
   def EA_GetMenuState(self, Repository, MenuLocation, MenuName,
                       ItemName, IsEnabled, IsChecked):
       ##   print "EA_GetMenuState"
       if MenuLocation == "TreeView":
           IsEnabled = False
       elif MenuLocation == "Diagram":
           IsEnabled = False
       elif  MenuLocation == "MainMenu":
           IsEnabled = False
           if MenuName == u'&AAA':
               IsEnabled = False
       print MenuName, ItemName, IsEnabled

   def EA_MenuClick(self, Repository, MenuLocation, MenuName, ItemName):
       print "No choice"

def main():
   print "TestPlugin ver", version
   app = TestPlugIn(0)
   app.MainLoop()

if __name__ == '__main__':
   if len(sys.argv) < 2:
       main()
   else:
       import win32com.server.register
       if sys.argv[1] == "--register":
           print "regist COM server"
           print "TestPlugin ver", version
           win32com.server.register.UseCommandLine(TestPlugIn,
                                                   debug=debugging)
       elif sys.argv[1] == "--unregister":
           print "Unregist COM server"
           print "TestPlugin ver", version
           win32com.server.register.UseCommandLine(TestPlugIn)
       else:
           print "Usage: testplugin.py [--register|--unregister]"


I tried above code, but the menu "AAA" is selectable.
So, debug print is as follows,
Code: [Select]

&AAA False
&AAA False
&AAA False
...
&AAA False
&AAA False
&AAA False
No choice


Sigh... :-/

thomaskilian

  • Guest
Re: I can't control menu state in Python
« Reply #6 on: November 24, 2005, 05:03:07 am »
I now tried this with Perl and - no matter what I set isSelected or isEnabled - the entries always appear and are selectable. Looks like a bug. I didn't come across since I simply included menu items or left them out. That still is okay for me, but EA_GetMenuState doesn't seem to work correctly.

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: I can't control menu state in Python
« Reply #7 on: November 24, 2005, 01:29:31 pm »
EA_GetMenuState seems to work for me, but I'm not using Python (or Perl).  The possibility that occurs to me is that maybe you haven't declared your functions to have those parameters passed by reference.

I had a bit of a look for how to do this in python and came up with the following page.  Hope it helps http://mail.python.org/pipermail/python-win32/2002-November/000590.html

goshawk

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
  • I love YaBB 1G - SP1!
    • View Profile
Re: I can't control menu state in Python
« Reply #8 on: November 24, 2005, 08:51:26 pm »
Hello simonm
Thank you for your importtant advice.
Quote
I had a bit of a look for how to do this in python and came up with the following page.  Hope it helps http://mail.python.org/pipermail/python-win32/2002-November/000590.html

I refered that webpage. That's it.
I added code "return 0, IsEnabled, IsChecked" to method EA_GetMenuState for reference values.
Code: [Select]

#!python
# -*- coding: shift_jis -*-
#
# testplugin2.py
#

version = "0.01"

import sys
from win32com.server.util import wrap, unwrap
import win32com.client
import wx

# For defaultencoding
if hasattr(sys,"setdefaultencoding"):
   sys.setdefaultencoding("shift_jis")

# For Late Bound
from win32com.client import dynamic

# For debug
debugging = 0

if debugging:
   from win32com.server.dispatcher import DefaultDebugDispatcher
   useDispatcher = DefaultDebugDispatcher
else:
   useDispatcher = None

#
class TestPlugIn(wx.App):
   #
   _public_methods_ = [
       'EA_MenuClick',
       'EA_GetMenuItems',
       'EA_GetMenuState',
    ]
   #
   _reg_progid_ = "PythonUtil.TestPlugIn"
   #  
   #  
   # >>> import pythoncom
   # >>> print pythoncom.CreateGuid()
   #
   _reg_clsid_ = "{EE11FD80-F4D2-4DE1-9F9E-01838711405A}"

   # Menu items
   def EA_GetMenuItems(self, Repository, MenuLocation, MenuName):
       if MenuName == "":
           menu = [
               u'&AAA',                ]
       elif MenuName == u'&AAA':
           menu = [                ]
       return menu

   # Menu state control
   def EA_GetMenuState(self, Repository, MenuLocation, MenuName,
                       ItemName, IsEnabled, IsChecked):
       ##   print "EA_GetMenuState"
       if MenuLocation == "TreeView":
           IsEnabled = False
       elif MenuLocation == "Diagram":
           IsEnabled = False
       elif  MenuLocation == "MainMenu":
           IsEnabled = False
           if MenuName == u'&AAA':
               IsEnabled = False
       print MenuName, ItemName, IsEnabled
       return 0, IsEnabled, IsChecked

   def EA_MenuClick(self, Repository, MenuLocation, MenuName, ItemName):
       print "No choice"

def main():
   print "TestPlugin ver", version
   app = TestPlugIn(0)
   app.MainLoop()

if __name__ == '__main__':
   if len(sys.argv) < 2:
       main()
   else:
       import win32com.server.register
       if sys.argv[1] == "--register":
           print "regist COM server"
           print "TestPlugin ver", version
           win32com.server.register.UseCommandLine(TestPlugIn,
                                                   debug=debugging)
       elif sys.argv[1] == "--unregister":
           print "Unregist COM server"
           print "TestPlugin ver", version
           win32com.server.register.UseCommandLine(TestPlugIn)
       else:
           print "Usage: testplugin.py [--register|--unregister]"

I could control the menu state.
In this code, the menu "AAA" is unselectable. I got it!

Thank youf so much, everyone.

thomaskilian

  • Guest
Re: I can't control menu state in Python
« Reply #9 on: November 25, 2005, 12:33:07 am »
Unfortunately there is no such construct for Perl :'( So one can't actually make use of that feature. By default Perl->Perl uses always by-reference, but the COM interface seems to behave somewhat different.

goshawk

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
  • I love YaBB 1G - SP1!
    • View Profile
Re: I can't control menu state in Python
« Reply #10 on: November 28, 2005, 05:28:07 am »
Hi there, I have a problem again.

Quote

I could control the menu state.
In this code, the menu "AAA" is unselectable. I got it!


I added two more sub menus "BBB", "CCC" to EA_GetMenuItems.

I also added the method "SomeMethod" and call in EA_MenuClick at the menu "BBB".
Code: [Select]

...
   # Menu items
   def EA_GetMenuItems(self, Repository, MenuLocation, MenuName):
       if MenuName == "":
           menu = [
               u'-AAA',                ]
       elif MenuName == u'-AAA':
           menu = [
               u'BBB',
               u'CCC',
               ]
       else:
           menu = ""
       return menu

   # Menu state control
   def EA_GetMenuState(self, Repository, MenuLocation, MenuName,
                       ItemName, IsEnabled, IsChecked):
       ##   print "EA_GetMenuState"
       if MenuLocation == "TreeView":
           IsEnabled = False
       elif MenuLocation == "Diagram":
           IsEnabled = False
       elif  MenuLocation == "MainMenu":
           IsEnabled = True
           if (MenuName == u'-AAA') and (ItemName == u'BBB'):
               IsEnabled = True
           elif (MenuName == u'-AAA') and (ItemName == u'CCC'):
               IsEnabled = False
       print MenuName, ItemName, IsEnabled
       return 0, IsEnabled, IsChecked

   def EA_MenuClick(self, Repository, MenuLocation, MenuName, ItemName):
       print "EA_MenuClick"
       if MenuLocation == "TreeView":
           pass
       elif MenuLocation == "Diagram":
           pass
       elif  MenuLocation == "MainMenu":
           if (MenuName == u'-AAA') and (ItemName == u'BBB'):
               print "Selected", MenuName, ItemName
               self.SomeMethod()
           elif (MenuName == u'-AAA') and (ItemName == u'CCC'):
               print "Selected", MenuName, ItemName
       return 0

   def SomeMethod(self):
       print "Do something"

I executed this code form EA. Then I got the debug print as follows,
Code: [Select]
-AAA BBB True
-AAA CCC False
-AAA BBB True
-AAA CCC False
...
-AAA CCC False
-AAA BBB True
-AAA BBB True
EA_MenuClick
Selected -AAA BBB
Do something


I could executed the method "SomeMethod" as I expected.

Next, I added one more menu "DDD". This menu is not a sub menu as "BBB" and "CCC".

Code: [Select]

   def EA_GetMenuItems(self, Repository, MenuLocation, MenuName):
       if MenuName == "":
           menu = [
               u'-AAA',
               u'DDD',
               ]
       elif MenuName == u'-AAA':
           menu = [
               u'BBB',
               u'CCC',
               ]
       else:
           menu = ""
       return menu

   # Menu state control
   def EA_GetMenuState(self, Repository, MenuLocation, MenuName,
                       ItemName, IsEnabled, IsChecked):
       ##   print "EA_GetMenuState"
       if MenuLocation == "TreeView":
           IsEnabled = False
       elif MenuLocation == "Diagram":
           IsEnabled = False
       elif  MenuLocation == "MainMenu":
           IsEnabled = True
           if (MenuName == u'-AAA') and (ItemName == u'BBB'):
               IsEnabled = True
           elif (MenuName == u'-AAA') and (ItemName == u'CCC'):
               IsEnabled = False
           elif ItemName == u'DDD':
               IsEnabled = False
       print MenuName, ItemName, IsEnabled
       return 0, IsEnabled, IsChecked

   def EA_MenuClick(self, Repository, MenuLocation, MenuName, ItemName):
       print "EA_MenuClick"
       if MenuLocation == "TreeView":
           pass
       elif MenuLocation == "Diagram":
           pass
       elif  MenuLocation == "MainMenu":
           if (MenuName == u'-AAA') and (ItemName == u'BBB'):
               print "Selected", MenuName, ItemName
               self.SomeMethod()
           elif (MenuName == u'-AAA') and (ItemName == u'CCC'):
               print "Selected", MenuName, ItemName
           elif ItemName == u'DDD':
               print "Selected", MenuName, ItemName
       return 0

So, I tried this code again.
But I couldn't execute the method "SomeMthod".
I got debug print as follows,
Code: [Select]

DDD False
DDD False
...
DDD False
DDD False
-AAA BBB True
-AAA CCC False
DDD False
-AAA BBB True
-AAA CCC False
DDD False
...
DDD False
-AAA BBB True
-AAA BBB False

Why is IsEnabled "False" when I chose the menu "BBB"?
Why can't I execute the method "SomeMethod"?
Is there any advice or suggestion?
thank you.