Ejemplo n.º 1
0
 def make_check_table(my, dictoid, arr, sob, my_name, color, is_external_rejection=False):
     table = Table()
     table.add_style('background-color: %s;' % color)
     max_width = 3
     table.add_row()
     top_cell = table.add_cell('<b><u>%s</u></b>' % my_name)
     top_cell.add_attr('colspan',max_width)
     top_cell.add_attr('align','center')
     count = 0
     for entry in arr:
         if count % max_width == 0:
             table.add_row()
         checker = CheckboxWdg('check_%s' % dictoid[entry])
         checker.add_attr('code', sob.get('code'))
         checker.add_attr('field', dictoid[entry])
         #checker.set_persistence()
         if sob.get(dictoid[entry]):
             checker.set_value(True)
         else:
             checker.set_value(False)
         if not is_external_rejection:
             checker.add_behavior(my.get_reason_check_behavior(dictoid[entry]))
         check_hold = table.add_cell(checker)
         check_hold.add_attr('code', sob.get('code'))
         check_hold.add_attr('field', dictoid[entry])
         label = table.add_cell(entry)
         label.add_attr('nowrap','nowrap')
         label.add_attr('width','190px')
         count = count + 1 
     return table
Ejemplo n.º 2
0
 def make_login_table(my, sob):
     table = Table()
     table.add_style('background-color: #fffff1;')
     max_width = 4
     table.add_row()
     top_cell = table.add_cell('<b><u>Responsible</u></b>')
     top_cell.add_attr('colspan',max_width)
     top_cell.add_attr('align','center')
     count = 0
     users = my.server.eval("@SOBJECT(sthpw/login['location','internal']['license_type','user']['@ORDER_BY','login'])")
     for u in users:
         if count % max_width == 0:
             table.add_row()
         checker = CheckboxWdg('responsible_%s' % u.get('login'))
         checker.add_attr('login',u.get('login'))
         checker.add_attr('code',sob.get('code'))
         checker.add_attr('current_list', sob.get('responsible_users'))
         #checker.set_persistence()
         if sob.get('responsible_users') not in [None,'']:
             if u.get('login') in sob.get('responsible_users'):
                 checker.set_value(True)
             else:
                 checker.set_value(False)
         else:
             checker.set_value(False)
         checker.add_behavior(my.get_make_responsible_behavior())
         table.add_cell(checker)
         label = table.add_cell(u.get('login'))
         label.add_attr('nowrap','nowrap')
         label.add_attr('width','137px')
         count = count + 1
     return table
Ejemplo n.º 3
0
    def make_intermediate_unit(my, in_link, work_order_code, in_or_out, type_str):
        inlink_st = in_link.get('__search_key__').split('?')[0]
        if inlink_st == 'twog/work_order_intermediate':
            lookmeup = in_link.get('intermediate_file_code')
        elif inlink_st == 'twog/work_order_passin':
            lookmeup = in_link.get('intermediate_file_code')
        sob = my.server.eval("@SOBJECT(twog/intermediate_file['code','%s'])" % lookmeup)[0]
        table = Table()
        name = sob.get('name')
        description = sob.get('description')
        table.add_attr('width','100%s' % '%')
        table.add_attr('border','1')
        table.add_style('background-color: %s;' % my.color_lookup[in_or_out])
        table.add_row()
        table_src = Table()
        type_cell = table_src.add_cell(type_str)
        type_cell.add_attr('width', '25%s' % '%')
        table_src.add_row()
        checkbox = CheckboxWdg('src_disp_chk_%s' % sob.get('code'))
        checkbox.add_attr('code',sob.get('code'))
        checkbox.add_attr('special_name',name)
        checkbox.add_attr('location',sob.get('location'))
        checkbox.set_value(False)
        #checkbox.set_persistence()
        table_src.add_cell(checkbox)
        table.add_cell(table_src)

        info_tbl = Table() 
        info_tbl.add_attr('width','100%s' % '%')
        info_tbl.add_row()
        cell1 = info_tbl.add_cell('<u>Title:</u> %s' % name)
        cell1.add_style('cursor: pointer;')
        cell1.add_behavior(my.inspect_intermediate_popup(sob.get('code')))
        if in_or_out == 'IN':
            killer = info_tbl.add_cell(my.x_butt)
            killer.add_style('cursor: pointer;')
            killer.add_behavior(my.get_intermediate_passin_killer_behavior(in_link.get('code'), work_order_code, name))
            info_tbl.add_row()
            desc = info_tbl.add_cell(description)
            desc.add_attr('colspan','2')
        else:
            info_tbl.add_row()
            desc = info_tbl.add_cell(description)

        long_cell = table.add_cell(info_tbl)
        long_cell.add_attr('width','75%s' % '%')
        table.add_row()
        loc_cell1 = table.add_cell('&nbsp;&nbsp;<u>Location:</u>')
        loc_cell1.add_style('cursor: pointer;')
        loc_cell1.add_behavior(my.location_changer(sob.get('__search_key__')))
        loc_cell2 = table.add_cell(sob.get('location'))
        loc_cell2.add_attr('class', 'sd_location_%s' % sob.get('code'))
        loc_cell2.add_attr('colspan','2')
        return table
