ed_shelf.py :  » GUI » wxPython » wxPython-src-2.8.11.0 » wxPython » wx » tools » Editra » src » 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 » GUI » wxPython 
wxPython » wxPython src 2.8.11.0 » wxPython » wx » tools » Editra » src » ed_shelf.py
###############################################################################
# Name: ed_shelf.py                                                           #
# Purpose: Editra Shelf container                                             #
# Author: Cody Precord <cprecord@editra.org>                                  #
# Copyright: (c) 2009 Cody Precord <staff@editra.org>                         #
# License: wxWindows License                                                  #
###############################################################################

"""
Shelf plugin and control implementation

@summary: Shelf Implementation

"""

__author__ = "Cody Precord <cprecord@editra.org>"
__svnid__ = "$Id: ed_shelf.py 64251 2010-05-08 23:42:10Z CJP $"
__revision__ = "$Revision: 64251 $"

#-----------------------------------------------------------------------------#
# Imports
import re
import wx

# Editra Libraries
import ed_menu
import ed_glob
from profiler import Profile_Get
import plugin
import iface
import extern.aui as aui

#--------------------------------------------------------------------------#
# Globals

PGNUM_PAT = re.compile(' - [0-9]+')
_ = wx.GetTranslation

#-----------------------------------------------------------------------------#

def mainwinonly(func):
    """Decorator method to add guards for methods that require the parent
    to be a MainWindow instance

    """
    def WrapMainWin(*args, **kwargs):
        self = args[0]
        if not hasattr(self._parent, 'GetFrameManager'):
            return
        else:
            func(*args, **kwargs)

    WrapMainWin.__name__ = func.__name__
    WrapMainWin.__doc__ = func.__doc__
    return WrapMainWin

#-----------------------------------------------------------------------------#

class Shelf(plugin.Plugin):
    """Plugin that creates a notebook for holding the various Shelf items
    implemented by L{ShelfI}.

    """
    SHELF_NAME = u'Shelf'
    observers = plugin.ExtensionPoint(iface.ShelfI)
    delegate = None

    def GetUiHandlers(self):
        """Gets the update ui handlers for the shelf's menu
        @return: [(ID, handler),]

        """
        handlers = [ (item.GetId(), Shelf.delegate.UpdateShelfMenuUI)
                     for item in self.observers ]
        return handlers

    def Init(self, parent):
        """Mixes the shelf into the parent window
        @param parent: Reference to MainWindow

        """
        # First check if the parent has an instance already
        parent = parent
        mgr = parent.GetFrameManager()
        if mgr.GetPane(Shelf.SHELF_NAME).IsOk():
            return

        shelf = EdShelfBook(parent)
        mgr.AddPane(shelf,
                    wx.aui.AuiPaneInfo().Name(Shelf.SHELF_NAME).\
                            Caption("Shelf").Bottom().Layer(0).\
                            CloseButton(True).MaximizeButton(False).\
                            BestSize(wx.Size(500,250)))

        # Hide the pane and let the perspective manager take care of it
        mgr.GetPane(Shelf.SHELF_NAME).Hide()
        mgr.Update()

        # Create the delegate
        # Parent MUST take ownership and clear the class variable before
        # another call to Init is made.
        delegate = EdShelfDelegate(shelf, self)
        assert Shelf.delegate is None, "Delegate not cleared!"
        Shelf.delegate = delegate

        # Install Shelf menu under View and bind event handlers
        view = parent.GetMenuBar().GetMenuByName("view")
        menu = delegate.GetMenu()
        pos = 0
        for pos in xrange(view.GetMenuItemCount()):
            mitem = view.FindItemByPosition(pos)
            if mitem.GetId() == ed_glob.ID_PERSPECTIVES:
                break

        view.InsertMenu(pos + 1, ed_glob.ID_SHELF, _("Shelf"), 
                        menu, _("Put an item on the Shelf"))

        for item in menu.GetMenuItems():
            if item.IsSeparator():
                continue
            parent.Bind(wx.EVT_MENU, delegate.OnGetShelfItem, item)

        if menu.GetMenuItemCount() < 3:
            view.Enable(ed_glob.ID_SHELF, False)

        # Check for any other plugin specific install needs
        for observer in self.observers:
            if not observer.IsInstalled() and \
               hasattr(observer, 'InstallComponents'):
                observer.InstallComponents(parent)

        delegate.StockShelf(Profile_Get('SHELF_ITEMS', 'list', []))

#--------------------------------------------------------------------------#

