menu.py :  » Project-Management » Task-Coach » TaskCoach-1.0.3 » taskcoachlib » gui » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Project Management » Task Coach 
Task Coach » TaskCoach 1.0.3 » taskcoachlib » gui » menu.py
'''
Task Coach - Your friendly task manager
Copyright (C) 2004-2010 Frank Niessink <frank@niessink.com>

Task Coach is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Task Coach is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''

import wx, os
from taskcoachlib import patterns
from taskcoachlib.domain import task,base,category
from taskcoachlib.i18n import _
import uicommand, viewer


class Menu(wx.Menu, uicommand.UICommandContainerMixin):
    def __init__(self, window):
        super(Menu, self).__init__()
        self._window = window
        
    def __len__(self):
        return self.GetMenuItemCount()

    def appendUICommand(self, uiCommand):
        return uiCommand.addToMenu(self, self._window)
    
    def appendMenu(self, text, subMenu, bitmap=None):
        subMenuItem = wx.MenuItem(self, id=wx.NewId(), text=text, subMenu=subMenu)
        if not bitmap and '__WXMSW__' in wx.PlatformInfo:
            # hack to force a 16 bit margin. SetMarginWidth doesn't work
            bitmap = 'nobitmap'
        if bitmap:
            subMenuItem.SetBitmap(wx.ArtProvider_GetBitmap(bitmap, 
                wx.ART_MENU, (16,16)))
        self.AppendItem(subMenuItem)

    def invokeMenuItem(self, menuItem):
        ''' Programmatically invoke the menuItem. This is mainly for testing 
            purposes. '''
        self._window.ProcessEvent(wx.CommandEvent( \
            wx.wxEVT_COMMAND_MENU_SELECTED, winid=menuItem.GetId()))
    
    def openMenu(self):
        ''' Programmatically open the menu. This is mainly for testing 
            purposes. '''
        # On Mac OSX, an explicit UpdateWindowUI is needed to ensure that
        # menu items are updated before the menu is opened. This is not needed
        # on other platforms, but it doesn't hurt either.
        self._window.UpdateWindowUI() 
        self._window.ProcessEvent(wx.MenuEvent(wx.wxEVT_MENU_OPEN, menu=self))


class DynamicMenu(Menu):
    ''' A menu that registers for events and then updates itself whenever the
        event is fired. '''
    def __init__(self, window, parentMenu=None, labelInParentMenu=''):
        ''' Initialize the menu. labelInParentMenu is needed to be able to
            find this menu in its parentMenu. '''
        super(DynamicMenu, self).__init__(window)
        self._parentMenu = parentMenu
        self._labelInParentMenu = self.__GetLabelText(labelInParentMenu)
        self.registerForMenuUpdate()
        self.updateMenu()
         
    def registerForMenuUpdate(self):
        ''' Subclasses are responsible for binding an event to onUpdateMenu so
            that the menu gets a chance to update itself at the right time. '''
        raise NotImplementedError

    def onUpdateMenu(self, event):
        ''' This event handler should be called at the right times so that
            the menu has a chance to update itself. '''
        # If this is called by wx, 'skip' the event so that other event
        # handlers get a chance too:
        if hasattr(event, 'Skip'):
            event.Skip()
        try: # Prepare for menu or window to be destroyed
            self.updateMenu()
        except wx.PyDeadObjectError:
            pass
        
    def updateMenu(self):
        ''' Updating the menu consists of two steps: updating the menu item
            of this menu in its parent menu, e.g. to enable or disable it, and
            updating the menu items of this menu. '''
        self.updateMenuItemInParentMenu()
        self.updateMenuItems()
        
    def clearMenu(self):
        ''' Remove all menu items. '''
        for menuItem in self.MenuItems:
            self.DestroyItem(menuItem)       
            
    def updateMenuItemInParentMenu(self):
        ''' Enable or disable the menu item in the parent menu, depending on
            what enabled() returns. '''
        if self._parentMenu:
            myId = self.myId()
            if myId != wx.NOT_FOUND:
                self._parentMenu.Enable(myId, self.enabled())

    def myId(self):
        ''' Return the id of our menu item in the parent menu. '''
        # I'd rather use wx.Menu.FindItem, but it seems that that
        # method currently does not work for menu items with accelerators
        # (wxPython 2.8.6 on Ubuntu). When that is fixed replace the 7
        # lines below with this one:
        # myId = self._parentMenu.FindItem(self._labelInParentMenu)
        for item in self._parentMenu.MenuItems:
            if self.__GetLabelText(item.GetText()) == self._labelInParentMenu:
                return item.Id
        return wx.NOT_FOUND

    def updateMenuItems(self):
        ''' Update the menu items of this menu. '''
        pass
    
    def enabled(self):
        ''' Return a boolean indicating whether this menu should be enabled in
            its parent menu. This method is called by 
            updateMenuItemInParentMenu(). It returns True by default. Override
            in a subclass as needed.'''
        return True
    
    @staticmethod
    def __GetLabelText(menuText):
        ''' Remove accelerators from themenuText.Thisnecessarybecauseon import 
            some platforms '&' is changed into '_' so menuTexts would compare
            different even though they are really the same. '''
        return menuText.replace('&', '').replace('_', '')

            
class DynamicMenuThatGetsUICommandsFromViewer(DynamicMenu):
    def __init__(self, viewer, parentMenu=None, labelInParentMenu=''): # pylint: disable-msg=W0621
        self._uiCommands = None
        super(DynamicMenuThatGetsUICommandsFromViewer, self).__init__(\
            viewer, parentMenu, labelInParentMenu)

    def registerForMenuUpdate(self):
        # Refill the menu whenever the menu is opened, because the menu might 
        # depend on the status of the viewer:
        self._window.Bind(wx.EVT_MENU_OPEN, self.onUpdateMenu)
        
    def updateMenuItems(self):
        newCommands = self.getUICommands()
        try:
            if newCommands == self._uiCommands:
                return
        except wx._core.PyDeadObjectError: # pylint: disable-msg=W0212
            pass  # Old viewer was closed
        self.clearMenu()
        self.fillMenu(newCommands)
        self._uiCommands = newCommands
            
    def fillMenu(self, uiCommands):
        self.appendUICommands(*uiCommands) # pylint: disable-msg=W0142
        
    def getUICommands(self):
        raise NotImplementedError


class MainMenu(wx.MenuBar):
    def __init__(self, mainwindow, settings, iocontroller, viewerContainer,
                 taskFile):
        super(MainMenu, self).__init__()
        self.Append(FileMenu(mainwindow, settings, iocontroller,
                             viewerContainer), _('&File'))
        self.Append(EditMenu(mainwindow, settings, iocontroller, 
                             viewerContainer), _('&Edit'))
        self.Append(ViewMenu(mainwindow, settings, viewerContainer, taskFile),
                    _('&View'))
        self.Append(TaskMenu(mainwindow, settings, taskFile, viewerContainer),
                    _('&Task'))
        if settings.getboolean('feature', 'effort'):
            self.Append(EffortMenu(mainwindow, settings, taskFile, 
                        viewerContainer), _('Eff&ort'))
        self.Append(CategoryMenu(mainwindow, settings, taskFile.categories(),
                                 viewerContainer), _('&Category'))
        if settings.getboolean('feature', 'notes'):
            self.Append(NoteMenu(mainwindow, settings, taskFile,
                                 viewerContainer), _('&Note'))
        self.Append(HelpMenu(mainwindow, settings), _('&Help'))

       
class FileMenu(Menu):
    def __init__(self, mainwindow, settings, iocontroller, viewerContainer):
        super(FileMenu, self).__init__(mainwindow)
        self.__settings = settings
        self.__iocontroller = iocontroller
        self.__recentFileUICommands = []
        self.__separator = None
        self.appendUICommands(
            uicommand.FileOpen(iocontroller=iocontroller),
            uicommand.FileMerge(iocontroller=iocontroller),
            uicommand.FileClose(iocontroller=iocontroller),
            None,
            uicommand.FileSave(iocontroller=iocontroller),
            uicommand.FileSaveAs(iocontroller=iocontroller),
            uicommand.FileSaveSelection(iocontroller=iocontroller,
                                        viewer=viewerContainer))
        if not settings.getboolean('feature', 'syncml'):
            self.appendUICommands(uicommand.FilePurgeDeletedItems(iocontroller=iocontroller))
        self.appendUICommands(
            None,
            uicommand.FileSaveSelectedTaskAsTemplate(iocontroller=iocontroller,
                                                     viewer=viewerContainer),
            uicommand.FileAddTemplate(iocontroller=iocontroller),
            None,
            uicommand.PrintPageSetup(settings=settings),
            uicommand.PrintPreview(viewer=viewerContainer, settings=settings),
            uicommand.Print(viewer=viewerContainer, settings=settings),
            None)
        self.appendMenu(_('&Export'),
                        ExportMenu(mainwindow, iocontroller, viewerContainer),
                        'export')
        if settings.getboolean('feature', 'syncml'):
            try:
                import taskcoachlib.syncml.core # pylint: disable-msg=W0612
            except ImportError:
                pass
            else:
                self.appendUICommands(uicommand.FileSynchronize(iocontroller=iocontroller, settings=settings))
        self.__recentFilesStartPosition = len(self) 
        self.appendUICommands(None, uicommand.FileQuit())
        self._window.Bind(wx.EVT_MENU_OPEN, self.onOpenMenu)

    def onOpenMenu(self, event):
        if event.GetMenu() == self:
            self.__removeRecentFileMenuItems()
            self.__insertRecentFileMenuItems()        
        event.Skip()
    
    def __insertRecentFileMenuItems(self):
        recentFiles = self.__settings.getlist('file', 'recentfiles')
        if not recentFiles:
            return
        maximumNumberOfRecentFiles = self.__settings.getint('file', 
            'maxrecentfiles')
        recentFiles = recentFiles[:maximumNumberOfRecentFiles]
        self.__separator = self.InsertSeparator(self.__recentFilesStartPosition)
        for index, recentFile in enumerate(recentFiles):
            recentFileNumber = index + 1 # Only computer nerds start counting at 0 :-)
            recentFileMenuPosition = self.__recentFilesStartPosition + 1 + index
            recentFileOpenUICommand = uicommand.RecentFileOpen(filename=recentFile,
                index=recentFileNumber, iocontroller=self.__iocontroller)
            recentFileOpenUICommand.addToMenu(self, self._window, 
                recentFileMenuPosition)
            self.__recentFileUICommands.append(recentFileOpenUICommand)

    def __removeRecentFileMenuItems(self):
        for recentFileUICommand in self.__recentFileUICommands:
            recentFileUICommand.removeFromMenu(self, self._window)
        self.__recentFileUICommands = []
        if self.__separator:
            self.RemoveItem(self.__separator)
            self.__separator = None


class ExportMenu(Menu):
    def __init__(self, mainwindow, iocontroller, viewerContainer):
        super(ExportMenu, self).__init__(mainwindow)
        kwargs = dict(iocontroller=iocontroller, viewer=viewerContainer)
        # pylint: disable-msg=W0142
        self.appendUICommands(
            uicommand.FileExportAsHTML(**kwargs),
            uicommand.FileExportSelectionAsHTML(**kwargs),
            uicommand.FileExportAsCSV(**kwargs),
            uicommand.FileExportSelectionAsCSV(**kwargs),
            uicommand.FileExportAsICalendar(**kwargs),
            uicommand.FileExportSelectionAsICalendar(**kwargs))


class TaskTemplateMenu(DynamicMenu):
    def __init__(self, mainwindow, taskList, settings):
        self._uiCommands = None
        self.settings = settings
        self.taskList = taskList
        super(TaskTemplateMenu, self).__init__(mainwindow)

    def registerForMenuUpdate(self):
        self._window.Bind(wx.EVT_MENU_OPEN, self.onUpdateMenu)
        
    def updateMenuItems(self):
        newCommands = self.getUICommands()
        if newCommands != self._uiCommands:
            self.clearMenu()
            self.fillMenu(newCommands)
            self._uiCommands = newCommands
     
    def fillMenu(self, uiCommands):
        self.appendUICommands(*uiCommands) # pylint: disable-msg=W0142

    def getUICommands(self):
        path = self.settings.pathToTemplatesDir()
        commands = []
        for name in os.listdir(path):
            fullname = os.path.join(path, name)
            if name.endswith('.tsktmpl'):
                commands.append(uicommand.TaskNewFromTemplate(fullname,
                                  taskList=self.taskList, 
                                  settings=self.settings))
        return commands


class EditMenu(Menu):
    def __init__(self, mainwindow, settings, iocontroller, viewerContainer):
        super(EditMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.EditUndo(),
            uicommand.EditRedo(),
            None,
            uicommand.EditCut(viewer=viewerContainer, id=wx.ID_CUT),
            uicommand.EditCopy(viewer=viewerContainer, id=wx.ID_COPY),
            uicommand.EditPaste(),
            uicommand.EditPasteIntoTask(viewer=viewerContainer),
            None)
        # Leave sufficient room for command names in the Undo and Redo menu items:
        self.appendMenu(_('&Select')+' '*50,
                        SelectMenu(mainwindow, viewerContainer))
        self.appendUICommands(None, uicommand.EditPreferences(settings))
        if settings.getboolean('feature', 'syncml'):
            try:
                import taskcoachlib.syncml.core # pylint: disable-msg=W0612
            except ImportError:
                pass
            else:
                self.appendUICommands(uicommand.EditSyncPreferences(mainwindow=mainwindow,
                                                                    iocontroller=iocontroller))


class SelectMenu(Menu):
    def __init__(self, mainwindow, viewerContainer):
        super(SelectMenu, self).__init__(mainwindow)
        kwargs = dict(viewer=viewerContainer)
        # pylint: disable-msg=W0142
        self.appendUICommands(uicommand.SelectAll(**kwargs),
                              uicommand.ClearSelection(**kwargs))


class ViewMenu(Menu):
    def __init__(self, mainwindow, settings, viewerContainer, taskFile):
        super(ViewMenu, self).__init__(mainwindow)
        self.appendMenu(_('&New viewer'), 
            ViewViewerMenu(mainwindow, settings, viewerContainer, taskFile),
                'viewnewviewer')
        activateNextViewer = uicommand.ActivateViewer(viewer=viewerContainer,
            menuText=_('&Activate next viewer\tCtrl+PgDn'),
            helpText=_('Activate the next open viewer'), forward=True,
            bitmap='activatenextviewer')
        activatePreviousViewer = uicommand.ActivateViewer(viewer=viewerContainer,
            menuText=_('Activate &previous viewer\tCtrl+PgUp'),
            helpText=_('Activate the previous open viewer'), forward=False,
            bitmap='activatepreviousviewer')
        self.appendUICommands(
            activateNextViewer,
            activatePreviousViewer,
            uicommand.RenameViewer(viewer=viewerContainer),
            None)
        self.appendMenu(_('&Filter'), 
                        FilterMenu(mainwindow, self, _('&Filter')))
        self.appendMenu(_('&Sort'),
                        SortMenu(mainwindow, self, _('&Sort')))
        self.appendMenu(_('&Columns'), 
                        ColumnMenu(mainwindow, self, _('&Columns')))
        self.appendUICommands(None)
        self.appendMenu(_('&Tree options'), 
                        ViewTreeOptionsMenu(mainwindow, viewerContainer),
                        'treeview')
        self.appendUICommands(None)
        self.appendMenu(_('T&oolbar'), ToolBarMenu(mainwindow, settings))
        self.appendUICommands(uicommand.UICheckCommand(settings=settings,
            menuText=_('Status&bar'), helpText=_('Show/hide status bar'),
            setting='statusbar'))


class ViewViewerMenu(Menu):
    def __init__(self, mainwindow, settings, viewerContainer, taskFile):
        super(ViewViewerMenu, self).__init__(mainwindow)
        ViewViewer = uicommand.ViewViewer
        kwargs = dict(viewer=viewerContainer, taskFile=taskFile, settings=settings)
        # pylint: disable-msg=W0142
        viewViewerCommands = [\
            ViewViewer(menuText=_('&Task'),
                       helpText=_('Open a new tab with a viewer that displays tasks'),
                       viewerClass=viewer.TaskViewer, **kwargs),
            ViewViewer(menuText=_('Task &square map'),
                       helpText=_('Open a new tab with a viewer that displays tasks in a square map'),
                       viewerClass=viewer.SquareTaskViewer, **kwargs),
            ViewViewer(menuText=_('T&imeline'),
                       helpText=_('Open a new tab with a viewer that displays a timeline of tasks and effort'),
                       viewerClass=viewer.TimelineViewer, **kwargs),
            ViewViewer(menuText=_('&Calendar'),
                       helpText=_('Open a new tab with a viewer that displays tasks in a calendar'),
                       viewerClass=viewer.CalendarViewer, **kwargs),
            ViewViewer(menuText=_('&Category'),
                       helpText=_('Open a new tab with a viewer that displays categories'),
                       viewerClass=viewer.CategoryViewer, **kwargs)]
        if settings.getboolean('feature', 'effort'):
            viewViewerCommands.append(
                ViewViewer(menuText=_('&Effort'),
                       helpText=_('Open a new tab with a viewer that displays efforts'),
                       viewerClass=viewer.EffortViewer, **kwargs))
            viewViewerCommands.append(
                uicommand.ViewEffortViewerForSelectedTask(menuText=_('Effort for &one task'),
                        helpText=_('Open a new tab with a viewer that displays efforts for the selected task'),
                        viewerClass=viewer.EffortViewer, **kwargs))
        if settings.getboolean('feature', 'notes'):
            viewViewerCommands.append(
                ViewViewer(menuText=_('&Note'),
                       helpText=_('Open a new tab with a viewer that displays notes'),
                       viewerClass=viewer.NoteViewer, **kwargs))
        self.appendUICommands(*viewViewerCommands)
       
                                      
class ViewTreeOptionsMenu(Menu):
    def __init__(self, mainwindow, viewerContainer):
        super(ViewTreeOptionsMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.ViewExpandSelected(viewer=viewerContainer),
            uicommand.ViewCollapseSelected(viewer=viewerContainer),
            None,
            uicommand.ViewExpandAll(viewer=viewerContainer),
            uicommand.ViewCollapseAll(viewer=viewerContainer))


class FilterMenu(DynamicMenuThatGetsUICommandsFromViewer):
    def enabled(self):
        return self._window.viewer.isFilterable() and \
            bool(self._window.viewer.getFilterUICommands())
    
    def getUICommands(self):
        return self._window.viewer.getFilterUICommands()
    
    
class ColumnMenu(DynamicMenuThatGetsUICommandsFromViewer):
    def enabled(self):
        return self._window.viewer.hasHideableColumns()
    
    def getUICommands(self):
        return self._window.viewer.getColumnUICommands()
        

class SortMenu(DynamicMenuThatGetsUICommandsFromViewer):
    def enabled(self):
        return self._window.viewer.isSortable()
    
    def getUICommands(self):
        return self._window.viewer.getSortUICommands()


class ToolBarMenu(Menu):
    def __init__(self, mainwindow, settings):
        super(ToolBarMenu, self).__init__(mainwindow)
        toolbarCommands = []
        for value, menuText, helpText in \
            [(None, _('&Hide'), _('Hide the toolbar')),
             ((16, 16), _('&Small images'), _('Small images (16x16) on the toolbar')),
             ((22, 22), _('&Medium-sized images'), _('Medium-sized images (22x22) on the toolbar')),
             ((32, 32), _('&Large images'), _('Large images (32x32) on the toolbar'))]:
            toolbarCommands.append(uicommand.UIRadioCommand(settings=settings,
                setting='toolbar', value=value, menuText=menuText,
                helpText=helpText))
        # pylint: disable-msg=W0142
        self.appendUICommands(*toolbarCommands)


class TaskMenu(Menu):
    def __init__(self, mainwindow, settings, taskFile, viewerContainer):
        super(TaskMenu, self).__init__(mainwindow)
        tasks = taskFile.tasks()
        categories = taskFile.categories()
        self.appendUICommands(
            uicommand.TaskNew(taskList=tasks, settings=settings))
        self.appendMenu(_('New task &from template'),
                        TaskTemplateMenu(mainwindow, taskList=tasks, 
                                         settings=settings),
                        'newtmpl')
        self.appendUICommands(uicommand.TaskNewSubTask(taskList=tasks,
                                     viewer=viewerContainer),
            None,
            uicommand.TaskEdit(taskList=tasks, viewer=viewerContainer),
            uicommand.TaskToggleCompletion(viewer=viewerContainer),
            uicommand.TaskIncPriority(taskList=tasks, viewer=viewerContainer),
            uicommand.TaskDecPriority(taskList=tasks, viewer=viewerContainer),
            uicommand.TaskMaxPriority(taskList=tasks, viewer=viewerContainer),
            uicommand.TaskMinPriority(taskList=tasks, viewer=viewerContainer),
            None,
            uicommand.TaskDelete(taskList=tasks, viewer=viewerContainer),
            None,
            uicommand.TaskMail(viewer=viewerContainer),
            uicommand.AddTaskAttachment(taskList=tasks,
                                        viewer=viewerContainer,
                                        settings=settings),
            uicommand.OpenAllTaskAttachments(viewer=viewerContainer,
                                             settings=settings))
        if settings.getboolean('feature', 'notes'):
            self.appendUICommands(
                uicommand.TaskAddNote(viewer=viewerContainer,
                                      settings=settings)
                )
        self.appendMenu(_('&Toggle category'),
                        ToggleCategoryMenu(mainwindow, categories=categories,
                                           viewer=viewerContainer),
                        'folder_blue_arrow_icon')
            
            
class EffortMenu(Menu):
    def __init__(self, mainwindow, settings, taskFile, viewerContainer):
        super(EffortMenu, self).__init__(mainwindow)
        tasks = taskFile.tasks()
        efforts = taskFile.efforts()
        self.appendUICommands(
            uicommand.EffortNew(viewer=viewerContainer, effortList=efforts,
                                taskList=tasks, settings=settings),
            uicommand.EffortEdit(viewer=viewerContainer, effortList=efforts),
            uicommand.EffortDelete(viewer=viewerContainer, effortList=efforts),
            None,
            uicommand.EffortStart(viewer=viewerContainer, taskList=tasks),
            uicommand.EffortStop(taskList=tasks))
       

class CategoryMenu(Menu):
    def __init__(self, mainwindow, settings, categories, viewerContainer):
        super(CategoryMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.CategoryNew(categories=categories, settings=settings),
            uicommand.CategoryNewSubCategory(viewer=viewerContainer,
                                             categories=categories),
            uicommand.CategoryEdit(viewer=viewerContainer,
                                   categories=categories),
            uicommand.CategoryDelete(viewer=viewerContainer,
                                     categories=categories),
            None,
            uicommand.AddCategoryAttachment(viewer=viewerContainer,
                                            settings=settings),
            uicommand.OpenAllCategoryAttachments(viewer=viewerContainer,
                                                 settings=settings))
        if settings.getboolean('feature', 'notes'):
            self.appendUICommands(
                uicommand.CategoryAddNote(viewer=viewerContainer,
                                          settings=settings)
                )

        
class NoteMenu(Menu):
    def __init__(self, mainwindow, settings, taskFile, viewerContainer):
        super(NoteMenu, self).__init__(mainwindow)
        notes = taskFile.notes()
        categories = taskFile.categories()
        self.appendUICommands(
            uicommand.NoteNew(notes=notes, settings=settings),
            uicommand.NoteNewSubNote(viewer=viewerContainer, notes=notes),
            uicommand.NoteEdit(viewer=viewerContainer, notes=notes),
            uicommand.NoteDelete(viewer=viewerContainer, notes=notes),
            uicommand.NoteMail(viewer=viewerContainer),
            None,
            uicommand.AddNoteAttachment(viewer=viewerContainer,
                                        settings=settings),
            uicommand.OpenAllNoteAttachments(viewer=viewerContainer,
                                             settings=settings))
        self.appendMenu(_('&Toggle category'),
                        ToggleCategoryMenu(mainwindow, categories=categories,
                                           viewer=viewerContainer),
                        'folder_blue_arrow_icon')

        
class HelpMenu(Menu):
    def __init__(self, mainwindow, settings):
        super(HelpMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.Help(),
            uicommand.Tips(settings=settings),
            None,
            uicommand.HelpAbout(),
            uicommand.HelpLicense())


class TaskBarMenu(Menu):
    def __init__(self, taskBarIcon, settings, taskFile, viewerContainer):
        super(TaskBarMenu, self).__init__(taskBarIcon)
        tasks = taskFile.tasks()
        efforts = taskFile.efforts()
        self.appendUICommands(
            uicommand.TaskNew(taskList=tasks, settings=settings))
        if settings.getboolean('feature', 'effort'):
            self.appendUICommands(
                uicommand.EffortNew(viewer=viewerContainer, effortList=efforts,
                                    taskList=tasks, settings=settings))
        if settings.getboolean('feature', 'notes'):
            self.appendUICommands(
                uicommand.NoteNew(notes=taskFile.notes(), settings=settings))
        if settings.getboolean('feature', 'effort'):
            self.appendUICommands(None) # Separator
            label = _('&Start tracking effort')
            self.appendMenu(label,
                StartEffortForTaskMenu(taskBarIcon, 
                                       base.filter.DeletedFilter(tasks), 
                                       self, label), 'clock_icon')
            self.appendUICommands(uicommand.EffortStop(taskList=tasks))
        self.appendUICommands(
            None,
            uicommand.MainWindowRestore(),
            uicommand.FileQuit())
        

class ToggleCategoryMenu(DynamicMenu):
    def __init__(self, mainwindow, categories, viewer): # pylint: disable-msg=W0621
        self.categories = categories
        self.viewer = viewer
        if viewer.isViewerContainer():
            self.uiCommandClass = uicommand.ToggleCategory
        elif viewer.isShowingTasks():
            self.uiCommandClass = uicommand.TaskToggleCategory
        else:
            self.uiCommandClass = uicommand.NoteToggleCategory
        super(ToggleCategoryMenu, self).__init__(mainwindow)
        
    def registerForMenuUpdate(self):
        for eventType in (self.categories.addItemEventType(), 
                          self.categories.removeItemEventType()):
            patterns.Publisher().registerObserver(self.onUpdateMenu,
                                                  eventType=eventType,
                                                  eventSource=self.categories)
        patterns.Publisher().registerObserver(self.onUpdateMenu, 
            eventType=category.Category.subjectChangedEventType())
           
    def updateMenuItems(self):
        self.clearMenu()
        self.addMenuItemsForCategories(self.categories.rootItems(), self)
            
    def addMenuItemsForCategories(self, categories, menu):
        categories = categories[:]
        categories.sort(key=lambda category: category.subject())
        for category in categories:
            uiCommand = self.uiCommandClass(category=category, viewer=self.viewer)
            uiCommand.addToMenu(menu, self._window)
        categoriesWithChildren = [category for category in categories if category.children()]
        if categoriesWithChildren:
            menu.AppendSeparator()
            for category in categoriesWithChildren:
                subMenu = wx.Menu()
                self.addMenuItemsForCategories(category.children(), subMenu)
                menu.AppendSubMenu(subMenu, self.subMenuLabel(category))            
    
    @staticmethod
    def subMenuLabel(category): # pylint: disable-msg=W0621
        return _('%s (subcategories)')%category.subject()
    
    def enabled(self):
        return bool(self.categories)
    
                   
class StartEffortForTaskMenu(DynamicMenu):
    def __init__(self, taskBarIcon, tasks, parentMenu=None, labelInParentMenu=''):
        self.tasks = tasks
        super(StartEffortForTaskMenu, self).__init__(taskBarIcon, parentMenu, 
                                                     labelInParentMenu)

    def registerForMenuUpdate(self):
        for eventType in (self.tasks.addItemEventType(), 
                          self.tasks.removeItemEventType()):
            patterns.Publisher().registerObserver(self.onUpdateMenu,
                                                  eventType=eventType,
                                                  eventSource=self.tasks)
        for eventType in (task.Task.subjectChangedEventType(),
                          task.Task.trackStartEventType(), 
                          task.Task.trackStopEventType(),
                          'task.startDate', 'task.dueDate', 
                          'task.completionDate'):
            patterns.Publisher().registerObserver(self.onUpdateMenu, eventType)
    
    def updateMenuItems(self):
        self.clearMenu()
        activeRootTasks = self._activeRootTasks()
        activeRootTasks.sort(key=lambda task: task.subject())
        for activeRootTask in activeRootTasks:
            self.addMenuItemForTask(activeRootTask, self)
                
    def addMenuItemForTask(self, task, menu): # pylint: disable-msg=W0621
        uiCommand = uicommand.EffortStartForTask(task=task, taskList=self.tasks)
        uiCommand.addToMenu(menu, self._window)
        activeChildren = [child for child in task.children() if \
                          child in self.tasks and child.active()]
        if activeChildren:
            activeChildren.sort(key=lambda task: task.subject())
            subMenu = wx.Menu()
            for child in activeChildren:
                self.addMenuItemForTask(child, subMenu)
            menu.AppendSubMenu(subMenu, _('%s (subtasks)')%task.subject())
                        
    def enabled(self):
        return bool(self._activeRootTasks())

    def _activeRootTasks(self):
        return [rootTask for rootTask in self.tasks.rootItems() \
                if rootTask.active()]
    

class TaskPopupMenu(Menu):
    def __init__(self, mainwindow, settings, tasks, efforts, categories, taskViewer):
        super(TaskPopupMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.EditCut(viewer=taskViewer),
            uicommand.EditCopy(viewer=taskViewer),
            uicommand.EditPaste(),
            uicommand.EditPasteIntoTask(viewer=taskViewer),
            None,
            uicommand.TaskNew(taskList=tasks, settings=settings))
        self.appendMenu(_('New task &from template'),
                        TaskTemplateMenu(mainwindow, taskList=tasks, 
                                         settings=settings),
                        'newtmpl')
        self.appendUICommands(
            uicommand.TaskNewSubTask(taskList=tasks, viewer=taskViewer),
            None,
            uicommand.TaskEdit(taskList=tasks, viewer=taskViewer),
            uicommand.TaskToggleCompletion(viewer=taskViewer),
            uicommand.TaskIncPriority(taskList=tasks, viewer=taskViewer),
            uicommand.TaskDecPriority(taskList=tasks, viewer=taskViewer),
            uicommand.TaskMaxPriority(taskList=tasks, viewer=taskViewer),
            uicommand.TaskMinPriority(taskList=tasks, viewer=taskViewer),
            None,
            uicommand.TaskDelete(taskList=tasks, viewer=taskViewer),
            None,
            uicommand.TaskMail(viewer=taskViewer),
            uicommand.AddTaskAttachment(taskList=tasks, viewer=taskViewer,
                                        settings=settings),
            uicommand.OpenAllTaskAttachments(viewer=taskViewer,
                                             settings=settings)
            )
        if settings.getboolean('feature', 'notes'):
            self.appendUICommands(
                uicommand.TaskAddNote(viewer=taskViewer,
                                      settings=settings))
        self.appendMenu(_('&Toggle category'),
                        ToggleCategoryMenu(mainwindow, categories=categories,
                                           viewer=taskViewer),
                        'folder_blue_arrow_icon')
        if settings.getboolean('feature', 'effort'):
            self.appendUICommands(
                None,
                uicommand.EffortNew(viewer=taskViewer, effortList=efforts,
                                    taskList=tasks, settings=settings),
                uicommand.EffortStart(viewer=taskViewer, taskList=tasks),
                uicommand.EffortStop(taskList=tasks))
        if taskViewer.isTreeViewer():
            self.appendUICommands(None,
                uicommand.ViewExpandSelected(viewer=taskViewer),
                uicommand.ViewCollapseSelected(viewer=taskViewer))


class EffortPopupMenu(Menu):
    def __init__(self, mainwindow, tasks, settings, efforts, effortViewer):
        super(EffortPopupMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.EditCut(viewer=effortViewer),
            uicommand.EditCopy(viewer=effortViewer),
            uicommand.EditPaste(),
            None,
            uicommand.EffortNew(viewer=effortViewer, effortList=efforts,
                                taskList=tasks, settings=settings),
            uicommand.EffortEdit(viewer=effortViewer, effortList=efforts),
            uicommand.EffortDelete(viewer=effortViewer, effortList=efforts),
            None,
            uicommand.EffortStop(taskList=tasks))


class CategoryPopupMenu(Menu):
    def __init__(self, mainwindow, settings, taskFile, categoryViewer, localOnly=False):
        super(CategoryPopupMenu, self).__init__(mainwindow)
        categories = categoryViewer.presentation()
        tasks = taskFile.tasks()
        notes = taskFile.notes()
        self.appendUICommands(
            uicommand.EditCut(viewer=categoryViewer),
            uicommand.EditCopy(viewer=categoryViewer),
            uicommand.EditPaste())
        if not localOnly:
            self.appendUICommands(
                None,
                uicommand.NewTaskWithSelectedCategories(taskList=tasks,
                                                        settings=settings,
                                                        categories=categories,
                                                        viewer=categoryViewer))
            if settings.getboolean('feature', 'notes'):
                self.appendUICommands(
                    uicommand.NewNoteWithSelectedCategories(notes=notes,
                        settings=settings, categories=categories,
                        viewer=categoryViewer))
        self.appendUICommands(
            None,
            uicommand.CategoryNew(categories=categories, settings=settings),
            uicommand.CategoryNewSubCategory(viewer=categoryViewer,
                                             categories=categories),
            uicommand.CategoryEdit(viewer=categoryViewer,
                                   categories=categories),
            uicommand.CategoryDelete(viewer=categoryViewer,
                                     categories=categories),
            None,
            uicommand.AddCategoryAttachment(viewer=categoryViewer,
                                            settings=settings),
            uicommand.OpenAllCategoryAttachments(viewer=categoryViewer,
                                                 settings=settings))
        if settings.getboolean('feature', 'notes'):
            self.appendUICommands(
                uicommand.CategoryAddNote(viewer=categoryViewer,
                                          settings=settings))
        self.appendUICommands(
            None,
            uicommand.ViewExpandSelected(viewer=categoryViewer),
            uicommand.ViewCollapseSelected(viewer=categoryViewer))


class NotePopupMenu(Menu):
    def __init__(self, mainwindow, settings, notes, categories, noteViewer):
        super(NotePopupMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.EditCut(viewer=noteViewer),
            uicommand.EditCopy(viewer=noteViewer),
            uicommand.EditPaste(),
            None,
            uicommand.NoteNew(notes=notes, settings=settings),
            uicommand.NoteNewSubNote(viewer=noteViewer, notes=notes),
            uicommand.NoteEdit(viewer=noteViewer, notes=notes),
            uicommand.NoteDelete(viewer=noteViewer, notes=notes),
            None,
            uicommand.NoteMail(viewer=noteViewer),
            None,
            uicommand.AddNoteAttachment(viewer=noteViewer, settings=settings),
            uicommand.OpenAllNoteAttachments(viewer=noteViewer,
                                             settings=settings))
        self.appendMenu(_('&Toggle category'),
                        ToggleCategoryMenu(mainwindow, categories=categories,
                                           viewer=noteViewer),
                        'folder_blue_arrow_icon')
        self.appendUICommands(
            None,
            uicommand.ViewExpandSelected(viewer=noteViewer),
            uicommand.ViewCollapseSelected(viewer=noteViewer))
       
        
# Column header popup menu

class ColumnPopupMenu(Menu):
    def __init__(self, window):
        super(ColumnPopupMenu, self).__init__(window)
        wx.CallAfter(self.appendUICommands, *self.getUICommands())
        
    def __setColumn(self, columnIndex):
        self.__columnIndex = columnIndex # pylint: disable-msg=W0201
    
    def __getColumn(self):
        return self.__columnIndex
    
    # columnIndex is the index of the column clicked by the user to popup 
    # this menu.  This property should be set by the control popping up this 
    # menu (see widgets._CtrlWithColumnPopupMenuMixin).
    columnIndex = property(__getColumn, __setColumn) 
                            
    def getUICommands(self):
        return [uicommand.HideCurrentColumn(viewer=self._window), None] + \
            self._window.getColumnUICommands()
            

class EffortViewerColumnPopupMenu(DynamicMenuThatGetsUICommandsFromViewer):
    def __setColumn(self, columnIndex):
        self.__columnIndex = columnIndex # pylint: disable-msg=W0201
    
    def __getColumn(self):
        return self.__columnIndex
    
    # columnIndex is the index of the column clicked by the user to popup 
    # this menu. This property should be set by the control popping up 
    # this menu (see widgets._CtrlWithColumnPopupMenuMixin).
    columnIndex = property(__getColumn, __setColumn) 

    def registerForMenuUpdate(self):
        self._window.Bind(wx.EVT_UPDATE_UI, self.onUpdateMenu)
                            
    def getUICommands(self):
        if not self._window: # Prevent PyDeadObject exception when running tests
            return []
        return [uicommand.HideCurrentColumn(viewer=self._window), None] + \
            self._window.getColumnUICommands()


class AttachmentPopupMenu(Menu):
    def __init__(self, mainwindow, settings, attachments, attachmentViewer):
        super(AttachmentPopupMenu, self).__init__(mainwindow)
        self.appendUICommands(
            uicommand.EditCut(viewer=attachmentViewer),
            uicommand.EditCopy(viewer=attachmentViewer),
            uicommand.EditPaste(),
            None,
            uicommand.AttachmentNew(attachments=attachments, settings=settings),
            uicommand.AttachmentEdit(viewer=attachmentViewer, attachments=attachments),
            uicommand.AttachmentDelete(viewer=attachmentViewer, attachments=attachments),
            uicommand.AttachmentOpen(viewer=attachmentViewer, attachments=attachments),
            )

        if settings.getboolean('feature', 'notes'):
            self.appendUICommands(
                None,
                uicommand.AttachmentAddNote(viewer=attachmentViewer,
                                            settings=settings))
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.