Ejemplo n.º 4
0
    def make_source_unit(my, in_link, work_order_code, in_or_out, type_str):
        inlink_st = in_link.get('__search_key__').split('?')[0]
        linker = ''
        if inlink_st == 'twog/work_order_passin':
            linker = in_link.get('deliverable_source_code')
        elif inlink_st == 'twog/work_order_deliverables':
            linker = in_link.get('deliverable_source_code')
        elif inlink_st == 'twog/work_order_sources':
            linker = in_link.get('source_code')
            
        sob = my.server.eval("@SOBJECT(twog/source['code','%s'])" % linker)[0]
        st = sob.get('__search_key__').split('?')[0]
        title = sob.get('title')
        if sob.get('episode') not in [None,'']:
            title = "%s: %s" % (title, sob.get('episode'))
        part = ''
        if sob.get('part') not in [None,'']:
            part = sob.get('part') 
        table = Table()
        table.add_attr('width','100%s' % '%')
        table.add_attr('border','1')
        table.add_style('background-color: %s;' % my.color_lookup[in_or_out])
        table.add_row()
        table_src = Table()
        type_cell = table_src.add_cell(type_str)
        type_cell.add_attr('width', '25%s' % '%')
        table_src.add_row()
        checkbox = CheckboxWdg('src_disp_chk_%s' % sob.get('code'))
        checkbox.add_attr('code',sob.get('code'))
        checkbox.add_attr('special_name',sob.get('barcode'))
        checkbox.add_attr('location',sob.get('location'))
        checkbox.set_value(False)
        #checkbox.set_persistence()
        table_src.add_cell(checkbox)
        table.add_cell(table_src)

        top_tbl = Table()
        top_tbl.add_attr('width','100%s' % '%')
        top_tbl.add_row()
        top_tbl.add_cell('<u>Title:</u> %s' % title)
        if type_str == 'SRC':
            killer = top_tbl.add_cell(my.x_butt)
            killer.add_style('cursor: pointer;')
            killer.add_behavior(my.get_source_killer_behavior(in_link.get('code'), work_order_code, title))
        elif type_str == 'SRC-PASSIN':
            killer = top_tbl.add_cell(my.x_butt)
            killer.add_style('cursor: pointer;')
            killer.add_behavior(my.get_deliverable_passin_killer_behavior(in_link.get('code'), work_order_code, title))

        info_tbl = Table() 
        info_tbl.add_attr('width','100%s' % '%')
        info_tbl.add_row()
        info_tbl.add_cell(top_tbl)
        info_tbl.add_row()
        info_tbl.add_cell('<u>Part:</u> %s' % part)
        info_tbl.add_row()
        cell1 = info_tbl.add_cell('<u>Barcode: <b>%s</u></b>' % (sob.get('barcode')))
        cell1.add_style('cursor: pointer;')
        cell1.add_behavior(my.inspect_source_popup(sob.get('code'), sob.get('high_security')))
        info_tbl.add_row()
        info_tbl.add_cell('%s, %s, %s' % (sob.get('standard'), sob.get('aspect_ratio'), sob.get('total_run_time')))
        
        long_cell = table.add_cell(info_tbl)
        long_cell.add_attr('width','75%s' % '%')
        table.add_row()
        loc_cell1 = table.add_cell('&nbsp;&nbsp;<u>Location:</u>')
        loc_cell1.add_style('cursor: pointer;')
        loc_cell1.add_behavior(my.location_changer(sob.get('__search_key__')))
        loc_cell2 = table.add_cell(sob.get('location'))
        loc_cell2.add_attr('class', 'sd_location_%s' % sob.get('code'))
        loc_cell2.add_attr('colspan','2')
        
        return table
Ejemplo n.º 5
0
    def get_display(my):
        search_type = my.kwargs.get("search_type")

        search = Search(search_type)
        if not search.column_exists("_is_collection"):
            return my.top

        search.add_filter("_is_collection", True)
        collections = search.get_sobjects()

        top = my.top
        top.add_class("spt_dialog")
        button = IconButtonWdg(title='Add to Collection', icon="BS_TH_LARGE", show_arrow=True)
        top.add(button)

        detail_wdg = DivWdg()
        top.add(detail_wdg)

        dialog = DialogWdg()
        top.add(dialog)
        
        dialog.set_as_activator(button, offset={'x':-25,'y': 0})
        dialog.add_title("Collections")

        dialog.add("<div style='margin: 10px'><b>Add selected items to a collection</b></div>")

        add_div = DivWdg()
        dialog.add(add_div)
        icon = IconWdg(name="Add new collection", icon="BS_PLUS")
        icon.add_style("opacity: 0.6")
        icon.add_style("padding-right: 3px")
        add_div.add(icon)
        add_div.add("Create new Collection")
        add_div.add_style("text-align: center")
        add_div.add_style("background-color: #EEEEEE")
        add_div.add_style("padding: 5px")
        add_div.add_style("height: 20px")
        add_div.add_class("hand")


        insert_view = "edit_collection"

        add_div.add_behavior( {
            'type': 'click_up',
            'insert_view': insert_view,
            'cbjs_action': '''
                var top = bvr.src_el.getParent(".spt_table_top");
                var table = top.getElement(".spt_table");
                var search_type = top.getAttribute("spt_search_type");
                
                // Hide the dialog when popup loads.
                var dialog_top = bvr.src_el.getParent(".spt_dialog_top");
                dialog_top.style.visibility = "hidden";

                kwargs = {
                  search_type: search_type,
                  mode: "insert",
                  view: bvr.insert_view,
                  save_event: bvr.event_name,
                  show_header: false,
                  'num_columns': 2,
                  default: {
                    _is_collection: true
                  }
                };
                spt.panel.load_popup("Add New Collection", "tactic.ui.panel.EditWdg", kwargs);
            '''
        } )

        content_div = DivWdg()
        dialog.add(content_div)
        content_div.add_style("width: 270px")
        content_div.add_style("padding: 5px")
        content_div.add_style("padding-bottom: 0px")

        custom_cbk = {}
        custom_cbk['enter'] = '''

            var top = bvr.src_el.getParent(".spt_dialog");
            var input = top.getElement(".spt_main_search");
            var search_value = input.value.toLowerCase();
            var collections = top.getElements(".spt_collection_div");
            var num_result = 0;
            for (i = 0; i < collections.length; i++) {
                // Access the Collection title (without number count) 
                var collection_title = collections[i].attributes[0].value.toLowerCase();

                if (collection_title.indexOf(search_value) != '-1') {
                    collections[i].style.display = "block";
                    num_result += 1;
                }
                else {
                    collections[i].style.display = "none";
                }
            }
            // if no search results, display all
            if (num_result == 0) {
                for (i = 0; i < collections.length; i++) {
                    collections[i].style.display = "block";
                }
            }

        '''
        filters = []
        filters.append(("_is_collection",True))
        filters.append(("status","Verified"))
        text = LookAheadTextInputWdg(
            search_type = "workflow/asset",
            column="name",
            icon="BS_SEARCH",
            icon_pos="right",
            width="100%",
            hint_text="'Enter' to search for Colllection...",
            value_column="name",
            filters=filters,
            custom_cbk=custom_cbk,
            is_collection=True
        )
        text.add_class("spt_main_search")

        content_div.add(text)
        # set minimum if there is at least one collection
        if len(collections) > 0:
            content_div.add_style("min-height: 300")
        content_div.add_style("max-height: 300")
        content_div.add_style("overflow-y: auto")

        content_div.add("<br clear='all'/>")

        for collection in collections:

            search_type = collection.get_base_search_type()
            parts = search_type.split("/")
            collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1])
            search = Search(collection_type)
            search.add_filter("parent_code", collection.get_code())
            num_items = search.get_count()


            collection_div = DivWdg()
            collection_div.add_class("spt_collection_div")
            content_div.add(collection_div)
            collection_div.add_style("margin: 3px 5px 0px 5px")

            go_wdg = DivWdg()
            collection_div.add(go_wdg)
            go_wdg.add_style("float: right")

            icon = IconWdg(name="View Collection", icon="BS_CHEVRON_RIGHT")
            go_wdg.add(icon)
            #go_wdg.add_behavior( {
            #    'type': 'click_upX',
            #    'cbjs_action': '''
            #    alert("Not Implemented");
            #    '''
            #} )


            name = collection.get_value("name")
            # Adding Collection title (without the number count) as an attribute
            collection_div.set_attr("collection_name", name)

            if not name:
                name = collection.get_value("code")

            check_div = DivWdg()
            collection_div.add(check_div)

            check = CheckboxWdg("collection_key")
            check.add_class("spt_collection_checkbox")
            check_div.add(check)
            check_div.add_style("float: left")
            check_div.add_style("margin-right: 5px")
            check_div.add_style("margin-top: -3px")

            check.add_attr("collection_key", collection.get_search_key() )

            info_div = DivWdg()
            collection_div.add(info_div)
            info_div.add(name)

            if num_items:
                info_div.add(" (%s)" % num_items)

            collection_div.add("<hr/>")


        add_button = DivWdg()
        add_button.add("Add")
        add_button.add_style("margin: 0px 10px 10px 10px")
        add_button.add_style("width: 50px")
        add_button.add_class("btn btn-primary")
        dialog.add(add_button)

        add_button.add_behavior( {
            'type': 'click',
            'cbjs_action': '''
            var search_keys = spt.table.get_selected_search_keys(false);

            if (search_keys.length == 0) {
                spt.notify.show_message("No assets selected.");
                return;
            }

            var top = bvr.src_el.getParent(".spt_dialog");
            var checkboxes = top.getElements(".spt_collection_checkbox");
            var cmd = "tactic.ui.panel.CollectionAddCmd";
            var server = TacticServerStub.get();
            var is_checked = false;

            var dialog_top = bvr.src_el.getParent(".spt_dialog_top");

            for (i = 0; i < checkboxes.length; i++) {
                var checked_collection_attr = checkboxes[i].attributes;
                var collection_key = checked_collection_attr[3].value;
                // Preventing a collection being added to itself, check if search_keys contain collection_key.
                if (search_keys.indexOf(collection_key) != -1) {
                    spt.notify.show_message("Collection cannot be added to itself.");
                    return;
                }

                if (checkboxes[i].checked == true) {
                    // if there is at least one checkbox selected, set is_checked to 'true'
                    is_checked = true;

                    var search_keys = spt.table.get_selected_search_keys(false);
                    var kwargs = {
                        collection_key: collection_key,
                        search_keys: search_keys
                    }
                    server.execute_cmd(cmd, kwargs);
                }
            }

            if (is_checked == false) {
                spt.notify.show_message("No collection selected.");
                return;
            }
            else {
                spt.notify.show_message("Assets added to Collection.");
                // refresh dialog_top, so users can see the number change in Collections
                spt.panel.refresh(dialog_top);
            }
            
            '''
        } )
        

        return top