class EdShelfBook(aui.AuiNotebook):
    """Shelf notebook control"""
    def __init__(self, parent):
        style = aui.AUI_NB_BOTTOM | \
                aui.AUI_NB_TAB_SPLIT | \
                aui.AUI_NB_SCROLL_BUTTONS | \
                aui.AUI_NB_CLOSE_ON_ACTIVE_TAB | \
                aui.AUI_NB_TAB_MOVE | \
                aui.AUI_NB_DRAW_DND_TAB
        if wx.Platform == '__WXMAC__':
            style |= aui.AUI_NB_CLOSE_ON_TAB_LEFT
        aui.AuiNotebook.__init__(self, parent, agwStyle=style)

        # Attributes
        self._parent = parent
        self._open = dict()
        self._imgidx = dict()
        self._imglst = wx.ImageList(16, 16)

        # Setup
        self.SetImageList(self._imglst)
        self.SetSashDClickUnsplit(True)

    @property
    def ImgIdx(self):
        return self._imgidx

    @property
    def ImageList(self):
        return self._imglst

    def AddItem(self, item, name, imgid=-1):
        """Add an item to the shelf's notebook. This is useful for interacting
        with the Shelf from outside its interface. It may be necessary to
        call L{EnsureShelfVisible} before or after adding an item if you wish
        the shelf to be shown when the item is added.
        @param item: A panel like instance to add to the shelf's notebook
        @param name: Items name used for page text in notebook

        """
        self.AddPage(item, 
                     u"%s - %d" % (name, self._open.get(name, 0)),
                     select=True)

        # Set the tab icon
        if imgid >= 0 and Profile_Get('TABICONS', default=True):
            self.SetPageImage(self.GetPageCount()-1, imgid)
        self._open[name] = self._open.get(name, 0) + 1

    @mainwinonly
    def EnsureShelfVisible(self):
        """Make sure the Shelf is visible
        @precondition: Shelf.Init has been called
        @postcondition: Shelf is shown

        """
        mgr = self._parent.GetFrameManager()
        pane = mgr.GetPane(Shelf.SHELF_NAME)
        if not pane.IsShown():
            pane.Show()
            mgr.Update()

    def GetCount(self, item_name):
        """Get the number of open instances of a given Shelf Item
        @param item_name: Name of the Shelf item
        @return: number of instances on the Shelf

        """
        count = 0
        for page in xrange(self.GetPageCount()):
            if self.GetPageText(page).startswith(item_name):
                count = count + 1
        return count

    def GetMainWindow(self):
        """Get the main window that this shelf instance was created for
        @return: ed_main.MainWindow

        """
        return self._parent

    def GetOpen(self):
        """Get the list of open shelf items
        @return: list

        """
        return self._open

    @mainwinonly
    def Hide(self):
        """Hide the shelf
        @postcondition: Shelf is hidden by aui manager

        """
        mgr = self._parent.GetFrameManager()
        pane = mgr.GetPane(Shelf.SHELF_NAME)
        if pane.IsOk():
            pane.Hide()
            mgr.Update()

    def ItemIsOnShelf(self, item_name):
        """Check if at least one instance of a given item
        is currently on the Shelf.
        @param item_name: name of Item to look for

        """
        for page in xrange(self.GetPageCount()):
            if self.GetPageText(page).startswith(item_name):
                return True
        return False

    @mainwinonly
    def IsShown(self):
        """Is the shelf visible?
        @return: bool

        """
        mgr = self._parent.GetFrameManager()
        pane = mgr.GetPane(Shelf.SHELF_NAME)
        if pane.IsOk():
            return pane.IsShown()
        else:
            return False

#--------------------------------------------------------------------------#

