Esempio n. 1
0
    def get_action_nodes(my, scope="dependent"):
        action_nodes = []
        nodes = Xml.get_children(my.node)
        for node in nodes:
            node_name = Xml.get_node_name(node)
            if node_name == "action":
                node_scope = Xml.get_attribute(node, "scope")
                if scope and node_scope != scope:
                    continue

                action_nodes.append(node)
        return action_nodes
Esempio n. 2
0
    def get_action_nodes(my, scope="dependent"):
        action_nodes = []
        nodes = Xml.get_children(my.node)
        for node in nodes:
            node_name = Xml.get_node_name(node)
            if node_name == "action":
                node_scope = Xml.get_attribute(node, "scope")
                if scope and node_scope != scope:
                    continue

                action_nodes.append(node)
        return action_nodes
Esempio n. 3
0
    def get_action_node(my, event_name, scope="dependent"):
        nodes = Xml.get_children(my.node)
        for node in nodes:
            node_name = Xml.get_node_name(node)
            if node_name == "action":
                node_event = Xml.get_attribute(node, "event")
                if node_event != event_name:
                    continue

                node_scope = Xml.get_attribute(node, "scope")
                if scope and node_scope != scope:
                    continue

                return node
Esempio n. 4
0
    def get_action_node(my, event_name, scope="dependent"):
        nodes = Xml.get_children(my.node)
        for node in nodes:
            node_name = Xml.get_node_name(node)
            if node_name == "action":
                node_event = Xml.get_attribute(node, "event")
                if node_event != event_name:
                    continue

                node_scope = Xml.get_attribute(node, "scope")
                if scope and node_scope != scope:
                    continue

                return node
Esempio n. 5
0
    def get_action_options(my, event_name, scope="dependent"):
        options = {}
        action_node = my.get_action_node(event_name, scope=scope)
        if action_node is None:
            return options

        nodes = Xml.get_children(action_node)
        for node in nodes:
            name = Xml.get_node_name(node)
            if name == "#text":
                continue
            value = Xml.get_node_value(node)
            options[name] = value

        return options
Esempio n. 6
0
    def get_action_options(my, event_name, scope="dependent"):
        options = {}
        action_node = my.get_action_node(event_name, scope=scope)
        if action_node is None:
            return options

        nodes = Xml.get_children(action_node)
        for node in nodes:
            name = Xml.get_node_name(node)
            if name == "#text":
                continue
            value = Xml.get_node_value(node)
            options[name] = value

        return options
Esempio n. 7
0
    def add_xml_rules(my, xml):
        '''xml should be an XML object with the data in the form of
        <rules>
          <group type='sobject' default='<default>'>
            <rule key='<key>' access='<access>'/>
          </group>
        </rules>
        '''

        if isinstance(xml, basestring):
            xmlx = Xml()
            xmlx.read_string(xml)
            xml = xmlx


        my.xml = xml

        # parse shorthand rules
        rule_nodes = xml.get_nodes("rules/rule")
        if not rule_nodes:
            return


        if my.project_codes == None:
            search = Search('sthpw/project')
            projects = search.get_sobjects()
            my.project_codes = [x.get_code() for x in projects]
            my.project_codes.append('*')

        for rule_node in rule_nodes:
            # initiate the project_code here for each loop
            project_code = '*'
            group_type = Xml.get_attribute( rule_node, "group" )
            if not group_type:
                # category is the preferred name over group now
                # TODO: phase out the use of group completely
                group_type = Xml.get_attribute( rule_node, "category" )

            # get an existing rule set or create a new one
            if my.groups.has_key(group_type):
                rules = my.groups[group_type]
            else:
                rules = {}
                my.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( rule_node, "default" )
            if group_default:
                rules['__DEFAULT__'] = group_default
                continue


            # generate the rule key
            #rule_key = xml.get_attribute(rule_node, 'key')
            attrs = xml.get_attributes(rule_node)
            attrs2 = {}
            count = 0
            for name, value in attrs.items():
                if name in ['access', 'group', 'category', 'project']:
                    continue
                # have to turn everything into strings
                attrs2[str(name)] = str(value)
                count += 1


            if count == 1 and attrs2.has_key('key'):
                # backwards compatibility
                rule_key = attrs2['key']
            else:
                #rule_key = str(attrs2)
                rule_key = str(Common.get_dict_list(attrs2))

            rule_project =  xml.get_attribute(rule_node, 'project')
            if rule_project:
                project_code = rule_project
                # special treatment for search_filter to enable
                # project-specific search
                if group_type=='search_filter':
                    attrs2['project'] = rule_project
            
            # if there is a value, then combine it with the key
            rule_value = xml.get_attribute(rule_node, 'value')
            if rule_value:
                rule_key = "%s||%s" % (rule_key, rule_value)

            # add a project code qualifier
            rule_keys = []
            if project_code == '*' and group_type != 'search_filter':
                for code in my.project_codes:
                    key = "%s?project=%s" % (rule_key, code)
                    rule_keys.append(key)
            else:
                key= "%s?project=%s" % (rule_key, project_code)

                #key = str(key) # may need to stringify unicode string
                rule_keys.append(key)

            rule_access = xml.get_attribute(rule_node, 'access')

            #if rule_access == "":
            #    raise AccessException("Cannot have empty 'access':\n%s" \
            #        % xml.to_string(rule_node) )

            # if no key is specified, it is considered a DEFAULT
            if not rule_keys and not rule_value:
                rule_keys = ['__DEFAULT__']
            for rule_key in rule_keys:
                # check if rule_access exists first, which doesn't for search_filter,
                # but it has to go into the rules regardless
                # if the rule already exists, take the highest one
                if rule_access and rules.has_key(rule_key):
                    curr_access, cur_attrs = rules[rule_key]

                    try:
                        access_enum = my._get_access_enum(rule_access)
                        if my._get_access_enum(curr_access) > access_enum:
                            continue
                    except:
                        if group_type == "builtin":
                            continue
                        else:
                            raise


                rules[rule_key] = rule_access, attrs2


        #for rule, values in rules.items():
        #    print "rule: ", rule, values[0]


        # FIXME: this one doesn't support the multi-attr structure
        # convert this to a python data structure
        group_nodes = xml.get_nodes("rules/group")
        for group_node in group_nodes:

            group_type = Xml.get_attribute( group_node, "type" )

            # get an existing rule set or create a new one
            if my.groups.has_key(group_type):
                rules = my.groups[group_type]
            else:
                rules = {}
                my.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( group_node, "default" )
            if group_default != "":
                rules['__DEFAULT__'] = group_default


            # get all of the rule nodes
            rule_nodes = Xml.get_children(group_node)
            for rule_node in rule_nodes:
                project_code='*'

                if Xml.get_node_name(rule_node) != 'rule':
                    continue

                rule_key = xml.get_attribute(rule_node, 'key')
                rule_access = xml.get_attribute(rule_node, 'access')

                rule_project =  xml.get_attribute(rule_node, 'project')
                if rule_project:
                    project_code = rule_project
                if rule_access == "":
                    raise AccessException("Cannot have empty 'access':\n%s" \
                        % xml.to_string(rule_node) )

                rule_keys = []
                attrs2 = {'key': rule_key}

                # add a project code qualifier
                if project_code == '*' and group_type != 'search_filter':
                    for code in my.project_codes:
                        key = "%s?project=%s" % (rule_key, code)
                        rule_keys.append(key)
                else:
                    key= "%s?project=%s" % (rule_key, project_code)
                    rule_keys.append(key)

                for rule_key in rule_keys:
                    rules[rule_key] = rule_access, attrs2