Ejemplo n.º 6
0
    def get_display(self):

        search_key = self.kwargs.get("search_key")
        path = self.kwargs.get("path")
        parser_str = self.kwargs.get("parser")
        use_tactic_tags = self.kwargs.get("use_tactic_tags")

        from pyasm.checkin import BaseMetadataParser

        #parser_str = "EXIF"
        if parser_str:
            parser = BaseMetadataParser.get_parser(parser_str, path)
        else:
            parser = BaseMetadataParser.get_parser_by_path(path)

        if parser:
            if use_tactic_tags in ['true', True]:
                metadata = parser.get_tactic_metadata()
            else:
                metadata = parser.get_metadata()
        else:
            metadata = {}

        parser_title = parser.get_title()

        top = self.top
        top.add_color("background", "background")
        top.add_class("spt_metadata_top")

        shelf = DivWdg()
        top.add(shelf)
        from tactic.ui.widget import ActionButtonWdg
        button = ActionButtonWdg(title="Add Selected to Keywords", width="200")
        shelf.add(button)
        shelf.add_style("margin: 10px 0px")
        button.add_behavior({
            'search_key':
            search_key,
            'cbjs_action':
            '''
            var top = bvr.src_el.getParent(".spt_metadata_top");
            var values = spt.api.get_input_values(top, null, true);
            var searchables = values.searchable;
            var items = [];
            for (var i = 0; i < searchables.length; i++) {
                if (searchables[i] == "") {
                    continue;
                }
                items.push(searchables[i]);
            }

            var server = TacticServerStub.get();

            var class_name = 'spt.modules.workflow.AssetAddMetadataToKeywordsCmd';
            var kwargs = {
                search_key: bvr.search_key,
                items: items,
            };
            server.p_execute_cmd(class_name, kwargs)
            .then( function() {
                spt.api.clear_inputs(top);
                spt.notify.show_message("Added Keywords");
            } )


            '''
        })

        table = Table()
        table.add_style("width: 100%")
        #table.add_style("table-layout: fixed")
        top.add(table)
        table.set_unique_id()

        table.add_smart_styles("spt_cell", {'padding': '3px'})

        tr, td = table.add_row_cell()
        td.add(parser_title)
        td.add_style("height: 20px")
        td.add_style("font-weight: bold")
        td.add_style("padding: 5px 3px")
        td.add_color("background", "background", -5)
        border_color = td.get_color("border")
        td.add_color("border-bottom", "solid 1px %s" % border_color)

        tr.add_class("tactic_hover")
        """
        tr = table.add_row()
        tr.add_color("background", "background", -5)
        th = table.add_header("Property")
        th.add_style("min-width: 200px")
        th.add_style("padding: 5px")
        th = table.add_header("Value")
        #th.add_style("min-width: 400px")
        th.add_style("padding: 5px")
        """

        keys = metadata.get("__keys__")
        if not keys:
            keys = metadata.keys()

        empty = False
        if not keys:
            empty = True
            keys = ['', '', '', '', '', '', '']
            table.add_smart_styles("spt_cell", {'height': '20px'})

        keys.sort()

        for i, key in enumerate(keys):
            value = metadata.get(key)

            value = Common.process_unicode_string(value)

            if not isinstance(key, basestring):
                key = str(key)
            #title = Common.get_display_title(key)
            title = key

            tr = table.add_row()
            tr.add_class("tactic_hover")

            if i % 2:
                tr.add_color("background", "background", -2)
                tr.add_color("color", "color")
            else:
                tr.add_color("background", "background")
                tr.add_color("color", "color")

            td = table.add_cell()
            td.add_class("spt_cell")
            td.add(title)
            td.add_style("width: 300px")
            td.add_style("min-width: 200px")

            td = table.add_cell()
            td.add_class("spt_cell")

            if len(str(value)) > 500:
                inside = DivWdg()
                td.add(inside)
                value = value[:500]
                inside.add(value)
                inside.add_style("max-width: 600px")
            else:
                td.add(value)
            td.add_style("max-width: 600px")

            td.add_style("overflow: hidden")
            td.add_style("text-overflow: ellipsis")
            td.add_style("white-space: nowrap")

            td = table.add_cell()
            td.add_class("spt_cell")

            try:
                is_ascii = True
                for c in str(value):
                    if ord(c) > 128:
                        is_ascii = False
                        break
                if not is_ascii:
                    continue
            except Exception as e:
                print("WARNING: ", e)
                continue

            from pyasm.widget import CheckboxWdg
            checkbox = CheckboxWdg("searchable")
            checkbox.add_attr("spt_is_multiple", "true")
            td.add(checkbox)
            td.add_style("width: 40px")
            td.add_style("max-width: 30px")
            checkbox.set_option("value",
                                "%s|%s|%s" % (parser_title, key, value))

        if empty:
            div = DivWdg()
            top.add(div)
            div.add_style("height: 30px")
            div.add_style("width: 150px")
            div.add_style("margin-top: -110px")
            div.center()
            div.add("<b>No Metadata</b>")
            div.add_border()
            div.add_color("background", "background3")
            div.add_color("color", "color3")
            div.add_style("padding: 20px")
            div.add_style("text-align: center")

            top.add_style("min-height: 200px")

        return top
