navtree.py 6.47 KB
Newer Older
Renaud Le Gac's avatar
Renaud Le Gac committed
1
""" Author: R. Le Gac
2 3 4 5

"""

import locale
6
import os
7
from gluon import current
Renaud Le Gac's avatar
Renaud Le Gac committed
8
from helper import is_mathjax
9 10


11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
def to_panel(**kwargs):
    """Return the configuration dictionary of an Ext.Panel.

    The keyword arguments are the configuration options of
    the Ext.Panel widget.
    
    """
    cfg = {'xtype': 'panel'}
    cfg.update(kwargs)
    return cfg


def to_fieldset(fields, **kwargs):
    """Return the confiuration dictionary of Ext.form.Fieldset.
    This widget contains list of Ext.form.Field.
    
    fields is a list of configuration dictioanry for form.Fields.

    The keyword arguments are the configuration options of
    the Ext.form.FieldSet widget.
    
    """
    cfg = {'defaults': {'anchor': '99%'},
           'items': fields,
           'xtype': 'fieldset'}
    cfg.update(kwargs)
    return cfg

    
def to_panelWithUrlSelector(panelCfg,
                            selectorCfg,
42
                            baseUrl=None,
43
                            application=None,
44
                            controller=None,
45
                            function=None,
46
                            ctrlField=None,
47 48
                            extField=None,
                            funcField=None):
Renaud Le Gac's avatar
Renaud Le Gac committed
49
    """Return the configuration dictionary for an App.PanelWithUrlSelector.
50
    
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    This widget is split in two part a main panel and a selector.
    The selector display a list of fields organized in fieldset.
    There values define the URL parameters. The main panel displays 
    the URL content.
    
    Configuration dictionary for the main panel and fieldset are set via:
    
        panelCfg
        
        selectorCfg
        
    In web2py an URL is defined as application/controller/function.extension
    There are several ways to define it. 
    
        application
            The base URL is: /application
67 68
            By default the application is the current application.
            
Renaud Le Gac's avatar
Renaud Le Gac committed
69
        baseUrl
70 71 72 73 74 75 76 77 78 79 80 81 82
            Another way to defined the URL associated to the panel.
            It should be a well-formed URL string, i.e http://blabla.
            It is a more general approach where the URL can point to a
            any links.
            
        controller
            The base URL is: /application/controller.

        function
            The base URL is: /application/controller/function.
        
    The URL can be modified dynamicaly by extracting the name of the
    controller, function and/or  extension from the selector fields.
83
                        
Renaud Le Gac's avatar
Renaud Le Gac committed
84
        ctrlField
85 86
            Name of the field defining the name of the controller.
            When define the URL become baseURL/ctrlFieldValue.
Renaud Le Gac's avatar
Renaud Le Gac committed
87
        
88
        extField
89 90 91 92 93 94 95 96 97 98 99
            Name of the field defining the name of the extension.
            When define the URL become baseUrl.extFieldValue.
            Useful to play with different view rendering the same
            controller/function.

        funcField
            Name of the form field defining the name of the function.
            When define the URL become baseURL/funcFieldValue.
            To be used with ctrlField. In that case the URL is
            /application/ctrFieldValue/funcFieldValue.
    
100
    """
101 102 103
    url = baseUrl
    if not url:
        if application:
104
            url = os.path.join('/', application)
105
        else:
106 107 108 109 110 111 112
            url = os.path.join('/', current.request.application)

        if controller:
            url = os.path.join(url, controller)

        if function:
            url = os.path.join(url, function)
113 114
        
    cfg = {'baseUrl': url,
Renaud Le Gac's avatar
Renaud Le Gac committed
115
           'ctrlField': ctrlField,
legac's avatar
legac committed
116
           'extField': extField,
117
           'funcField': funcField,
118
           'isMathJax': is_mathjax(),
119 120
           'panelCfg': panelCfg,
           'selectorCfg': selectorCfg,
121
           'xtype': 'xpanelwithurlselector'}
122

123 124 125
    return cfg


Renaud Le Gac's avatar
Renaud Le Gac committed
126
def to_urlPanel(url):
127
    """Return the configuration dictionary for an Ext.Panel
128
    displaying an URL.
129 130
    
        url
Renaud Le Gac's avatar
Renaud Le Gac committed
131
            well-formed URL string, i.e http://blabla
132
    
133
    """
134 135
    cfg = to_panel(autoload=url,
                   preventBodyReset=True)
Renaud Le Gac's avatar
Renaud Le Gac committed
136

137 138
    if is_mathjax():
        cfg['plugins'] = ['pPanelMathJax']
139 140
    
    return cfg
141

142

143 144 145 146
class Node(object):
    """Node associating a leaf to a widget.
    
    """
Renaud Le Gac's avatar
Renaud Le Gac committed
147
    def __init__(self, text):
148
        """Constructor of the node
149 150
        
                text
151
                    name of the node appearing in the viewport
Renaud Le Gac's avatar
Renaud Le Gac committed
152 153 154 155 156 157 158 159 160 161 162 163
                                    
        """
        self.text = text
        self.children = []
        self.hidden = []


    def add_child(self, text, cfg):
        """Add a child (leaf) to the node.
        
                text
                    the name of the leaf
164
                    
Renaud Le Gac's avatar
Renaud Le Gac committed
165 166 167 168 169 170 171 172 173 174 175 176
                cfg
                    configuration dictionary for the associated
                    ExtJS widget

        """
        di = {'cfg': cfg, 'leaf': True, 'text': text}
        self.children.append(di)


    def add_children(self, leaves, func=None, hidden=[]):
        """Helper method to add children to the node.
        
177
                leaves
Renaud Le Gac's avatar
Renaud Le Gac committed
178
                    a list of string
179
                    
Renaud Le Gac's avatar
Renaud Le Gac committed
180 181 182 183
                func
                    function to translate the leaf name into 
                    the configuration dictionary of the associated ExtJS widget

184
                hidden
Renaud Le Gac's avatar
Renaud Le Gac committed
185 186 187
                    List of children to be hidden
                    
        Leaf names are translated and sorted by alphabetic order.
188

Renaud Le Gac's avatar
Renaud Le Gac committed
189
        """
190
        # translator
191 192
        T = current.T
        
Renaud Le Gac's avatar
Renaud Le Gac committed
193
        # translate and order leaves in alphabetic order 
194 195 196 197
        # according to local setting
        cvt = {}
        for el in leaves:
            cvt[T(el)] = el
198
                  
199 200 201
        translate_leaves = cvt.keys()
        translate_leaves.sort(cmp=locale.strcoll)            

202
        # fill the node with its children        
203 204 205
        for tr_leaf in translate_leaves:
            leaf = cvt[tr_leaf]        
            if leaf in hidden:
206
                continue
207

Renaud Le Gac's avatar
Renaud Le Gac committed
208
            self.add_child(tr_leaf, func(leaf))
209
                
Renaud Le Gac's avatar
Renaud Le Gac committed
210

211 212
    def get_node(self):
        """Return the configuration dictionary for the node.
Renaud Le Gac's avatar
Renaud Le Gac committed
213
        
214 215
        """
        return {'text': self.text, 'children': self.children}
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231


    def sort_children(self):
        """sort children according to alphabetical order.
        
        """
        di = {}
        for child in self.children:
            di[child['text']] = child
            
        names = di.keys()
        names.sort(cmp=locale.strcoll)
        
        self.children = []
        for name in names:
            self.children.append(di[name])