Esempio n. 8
0
class PageNavContainerWdg(BaseRefreshWdg):
    def init(self):

        link = self.kwargs.get('link')
        hash = self.kwargs.get('hash')

        self.widget = None

        if link:
            from tactic.ui.panel import SideBarBookmarkMenuWdg
            personal = False
            if '.' in link:
                personal = True

            config = SideBarBookmarkMenuWdg.get_config("SideBarWdg",
                                                       link,
                                                       personal=personal)
            options = config.get_display_options(link)

            # this is vital for view saving
            element_name = link
            attr_dict = config.get_element_attributes(link)
            title = attr_dict.get('title')

            hash = "/tab/%s" % link

            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.panel.HashPanelWdg">
                <hash>%s</hash>
                <element_name>%s</element_name>
                <title>%s</title>
              </display>
              <web/>
            </element>
            </application>
            </config>
            ''' % (hash, element_name, title)

        elif hash:
            from tactic.ui.panel import HashPanelWdg
            self.widget = HashPanelWdg.get_widget_from_hash(
                hash, force_no_index=True)
            config = None

        else:
            security = Environment.get_security()
            start_link = security.get_start_link()
            if start_link:
                self.kwargs['link'] = start_link
                return self.init()

            # search for a defined welcome view
            search = Search("config/widget_config")
            search.add_filter("category", "top_layout")
            search.add_filter("view", "welcome")
            config_sobj = search.get_sobject()
            if config_sobj:
                config = config_sobj.get_value("config")

            else:
                config = WidgetSettings.get_value_by_key("top_layout")

        if not config:
            config = self.get_default_config()

        self.config_xml = Xml()
        self.config_xml.read_string(config)

    def get_default_config(self):
        use_sidebar = self.kwargs.get('use_sidebar')
        if use_sidebar == False:
            config = '''
            <config>
            <application>
            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        else:
            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
                <auto_size>True</auto_size>
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        return config

    def set_state(self, panel_name, widget_class, options, values):
        '''this is called by side_bar.js mostly'''

        # set the class name
        display_node = self.config_xml.get_node(
            "config/application/element[@name='%s']/display" % (panel_name))
        self.config_xml.set_attribute(display_node, "class", widget_class)

        # remove all the old options
        #display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % panel_name )
        for child_node in self.config_xml.get_children(display_node):
            self.config_xml.remove_child(display_node, child_node)

        # set the options
        for name, value in options.items():
            node = self.config_xml.get_node(
                "config/application/element[@name='%s']/display/%s" %
                (panel_name, name))

            if isinstance(value, basestring):
                #print("WARNING: set application: skipping [%s] with value [%s]" % (name, value))
                #continue
                element = self.config_xml.create_text_element(name, value)
                self.config_xml.append_child(display_node, element)

            elif isinstance(value, dict):  # if it is a dictionary
                # TODO: run recursively.. supports 2 level only now
                sub_element = self.config_xml.create_element(name)
                self.config_xml.append_child(display_node, element)
                for name2, value2 in value.items():
                    if isinstance(value2, dict):
                        sub_element2 = self.config_xml.create_element(name2)
                        self.config_xml.append_child(sub_element, sub_element2)
                        for name3, value3 in value2.items():
                            element = self.config_xml.create_text_element(
                                name3, value3)
                            self.config_xml.append_child(sub_element2, element)
                    else:
                        element = self.config_xml.create_text_element(
                            name2, value2)
                        self.config_xml.append_child(sub_element, element)

        # web value node
        value_node = self.config_xml.get_node(
            "config/application/element[@name='%s']/web" % (panel_name))
        if value_node != None:
            for child_node in self.config_xml.get_children(value_node):
                self.config_xml.remove_child(value_node, child_node)
        else:  # create it
            value_node = self.config_xml.create_element('web')
            element_node = self.config_xml.get_node(
                "config/application/element[@name='%s']" % (panel_name))
            self.config_xml.append_child(element_node, value_node)

        # set the values
        for name, value in values.items():
            node = self.config_xml.get_node(
                "config/application/element[@name='%s']/web/%s" %
                (panel_name, name))

            if not isinstance(value, basestring):
                print(
                    "WARNING: set application: skipping [%s] with value [%s]" %
                    (name, value))
                continue
            element = self.config_xml.create_text_element(name, value)
            self.config_xml.append_child(value_node, element)
        WidgetSettings.set_key_values("top_layout",
                                      [self.config_xml.to_string()])

    def get_state(self):
        return self.config_xml

    def get_side_bar_cache(self, left_nav_wdg):
        project = Project.get()
        project_code = project.get_code()

        # do it with sobject
        #key = "%s_side_bar" % project.get_code()
        #cache = Search.get("sthpw/widget_cache")
        #cache.add_filter("key", key)
        #sobject = cache.get_sobject()
        #value = sobject.get_value("cache")

        login = Environment.get_user_name()
        tmp_dir = "%s/cache/side_bar" % Environment.get_tmp_dir()

        filename = "%s__%s.html" % (project_code, login)
        path = "%s/%s" % (tmp_dir, filename)

        # use files
        import os
        if os.path.exists(path):
            f = open(path, "r")
            html = f.read()
            f.close()
        else:
            dirname = os.path.dirname(path)
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            f = open(path, "w")
            html = left_nav_wdg.get_buffer_display()
            f.write(html)
            f.close()

        return html

    def get_display(self):
        is_admin_project = Project.get().is_admin()
        security = Environment.get_security()
        if is_admin_project and not security.check_access(
                "builtin", "view_site_admin", "allow"):
            return Error403Wdg()

        # create the elements
        config = WidgetConfig.get(xml=self.config_xml, view="application")

        left_nav_handler = config.get_display_handler("left_nav")
        left_nav_options = config.get_display_options("left_nav")

        view_side_bar = None
        if left_nav_handler:
            left_nav_wdg = Common.create_from_class_path(
                left_nav_handler, [], left_nav_options)

            # caching
            side_bar_cache = self.get_side_bar_cache(left_nav_wdg)
        else:
            view_side_bar = False

        # create the main table
        core_table = Table()
        core_table.add_tbody()
        core_table.set_style(
            "border: 0px; border-collapse: collapse; width: 100%;")

        # add a spacer row
        #spacer_tr = core_table.add_row()
        #spacer_tr.add_style("width: 100%")
        #td = core_table.add_cell()
        #td.set_style("min-height: 1px; height: 1px;")
        #core_table.add_cell()
        #core_table.add_cell()

        # determine if the side bar is visible
        if view_side_bar == None:
            view_side_bar = security.check_access("builtin",
                                                  "view_side_bar",
                                                  "allow",
                                                  default='allow')

        # add the main cells
        tr, td = core_table.add_row_cell()
        td.add_style("padding: 0px")
        td.add_style("margin: 0px")

        # add the main resizable table
        from tactic.ui.container import ResizableTableWdg
        main_table = ResizableTableWdg()
        main_table.set_keep_table_size()

        main_table.add_style("width: 100%")

        td.add(main_table)

        left_nav_td = main_table.add_cell()
        if view_side_bar:
            left_nav_td.add_class("spt_panel")
            left_nav_td.add_style("padding: 0px")

        main_body_td = main_table.add_cell(resize=False)
        main_body_td.add_style("padding: 10px")
        main_body_td.set_style(
            "width: 100%; vertical-align: top; text-align: center; padding-top: 3px"
        )

        if view_side_bar:
            left_nav_td.set_style("vertical-align: top")

            # create the left navigation panel
            left_nav_div = DivWdg()
            left_nav_td.add(left_nav_div)

            left_nav_div.set_id("side_bar")
            # add the detail to the panel
            left_nav_div.add_attr("spt_class_name", left_nav_handler)
            for name, value in left_nav_options.items():
                left_nav_div.add_attr("spt_%s" % name, value)

            left_nav_div.add_style("max_width: 185px")
            left_nav_div.add_style("width: 185px")
            left_nav_div.add_style("text-align: right")
            left_nav_div.add_style("vertical-align: top")
            left_nav_div.add_style("overflow: hidden")

            left_nav_div.add_class("spt_resizable")
            side_bar_inner = DivWdg()
            left_nav_div.add(side_bar_inner)

            #side_bar_inner.add_style("padding-left: 1px")
            side_bar_inner.add_style("width: 100%")

            # add side bar to nav
            side_bar_inner.add(side_bar_cache)

            left_nav_div.add_style("border-style: solid")
            left_nav_div.add_style("border-width: 0px 1px 0px 0px")
            #left_nav_div.add_color("border-color", "border")
            left_nav_div.add_color("border-color", "border", -10)

            web = WebContainer.get_web()
            browser = web.get_browser()
            if browser in ['Qt', 'Webkit']:
                min_width = "1px"
            else:
                min_width = "0px"

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|hide_now',
                'min_width':
                min_width,
                'cbjs_action':
                '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                bvr.src_el.setStyle("width", bvr.min_width);

                '''
            })

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|hide',
                'min_width':
                min_width,
                'cbjs_action':
                '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width);

                '''
            })

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|show',
                'min_width':
                min_width,
                'cbjs_action':
                '''
                var width = bvr.src_el.getAttribute("spt_size");
                if (!width) {
                   width = 185;
                }
                if (parseInt(width) < 5) {
                    width = 185;
                }
                //bvr.src_el.setStyle("width", width + "px");
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width, width+"px");
                '''
            })

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|toggle',
                'cbjs_action':
                '''
                var size = bvr.src_el.getSize();
                if (size.x < 5) {
                    spt.named_events.fire_event("side_bar|show", {} );
                }
                else {
                    spt.named_events.fire_event("side_bar|hide", {} );
                }
                '''
            })

        # create the main body panel

        palette = WebContainer.get_palette()
        color = palette.color("background2")
        main_body_rounded = DivWdg()
        main_body_inner = main_body_rounded

        main_body_inner.add_style("min-height: 500px")

        # DEBREACATED
        """
        # add a breadcrumb
        breadcrumb_wdg = DivWdg()
        # hide the breadcrumb
        breadcrumb_wdg.add_style("display", "none")
        Container.put("breadcrumb", breadcrumb_wdg)
        breadcrumb_wdg.set_id("breadcrumb")
        breadcrumb_wdg.add_style("text-align: left")
        breadcrumb_wdg.add_looks( "fnt_title_3" )
        main_body_inner.add(breadcrumb_wdg)
        """

        main_body_panel = DivWdg()
        main_body_panel.set_id("main_body")
        main_body_panel.add_class("spt_main_panel")
        main_body_inner.add(main_body_panel)

        tab = MainBodyTabWdg()
        main_body_panel.add(tab)

        # TEST: NEW LAYOUT
        if Config.get_value("install", "layout") == "fixed":
            main_body_panel.add_style("margin-top: 31px")
            main_body_rounded.add_color("background", "background")
            main_body_rounded.add_style("padding: 3px 0px 0px 0px")

        # add the content to the main body panel
        try:
            if self.widget:
                tab.add(self.widget)
                element_name = self.widget.get_name()

            else:
                main_body_handler = config.get_display_handler("main_body")
                main_body_options = config.get_display_options("main_body")
                element_name = main_body_options.get("element_name")
                title = main_body_options.get("title")

                main_body_content = Common.create_from_class_path(
                    main_body_handler, [], main_body_options)
                # get the web values from top_layout
                main_body_values = config.get_web_options("main_body")
                web = WebContainer.get_web()
                if isinstance(main_body_values, dict):
                    for name, value in main_body_values.items():
                        web.set_form_value(name, value)

                main_body_content.set_name(element_name)
                tab.add(main_body_content, element_name, title)

                self.set_as_panel(main_body_panel,
                                  class_name=main_body_handler,
                                  kwargs=main_body_options)

            main_body_panel.add_behavior({
                'type':
                'load',
                'element_name':
                element_name,
                'cbjs_action':
                '''
                if (spt.help)
                    spt.help.set_view(bvr.element_name);
                '''
            })

        except Exception as e:
            # handle an error in the drawing
            buffer = self.get_buffer_on_exception()
            error_wdg = self.handle_exception(e)
            main_body_content = DivWdg()
            main_body_content.add(error_wdg)
            main_body_content = main_body_content.get_buffer_display()
            tab.add(main_body_content, element_name, title)

        # add the main container
        container_div = DivWdg()
        container_div.set_style("width: 100%;")

        # NOTE: the td should not be the sliding element! So we create a div inside the TD to be the sliding element
        main_body_div = DivWdg()
        main_body_div.set_id("horizontal_main_body_slider")

        main_body_div.add(main_body_inner)
        """
        # get the global drag_ghost_div
        drag_ghost_div = self.get_drag_ghost_div()
        drag_ghost_div.set_id( "drag_ghost_copy" )
        drag_ghost_div.add_class( "SPT_PUW" )  # make it a Page Utility Widget (now processed client side)

        drag_ghost_div.set_z_start( 400 )
        """

        from page_header_wdg import PageHeaderWdg
        header_panel = DivWdg()
        header_panel.set_id("main_header")
        header_panel.add_attr("spt_class_name", "tactic.ui.app.PageHeaderWdg")
        header_wdg = PageHeaderWdg()
        header_panel.add(header_wdg)

        container_div.add(header_panel.get_buffer_display())

        main_body_dis = main_body_div.get_buffer_display()
        main_body_td.add(main_body_dis)

        container_div.add(core_table)
        #container_div.add( drag_ghost_div )

        is_admin = False
        security = Environment.get_security()
        if security.check_access("builtin", "view_site_admin", "allow"):
            is_admin = True

        if is_admin:
            from quick_box_wdg import QuickBoxWdg
            quick_box = QuickBoxWdg()
            container_div.add(quick_box)

        container_div.add_behavior({
            'type':
            'load',
            'cbjs_action':
            '''
            spt.named_events.fire_event("close_admin_bar");
            '''
        })

        return container_div

    def handle_exception(self, e):
        '''The tab widget is a special widget concerning exceptions because
        it usually represents the outer skin of the content of the web page.
        The titles of the tab must be displayed in order for the site to remain
        functional in the case of an exception'''
        from pyasm.widget import ExceptionWdg
        widget = ExceptionWdg(e)
        self.error_wdg = Widget()
        self.error_wdg.add(widget)
        return self.error_wdg

    """
    def get_drag_ghost_div(self):
        drag_ghost_div = HtmlElement.div()
        drag_ghost_div.set_attr( "id", "drag_ghost_copy" )
        drag_ghost_div.set_attr( "element_copied", "_NONE_" )
        drag_ghost_div.add_class( "REG_ID" )
        drag_ghost_div.set_style("background: #393950; color: #c2c2c2; border: solid 1px black;' \
                                 'text-align: left; padding: 10px;', filter: alpha(opacity=60); " +
                                 "opacity: 0.6; position: absolute; display: none; left: 0px; top: 0px;" +
                                 " z-index: 110;" )
        drag_ghost_div.add("Ghost Div")
        return drag_ghost_div
    """

    def get_drag_div(self):
        drag_div = HtmlElement.div()
        drag_div.set_style(
            "position: absolute; left: 100px; top: 400px; min-width: 400px; width: 400px; "
            + "background-color: white; border: solid black;")

        drag_handle_div = HtmlElement.div()
        drag_handle_div.set_style(
            "cursor: default; background-color: gray; border-bottom: dotted black; "
            + "padding: 3px; font-family: sans-serif; font-weight: bold;")

        # NOTE: to specify behaviors on a widget, you can use the .add_behavior() method ... use one behavior
        #       specification dictionary (hash) string per call to add_behavior (but you can add multiple
        #       behaviors by making multiple calls to add_behavior)
        #
        drag_handle_div.add_behavior(
            "{type:'click', mouse_btn:'LMB', modkeys:'SHIFT', dst_el:'@.parentNode', "
            + "cbfn_action: spt.cb.change_color_action}")
        drag_handle_div.add_behavior(
            "{type:'drag', mouse_btn:'LMB', modkeys:'', src_el:'@.parentNode'}"
        )
        drag_handle_div.add("Drag Handle -- click and drag me!")

        drag_div.add(drag_handle_div)
        drag_div.add(
            "<p>This is a draggable div ... click on the drag handle above and drag this thing around!</p>"
        )

        return drag_div