Ejemplo n.º 7
0
    def get_display(my):

        search_type = my.kwargs.get("search_type")

        search = Search(search_type)
        if not search.column_exists("_is_collection"):
            return my.top

        search.add_filter("_is_collection", True)
        collections = search.get_sobjects()

        dialog = DivWdg()
        my.set_as_panel(dialog)
        dialog.add_class('spt_col_dialog_top')

        title_div = DivWdg()
        title_div.add_style('margin: 10px')
        title_div.add(HtmlElement.b("Add selected items to collection(s)"))
        dialog.add(title_div)

        add_div = DivWdg()
        dialog.add(add_div)
        icon = IconWdg(name="Add new collection", icon="BS_PLUS")
        icon.add_style("opacity: 0.6")
        icon.add_style("padding-right: 3px")
        add_div.add(icon)
        add_div.add("Create new Collection")
        add_div.add_style("text-align: center")
        add_div.add_style("background-color: #EEEEEE")
        add_div.add_style("padding: 5px")
        add_div.add_style("height: 20px")
        add_div.add_class("hand")

        insert_view = "edit_collection"

        add_div.add_behavior({
            'type':
            'listen',
            'event_name':
            'refresh_col_dialog',
            'cbjs_action':
            '''
                var dialog_content = bvr.src_el.getParent('.spt_col_dialog_top');
                spt.panel.refresh(dialog_content);
            '''
        })

        add_div.add_behavior({
            'type':
            'click_up',
            'insert_view':
            insert_view,
            'event_name':
            'refresh_col_dialog',
            'cbjs_action':
            '''
                var top = bvr.src_el.getParent(".spt_table_top");
                var table = top.getElement(".spt_table");
                var search_type = top.getAttribute("spt_search_type");
                
                // Hide the dialog when popup loads.
                var dialog_top = bvr.src_el.getParent(".spt_dialog_top");
                dialog_top.style.visibility = "hidden";

                kwargs = {
                  search_type: search_type,
                  mode: "insert",
                  view: bvr.insert_view,
                  save_event: bvr.event_name,
                  show_header: false,
                  'num_columns': 2,
                  default: {
                    _is_collection: true
                  }
                };
                spt.panel.load_popup("Create New Collection", "tactic.ui.panel.EditWdg", kwargs);
            '''
        })

        content_div = DivWdg()
        dialog.add(content_div)
        content_div.add_style("width: 270px")
        content_div.add_style("padding: 5px")
        content_div.add_style("padding-bottom: 0px")

        custom_cbk = {}
        custom_cbk['enter'] = '''

            var top = bvr.src_el.getParent(".spt_dialog");
            var input = top.getElement(".spt_main_search");
            var search_value = input.value.toLowerCase();
            var collections = top.getElements(".spt_collection_div");
            var num_result = 0;
            for (i = 0; i < collections.length; i++) {
                // Access the Collection title (without number count) 
                var collection_title = collections[i].attributes[0].value.toLowerCase();

                if (collection_title.indexOf(search_value) != '-1') {
                    collections[i].style.display = "block";
                    num_result += 1;
                }
                else {
                    collections[i].style.display = "none";
                }
            }
            // if no search results, display all
            if (num_result == 0) {
                for (i = 0; i < collections.length; i++) {
                    collections[i].style.display = "block";
                }
            }

        '''
        filters = []
        filters.append(("_is_collection", True))
        filters.append(("status", "Verified"))
        text = LookAheadTextInputWdg(
            search_type="workflow/asset",
            column="name",
            icon="BS_SEARCH",
            icon_pos="right",
            width="100%",
            height="30px",
            hint_text="'Enter' to search for Colllection...",
            value_column="name",
            filters=filters,
            custom_cbk=custom_cbk,
            is_collection=True)
        text.add_class("spt_main_search")

        content_div.add(text)
        # set minimum if there is at least one collection
        if len(collections) > 0:
            content_div.add_style("min-height: 300")
        content_div.add_style("max-height: 300")
        content_div.add_style("overflow-y: auto")

        content_div.add("<br clear='all'/>")

        for collection in collections:

            search_type = collection.get_base_search_type()
            parts = search_type.split("/")
            collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1])
            search = Search(collection_type)
            search.add_filter("parent_code", collection.get_code())
            num_items = search.get_count()

            collection_div = DivWdg()
            collection_div.add_class("spt_collection_div")
            content_div.add(collection_div)
            collection_div.add_style("margin: 3px 5px 0px 5px")

            go_wdg = DivWdg()
            collection_div.add(go_wdg)
            go_wdg.add_style("float: right")

            #TODO: add some interaction with this arrow
            # icon = IconWdg(name="View Collection", icon="BS_CHEVRON_RIGHT")
            # go_wdg.add(icon)
            #go_wdg.add_behavior( {
            #    'type': 'click_upX',
            #    'cbjs_action': '''
            #    alert("Not Implemented");
            #    '''
            #} )

            name = collection.get_value("name")
            # Adding Collection title (without the number count) as an attribute
            #collection_div.set_attr("collection_name", name)

            if not name:
                name = collection.get_value("code")

            check_div = DivWdg()
            collection_div.add(check_div)

            check = CheckboxWdg("collection_key")
            check.add_class("spt_collection_checkbox")
            check_div.add(check)
            check_div.add_style("float: left")
            check_div.add_style("margin-right: 5px")
            check_div.add_style("margin-top: -3px")

            check.add_attr("collection_key", collection.get_search_key())

            check.add_attr("collection_name", collection.get_name())

            info_div = DivWdg()
            collection_div.add(info_div)
            info_div.add(name)

            if num_items:
                info_div.add(" (%s)" % num_items)

            collection_div.add("<hr/>")

        add_button = DivWdg()
        add_button.add("Add")
        add_button.add_style("margin: 0px 10px 10px 10px")
        add_button.add_style("width: 50px")
        add_button.add_class("btn btn-primary")
        dialog.add(add_button)

        add_button.add_behavior({
            'type':
            'click',
            'cbjs_action':
            '''
            var search_keys = spt.table.get_selected_search_keys(false);

            if (search_keys.length == 0) {
                spt.notify.show_message("No items selected.");
                return;
            }

            var top = bvr.src_el.getParent(".spt_dialog");
            var checkboxes = top.getElements(".spt_collection_checkbox");
            var cmd = "tactic.ui.panel.CollectionAddCmd";
            var server = TacticServerStub.get();
            var is_checked = false;
            var added = [];
            var collection_keys = [];
            
            var dialog_top = bvr.src_el.getParent(".spt_col_dialog_top");
            
            for (i = 0; i < checkboxes.length; i++) {

                if (checkboxes[i].checked == true) {
                    var collection_key = checkboxes[i].getAttribute('collection_key');
                    var collection_name = checkboxes[i].getAttribute('collection_name');
                    
                    
                    // Preventing a collection being added to itself, check if search_keys contain collection_key.
                    if (search_keys.indexOf(collection_key) != -1) {
                        spt.notify.show_message("Collection [" + collection_name + " ] cannot be added to itself.");
                        return;
                    }
                    // if there is at least one checkbox selected, set is_checked to 'true'
                    is_checked = true;

                    // If the collection is not being added to itself, append to the list of collection keys
                    collection_keys.push(collection_key);
                }
            }

            if (is_checked == false) {
                spt.notify.show_message("No collection selected.");
            }
            else {
                var kwargs = {
                    collection_keys: collection_keys,
                    search_keys: search_keys
                }
                var rtn = server.execute_cmd(cmd, kwargs);
                var rtn_message = rtn.info.message;

                if (rtn_message['circular'] == 'True') {
                    var parent_collection_names = rtn_message['parent_collection_names'].join(", ");
                    spt.notify.show_message("Collection [" + collection_name + " ] is a child of the source [" + parent_collection_names + "]");
                    
                    return;
                }
                for (var collection_name in rtn_message) {
                    if (rtn_message[collection_name] != 'No insert')
                        added.push(collection_name);
                }

                if (added.length == 0)
                    spt.notify.show_message("Items already added to Collection.");
                else 
                    spt.notify.show_message("Items added to Collection [ " + added.join(', ') + " ].");
                // refresh dialog_top, so users can see the number change in Collections
                spt.panel.refresh(dialog_top);
            }
            
            '''
        })

        return dialog