class EdShelfDelegate(object):
    """Delegate class to mediate between the plugin singleton object and the
    UI implementation.

    """
    def __init__(self, shelf, pobject):
        """Create the delegate object
        @param shelf: Ui component instance
        @param pobject: Reference to the plugin object

        """
        object.__init__(self)

        # Attributes
        self._log = wx.GetApp().GetLog()
        self._shelf = shelf
        self._pin = pobject

    @property
    def observers(self):
        return self._pin.observers

    def AddItem(self, item, name, imgid=-1):
        """Add an item to the shelf"""
        self._shelf.AddItem(item, name, imgid)

    def CanStockItem(self, item_name):
        """See if a named item can be stocked or not, meaning if it
        can be saved and opened in the next session or not.
        @param item_name: name of item to check
        @return: bool whether item can be stocked or not

        """
        for item in self.observers:
            if item_name == item.GetName():
                if hasattr(item, 'IsStockable'):
                    return item.IsStockable()
                else:
                    break
        return False

    def EnsureShelfVisible(self):
        """Ensure the shelf is visible"""
        self._shelf.EnsureShelfVisible()

    def GetItemById(self, itemid):
        """Get the shelf item by its id
        @param itemid: Shelf item id
        @return: reference to a ShelfI object

        """
        for item in self.observers:
            if item.GetId() == itemid:
                return item
        return None

    def GetItemId(self, item_name):
        """Get the id that identifies a given item
        @param item_name: name of item to get ID for
        @return: integer id or None if not found

        """
        for item in self.observers:
            if item_name == item.GetName():
                return item.GetId()
        return None

    def GetItemStack(self):
        """Returns a list of ordered named items that are open in the shelf
        @return: list of strings

        """
        rval = list()
        if self._shelf is None:
            return rval

        for page in xrange(self._shelf.GetPageCount()):
            rval.append(re.sub(PGNUM_PAT, u'', 
                        self._shelf.GetPageText(page), 1))
        return rval

    def GetMenu(self):
        """Return the menu of this object
        @return: ed_menu.EdMenu()

        """
        menu = ed_menu.EdMenu()
        menu.Append(ed_glob.ID_SHOW_SHELF, _("Show Shelf") + \
                    ed_menu.EdMenuBar.keybinder.GetBinding(ed_glob.ID_SHOW_SHELF), 
                    _("Show the Shelf"))
        menu.AppendSeparator()
        menu_items = list()
        open_items = self._shelf.GetOpen()
        for observer in self.observers:
            # Register Observers
            open_items[observer.GetName()] = 0
            try:
                menu_i = observer.GetMenuEntry(menu)
                if menu_i is not None:
                    menu_items.append((menu_i.GetItemLabel(), menu_i))
            except Exception, msg:
                self._log("[shelf][err] %s" % str(msg))
        menu_items.sort()

        combo = 0
        for item in menu_items:
            combo += 1
            item[1].SetText(item[1].GetText() + "\tCtrl+Alt+" + str(combo))
            menu.AppendItem(item[1])
        return menu

    def GetOwnerWindow(self):
        """Return the L{ed_main.MainWindow} instance that owns/created
        this Shelf.
        @return: reference to ed_main.MainWindow or None

        """
        return self._shelf.GetMainWindow()

    def GetWindow(self):
        """Return reference to the Shelfs window component
        @return: FlatnoteBook

        """
        return self._shelf

    def OnGetShelfItem(self, evt):
        """Handles menu events that have been registered
        by the Shelf Items on the Shelf.
        @param evt: Event that called this handler

        """
        e_id = evt.GetId()
        if e_id == ed_glob.ID_SHOW_SHELF:
            parent = self.GetOwnerWindow()
            if self._shelf.IsShown():
                self._shelf.Hide()
                nb = parent.GetNotebook()
                nb.GetCurrentCtrl().SetFocus()
            else:
                self._shelf.EnsureShelfVisible()
                mgr = parent.GetFrameManager()
                pane = mgr.GetPane(Shelf.SHELF_NAME)
                if pane is not None:
                    page = pane.window.GetCurrentPage()
                    if hasattr(page, 'SetFocus'):
                        page.SetFocus()
        else:
            self.PutItemOnShelf(evt.GetId())

    def OnPutShelfItemAway(self, evt):
        """Handles when an item is closed
        @param evt: event that called this handler
        @todo: is this needed?

        """
        raise NotImplementedError

    def PutItemOnShelf(self, shelfid):
        """Put an item on the shelf by using its unique shelf id.
        This is only for use with loading items implementing the
        L{ShelfI} interface. See L{AddItem} if you wish to pass
        a panel to the shelf to add.
        @param shelfid: id of the ShelfItem to open

        """
        item = None
        for shelfi in self.observers:
            if shelfi.GetId() == shelfid:
                item = shelfi
                break

        if item is None:
            return

        name = item.GetName()
        if self._shelf.ItemIsOnShelf(name) and \
            not item.AllowMultiple() or self._shelf is None:
            return
        else:
            self.EnsureShelfVisible()
            item_id = item.GetId()
            index = -1
            if hasattr(item, 'GetBitmap'):
                if item_id in self._shelf.ImgIdx:
                    index = self._shelf.ImgIdx[item_id]
                else:
                    bmp = item.GetBitmap()
                    if bmp.IsOk():
                        index = self._shelf.ImageList.Add(bmp)
                        self._shelf.ImgIdx[item_id] = index

            self.AddItem(item.CreateItem(self._shelf), name, index)

    def RaiseItem(self, item_name):
        """Set the selection in the notebook to be the that of the first
        instance of item_name that is found in the shelf.
        @param item_name: ShelfI name
        @return: reference to the selected page or None if no instance is

        """
        for page in xrange(self._shelf.GetPageCount()):
            if self._shelf.GetPageText(page).startswith(item_name):
                self._shelf.SetSelection(page)
                return self._shelf.GetPage(page)
        else:
            return None

    def RaiseWindow(self, window):
        """Set the selection in the notebook to be the that of the given
        window. Mostly used internally by items implementing L{ShelfI}.
        @param window: Window object
        @return: reference to the selected page or None if no instance is

        """
        for page in xrange(self._shelf.GetPageCount()):
            ctrl = self._shelf.GetPage(page)
            if window == ctrl:
                self._shelf.SetSelection(page)
                return ctrl
        else:
            return None

    def StockShelf(self, i_list):
        """Fill the shelf by opening an ordered list of items
        @param i_list: List of named L{ShelfI} instances
        @type i_list: list of strings

        """
        for item in i_list:
            if self.CanStockItem(item):
                itemid = self.GetItemId(item)
                if itemid:
                    self.PutItemOnShelf(itemid)

    def UpdateShelfMenuUI(self, evt):
        """Enable/Disable shelf items based on whether they support
        muliple instances or not.
        @param evt: wxEVT_UPDATEUI

        """
        item = self.GetItemById(evt.GetId())
        if item is None:
            evt.Skip()
            return

        count = self._shelf.GetCount(item.GetName())
        if count and not item.AllowMultiple():
            evt.Enable(False)
        else:
            evt.Enable(True)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.