Esempio n. 9
0
class PageNavContainerWdg(BaseRefreshWdg):

    def init(self):

        link = self.kwargs.get('link')
        hash = self.kwargs.get('hash')
        
        self.widget = None

        if link:
            from tactic.ui.panel import SideBarBookmarkMenuWdg
            personal = False
            if '.' in link:
                personal = True

            config = SideBarBookmarkMenuWdg.get_config("SideBarWdg", link, personal=personal)
            options = config.get_display_options(link)

            # this is vital for view saving
            element_name = link
            attr_dict = config.get_element_attributes(link)
            title = attr_dict.get('title')

            hash = "/tab/%s" % link

           
            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.panel.HashPanelWdg">
                <hash>%s</hash>
                <element_name>%s</element_name>
                <title>%s</title>
              </display>
              <web/>
            </element>
            </application>
            </config>
            ''' % (hash, element_name, title)


        elif hash:
            from tactic.ui.panel import HashPanelWdg
            self.widget = HashPanelWdg.get_widget_from_hash(hash, force_no_index=True)
            config = None
 
        else:
            security = Environment.get_security()
            start_link = security.get_start_link()
            if start_link:
                self.kwargs['link'] = start_link
                return self.init()



            # search for a defined welcome view
            search = Search("config/widget_config")
            search.add_filter("category", "top_layout")
            search.add_filter("view", "welcome")
            config_sobj = search.get_sobject()
            if config_sobj:
                config = config_sobj.get_value("config")

            else:
                config = WidgetSettings.get_value_by_key("top_layout")


        if not config:
            config = self.get_default_config()


        self.config_xml = Xml()
        self.config_xml.read_string(config)



    def get_default_config(self):
        use_sidebar = self.kwargs.get('use_sidebar')
        if use_sidebar==False:
            config = '''
            <config>
            <application>
            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        else:
            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
                <auto_size>True</auto_size>
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        return config









    def set_state(self, panel_name, widget_class, options, values):
        '''this is called by side_bar.js mostly'''

        # set the class name
        display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % (panel_name) )
        self.config_xml.set_attribute(display_node, "class", widget_class)

        # remove all the old options
        #display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % panel_name )
        for child_node in self.config_xml.get_children(display_node):
            self.config_xml.remove_child(display_node, child_node)

        # set the options
        for name, value in options.items():
            node = self.config_xml.get_node("config/application/element[@name='%s']/display/%s" % (panel_name, name) )

            if isinstance( value, basestring ):
                #print("WARNING: set application: skipping [%s] with value [%s]" % (name, value))
                #continue
                element = self.config_xml.create_text_element(name, value)
                self.config_xml.append_child(display_node, element)

            elif isinstance( value, dict): # if it is a dictionary
                # TODO: run recursively.. supports 2 level only now
                sub_element = self.config_xml.create_element(name)
                self.config_xml.append_child(display_node, element)
                for name2, value2 in value.items():
                    if isinstance(value2, dict):
                        sub_element2 = self.config_xml.create_element(name2)
                        self.config_xml.append_child(sub_element, sub_element2)
                        for name3, value3 in value2.items():
                            element = self.config_xml.create_text_element(name3, value3)
                            self.config_xml.append_child(sub_element2, element)
                    else:        
                        element = self.config_xml.create_text_element(name2, value2)
                        self.config_xml.append_child(sub_element, element)
                    
                
        # web value node
        value_node = self.config_xml.get_node("config/application/element[@name='%s']/web" % (panel_name) )
        if value_node != None:
            for child_node in self.config_xml.get_children(value_node):
                self.config_xml.remove_child(value_node, child_node)
        else: # create it
            value_node = self.config_xml.create_element('web')
            element_node = self.config_xml.get_node("config/application/element[@name='%s']" % (panel_name) )
            self.config_xml.append_child(element_node, value_node)

        # set the values
        for name, value in values.items():
            node = self.config_xml.get_node("config/application/element[@name='%s']/web/%s" % (panel_name, name) )

            if not isinstance(value, basestring):
                print("WARNING: set application: skipping [%s] with value [%s]" % (name, value))
                continue
            element = self.config_xml.create_text_element(name, value)
            self.config_xml.append_child(value_node, element)
        WidgetSettings.set_key_values("top_layout", [self.config_xml.to_string()])



    def get_state(self):
        return self.config_xml



    def get_side_bar_cache(self, left_nav_wdg):
        project = Project.get()
        project_code = project.get_code()

        # do it with sobject
        #key = "%s_side_bar" % project.get_code()
        #cache = Search.get("sthpw/widget_cache")
        #cache.add_filter("key", key)
        #sobject = cache.get_sobject()
        #value = sobject.get_value("cache")

        login = Environment.get_user_name()
        tmp_dir = "%s/cache/side_bar" % Environment.get_tmp_dir()

        filename = "%s__%s.html" % (project_code, login)
        path = "%s/%s" % (tmp_dir, filename)

        # use files
        import os
        if os.path.exists(path):
            f = open(path, "r")
            html = f.read()
            f.close()
        else:            
            dirname = os.path.dirname(path)
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            f = open(path, "w")
            html = left_nav_wdg.get_buffer_display()
            f.write(html)
            f.close()

        return html




    def get_display(self):
        is_admin_project = Project.get().is_admin()
        security = Environment.get_security() 
        if is_admin_project and not security.check_access("builtin", "view_site_admin", "allow"):
            return Error403Wdg()
                
        # create the elements
        config = WidgetConfig.get(xml=self.config_xml, view="application")

        left_nav_handler = config.get_display_handler("left_nav")
        left_nav_options = config.get_display_options("left_nav")

        view_side_bar = None
        if left_nav_handler:
            left_nav_wdg = Common.create_from_class_path(left_nav_handler, [], left_nav_options)

            # caching
            side_bar_cache = self.get_side_bar_cache(left_nav_wdg)
        else:
            view_side_bar = False

        # create the main table
        core_table = Table()
        core_table.add_tbody()
        core_table.set_style("border: 0px; border-collapse: collapse; width: 100%;")


        # add a spacer row
        #spacer_tr = core_table.add_row()
        #spacer_tr.add_style("width: 100%")
        #td = core_table.add_cell()
        #td.set_style("min-height: 1px; height: 1px;")
        #core_table.add_cell()
        #core_table.add_cell()

        # determine if the side bar is visible
        if view_side_bar == None:
            view_side_bar = security.check_access("builtin", "view_side_bar", "allow", default='allow')


        # add the main cells
        tr, td = core_table.add_row_cell()
        td.add_style("padding: 0px")
        td.add_style("margin: 0px")

        # add the main resizable table
        from tactic.ui.container import ResizableTableWdg
        main_table = ResizableTableWdg()
        main_table.set_keep_table_size()

        main_table.add_style("width: 100%")

        td.add(main_table)

        left_nav_td = main_table.add_cell()
        if view_side_bar:
            left_nav_td.add_class("spt_panel")
            left_nav_td.add_style("padding: 0px")

        main_body_td = main_table.add_cell(resize=False)
        main_body_td.add_style("padding: 10px")
        main_body_td.set_style( "width: 100%; vertical-align: top; text-align: center; padding-top: 3px" )

        if view_side_bar:
            left_nav_td.set_style( "vertical-align: top" )

            # create the left navigation panel
            left_nav_div = DivWdg()
            left_nav_td.add(left_nav_div)

            left_nav_div.set_id("side_bar" )
            # add the detail to the panel
            left_nav_div.add_attr("spt_class_name", left_nav_handler)
            for name, value in left_nav_options.items():
                left_nav_div.add_attr("spt_%s" % name, value)


            left_nav_div.add_style("max_width: 185px")
            left_nav_div.add_style("width: 185px")
            left_nav_div.add_style("text-align: right")
            left_nav_div.add_style("vertical-align: top")
            left_nav_div.add_style("overflow: hidden")

            left_nav_div.add_class("spt_resizable")
            side_bar_inner = DivWdg()
            left_nav_div.add(side_bar_inner)

            #side_bar_inner.add_style("padding-left: 1px")
            side_bar_inner.add_style("width: 100%")

            # add side bar to nav
            side_bar_inner.add(side_bar_cache)

            left_nav_div.add_style("border-style: solid")
            left_nav_div.add_style("border-width: 0px 1px 0px 0px")
            #left_nav_div.add_color("border-color", "border")
            left_nav_div.add_color("border-color", "border", -10)

            web = WebContainer.get_web()
            browser = web.get_browser()
            if browser in ['Qt','Webkit']:
                min_width = "1px"
            else:
                min_width = "0px"

            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|hide_now',
                'min_width': min_width,
                'cbjs_action': '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                bvr.src_el.setStyle("width", bvr.min_width);

                '''
            } )


            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|hide',
                'min_width': min_width,
                'cbjs_action': '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width);

                '''
            } )


            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|show',
                'min_width': min_width,
                'cbjs_action': '''
                var width = bvr.src_el.getAttribute("spt_size");
                if (!width) {
                   width = 185;
                }
                if (parseInt(width) < 5) {
                    width = 185;
                }
                //bvr.src_el.setStyle("width", width + "px");
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width, width+"px");
                '''
            } )


            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|toggle',
                'cbjs_action': '''
                var size = bvr.src_el.getSize();
                if (size.x < 5) {
                    spt.named_events.fire_event("side_bar|show", {} );
                }
                else {
                    spt.named_events.fire_event("side_bar|hide", {} );
                }
                '''
            } )




        # create the main body panel

        palette = WebContainer.get_palette()
        color = palette.color("background2")
        main_body_rounded = DivWdg()
        main_body_inner = main_body_rounded

        main_body_inner.add_style("min-height: 500px")


        # DEBREACATED
        """
        # add a breadcrumb
        breadcrumb_wdg = DivWdg()
        # hide the breadcrumb
        breadcrumb_wdg.add_style("display", "none")
        Container.put("breadcrumb", breadcrumb_wdg)
        breadcrumb_wdg.set_id("breadcrumb")
        breadcrumb_wdg.add_style("text-align: left")
        breadcrumb_wdg.add_looks( "fnt_title_3" )
        main_body_inner.add(breadcrumb_wdg)
        """

        main_body_panel = DivWdg()
        main_body_panel.set_id("main_body")
        main_body_panel.add_class("spt_main_panel")
        main_body_inner.add(main_body_panel)


        tab = MainBodyTabWdg()
        main_body_panel.add(tab)

        # TEST: NEW LAYOUT
        if Config.get_value("install", "layout") == "fixed":
            main_body_panel.add_style("margin-top: 31px")
            main_body_rounded.add_color("background", "background")
            main_body_rounded.add_style("padding: 3px 0px 0px 0px")



        # add the content to the main body panel
        try:
            if self.widget:
                tab.add(self.widget)
                element_name = self.widget.get_name()

            else:
                main_body_handler = config.get_display_handler("main_body")
                main_body_options = config.get_display_options("main_body")
                element_name = main_body_options.get("element_name")
                title = main_body_options.get("title")

                main_body_content = Common.create_from_class_path(main_body_handler, [], main_body_options)
                # get the web values from top_layout
                main_body_values = config.get_web_options("main_body")
                web = WebContainer.get_web()
                if isinstance(main_body_values, dict):
                    for name, value in main_body_values.items():
                        web.set_form_value(name, value)

                main_body_content.set_name(element_name)
                tab.add(main_body_content, element_name, title)

                self.set_as_panel(main_body_panel, class_name=main_body_handler, kwargs=main_body_options)

            main_body_panel.add_behavior( {
                'type': 'load',
                'element_name': element_name,
                'cbjs_action': '''
                if (spt.help)
                    spt.help.set_view(bvr.element_name);
                '''
            } )


           
        except Exception as e:
            # handle an error in the drawing
            buffer = self.get_buffer_on_exception()
            error_wdg = self.handle_exception(e)
            main_body_content = DivWdg()
            main_body_content.add(error_wdg)
            main_body_content = main_body_content.get_buffer_display()
            tab.add(main_body_content, element_name, title)


        # add the main container
        container_div = DivWdg()
        container_div.set_style("width: 100%;")


        # NOTE: the td should not be the sliding element! So we create a div inside the TD to be the sliding element
        main_body_div = DivWdg()
        main_body_div.set_id("horizontal_main_body_slider")

        main_body_div.add(main_body_inner)



        """
        # get the global drag_ghost_div
        drag_ghost_div = self.get_drag_ghost_div()
        drag_ghost_div.set_id( "drag_ghost_copy" )
        drag_ghost_div.add_class( "SPT_PUW" )  # make it a Page Utility Widget (now processed client side)

        drag_ghost_div.set_z_start( 400 )
        """
       

        from page_header_wdg import PageHeaderWdg
        header_panel = DivWdg()
        header_panel.set_id("main_header")
        header_panel.add_attr("spt_class_name", "tactic.ui.app.PageHeaderWdg")
        header_wdg = PageHeaderWdg()
        header_panel.add(header_wdg)

        container_div.add( header_panel.get_buffer_display() )
       

        main_body_dis = main_body_div.get_buffer_display()
        main_body_td.add(main_body_dis) 


        container_div.add( core_table )
        #container_div.add( drag_ghost_div )


        is_admin = False
        security = Environment.get_security()
        if security.check_access("builtin", "view_site_admin", "allow"):
            is_admin = True

        if is_admin:
            from quick_box_wdg import QuickBoxWdg
            quick_box = QuickBoxWdg()
            container_div.add(quick_box)


        container_div.add_behavior( {
            'type': 'load',
            'cbjs_action': '''
            spt.named_events.fire_event("close_admin_bar");
            '''
        } )


        return container_div



    def handle_exception(self, e):
        '''The tab widget is a special widget concerning exceptions because
        it usually represents the outer skin of the content of the web page.
        The titles of the tab must be displayed in order for the site to remain
        functional in the case of an exception'''
        from pyasm.widget import ExceptionWdg
        widget = ExceptionWdg(e)
        self.error_wdg = Widget()
        self.error_wdg.add(widget)
        return self.error_wdg



    """
    def get_drag_ghost_div(self):
        drag_ghost_div = HtmlElement.div()
        drag_ghost_div.set_attr( "id", "drag_ghost_copy" )
        drag_ghost_div.set_attr( "element_copied", "_NONE_" )
        drag_ghost_div.add_class( "REG_ID" )
        drag_ghost_div.set_style("background: #393950; color: #c2c2c2; border: solid 1px black;' \
                                 'text-align: left; padding: 10px;', filter: alpha(opacity=60); " +
                                 "opacity: 0.6; position: absolute; display: none; left: 0px; top: 0px;" +
                                 " z-index: 110;" )
        drag_ghost_div.add("Ghost Div")
        return drag_ghost_div
    """


    def get_drag_div(self):
        drag_div = HtmlElement.div()
        drag_div.set_style( "position: absolute; left: 100px; top: 400px; min-width: 400px; width: 400px; " +
                            "background-color: white; border: solid black;" )

        drag_handle_div = HtmlElement.div()
        drag_handle_div.set_style( "cursor: default; background-color: gray; border-bottom: dotted black; " +
                                    "padding: 3px; font-family: sans-serif; font-weight: bold;" )

        # NOTE: to specify behaviors on a widget, you can use the .add_behavior() method ... use one behavior
        #       specification dictionary (hash) string per call to add_behavior (but you can add multiple
        #       behaviors by making multiple calls to add_behavior)
        #
        drag_handle_div.add_behavior( "{type:'click', mouse_btn:'LMB', modkeys:'SHIFT', dst_el:'@.parentNode', " +
                                      "cbfn_action: spt.cb.change_color_action}" )
        drag_handle_div.add_behavior( "{type:'drag', mouse_btn:'LMB', modkeys:'', src_el:'@.parentNode'}" )
        drag_handle_div.add("Drag Handle -- click and drag me!")

        drag_div.add( drag_handle_div )
        drag_div.add( "<p>This is a draggable div ... click on the drag handle above and drag this thing around!</p>" )

        return drag_div