Ejemplo n.º 8
0
    def get_display(self):
        top = DivWdg()

        element_name = self.kwargs.get('element_name')

        config_view = self.kwargs.get("config_view")
        display_class = config_view.get_display_handler(element_name)
        display_options = config_view.get_display_options(element_name)
        element_attr = config_view.get_element_attributes(element_name)

        name = element_attr.get('name')
        edit = element_attr.get('edit')
        title = element_attr.get('title')
        width = element_attr.get('width')

        # add the name
        from pyasm.web import Table
        table = Table()
        top.add(table)

        table.add_row()
        td = table.add_cell("Name: ")
        td.add_style("padding: 5px")
        name_text = SpanWdg(name)
        name_text.add_style('font-weight: bold')
        name_text.add_attr("size", "50")
        table.add_cell(name_text)

        table.add_row_cell("<br/>Element Attributes:<br/>")

        # add the title
        table.add_row()
        td = table.add_cell("Title: ")
        td.add_style("padding: 5px")
        title_text = TextWdg("title")
        title_text.add_attr("size", "50")
        if title:
            title_text.set_value(title)
        table.add_cell(title_text)

        # add the width
        table.add_row()
        td = table.add_cell("Width: ")
        td.add_style("padding: 5px")
        width_text = TextWdg("width")
        if width:
            width_text.set_value(width)
        width_text.add_attr("size", "50")
        table.add_cell(width_text)

        # add the editable
        table.add_row()
        td = table.add_cell("Editable: ")
        td.add_style("padding: 5px")
        editable_text = CheckboxWdg("editable")
        editable_text.add_attr("size", "50")
        table.add_cell(editable_text)

        table.add_row_cell("<br/>Display:<br/>")

        # add the widget
        table.add_row()
        td = table.add_cell("Widget: ")
        td.add_style("padding: 5px")
        widget_select = SelectWdg("widget")
        options = ['Expression']
        widget_select.set_option("values", options)
        widget_select.add_empty_option("-- Select --")
        #widget_select.set_value(display_class)
        table.add_cell(widget_select)

        table.add_row_cell("&nbsp;&nbsp;&nbsp;&nbsp;- or -")

        # add the class
        table.add_row()
        td = table.add_cell("Class Name: ")
        td.add_style("padding: 5px")
        class_text = TextWdg("class_name")
        class_text.set_value(display_class)
        class_text.add_attr("size", "50")
        table.add_cell(class_text)

        # introspect the widget
        if not display_class:
            display_class = "pyasm.widget.SimpleTableElementWdg"
        #display_class = "tactic.ui.panel.ViewPanelWdg"

        from pyasm.common import Common
        import_stmt = Common.get_import_from_class_path(display_class)
        if import_stmt:
            exec(import_stmt)
        else:
            exec("from pyasm.widget import %s" % display_class)
        try:
            options = eval("%s.get_args_options()" % display_class)
        except AttributeError:
            try:
                info = eval("%s.get_args_keys()" % display_class)
            except AttributeError:
                return top

            options = []
            for key, description in info.items():
                option = {
                    'name': key,
                    'type': 'TextWdg',
                    'description': description
                }
                options.append(option)
        '''
        options = [
        {
            'name': 'expression',
            'type': 'TextWdg',
            'size': '50'
        },
        ]
        '''

        if options:
            top.add("<br/>Widget Options:<br/>")

        table = Table()
        top.add(table)

        for option in options:
            table.add_row()

            name = option.get('name')
            title = name
            type = option.get('type')

            td = table.add_cell("%s: " % title)
            td.add_style("padding: 5px")

            value = display_options.get(name)

            if type == 'SelectWdg':
                edit_wdg = SelectWdg("%s|value" % name)
                edit_wdg.add_style("width: 250px")
                edit_wdg.add_empty_option('-- Select --')
                values = option.get('values')
                edit_wdg.set_option('values', values)
                if value:
                    edit_wdg.set_value(value)
            elif type == 'TextAreaWdg':
                edit_wdg = TextAreaWdg("%s|value" % name)
                if value:
                    edit_wdg.set_value(value)
                edit_wdg.add_attr("cols", "60")
                edit_wdg.add_attr("rows", "3")
            else:
                edit_wdg = TextWdg("%s|value" % name)
                if value:
                    edit_wdg.set_value(value)
                edit_wdg.add_style("width: 250px")

            table.add_cell(edit_wdg)

        return top
Ejemplo n.º 9
0
    def get_display(self):
       
        search_type = self.kwargs.get("search_type")

        search = Search(search_type)
        if not search.column_exists("_is_collection"):
            return self.top

        search.add_filter("_is_collection", True)
        collections = search.get_sobjects()

        
        dialog = DivWdg()
        self.set_as_panel(dialog)
        dialog.add_class('spt_col_dialog_top')

        title_div = DivWdg()
        title_div.add_style('margin: 10px')
        title_div.add(HtmlElement.b("Add selected items to collection(s)"))
        dialog.add(title_div)

        add_div = DivWdg()
        dialog.add(add_div)
        icon = IconWdg(name="Add new collection", icon="BS_PLUS")
        icon.add_style("opacity: 0.6")
        icon.add_style("padding-right: 3px")
        add_div.add(icon)
        add_div.add("Create new Collection")
        add_div.add_style("text-align: center")
        add_div.add_style("background-color: #EEEEEE")
        add_div.add_style("padding: 5px")
        add_div.add_style("height: 20px")
        add_div.add_class("hand")


        insert_view = "edit_collection"

        add_div.add_behavior( {
            'type': 'listen',
            'event_name': 'refresh_col_dialog',
            'cbjs_action': '''
                var dialog_content = bvr.src_el.getParent('.spt_col_dialog_top');
                spt.panel.refresh(dialog_content);
            '''})

        add_div.add_behavior( {
            'type': 'click_up',
            'insert_view': insert_view,
            'event_name': 'refresh_col_dialog',
            'cbjs_action': '''
                var top = bvr.src_el.getParent(".spt_table_top");
                var table = top.getElement(".spt_table");
                var search_type = top.getAttribute("spt_search_type");
                
                // Hide the dialog when popup loads.
                var dialog_top = bvr.src_el.getParent(".spt_dialog_top");
                dialog_top.style.visibility = "hidden";

                kwargs = {
                  search_type: search_type,
                  mode: "insert",
                  view: bvr.insert_view,
                  save_event: bvr.event_name,
                  show_header: false,
                  'num_columns': 2,
                  default: {
                    _is_collection: true
                  }
                };
                spt.panel.load_popup("Create New Collection", "tactic.ui.panel.EditWdg", kwargs);
            '''
        } )

        content_div = DivWdg()
        dialog.add(content_div)
        content_div.add_style("width: 270px")
        content_div.add_style("padding: 5px")
        content_div.add_style("padding-bottom: 0px")

        custom_cbk = {}
        custom_cbk['enter'] = '''

            var top = bvr.src_el.getParent(".spt_dialog");
            var input = top.getElement(".spt_main_search");
            var search_value = input.value.toLowerCase();
            var collections = top.getElements(".spt_collection_div");

            var num_result = 0;
            var no_results_el = top.getElement(".spt_no_results");

            for (i = 0; i < collections.length; i++) {
                // Access the Collection title (without number count) 
                var collection_title = collections[i].getElement(".spt_collection_checkbox").getAttribute("collection_name").toLowerCase();
                if (collection_title.indexOf(search_value) != '-1') {
                    collections[i].style.display = "block";
                    num_result += 1;
                }
                else {
                    collections[i].style.display = "none";
                }
            }
            // if no search results, show "no_results_el"
            if (num_result == 0) {
                for (i = 0; i < collections.length; i++) {
                    collections[i].style.display = "none";
                }
                no_results_el.style.display = "block";
            }
            else {
                no_results_el.style.display = "none";
            }

        '''
        filters = []
        filters.append(("_is_collection",True))
        filters.append(("status","Verified"))
        text = LookAheadTextInputWdg(
            search_type = "workflow/asset",
            column="name",
            icon_pos="right",
            width="100%",
            height="30px",
            hint_text="Filter collections...",
            value_column="name",
            filters=filters,
            custom_cbk=custom_cbk,
            is_collection=True,
            validate='false'
        )
        text.add_class("spt_main_search")

        content_div.add(text)
        # set minimum if there is at least one collection
        if len(collections) > 0:
            content_div.add_style("min-height: 300")
        content_div.add_style("max-height: 300")
        content_div.add_style("overflow-y: auto")

        content_div.add("<br clear='all'/>")

        no_results_div = DivWdg()
        content_div.add(no_results_div)

        no_results_div.add_color("color", "color", 50)
        no_results_div.add_style("font: normal bold 1.1em arial,serif")
        no_results_div.add("No collections found.")
        no_results_div.add_style("display: none")
        no_results_div.add_style("margin: 10px 0px 0px 10px")
        no_results_div.add_class("spt_no_results")

        for collection in collections:

            search_type = collection.get_base_search_type()
            parts = search_type.split("/")
            collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1])
            search = Search(collection_type)
            search.add_filter("parent_code", collection.get_code())
            num_items = search.get_count()


            collection_div = DivWdg()
            collection_div.add_class("spt_collection_div")
            content_div.add(collection_div)
            collection_div.add_style("margin: 3px 5px 0px 5px")

            go_wdg = DivWdg()
            collection_div.add(go_wdg)
            go_wdg.add_style("float: right")
        
            #TODO: add some interaction with this arrow
            # icon = IconWdg(name="View Collection", icon="BS_CHEVRON_RIGHT")
            # go_wdg.add(icon)
            #go_wdg.add_behavior( {
            #    'type': 'click_upX',
            #    'cbjs_action': '''
            #    alert("Not Implemented");
            #    '''
            #} )


            name = collection.get_value("name")
            # Adding Collection title (without the number count) as an attribute
            #collection_div.set_attr("collection_name", name)

            if not name:
                name = collection.get_value("code")

            check_div = DivWdg()
            collection_div.add(check_div)

            check = CheckboxWdg("collection_key")
            check.add_class("spt_collection_checkbox")
            check_div.add(check)
            check_div.add_style("float: left")
            check_div.add_style("margin-right: 5px")
            check_div.add_style("margin-top: -3px")

            check.add_attr("collection_key", collection.get_search_key() )
            
            check.add_attr("collection_name", collection.get_name() )

            info_div = DivWdg()
            collection_div.add(info_div)
            info_div.add(name)

            if num_items:
                info_div.add(" (%s)" % num_items)

            collection_div.add("<hr/>")


        add_button = DivWdg()
        add_button.add("Add")
        add_button.add_style("margin: 0px 10px 10px 10px")
        add_button.add_style("width: 50px")
        add_button.add_class("btn btn-primary")
        dialog.add(add_button)

        add_button.add_behavior( {
            'type': 'click',
            'cbjs_action': '''
            var search_keys = spt.table.get_selected_search_keys(false);

            if (search_keys.length == 0) {
                spt.notify.show_message("No items selected.");
                return;
            }

            var top = bvr.src_el.getParent(".spt_dialog");
            var checkboxes = top.getElements(".spt_collection_checkbox");
            var cmd = "tactic.ui.panel.CollectionAddCmd";
            var server = TacticServerStub.get();
            var is_checked = false;
            var added = [];
            var collection_keys = [];
            
            var dialog_top = bvr.src_el.getParent(".spt_col_dialog_top");
            
            for (i = 0; i < checkboxes.length; i++) {

                if (checkboxes[i].checked == true) {
                    var collection_key = checkboxes[i].getAttribute('collection_key');
                    var collection_name = checkboxes[i].getAttribute('collection_name');
                    
                    
                    // Preventing a collection being added to itself, check if search_keys contain collection_key.
                    if (search_keys.indexOf(collection_key) != -1) {
                        spt.notify.show_message("Collection [" + collection_name + " ] cannot be added to itself.");
                        return;
                    }
                    // if there is at least one checkbox selected, set is_checked to 'true'
                    is_checked = true;

                    // If the collection is not being added to itself, append to the list of collection keys
                    collection_keys.push(collection_key);
                }
            }

            if (is_checked == false) {
                spt.notify.show_message("No collection selected.");
            }
            else {
                var kwargs = {
                    collection_keys: collection_keys,
                    search_keys: search_keys
                }
                var rtn = server.execute_cmd(cmd, kwargs);
                var rtn_message = rtn.info.message;

                if (rtn_message['circular'] == 'True') {
                    var parent_collection_names = rtn_message['parent_collection_names'].join(", ");
                    spt.notify.show_message("Collection [" + collection_name + " ] is a child of the source [" + parent_collection_names + "]");
                    
                    return;
                }
                for (var collection_name in rtn_message) {
                    if (rtn_message[collection_name] != 'No insert')
                        added.push(collection_name);
                }

                if (added.length == 0)
                    spt.notify.show_message("Items already added to Collection.");
                else 
                    spt.notify.show_message("Items added to Collection [ " + added.join(', ') + " ].");
                // refresh dialog_top, so users can see the number change in Collections
                spt.panel.refresh(dialog_top);
            }
            
            '''
        } )
        

        return dialog