Esempio n. 10
0
    def add_xml_rules(self, xml, project_code=None):
        '''xml should be an XML object with the data in the form of
        <rules>
          <group type='sobject' default='<default>'>
            <rule key='<key>' access='<access>'/>
          </group>
        </rules>
        '''

        from pyasm.search import SObject
        if isinstance(xml, SObject):
            sobject = xml
            xml = sobject.get_xml_value("access_rules")
            if not project_code:
                project_code = sobject.get_value("project_code")

        project_override = project_code
        if isinstance(xml, basestring):
            xmlx = Xml()
            xmlx.read_string(xml)
            xml = xmlx


        # parse shorthand rules
        rule_nodes = xml.get_nodes("rules/rule")
        if not rule_nodes:
            return

        # store all of the project codes (this will only run once)
        if self.project_codes == None:
            search = Search('sthpw/project')
            projects = search.get_sobjects()
            self.project_codes = [x.get_code() for x in projects]
            self.project_codes.append('*')

        for rule_node in rule_nodes:
            # initiate the project_code here for each loop
            project_code = '*'
            group_type = Xml.get_attribute( rule_node, "group" )
            if not group_type:
                # category is the preferred name over group now
                # TODO: phase out the use of group completely
                group_type = Xml.get_attribute( rule_node, "category" )

            # get an existing rule set or create a new one
            if self.groups.has_key(group_type):
                rules = self.groups[group_type]
            else:
                rules = {}
                self.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( rule_node, "default" )
            if group_default:
                rules['__DEFAULT__'] = group_default
                continue


            # generate the rule key
            #rule_key = xml.get_attribute(rule_node, 'key')
            attrs = xml.get_attributes(rule_node)
            attrs2 = {}
            count = 0
            for name, value in attrs.items():
                if name in ['access', 'group', 'category', 'project']:
                    continue
                # have to turn everything into strings
                attrs2[str(name)] = str(value)
                count += 1


            if count == 1 and attrs2.has_key('key'):
                # backwards compatibility
                rule_key = attrs2['key']
            else:
                #rule_key = str(attrs2)
                rule_key = str(Common.get_dict_list(attrs2))

            if project_override:
                rule_project = project_override
            else:
                rule_project =  xml.get_attribute(rule_node, 'project')

            if rule_project:
                project_code = rule_project
                # special treatment for search_filter to enable
                # project-specific search
                if group_type=='search_filter':
                    attrs2['project'] = rule_project
            
            # if there is a value, then combine it with the key
            rule_value = xml.get_attribute(rule_node, 'value')
            if rule_value:
                rule_key = "%s||%s" % (rule_key, rule_value)

            # add a project code qualifier
            rule_keys = []
         
            # project rule is special
            if group_type == 'project':
                key = str(rule_key)
                rule_keys.append(key)
            elif project_code == '*' and group_type != 'search_filter':
                for code in self.project_codes:
                    key = "%s?project=%s" % (rule_key, code)
                    rule_keys.append(key)
            else:
                key= "%s?project=%s" % (rule_key, project_code)

                #key = str(key) # may need to stringify unicode string
                rule_keys.append(key)
                    
                #key= "%s?project=*" % (rule_key)
                #rule_keys.append(key)

            rule_access = xml.get_attribute(rule_node, 'access')

            #if rule_access == "":
            #    raise AccessException("Cannot have empty 'access':\n%s" \
            #        % xml.to_string(rule_node) )

            # if no key is specified, it is considered a DEFAULT
            if not rule_keys and not rule_value:
                rule_keys = ['__DEFAULT__']
            for rule_key in rule_keys:
                # check if rule_access exists first, which doesn't for search_filter,
                # but it has to go into the rules regardless
                # if the rule already exists, take the highest one
                if rule_access and rules.has_key(rule_key):
                    curr_access, cur_attrs = rules[rule_key]

                    try:
                        access_enum = self._get_access_enum(rule_access)
                        if self._get_access_enum(curr_access) > access_enum:
                            continue
                    except:
                        if group_type == "builtin":
                            continue
                        else:
                            raise


                rules[rule_key] = rule_access, attrs2
            

        # FIXME: this one doesn't support the multi-attr structure
        # convert this to a python data structure
        group_nodes = xml.get_nodes("rules/group")
        for group_node in group_nodes:

            group_type = Xml.get_attribute( group_node, "type" )

            # get an existing rule set or create a new one
            if self.groups.has_key(group_type):
                rules = self.groups[group_type]
            else:
                rules = {}
                self.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( group_node, "default" )
            if group_default != "":
                rules['__DEFAULT__'] = group_default


            # get all of the rule nodes
            rule_nodes = Xml.get_children(group_node)
            for rule_node in rule_nodes:
                project_code='*'

                if Xml.get_node_name(rule_node) != 'rule':
                    continue

                rule_key = xml.get_attribute(rule_node, 'key')
                rule_access = xml.get_attribute(rule_node, 'access')

                if project_override:
                    rule_project = project_override
                else:
                    rule_project =  xml.get_attribute(rule_node, 'project')

                if rule_project:
                    project_code = rule_project
                if rule_access == "":
                    raise AccessException("Cannot have empty 'access':\n%s" \
                        % xml.to_string(rule_node) )

                rule_keys = []
                attrs2 = {'key': rule_key}

                # add a project code qualifier
                if project_code == '*' and group_type != 'search_filter':
                    for code in self.project_codes:
                        key = "%s?project=%s" % (rule_key, code)
                        rule_keys.append(key)
                else:
                    key= "%s?project=%s" % (rule_key, project_code)
                    rule_keys.append(key)

                for rule_key in rule_keys:
                    rules[rule_key] = rule_access, attrs2