Ejemplo n.º 10
0
    def get_display(my):
        top = DivWdg()

        element_name = my.kwargs.get('element_name')

        config_view = my.kwargs.get("config_view")
        display_class = config_view.get_display_handler(element_name)
        display_options = config_view.get_display_options(element_name)
        element_attr = config_view.get_element_attributes(element_name)

        name = element_attr.get('name')
        edit = element_attr.get('edit')
        title = element_attr.get('title')
        width = element_attr.get('width')


        # add the name
        from pyasm.web import Table
        table = Table()
        top.add(table)

        table.add_row()
        td = table.add_cell("Name: ")
        td.add_style("padding: 5px")
        name_text = SpanWdg(name)
        name_text.add_style('font-weight: bold')
        name_text.add_attr("size", "50")
        table.add_cell(name_text)


        table.add_row_cell("<br/>Element Attributes:<br/>")

        # add the title
        table.add_row()
        td = table.add_cell("Title: ")
        td.add_style("padding: 5px")
        title_text = TextWdg("title")
        title_text.add_attr("size", "50")
        if title:
            title_text.set_value(title)
        table.add_cell(title_text)



        # add the width
        table.add_row()
        td = table.add_cell("Width: ")
        td.add_style("padding: 5px")
        width_text = TextWdg("width")
        if width:
            width_text.set_value(width)
        width_text.add_attr("size", "50")
        table.add_cell(width_text)

        # add the editable
        table.add_row()
        td = table.add_cell("Editable: ")
        td.add_style("padding: 5px")
        editable_text = CheckboxWdg("editable")
        editable_text.add_attr("size", "50")
        table.add_cell(editable_text)




        table.add_row_cell("<br/>Display:<br/>")

        # add the widget
        table.add_row()
        td = table.add_cell("Widget: ")
        td.add_style("padding: 5px")
        widget_select = SelectWdg("widget")
        options = ['Expression']
        widget_select.set_option("values", options)
        widget_select.add_empty_option("-- Select --")
        #widget_select.set_value(display_class)
        table.add_cell(widget_select)

        table.add_row_cell("&nbsp;&nbsp;&nbsp;&nbsp;- or -")

        # add the class
        table.add_row()
        td = table.add_cell("Class Name: ")
        td.add_style("padding: 5px")
        class_text = TextWdg("class_name")
        class_text.set_value(display_class)
        class_text.add_attr("size", "50")
        table.add_cell(class_text)


        # introspect the widget
        if not display_class:
            display_class = "pyasm.widget.SimpleTableElementWdg"
        #display_class = "tactic.ui.panel.ViewPanelWdg"

        from pyasm.common import Common
        import_stmt = Common.get_import_from_class_path(display_class)
        if import_stmt:
            exec(import_stmt)
        else:
            exec("from pyasm.widget import %s" % display_class)
        try:
            options = eval("%s.get_args_options()" % display_class)
        except AttributeError:
            try:
                info = eval("%s.get_args_keys()" % display_class)
            except AttributeError:
                return top
                
            options = []
            for key, description in info.items():
                option = {
                    'name': key,
                    'type': 'TextWdg',
                    'description': description
                }
                options.append(option)


        '''
        options = [
        {
            'name': 'expression',
            'type': 'TextWdg',
            'size': '50'
        },
        ]
        '''

        if options:
            top.add("<br/>Widget Options:<br/>")

        table = Table()
        top.add(table)

        for option in options:
            table.add_row()

            name = option.get('name') 
            title = name
            type = option.get('type')

            td = table.add_cell( "%s: " % title )
            td.add_style("padding: 5px")

            value = display_options.get(name)

            if type == 'SelectWdg':
                edit_wdg = SelectWdg("%s|value" % name)
                edit_wdg.add_style("width: 250px")
                edit_wdg.add_empty_option('-- Select --')
                values = option.get('values')
                edit_wdg.set_option('values', values)
                if value:
                    edit_wdg.set_value(value)
            elif type == 'TextAreaWdg':
                edit_wdg = TextAreaWdg("%s|value" % name)
                if value:
                    edit_wdg.set_value(value)
                edit_wdg.add_attr("cols", "60")
                edit_wdg.add_attr("rows", "3")
            else:
                edit_wdg = TextWdg("%s|value" % name)
                if value:
                    edit_wdg.set_value(value)
                edit_wdg.add_style("width: 250px")

            table.add_cell(edit_wdg)

        return top
Ejemplo n.º 11
0
    def get_display(self):

        search_key = self.kwargs.get("search_key")
        path = self.kwargs.get("path")
        parser_str = self.kwargs.get("parser")
        use_tactic_tags = self.kwargs.get("use_tactic_tags")


        from pyasm.checkin import BaseMetadataParser

        #parser_str = "EXIF"
        if parser_str:
            parser = BaseMetadataParser.get_parser(parser_str, path)
        else:
            parser = BaseMetadataParser.get_parser_by_path(path)

        if parser:
            if use_tactic_tags in ['true', True]:
                metadata = parser.get_tactic_metadata()
            else:
                metadata = parser.get_metadata()
        else:
            metadata = {}


        parser_title = parser.get_title()


        top = self.top
        top.add_color("background", "background")
        top.add_class("spt_metadata_top")


        shelf = DivWdg()
        top.add(shelf)
        from tactic.ui.widget import ActionButtonWdg
        button = ActionButtonWdg(title="Add Selected to Keywords", width="200")
        shelf.add(button)
        shelf.add_style("margin: 10px 0px")
        button.add_behavior( {
            'search_key': search_key,
            'cbjs_action': '''
            var top = bvr.src_el.getParent(".spt_metadata_top");
            var values = spt.api.get_input_values(top, null, true);
            var searchables = values.searchable;
            var items = [];
            for (var i = 0; i < searchables.length; i++) {
                if (searchables[i] == "") {
                    continue;
                }
                items.push(searchables[i]);
            }

            var server = TacticServerStub.get();

            var class_name = 'spt.modules.workflow.AssetAddMetadataToKeywordsCmd';
            var kwargs = {
                search_key: bvr.search_key,
                items: items,
            };
            server.p_execute_cmd(class_name, kwargs)
            .then( function() {
                spt.api.clear_inputs(top);
                spt.notify.show_message("Added Keywords");
            } )


            '''
        } )


        table = Table()
        table.add_style("width: 100%")
        #table.add_style("table-layout: fixed")
        top.add(table)
        table.set_unique_id()

        table.add_smart_styles("spt_cell", {
            'padding': '3px'
        } )


        tr, td = table.add_row_cell()
        td.add(parser_title)
        td.add_style("height: 20px")
        td.add_style("font-weight: bold")
        td.add_style("padding: 5px 3px")
        td.add_color("background", "background", -5)
        border_color = td.get_color("border")
        td.add_color("border-bottom", "solid 1px %s" % border_color)

        tr.add_class("tactic_hover")


        """
        tr = table.add_row()
        tr.add_color("background", "background", -5)
        th = table.add_header("Property")
        th.add_style("min-width: 200px")
        th.add_style("padding: 5px")
        th = table.add_header("Value")
        #th.add_style("min-width: 400px")
        th.add_style("padding: 5px")
        """

        keys = metadata.get("__keys__")
        if not keys:
            keys = metadata.keys()

        empty = False
        if not keys:
            empty = True
            keys = ['','','','','','','']
            table.add_smart_styles("spt_cell", {
                'height': '20px'
            } )

        keys.sort()


        for i, key in enumerate(keys):
            value = metadata.get(key)

            value = Common.process_unicode_string(value)


            if not isinstance(key, basestring):
                key = str(key)
            #title = Common.get_display_title(key)
            title = key

            tr = table.add_row()
            tr.add_class("tactic_hover")

            if i % 2:
                tr.add_color("background", "background", -2)
                tr.add_color("color", "color")
            else:
                tr.add_color("background", "background")
                tr.add_color("color", "color")

            td = table.add_cell()
            td.add_class("spt_cell")
            td.add(title)
            td.add_style("width: 300px")
            td.add_style("min-width: 200px")

            td = table.add_cell()
            td.add_class("spt_cell")

            if len(str(value)) > 500:
                inside = DivWdg()
                td.add(inside)
                value = value[:500]
                inside.add(value)
                inside.add_style("max-width: 600px")
            else:
                td.add(value)
            td.add_style("max-width: 600px")

            td.add_style("overflow: hidden")
            td.add_style("text-overflow: ellipsis")
            td.add_style("white-space: nowrap")





            td = table.add_cell()
            td.add_class("spt_cell")

            try:
                is_ascii = True
                for c in str(value):
                    if ord(c) > 128:
                        is_ascii = False
                        break
                if not is_ascii:
                    continue
            except Exception as e:
                print("WARNING: ", e)
                continue



            from pyasm.widget import CheckboxWdg
            checkbox = CheckboxWdg("searchable")
            checkbox.add_attr("spt_is_multiple", "true")
            td.add(checkbox)
            td.add_style("width: 40px")
            td.add_style("max-width: 30px")
            checkbox.set_option("value", "%s|%s|%s" % (parser_title,key,value))



        if empty:
            div = DivWdg()
            top.add(div)
            div.add_style("height: 30px")
            div.add_style("width: 150px")
            div.add_style("margin-top: -110px")
            div.center()
            div.add("<b>No Metadata</b>")
            div.add_border()
            div.add_color("background", "background3")
            div.add_color("color", "color3")
            div.add_style("padding: 20px")
            div.add_style("text-align: center")

            top.add_style("min-height: 200px")

        return top