def get_info_wdg(my): widget = Widget() context_input = HiddenWdg("%s|context" % my.get_input_name(), my.context) context_input.add_class('spt_upload_context') widget.add(context_input) # override the column column = my.get_option("column") if column != "": column_input = HiddenWdg("%s|column" % my.get_input_name(), column) widget.add(column_input) return widget
def get_display(self): self.display_expr = self.kwargs.get('display_expr') self.values = [] instance_type = self.get_option("instance_type") accepted_type = self.get_option("accepted_drop_type") div = DivWdg() div.add_class("spt_drop_element_top") div.add_style("width: 100%") div.add_style("min-height: 70px") div.add_style("height: auto") div.add_style("min-width: 100px") div.add_style("max-height: 300px") div.add_style("overflow-y: auto") div.add_style("overflow-x: hidden") self.value_wdg = HiddenWdg(self.get_name()) self.value_wdg.add_class("spt_drop_element_value") div.add( self.value_wdg ) version = self.parent_wdg.get_layout_version() #if version != "2": self.add_drop_behavior(div, accepted_type) # add the hidden div which holds containers info for the sobject template_div = DivWdg() template_div.add_style("display: none") template_item = self.get_item_div(None) # float left for the new icon beside it item_div = template_item.get_widget('item_div') #item_div.add_style('float: left') template_item.add_class("spt_drop_template") new_icon = IconWdg("New", IconWdg.NEW) new_icon.add_style('padding-left','3px') #TODO: insert the new_icon at add(new_icon, index=0) and make sure # the js-side sobject_drop_action cloning align the template div properly #template_item.add(new_icon) template_div.add(template_item) div.add(template_div) content_div = DivWdg() div.add(content_div) content_div.add_class("spt_drop_content") if instance_type: instance_wdg = self.get_instance_wdg(instance_type) content_div.add(instance_wdg) return div
def get_display(my): top = DivWdg() top.add_color("color", "color") #top.add_color("background", "background") top.add_class("spt_simple_upload_top") top.add(my.browse) hidden = HiddenWdg( "%s|path" % my.get_input_name() ) hidden.add_class("spt_upload_hidden") top.add(hidden) # this can be used for some other transaction that picks up this file to checkin hidden = HiddenWdg( "%s|ticket" % my.get_input_name() ) hidden.add_class("spt_upload_ticket") top.add(hidden) # if not specified, get the sobject's icon context my.context = my.kwargs.get("context") if not my.context: current = my.get_current_sobject() if current: my.context = current.get_icon_context() else: from pyasm.biz import Snapshot my.context = Snapshot.get_default_context() top.add_attr("spt_context", my.context) top.add( my.get_info_wdg() ) files_div = DivWdg() top.add(files_div) files_div.add_class("spt_upload_files") files_div.add_style("font-size: 11px") files_div.add_style("margin-top: 10px") my.add_action() return top
def get_display(my): if not my.preprocessed: my.preprocess() if my.is_refresh: top = Widget() else: top = DivWdg() top.add_class("spt_work_hours_top") hidden = HiddenWdg('workhour_data') hidden.add_class('spt_workhour_data') header_data = {'start_date': str(my.start_date)} header_data = jsondumps(header_data).replace('"', """) hidden.set_value(header_data, set_form_value=False) top.add(hidden) days = [] for date in my.dates: days.append(date.strftime("%Y_%m_%d")) today = my.today.strftime("%Y_%m_%d") task = my.get_current_sobject() if not my.is_refresh: my.set_as_panel(top) entries = my.entries.get(task.get_code()) if isinstance(task, Task): parent = task.get_parent() if not parent: disabled = True else: disabled = False else: disabled = False if not entries: entries = {} table = Table() top.add(table) if my.use_straight_time: row_list = [my.ST_ROW] if my.show_overtime: row_list.append(my.OT_ROW) prefix_list = ['', 'ot'] else: row_list = [my.STT_ROW, my.ENT_ROW] prefix_list = ['stt', 'ent'] text = HiddenWdg(my.get_name()) text.add_class("spt_data") table.add_color("color", "color") table.add_styles("width: %spx; float: left" % my.table_width) for row_to_draw in row_list: tr = table.add_row() tr.add_style('line-height', '8px') td = table.add_blank_cell() offset_width = my.MONTH_WIDTH + my.LEFT_WIDTH + 8 td.add_style("min-width: %spx" % offset_width) td.add(text) # go through each day and draw an input for overtime total_hours_st = 0 total_hours_ot = 0 search_key = task.get_search_key() # Add a label to indicate if the row is straight time or overtime time_prefix = '' if row_to_draw == my.OT_ROW: time_prefix = 'ot' div = DivWdg() div.add("OT") div.add_styles('text-align: right; margin-right: 4px') td.add(div) elif row_to_draw == my.STT_ROW: time_prefix = 'stt' div = DivWdg() div.add("ST") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) elif row_to_draw == my.ENT_ROW: time_prefix = 'ent' div = DivWdg() div.add("ET") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) for idx, day in enumerate(days): day_wdg = DivWdg() day_wdg.add(day) td = table.add_cell() td.add_style("width: %spx" % my.day_width) text = TextWdg('%sday_%s' % (time_prefix, day)) if disabled: text.set_option('read_only', 'true') text.set_attr('disabled', 'disabled') td.add(text) text.add_class('spt_day%s' % (time_prefix)) text.add_styles( "width: %spx;text-align: right;padding-left: 2px" % (my.day_width - 2)) #text.add_styles("width: 100%;text-align: right;padding-left: 2px") if day == today: text.add_style("border: solid 1px black") week_day = my.weekday_dict[idx] if week_day in ['Sat', 'Sun']: # MAIN: Overtime, weekend if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[-15, 0, 5]) else: text.add_color("background", "background2", modifier=[0, 15, 20]) if row_to_draw == my.OT_ROW: text.add_attr('input_field_type', 'ot') else: text.add_attr('input_field_type', 'st') #TODO: while we may have multiple entries per task, we will only use the latest one here # for now, making the UI cleaner # if a corresponding entry exists, display its value entry_list_dict = entries.get(day) daily_sum = 0 value = 0 entry_list = [] if entry_list_dict: row_key = my.ROW_DICT.get(row_to_draw) entry_list = entry_list_dict.get(row_key) if entry_list: for entry in entry_list: # Check if there is something in the category column. category = entry.get_value("category") if row_to_draw == my.OT_ROW: # Skip if the category field does not have a 'ot' indicated. if not category: print "Warning this work_hour entry has no category [%s]" % entry.get_code( ) continue # Check if there exist a value in the straight_time column value, delta = my.get_time_value(entry, row_to_draw) if value: text.set_value(value) text.add_attr('orig_input_value', value) if row_to_draw == my.OT_ROW: total_hours_ot += float(delta) else: total_hours_st += float(delta) daily_sum += delta # we only use value instead of the sum "daily_sum" for now if row_to_draw == my.OT_ROW: my.summary_ot[idx].update({search_key: daily_sum}) else: my.summary_st[idx].update({search_key: daily_sum}) script = ''' var orig_value = bvr.src_el.getAttribute("orig_input_value"); var input_field_type = bvr.src_el.getAttribute("input_field_type"); bvr.src_el.value = bvr.src_el.value.strip(); if (bvr.src_el.value == '') { if (orig_value) { bvr.src_el.value = 0; } else { return; } } else if (bvr.src_el.value == orig_value) { return; } bvr.prefix_list.splice( bvr.prefix_list.indexOf(bvr.time_prefix),1) var other_time_prefix = bvr.prefix_list[0]; spt.work_hour.update_total(bvr, '.spt_day' + bvr.time_prefix); // register this as changed item var all_top_el = bvr.src_el.getParent(".spt_work_hours_top"); var values1 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ bvr.time_prefix, false); var values2 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ other_time_prefix, false); // Merge values from straight time and overtime fields in values variable. for (var attr in values2) { values1[attr] = values2[attr]; } for (val in values1) { if (values1[val] && isNaN(values1[val])) { spt.error('You have non-numeric values in your work hours. Please correct it: ' + values[val]); return; } } delete values1.data; var value_wdg = all_top_el.getElement(".spt_data"); var value = JSON.stringify(values1); value_wdg.value = value; var layout = bvr.src_el.getParent(".spt_layout"); var version = layout.getAttribute("spt_version"); if (version == "2") { spt.table.set_layout(layout); spt.table.accept_edit(all_top_el, value, false); } else { var cached_data = {}; spt.dg_table.edit.widget = all_top_el; spt.dg_table.inline_edit_cell_cbk( value_wdg, cached_data ); } ''' # accept on pressing Enter behavior = { 'type': 'keydown', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' if (evt.key=='enter') { %s } ''' % script } text.add_behavior(behavior) behavior = { 'type': 'blur', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' %s ''' % script } text.add_behavior(behavior) text = TextWdg("total") td = table.add_cell(text) td.add_style("width: 35px") text.add_attr('spt_total', '.spt_total%s' % (time_prefix)) text.add_class('spt_total%s' % (time_prefix)) text.add_styles( "width: %spx; text-align: right; padding-right: 3px" % my.day_width) text.set_attr("readonly", "readonly") # MAIN: Overtime, total. if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[5, -15, 0]) if total_hours_ot: text.set_value("%0.1f" % total_hours_ot) my.summary_ot[7].update({search_key: total_hours_ot}) else: text.add_color("background", "background2", modifier=[20, 0, 15]) if total_hours_st: text.set_value("%0.1f" % total_hours_st) my.summary_st[7].update({search_key: total_hours_st}) td = table.add_blank_cell() td.add_style('width: 100%') return top
def init(my): my.current_offset = 0 my.count = None #my.text = TextWdg(my.search_limit_name) my.text = HiddenWdg(my.search_limit_name) my.text.add_style("width: 23px") my.text.add_style("margin-bottom: -1px") my.text.add_class("spt_search_limit_text") my.text.set_persist_on_submit(prefix=my.prefix) behavior = { 'type': 'keydown', 'cbjs_action': ''' if (evt.key=='enter') { // register this as changed item var value = bvr.src_el.value; if (isNaN(value) || value.test(/[\.-]/)) { spt.error('You have to use an integer.'); } } ''' } my.text.add_behavior(behavior) # get the search limit that is passed in filter_data = FilterData.get() values = filter_data.get_values_by_prefix(my.prefix) if not values: # check web for embedded table web = WebContainer.get_web() values = {} limit_value = web.get_form_value("search_limit") label_value = web.get_form_value(my.label) if limit_value: values['search_limit'] = limit_value if label_value: values[my.label] = label_value else: values = values[0] my.values2 = filter_data.get_values_by_prefix("search_limit_simple") if not len(my.values2): my.values2 = {} elif len(my.values2) == 2: if my.values2[0]['page']: my.values2 = my.values2[0] else: my.values2 = my.values2[1] else: my.values2 = my.values2[0] my.stated_search_limit = values.get("search_limit") """ if not my.stated_search_limit: my.stated_search_limit = values.get("limit_select") if not my.stated_search_limit: my.stated_search_limit = values.get("custom_limit") """ if my.stated_search_limit: my.stated_search_limit = int(my.stated_search_limit) else: my.stated_search_limit = 0 # reused for alter_search() later my.values = values
def get_display(my): web = WebContainer.get_web() widget = DivWdg() widget.add_class("spt_search_limit_top") #widget.add_style("border", "solid 1px blue") widget.add_color("background", "background") widget.add_color("color", "color") widget.add_style("padding: 10px") hidden = HiddenWdg("prefix", my.prefix) widget.add(hidden) if not my.search and not my.sobjects: widget.add("No search or sobjects found") return widget # my.count should have been set in alter_search() # which can be called explicitly thru this instance, my. if not my.count: my.count = my.search.get_count(no_exception=True) # if my.sobjects exist thru inheriting from parent widgets # or explicitly set, (this is not mandatory though) if my.sobjects and len(my.sobjects) < my.search_limit: limit = len(my.sobjects) elif my.search and my.count < my.search_limit: # this is only true if the total result of the search is # less than the limit and so this wdg will not display limit = my.count else: limit = my.search_limit if not limit: limit = 50 my.search_limit = limit if my.refresh: prev = SpanWdg(IconButtonWdg(title="Prev", icon="BS_CHEVRON_LEFT")) prev.add_style("margin-left: 8px") prev.add_style("margin-right: 6px") prev.add_style("margin-top: 5px") next = SpanWdg(IconButtonWdg(title="Next", icon="BS_CHEVRON_RIGHT")) next.add_style("margin-left: 6px") next.add_style("margin-top: 5px") prev.add_behavior({ 'type': 'click_up', 'cbjs_action': my.refresh_script }) next.add_behavior({ 'type': 'click_up', 'cbjs_action': my.refresh_script }) prev.add_style("float: left") next.add_style("float: left") else: # the old code pre 2.5 prev = IconButtonWdg(title="Prev", icon="BS_CHEVRON_LEFT") hidden_name = my.prev_hidden_name hidden = HiddenWdg(hidden_name, "") prev.add(hidden) prev.add_event('onclick'," spt.api.Utility.get_input(document,'%s').value ='Prev';%s"\ %(hidden_name, my.refresh_script)) next = IconButtonWdg(title="Next", icon="BS_CHEVRON_RIGHT") hidden_name = my.next_hidden_name hidden = HiddenWdg(hidden_name, "") next.add(hidden) next.add_event('onclick',"spt.api.Utility.get_input(document,'%s').value ='Next';%s" \ %(hidden_name, my.refresh_script)) showing_wdg = DivWdg() widget.add(showing_wdg) showing_wdg.add_style("padding: 20px") showing_wdg.add_style("margin: 10px") showing_wdg.add_color("background", "background", -5) #showing_wdg.add_color("text-align", "center") showing_wdg.add_border() label_span = SpanWdg("Showing: ") showing_wdg.add(label_span) showing_wdg.add("<br clear='all'/>") showing_wdg.add("<br/>") showing_wdg.add(prev) # this min calculation is used so that if my.sobjects is not set # above for the calculation of the limit, which will make the last # set of range numbers too big left_bound = my.current_offset + 1 if not limit: # prevent error in ItemsNavigatorWdg if a search encounters query error limit = 50 my.search_limit = limit right_bound = min(my.current_offset + limit, my.count) if left_bound > right_bound: left_bound = 1 current_value = "%d - %d" % (left_bound, right_bound) if my.style == my.SIMPLE: showing_wdg.add(current_value) else: # add a range selector using ItemsNavigatorWdg from pyasm.widget import ItemsNavigatorWdg selector = ItemsNavigatorWdg(my.label, my.count, my.search_limit) selector.select.add_behavior({ 'type': 'change', 'cbjs_action': my.refresh_script }) selector.set_style(my.style) selector.select.add_style("width: 100px") #selector.add_style("display: inline") selector.add_style("float: left") selector.set_value(current_value) selector.set_display_label(False) showing_wdg.add(selector) showing_wdg.add(next) showing_wdg.add("<br clear='all'/>") showing_wdg.add("<br clear='all'/>") #showing_wdg.add( " x ") showing_wdg.add(my.text) my.text.add_style("margin-top: -3px") my.text.set_attr("size", "1") my.text.add_attr("title", "Set number of items per page") # set the limit set_limit_wdg = my.get_set_limit_wdg() widget.add(set_limit_wdg) from tactic.ui.widget.button_new_wdg import ActionButtonWdg button = ActionButtonWdg(title='Search') widget.add(button) button.add_style("float: right") button.add_style("margin-top: 8px") button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var select = top.getElement(".spt_search_limit_select"); var value = select.value; if (value == 'Custom') { custom = top.getElement(".spt_search_limit_custom_text"); value = custom.value; } if (value == '') { value = 20; } var text = top.getElement(".spt_search_limit_text"); text.value = value; spt.dg_table.search_cbk({}, bvr) ''' }) offset_wdg = HiddenWdg("%s_last_search_offset" % my.label) offset_wdg.set_value(my.current_offset) widget.add(offset_wdg) widget.add("<br clear='all'/>") return widget
def get_data_wdg(my): div = DivWdg() from pyasm.biz import Pipeline from pyasm.widget import SelectWdg search_type_obj = SearchType.get(my.search_type) base_type = search_type_obj.get_base_key() search = Search("sthpw/pipeline") search.add_filter("search_type", base_type) pipelines = search.get_sobjects() if pipelines: pipeline = pipelines[0] process_names = pipeline.get_process_names() if process_names: table = Table() div.add(table) table.add_row() table.add_cell("Process: ") select = SelectWdg("process") table.add_cell(select) process_names.append("---") process_names.append("publish") process_names.append("icon") select.set_option("values", process_names) #### buttons = Table() div.add(buttons) buttons.add_row() button = IconButtonWdg(title="Add Data", icon=IconWdg.FOLDER) buttons.add_cell(button) dialog = DialogWdg(display="false", show_title=False) div.add(dialog) dialog.set_as_activator(button, offset={'x':-10,'y':10}) dialog_data_div = DivWdg() dialog_data_div.add_color("background", "background") dialog_data_div.add_style("padding", "20px") dialog.add(dialog_data_div) # Order folders by date name_div = DivWdg() dialog_data_div.add(name_div) name_div.add_style("margin: 15px 0px") if SearchType.column_exists(my.search_type, "relative_dir"): category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "none") category_div.add(checkbox) category_div.add(" No categories") category_div.add_style("margin-bottom: 5px") checkbox.set_option("checked", "true") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_day") category_div.add(checkbox) category_div.add(" Categorize files by Day") category_div.add_style("margin-bottom: 5px") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_week") category_div.add(checkbox) category_div.add(" Categorize files by Week") category_div.add_style("margin-bottom: 5px") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_year") category_div.add(checkbox) category_div.add(" Categorize files by Year") category_div.add_style("margin-bottom: 5px") """ checkbox = RadioWdg("category") checkbox.set_option("value", "custom") name_div.add(checkbox) name_div.add(" Custom") """ name_div.add("<br/>") hidden = HiddenWdg(name="parent_key") dialog_data_div.add(hidden) hidden.add_class("spt_parent_key") parent_key = my.kwargs.get("parent_key") or "" if parent_key: hidden.set_value(parent_key) dialog_data_div.add("Keywords:<br/>") dialog.add(dialog_data_div) text = TextAreaWdg(name="keywords") dialog_data_div.add(text) text.add_class("spt_keywords") text.add_style("padding: 1px") dialog_data_div.add("<br/>"*2) extra_data = my.kwargs.get("extra_data") if not isinstance(extra_data, basestring): extra_data = jsondumps(extra_data) dialog_data_div.add("Extra Data (JSON):<br/>") text = TextAreaWdg(name="extra_data") dialog_data_div.add(text) if extra_data != "null": text.set_value(extra_data) text.add_class("spt_extra_data") text.add_style("padding: 1px") #### TEST Image options """ button = IconButtonWdg(title="Resize", icon=IconWdg.FILM) buttons.add_cell(button) dialog = DialogWdg(display="false", show_title=False) div.add(dialog) dialog.set_as_activator(button, offset={'x':-10,'y':10}) try: from spt.tools.convert import ConvertOptionsWdg convert_div = DivWdg() dialog.add(convert_div) convert_div.add_style("padding: 20px") convert_div.add_color("background", "background") convert_div.add_class("spt_image_convert") convert = ConvertOptionsWdg() convert_div.add(convert) except: pass """ # use base name for name """ name_div = DivWdg() dialog_data_div.add(name_div) name_div.add_style("margin: 15px 0px") checkbox = CheckboxWdg("use_file_name") name_div.add(checkbox) name_div.add(" Use name of file for name") name_div.add("<br/>") checkbox = CheckboxWdg("use_base_name") name_div.add(checkbox) name_div.add(" Remove extension") name_div.add("<br/>") checkbox = CheckboxWdg("file_keywords") name_div.add(checkbox) name_div.add(" Use file name for keywords") """ return div
def get_display(my): my.sobject = my.kwargs.get("sobject") search_key = my.sobject.get_search_key() top = DivWdg() top.add_class("spt_checkin_publish") top.add_style("padding: 10px") margin_top = '60px' top.add_style("margin-top", margin_top) top.add_style("position: relative") current_changelist = WidgetSettings.get_value_by_key("current_changelist") current_branch = WidgetSettings.get_value_by_key("current_branch") current_workspace = WidgetSettings.get_value_by_key("current_workspace") top.add("Branch: %s<br/>" % current_branch) top.add("Changelist: %s<br/>" % current_changelist) top.add("Workspace: %s<br/>" % current_workspace) top.add("<br/>") checked_out_div = DivWdg() checkbox = CheckboxWdg("editable") top.add(checked_out_div) checkbox.add_class("spt_checkin_editable") checked_out_div.add(checkbox) checked_out_div.add("Leave files editable") top.add("<br/>") top.add("Publish Description<br/>") text = TextAreaWdg("description") # this needs to be set or it will stick out to the right text.add_style("width: 220px") text.add_class("spt_checkin_description") top.add(text) # add as a note note_div = DivWdg() top.add(note_div) note_div.add_class("spt_add_note") checkbox = CheckboxWdg("add_note") web = WebContainer.get_web() browser = web.get_browser() if browser in ['Qt']: checkbox.add_style("margin-top: -4px") checkbox.add_style("margin-right: 3px") note_div.add_style("margin-top: 3px") checkbox.add_class("spt_checkin_add_note") note_div.add(checkbox) note_div.add("Also add as note") top.add("<br/><br/>") button = ActionButtonWdg(title="Check-in", icon=IconWdg.PUBLISH, size='medium') top.add(button) my.repo_type = 'perforce' if my.repo_type == 'perforce': # the depot is set per project (unless overridden) project = my.sobject.get_project() depot = project.get_value("location", no_exception=True) if not depot: depot = project.get_code() asset_dir = Environment.get_asset_dir() sandbox_dir = Environment.get_sandbox_dir() changelist = WidgetSettings.get_value_by_key("current_changelist") button.add_behavior( { 'type': 'click_up', 'depot': depot, 'changelist': changelist, 'sandbox_dir': sandbox_dir, 'search_key': search_key, 'cbjs_action': ''' var paths = spt.checkin.get_selected_paths(); spt.app_busy.show("Checking in "+paths.length+" file/s into Perforce"); var top = bvr.src_el.getParent(".spt_checkin_top"); var description = top.getElement(".spt_checkin_description").value; var add_note = top.getElement(".spt_checkin_add_note").value; var editable = top.getElement(".spt_checkin_editable").value; if (editable == 'on') { editable = true; } else { editable = false; } var process = top.getElement(".spt_checkin_process").value; // check into TACTIC var server = TacticServerStub.get(); var revisions = []; server.start({description: "File Check-in"}); try { var top = bvr.src_el.getParent(".spt_checkin_top"); var el = top.getElement(".spt_mode"); var mode = el.value; // check-in the changelist var changelist = 'default'; if (mode == 'changelist') { var scm_info = spt.scm.run("commit_changelist", [changelist, description]); for ( var i = 1; i < scm_info.length-1; i++) { // the first item is the changelist number //console.log(scm_info[i]); var action = scm_info[i]; revision = action.rev; revisions.push(revision); // Do an inplace check-in into TACTIC var path = action.depotFile; var parts = path.split("/"); var filename = parts[parts.length-1]; var context = process + "/" + filename; var snapshot = server.simple_checkin(bvr.search_key, context, path, {description: description, mode: "perforce", version: revision} ); } } else { // check in all of the files for ( var i = 0; i < paths.length; i++) { var path = paths[i]; var scm_info = spt.scm.run("commit_file", [path, description, editable]); // the first item is the changelist number var action = scm_info[1]; revision = action.rev; revisions.push(revision); var parts = path.split("/"); var filename = parts[parts.length-1]; var context = process + "/" + filename; //path = path.replace(bvr.sandbox_dir, "//"+bvr.depot); // NOTE: this assumes project == depot path = path.replace(bvr.sandbox_dir, "//"); // Do an inplace check-in into TACTIC var snapshot = server.simple_checkin(bvr.search_key, context, path, {description: description, mode: "perforce", version: revision} ); } } if (add_note == 'on') { var note = []; note.push('CHECK-IN'); for (var i = 0; i < paths.length; i++) { var parts = paths[i].split("/"); var filename = parts[parts.length-1]; note.push(filename+' (v'+revisions[i]+')'); } note.push(': '); note.push(description); note = note.join(" "); server.create_note(bvr.search_key, note, {process: process}); } server.finish({description: "File Check-in ["+paths.length+" file/s]"}); spt.panel.refresh(top); } catch(e) { spt.error("Error detected: " + e.msg) //console.log(e); server.abort(); } spt.app_busy.hide(); ''' } ) else: button.add_behavior(behavior) button.add_style("margin-right: auto") button.add_style("margin-left: auto") button.add_style("margin-top: 20px") button.add_style("margin-bottom: 20px") top.add("<br clear='all'/>") top.add("<hr/>") hidden = HiddenWdg("checkin_type") top.add(hidden) hidden.add_class("spt_checkin_type") grey_out_div = DivWdg() top.add(grey_out_div) grey_out_div.add_class("spt_publish_disable") grey_out_div.add_style("position: absolute") grey_out_div.add_style("left: 0px") grey_out_div.add_style("top: 10px") grey_out_div.add_style("opacity: 0.6") grey_out_div.add_color("background", "background") grey_out_div.add_style("height: 100%") grey_out_div.add_style("width: 100%") #grey_out_div.add_border() return top
def get_display(my): relative_dir = my.kwargs.get("relative_dir") my.relative_dir = relative_dir div = DivWdg() div.add_class("spt_ingest_top") div.add_style("width: 100%px") div.add_style("min-width: 500px") div.add_style("padding: 20px") div.add_color("background", "background") my.search_type = my.kwargs.get("search_type") if not my.search_type: div.add("No search type specfied") return div if relative_dir: folder_div = DivWdg() div.add(folder_div) folder_div.add("Folder: %s" % relative_dir) folder_div.add_style("opacity: 0.5") folder_div.add_style("font-style: italic") folder_div.add_style("margin-bottom: 10px") data_div = my.get_data_wdg() data_div.add_style("float: left") data_div.add_style("float: left") div.add(data_div) # create the help button help_button_wdg = DivWdg() div.add(help_button_wdg) help_button_wdg.add_style("float: right") help_button = ActionButtonWdg(title="?", tip="Ingestion Widget Help", size='s') help_button_wdg.add(help_button) help_button.add_behavior( { 'type': 'click_up', 'cbjs_action': '''spt.help.load_alias("ingestion_widget")''' } ) from tactic.ui.input import Html5UploadWdg upload = Html5UploadWdg(multiple=True) div.add(upload) button = ActionButtonWdg(title="Add") button.add_style("float: right") button.add_style("margin-top: -3px") div.add(button) button.add_behavior( { 'type': 'click_up', 'normal_ext': File.NORMAL_EXT, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var files_el = top.getElement(".spt_to_ingest_files"); var regex = new RegExp('(' + bvr.normal_ext.join('|') + ')$', 'i'); //clear upload progress var upload_bar = top.getElement('.spt_upload_progress'); if (upload_bar) { upload_bar.setStyle('width','0%'); upload_bar.innerHTML = ''; } var onchange = function (evt) { var files = spt.html5upload.get_files(); var delay = 0; for (var i = 0; i < files.length; i++) { var size = files[i].size; var file_name = files[i].name; var is_normal = regex.test(file_name); if (size >= 10*1024*1024 || is_normal) { spt.drag.show_file(files[i], files_el, 0, false); } else { spt.drag.show_file(files[i], files_el, delay, true); if (size < 100*1024) delay += 50; else if (size < 1024*1024) delay += 500; else if (size < 10*1024*1024) delay += 1000; } } } spt.html5upload.clear(); spt.html5upload.set_form( top ); spt.html5upload.select_file( onchange ); ''' } ) button = ActionButtonWdg(title="Clear") button.add_style("float: right") button.add_style("margin-top: -3px") div.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); }; ''' } ) div.add("<br clear='all'/>") div.add("<br clear='all'/>") border_color_light = div.get_color("background2", 8) border_color_dark = div.get_color("background2", -15) background_mouseout = div.get_color("background3", 10) background_mouseenter = div.get_color("background3", 8) files_div = DivWdg() files_div.add_style("position: relative") files_div.add_class("spt_to_ingest_files") div.add(files_div) files_div.add_style("max-height: 300px") files_div.add_style("height: 300px") files_div.add_style("overflow-y: auto") files_div.add_style("padding: 3px") files_div.add_color("background", background_mouseout) files_div.add_style("border: 3px dashed %s" % border_color_light) files_div.add_style("border-radius: 20px 20px 20px 20px") files_div.add_style("z-index: 1") #files_div.add_style("display: none") bgcolor = div.get_color("background3") bgcolor2 = div.get_color("background3", -3) #style_text = "text-align: center; margin-top: 100px; color: #A0A0A0; font-size: 3.0em; z-index: 10;" background = DivWdg() background.add_class("spt_files_background") files_div.add(background) background.add_style("text-align: center") background.add_style("margin-top: 100px") background.add_style("opacity: 0.65") background.add_style("font-size: 3.0em") background.add_style("z-index: 10") background_text = DivWdg("<p>Drag Files Here</p>") background.add(background_text) files_div.add_behavior( { 'type': 'mouseover', 'cbjs_action': ''' bvr.src_el.setStyle("border","3px dashed %s") bvr.src_el.setStyle("background","%s") ''' % (border_color_dark, background_mouseenter) } ) files_div.add_behavior( { 'type': 'mouseout', 'cbjs_action': ''' bvr.src_el.setStyle("border", "3px dashed %s") bvr.src_el.setStyle("background","%s") ''' % (border_color_light, background_mouseout) } ) # Test drag and drop files files_div.add_attr("ondragenter", "return false") files_div.add_attr("ondragover", "return false") files_div.add_attr("ondrop", "spt.drag.noop(event, this)") files_div.add_behavior( { 'type': 'load', 'normal_ext': File.NORMAL_EXT, 'cbjs_action': ''' spt.drag = {} var background; spt.drag.show_file = function(file, top, delay, icon) { if (!background) { background = top.getElement(".spt_files_background"); if (background) background.setStyle("display", "none"); } var template = top.getElement(".spt_upload_file_template"); var clone = spt.behavior.clone(template); clone.removeClass("spt_upload_file_template"); clone.addClass("spt_upload_file"); clone.setStyle("display", ""); if (typeof(delay) == 'undefined') { delay = 0; } // remember the file handle clone.file = file; var name = file.name; var size = parseInt(file.size / 1024 * 10) / 10; var thumb_el = clone.getElement(".spt_thumb"); var date_label_el = clone.getElement(".spt_date_label"); var date_el = clone.getElement(".spt_date"); //var loadingImage = loadImage( setTimeout( function() { var draw_empty_icon = function() { var img = $(document.createElement("div")); img.setStyle("width", "58"); img.setStyle("height", "34"); //img.innerHTML = "MP4"; img.setStyle("border", "1px dotted #222") thumb_el.appendChild(img); }; if (icon) { var loadingImage = loadImage( file, function (img) { if (img.width) thumb_el.appendChild(img); else draw_empty_icon(); }, {maxWidth: 80, maxHeight: 60, canvas: true, contain: true} ); } else { draw_empty_icon(); } loadImage.parseMetaData( file, function(data) { if (data.exif) { var date = data.exif.get('DateTimeOriginal'); if (date) { date_label_el.innerHTML = date; if (date_el) { date_el.value = date; } } } } ); }, delay ); /* var reader = new FileReader(); reader.thumb_el = thumb_el; reader.onload = function(e) { this.thumb_el.innerHTML = [ '<img class="thumb" src="', e.target.result, '" title="', escape(name), '" width="60px"', '" padding="5px"', '"/>' ].join(''); } reader.readAsDataURL(file); */ clone.getElement(".spt_name").innerHTML = file.name; clone.getElement(".spt_size").innerHTML = size + " KB"; clone.inject(top); } spt.drag.noop = function(evt, el) { var top = $(el).getParent(".spt_ingest_top"); var files_el = top.getElement(".spt_to_ingest_files"); evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; var files = evt.dataTransfer.files; var delay = 0; var skip = false; var regex = new RegExp('(' + bvr.normal_ext.join('|') + ')$', 'i'); for (var i = 0; i < files.length; i++) { var size = files[i].size; var file_name = files[i].name; var is_normal = regex.test(file_name); if (size >= 10*1024*1024 || is_normal) { spt.drag.show_file(files[i], files_el, 0, false); } else { spt.drag.show_file(files[i], files_el, delay, true); if (size < 100*1024) delay += 50; else if (size < 1024*1024) delay += 500; else if (size < 10*1024*1024) delay += 1000; } } } ''' } ) # create a template that will be filled in for each file files_div.add_relay_behavior( { 'type': 'mouseenter', 'color': files_div.get_color("background3", -5), 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.color); ''' } ) files_div.add_relay_behavior( { 'type': 'mouseleave', 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); ''' } ) files_div.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_remove', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_upload_file"); spt.behavior.destroy_element(top); ''' } ) """ metadata_view = "test/wizard/metadata" files_div.add_relay_behavior( { 'type': 'mouseup', 'view': metadata_view, 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: bvr.view } spt.app_busy.show("Loading Metadata"); spt.panel.load_popup("Metadata", class_name, kwargs); spt.app_busy.hide(); ''' } ) """ # template for each file item file_template = DivWdg() file_template.add_class("spt_upload_file_template") files_div.add(file_template) file_template.add_style("margin-bottom: 3px") file_template.add_style("padding: 3px") file_template.add_style("height: 40px") file_template.add_style("display: none") thumb_div = DivWdg() file_template.add(thumb_div) thumb_div.add_style("float: left") thumb_div.add_style("width: 60"); thumb_div.add_style("height: 40"); thumb_div.add_style("overflow: hidden"); thumb_div.add_style("margin: 3 10 3 0"); thumb_div.add_class("spt_thumb") info_div = DivWdg() file_template.add(info_div) info_div.add_style("float: left") name_div = DivWdg() name_div.add_class("spt_name") info_div.add(name_div) name_div.add("image001.jpg") name_div.add_style("width: 150px") """ dialog = DialogWdg(display="false", show_title=False) info_div.add(dialog) dialog.set_as_activator(info_div, offset={'x':0,'y':10}) dialog_data_div = DivWdg() dialog_data_div.add_color("background", "background") dialog_data_div.add_style("padding", "10px") dialog.add(dialog_data_div) dialog_data_div.add("Category: ") text = TextInputWdg(name="category") dialog_data_div.add(text) text.add_class("spt_category") text.add_style("padding: 1px") """ date_div = DivWdg() date_div.add_class("spt_date_label") info_div.add(date_div) date_div.add("") date_div.add_style("opacity: 0.5") date_div.add_style("font-size: 0.8em") date_div.add_style("font-style: italic") date_div.add_style("margin-top: 3px") hidden_date_div = HiddenWdg("date") hidden_date_div.add_class("spt_date") info_div.add(date_div) size_div = DivWdg() size_div.add_class("spt_size") file_template.add(size_div) size_div.add("433Mb") size_div.add_style("float: left") size_div.add_style("width: 150px") size_div.add_style("text-align: right") remove_div = DivWdg() remove_div.add_class("spt_remove") file_template.add(remove_div) icon = IconButtonWdg(title="Remove", icon=IconWdg.DELETE) icon.add_style("float: right") remove_div.add(icon) #remove_div.add_style("text-align: right") div.add("<br/>") info = DivWdg() div.add(info) info.add_class("spt_upload_info") progress_div = DivWdg() progress_div.add_class("spt_upload_progress_top") div.add(progress_div) progress_div.add_style("width: 100%") progress_div.add_style("height: 15px") progress_div.add_style("margin-bottom: 10px") progress_div.add_border() #progress_div.add_style("display: none") progress = DivWdg() progress_div.add(progress) progress.add_class("spt_upload_progress") progress.add_style("width: 0px") progress.add_style("height: 100%") progress.add_gradient("background", "background3", -10) progress.add_style("text-align: right") progress.add_style("overflow: hidden") progress.add_style("padding-right: 3px") from tactic.ui.app import MessageWdg progress.add_behavior( { 'type': 'load', 'cbjs_action': MessageWdg.get_onload_js() } ) # NOTE: files variable is passed in automatically upload_init = ''' server.start( {description: "Upload and check-in of ["+files.length+"] files"} ); var info_el = top.getElement(".spt_upload_info"); info_el.innerHTML = "Uploading ..."; ''' upload_progress = ''' var top = bvr.src_el.getParent(".spt_ingest_top"); progress_el = top.getElement(".spt_upload_progress"); var percent = Math.round(evt.loaded * 100 / evt.total); progress_el.setStyle("width", percent + "%"); progress_el.innerHTML = String(percent) + "%"; ''' oncomplete_script_path = my.kwargs.get("oncomplete_script_path") oncomplete_script = '' if oncomplete_script_path: script_folder, script_title = oncomplete_script_path.split("/") oncomplete_script_expr = "@GET(config/custom_script['folder','%s']['title','%s'].script)" %(script_folder,script_title) server = TacticServerStub.get() oncomplete_script_ret = server.eval(oncomplete_script_expr, single=True) if oncomplete_script_ret: oncomplete_script = '''var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); };''' + oncomplete_script_ret script_found = True else: script_found = False oncomplete_script = "alert('Error: oncomplete script not found');" if not oncomplete_script: oncomplete_script = ''' var click_action = function() { var fade = true; var pop = spt.popup.get_popup(top) spt.popup.close(pop, fade); } spt.info("Ingest Completed", {click: click_action}); server.finish(); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); }; var background = top.getElement(".spt_files_background"); background.setStyle("display", ""); spt.message.stop_interval(key); var info_el = top.getElement(".spt_upload_info"); info_el.innerHTML = ''; if (spt.table) { spt.table.run_search(); } spt.panel.refresh(top); ''' script_found = True on_complete = ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var update_data_top = top.getElement(".spt_edit_top"); var progress_el = top.getElement(".spt_upload_progress"); progress_el.innerHTML = "100%"; progress_el.setStyle("width", "100%"); var info_el = top.getElement(".spt_upload_info"); var search_type = bvr.kwargs.search_type; var relative_dir = bvr.kwargs.relative_dir; var update_mode_select = top.getElement(".spt_update_mode_select"); var update_mode = update_mode_select.value; var filenames = []; for (var i = 0; i != files.length;i++) { var name = files[i].name; filenames.push(name); } var key = spt.message.generate_key(); var values = spt.api.get_input_values(top); //var category = values.category[0]; //var keywords = values.keywords[0]; var extra_data = values.extra_data ? values.extra_data[0]: {}; var parent_key = values.parent_key[0]; var convert_el = top.getElement(".spt_image_convert") var convert = spt.api.get_input_values(convert_el); var processes = values.process; if (processes) { process = processes[0]; if (!process) { process = null; } } else { process = null; } var return_array = false; var update_data = spt.api.get_input_values(update_data_top, null, return_array); var kwargs = { search_type: search_type, relative_dir: relative_dir, filenames: filenames, key: key, parent_key: parent_key, //category: category, //keywords: keywords, extra_data: extra_data, update_data: update_data, process: process, convert: convert, update_mode: update_mode, } on_complete = function(rtn_data) { ''' + oncomplete_script + ''' }; var class_name = bvr.action_handler; // TODO: make the async_callback return throw an e so we can run // server.abort server.execute_cmd(class_name, kwargs, null, {on_complete:on_complete}); on_progress = function(message) { msg = JSON.parse(message.message); var percent = msg.progress; var description = msg.description; info_el.innerHTML = description; progress_el.setStyle("width", percent+"%"); progress_el.innerHTML = percent + "%"; } spt.message.set_interval(key, on_progress, 2000); ''' upload_div = DivWdg() div.add(upload_div) #button = UploadButtonWdg(**kwargs) button = ActionButtonWdg(title="Ingest") upload_div.add(button) button.add_style("float: right") upload_div.add_style("margin-bottom: 15px") upload_div.add("<br clear='all'/>") action_handler = my.kwargs.get("action_handler") if not action_handler: action_handler = 'tactic.ui.tools.IngestUploadCmd'; button.add_behavior( { 'type': 'click_up', 'action_handler': action_handler, 'kwargs': { 'search_type': my.search_type, 'relative_dir': relative_dir, 'script_found': script_found, }, 'cbjs_action': ''' if (bvr.kwargs.script_found != true) { spt.alert("Error: provided on_complete script not found"); return; } var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); // get the server that will be used in the callbacks var server = TacticServerStub.get(); // retrieved the stored file handles var files = []; for (var i = 0; i < file_els.length; i++) { files.push( file_els[i].file ); } if (files.length == 0) { alert("Either click 'Add' or drag some files over to ingest."); return; } // defined the callbacks var upload_start = function(evt) { } var upload_progress = function(evt) { %s; } var upload_complete = function(evt) { %s; spt.app_busy.hide(); } var upload_file_kwargs = { files: files, upload_start: upload_start, upload_complete: upload_complete, upload_progress: upload_progress }; if (bvr.ticket) upload_file_kwargs['ticket'] = bvr.ticket; %s; spt.html5upload.set_form( top ); spt.html5upload.upload_file(upload_file_kwargs); ''' % (upload_progress, on_complete, upload_init) } ) return div
def get_display(my): top = my.top top.add_color("background", "background") top.add_class("spt_columns_top") my.set_as_panel(top) top.add_style("padding: 10px") search_type = my.kwargs.get("search_type") search_type_obj = SearchType.get(search_type) inner = DivWdg() top.add(inner) inner.add_style("width: 500px") #text = TextWdg("search_type") text = HiddenWdg("search_type") inner.add(text) text.set_value(search_type) title_wdg = DivWdg() inner.add(title_wdg) title_wdg.add( search_type_obj.get_title() ) title_wdg.add(" <i style='font-size: 9px;opacity: 0.5'>(%s)</i>" % search_type) title_wdg.add_style("padding: 5px") title_wdg.add_color("background", "background3") title_wdg.add_color("color", "color3") title_wdg.add_style("margin: -10px -10px 10px -10px") title_wdg.add_style("font-weight: bold") shelf_wdg = DivWdg() inner.add(shelf_wdg) shelf_wdg.add_style("height: 30px") button = ActionButtonWdg(title='Create', icon=IconWdg.SAVE) shelf_wdg.add(button) shelf_wdg.add_style("float: right") button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'cbjs_action': ''' var class_name = 'tactic.ui.startup.ColumnEditCbk'; var top = bvr.src_el.getParent(".spt_columns_top"); var elements = top.getElements(".spt_columns_element"); var values = []; for (var i = 0; i < elements.length; i++ ) { var data = spt.api.Utility.get_input_values(elements[i], null, false); values.push(data) } var kwargs = { search_type: bvr.search_type, values: values } var server = TacticServerStub.get(); try { server.execute_cmd(class_name, kwargs); var names = []; for (var i = 0; i < values.length; i++) { var name = values[i].name; name = name.strip(); if (name == '') { continue; } names.push(name); } spt.table.add_columns(names) // prevent grabbing all values, pass in a dummy one spt.panel.refresh(top, {'refresh': true}); } catch(e) { spt.alert(spt.exception.handler(e)); } ''' } ) # add the headers table = Table() inner.add(table) table.add_style("width: 100%") tr = table.add_row() tr.add_gradient("background", "background3") tr.add_style("padding", "3px") th = table.add_header("Column Name") th.add_style("width: 170px") th.add_style("text-align: left") th = table.add_header("Format") th.add_style("text-align: left") from tactic.ui.container import DynamicListWdg dyn_list = DynamicListWdg() inner.add(dyn_list) from tactic.ui.manager import FormatDefinitionEditWdg for i in range(0, 4): column_div = DivWdg() column_div.add_class("spt_columns_element") if i == 0: dyn_list.add_template(column_div) else: dyn_list.add_item(column_div) column_div.add_style("padding: 3px") column_div.add_style("float: left") table = Table() column_div.add(table) table.add_row() text_wdg = NewTextWdg("name") td = table.add_cell(text_wdg) text_wdg.add_behavior( { 'type': 'blur', 'cbjs_action': ''' var value = bvr.src_el.value; var code = spt.convert_to_alpha_numeric(value); bvr.src_el.value = code; ''' } ) option = { 'name': 'xxx', 'values': 'integer|float|percent|currency|date|time|scientific|boolean|text|timecode', } format_wdg = FormatDefinitionEditWdg(option=option) td = table.add_cell(format_wdg) td.add_style("width: 260px") td.add_style("padding-left: 40px") # show the current columns title_wdg = DivWdg() inner.add(title_wdg) title_wdg.add_style("margin-top: 20px") title_wdg.add("<b>Existing Columns</b>") title_wdg.add_color("background", "background3") title_wdg.add_style("padding: 5px") title_wdg.add_style("margin: 20px -10px 10px -10px") config = WidgetConfigView.get_by_search_type(search_type, "definition") element_names = config.get_element_names() table = Table() inner.add(table) table.add_style("width: 100%") tr = table.add_row() tr.add_gradient("background", "background3") th = table.add_header("Column") th.add_style("text-align: left") th = table.add_header("Data Type") th.add_style("text-align: left") th = table.add_header("Format") th.add_style("text-align: left") th = table.add_header("Edit") th.add_style("text-align: left") count = 0 for element_name in element_names: display_class = config.get_display_handler(element_name) if display_class != 'tactic.ui.table.FormatElementWdg': continue table.add_row() display_options = config.get_display_options(element_name) format = display_options.get("format") if not format: format = '<i>text</i>' data_type = display_options.get("type") table.add_cell(element_name) table.add_cell(data_type) table.add_cell(format) td = table.add_cell() button = IconButtonWdg(title="Edit Definition", icon=IconWdg.EDIT) td.add(button) button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'element_name': element_name, 'cbjs_action': ''' var class_name = 'tactic.ui.manager.ElementDefinitionWdg'; var kwargs = { search_type: bvr.search_type, view: 'definition', element_name: bvr.element_name }; spt.panel.load_popup("Element Definition", class_name, kwargs); ''' } ) count += 1 if not count: table.add_row() td = table.add_cell() td.add_style("height: 50px") td.add("No existing columns found") td.add_style("text-align: center") td.add_border() td.add_color("background", "background", -5) if my.kwargs.get("is_refresh"): return inner else: return top
def get_top(my): top = my.top top.add_color("background", "background", -5) top.add_style("margin-bottom: -2px") top.add_class("spt_filter_top") table = Table() top.add(table) title_div = DivWdg() tr, td = table.add_row_cell() td.add(title_div) title_div.add("<div style='font-size: 16px'>Search Criteria</div>") title_div.add("<div>Select filters to refine your search</div>") title_div.add_style("padding: 20px 0px 0px 20px") table.add_style("margin-left: auto") table.add_style("margin-right: auto") table.add_style("margin-bottom: 15px") table.add_style("width: 100%") tr = table.add_row() if not my.content: my.content = DivWdg() my.content.add("No Content") td = table.add_cell() td.add(my.content) #my.content.add_style("margin: -2 -1 0 -1") show_search = my.kwargs.get("show_search") if show_search in [False, 'false']: show_search = False else: show_search = True show_search = False if show_search: search_wdg = my.get_search_wdg() table.add_row() search_wdg.add_style("float: left") search_wdg.add_style("padding-top: 6px") search_wdg.add_style("padding-left: 10px") search_wdg.add_style("height: 33px") td = table.add_cell() td.add(search_wdg) td.add_style("padding: 5px 20px") #td.add_border() #td.add_color("background", "background", -10) hidden = HiddenWdg("prefix", my.prefix) top.add(hidden) # this cannot be spt_search as it will confuse spt.dg_table.search_cbk() top.add_class("spt_simple_search") return top
def get_scale_wdg(my): if my.scale_called == True: return None my.scale_called = True show_scale = my.kwargs.get("show_scale") div = DivWdg() if show_scale in [False, 'false']: div.add_style("display: none") div.add_style("padding: 5px") div.add_class("spt_table_search") hidden = HiddenWdg("prefix", "tile_layout") div.add(hidden) div.add_behavior( { 'type': 'load', 'scale_prefix': my.scale_prefix, 'default_scale': my.scale, 'aspect_ratio': my.aspect_ratio, 'cbjs_action': ''' spt.tile_layout = {} spt.tile_layout.layout = null; spt.tile_layout.set_layout = function(layout) { if (!layout.hasClass("spt_layout")) { layout = layout.getParent(".spt_layout"); } spt.tile_layout.layout = layout; return layout; } spt.tile_layout.get_scale = function() { var scale_value = spt.tile_layout.layout.getElement(".spt_scale_value"); var value = scale_value.value; value = parseInt(value); return value; } spt.tile_layout.set_scale = function(scale) { var scale_value = spt.tile_layout.layout.getElement(".spt_scale_value"); scale_value.value = scale; var size_x = bvr.aspect_ratio[0]*scale/100; var size_y = bvr.aspect_ratio[1]*scale/100; //var top = bvr.src_el.getParent(".spt_tile_layout_top"); var top = spt.tile_layout.layout; var els = top.getElements(".spt_tile_content"); for (var i = 0; i < els.length; i++) { var el = els[i]; el.setStyle( "width", size_x); el.setStyle( "height", size_y); } var container_id = "tile_layout::scale"+bvr.scale_prefix; spt.container.set_value( container_id, scale); } spt.tile_layout.drag_start_x = null; spt.tile_layout.drag_start_value = null; spt.tile_layout.drag_setup = function(evt, bvr, mouse_411) { spt.tile_layout.set_layout(bvr.src_el); spt.tile_layout.drag_start_x = mouse_411.curr_x; var src_el = spt.behavior.get_bvr_src( bvr ); if (!src_el.value) { src_el.value = 0; } spt.tile_layout.drag_start_value = src_el.value; src_el.focus(); src_el.select(); } spt.tile_layout.drag_motion = function(evt, bvr, mouse_411) { var start_value = spt.tile_layout.drag_start_value; if (isNaN(parseInt(start_value))) { return; } var dx = mouse_411.curr_x - spt.tile_layout.drag_start_x; var increment = parseInt(dx / 5); var multiplier; if (increment < 0) multiplier = 0.975; else multiplier = 1 / 0.975; increment = Math.abs(increment); var scale = spt.tile_layout.drag_start_value; for (var i = 0; i < increment; i++) { scale = scale * multiplier; } if (scale > 400) scale = 400; scale = parseInt(scale); spt.tile_layout.set_scale(scale); } spt.tile_layout.setup_control = function() { var slider = spt.tile_layout.layout.getElement('.spt_slider'); var container_id = "tile_layout::scale"+bvr.scale_prefix; var initial_value = spt.container.get_value(container_id) ? spt.container.get_value(container_id) : bvr.default_scale; spt.tile_layout.set_scale(initial_value); new Slider(slider, slider.getElement('.knob'), { range: [30, 400], steps: 74, initialStep: initial_value, onChange: function(value){ if (value) spt.tile_layout.set_scale(value); } }); } spt.tile_layout.image_drag_setup = function(evt, bvr, mouse_411) { bvr.use_copy = true; bvr.use_delta = true; //bvr.border_color = border_color; bvr.dx = 10; bvr.dy = 10; bvr.drop_code = 'DROP_ROW'; } spt.tile_layout.image_drag_motion = function(evt, bvr, mouse_411) { spt.mouse._smart_default_drag_motion(evt, bvr, mouse_411); var target_el = spt.get_event_target(evt); target_el = spt.mouse.check_parent(target_el, bvr.drop_code); if (target_el) { var orig_border_color = target_el.getStyle('border-color'); var orig_border_style = target_el.getStyle('border-style'); target_el.setStyle('border','dashed 2px ' + bvr.border_color); if (!target_el.getAttribute('orig_border_color')) { target_el.setAttribute('orig_border_color', orig_border_color); target_el.setAttribute('orig_border_style', orig_border_style); } } } spt.tile_layout.image_drag_action = function(evt, bvr, mouse_411) { if (spt.drop) { spt.drop.sobject_drop_action(evt, bvr); } else { if( bvr._drag_copy_el ) { spt.behavior.destroy_element(bvr._drag_copy_el); } } } ''' } ) scale = my.kwargs.get("scale") div.add_behavior( { 'type': 'load', 'scale': scale, 'cbjs_action': ''' spt.tile_layout.set_layout(bvr.src_el); spt.tile_layout.setup_control(); if (bvr.scale) { spt.tile_layout.set_scale(bvr.scale); } ''' } ) table = Table() div.add(table) table.add_row() """ # TO BE DELETED less_div = DivWdg() less_div.add("<input type='button' value='<<'/>") table.add_cell(less_div) less_div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.tile_layout.set_layout(bvr.src_el); var scale = spt.tile_layout.get_scale(); scale = scale * 0.95; scale = parseInt(scale); spt.tile_layout.set_scale(scale); ''' } ) """ dark_color = div.get_color("background", -5) light_color = div.get_color('color') med_color = div.get_color('color2') slider_div = DivWdg(css='spt_slider') slider_div.add_styles('valign: bottom; background: %s; height: 6px; width: 100px;'% light_color) knob_div = DivWdg(css='knob') knob_div.add_behavior({'type':'click', 'cbjs_action': 'spt.tile_layout.set_layout(bvr.src_el)' }) knob_div.add_styles('background: %s; bottom: 4px;\ height: 16px; width: 12px; border-radius: 6px 6px 0 0;\ border: 1px %s solid'\ %(dark_color, med_color )) slider_div.add(knob_div) td = table.add_cell(slider_div) value_wdg = TextWdg("scale") value_wdg.add_class("spt_scale_value") td = table.add_cell(value_wdg) td.add(" %") td.add_style("padding: 3px 8px") """ # TO BE DELETED from tactic.ui.filter import FilterData filter_data = FilterData.get() data_list = filter_data.get_values_by_prefix("tile_layout") if data_list: data = data_list[0] else: data = {} my.scale = data.get("scale") if my.scale == None: my.scale = my.kwargs.get("scale") """ if my.scale: value_wdg.set_value(my.scale) value_wdg.add_style("width: 28px") value_wdg.add_style("text-align: center") value_wdg.add_behavior( { 'type': 'change', 'cbjs_action': ''' var value = bvr.src_el.value; var scale = parseInt(value); spt.tile_layout.set_layout(bvr.src_el); spt.tile_layout.set_scale(scale); ''' } ) value_wdg.add_behavior( { 'type': 'load', 'cbjs_action': ''' var value = bvr.src_el.value; if (!value) { value = 100; } var scale = parseInt(value); spt.tile_layout.set_layout(bvr.src_el); spt.tile_layout.set_scale(scale); ''' } ) value_wdg.add_behavior( { 'type': 'smart_drag', 'bvr_match_class': 'spt_scale_value', 'ignore_default_motion' : True, "cbjs_setup": 'spt.tile_layout.drag_setup( evt, bvr, mouse_411 );', "cbjs_motion": 'spt.tile_layout.drag_motion( evt, bvr, mouse_411 );' } ) """ # TO BE DELETED more_div = DivWdg() more_div.add("<input type='button' value='>>'/>") table.add_cell(more_div) more_div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.tile_layout.set_layout(bvr.src_el); var scale = spt.tile_layout.get_scale(); scale = scale / 0.95; scale = parseInt(scale); spt.tile_layout.set_scale(scale); ''' } ) """ return div
def get_display(my): top = my.top my.set_as_panel(top) top.add_class("spt_ingestion_top") top.add_color("background", "background", -5) my.data = {} rules_div = DivWdg() top.add(rules_div) rules_div.add_style("padding: 10px") rules_div.add("Rules: ") rules_select = SelectWdg("rule_code") rule_code = my.get_value('rule_code') if rule_code: rules_select.set_value(rule_code) rules_select.set_option("query", "config/ingest_rule|code|title") rules_select.add_empty_option("-- New --") rules_div.add(rules_select) rules_select.add_behavior( { 'type': 'change', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingestion_top"); value = bvr.src_el.value; var class_name = 'tactic.ui.tools.IngestionToolWdg'; spt.panel.load(top, class_name, {rule_code: value} ); ''' } ) rules_div.add("<hr/>") # read from the database if rule_code: search = Search("config/ingest_rule") search.add_filter("code", rule_code) sobject = search.get_sobject() else: sobject = None if sobject: my.data = sobject.get_value("data") if my.data: my.data = jsonloads(my.data) session_code = my.kwargs.get("session_code") if session_code: session = Search.get_by_code("config/ingest_session", session_code) else: if sobject: session = sobject.get_related_sobject("config/ingest_session") print "sobject: ", sobject.get_code(), sobject.get_value("spt_ingest_session_code") print "parent: ", session else: session = None if not session: #session = SearchType.create("config/ingest_session") #session.set_value("code", "session101") #session.set_value("location", "local") ##session.set_value("base_dir", "C:") top.add("No session defined!!!") return top rule = "" filter = "" ignore = "" # get the base path if sobject: base_dir = sobject.get_value("base_dir") else: base_dir = '' #else: # base_dir = my.get_value("base_dir") #if not base_dir: # base_dir = '' if sobject: title = sobject.get_value("title") else: title = '' if sobject: code = sobject.get_value("code") else: code = '' file_list = my.get_value("file_list") scan_type = my.get_value("scan_type") action_type = my.get_value("action_type") rule = my.get_value("rule") if not rule: rule = base_dir # get the rule for this path checkin_mode = "dir" depth = 0 table = Table() rules_div.add(table) table.add_color("color", "color") from tactic.ui.input.text_input_wdg import TextInputWdg # add the title table.add_row() td = table.add_cell() td.add("Title: ") td = table.add_cell() text = TextInputWdg(name="title") td.add(text) if title: text.set_value(title) text.add_class("spt_title") text.add_style("width: 400px") #text.add_color("background", "background", -10) # add the optional code table.add_row() td = table.add_cell() td.add("Code (optional): ") td = table.add_cell() text = TextInputWdg(name="code") td.add(text) if code: text.set_value(code) text.set_readonly() text.add_color("background", "background", -10) text.add_class("spt_code") text.add_style("width: 400px") table.add_row() td = table.add_cell() td.add_style("height: 10px") td.add("<hr/>") table.add_row() td = table.add_cell() td.add("<b>Scan:</b><br/>") td.add("The following information will be used to find the paths that will be operated on by the ingestion process<br/><br/>") # add a scan type table.add_row() td = table.add_cell() td.add("Type: ") select = SelectWdg("scan_type") select.add_class("spt_scan_type") td = table.add_cell() td.add(select) select.set_value( my.get_value("action") ) labels = ['Simple List', 'Rule', 'Script'] values = ['list', 'rule', 'script'] select.set_option("values", values) select.set_option("labels", labels) if scan_type: select.set_value(scan_type) table.add_row() table.add_cell(" ") select.add_behavior( { 'type': 'change', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingestion_top"); value = bvr.src_el.value; var elements = top.getElements(".spt_scan_list"); for (var i = 0; i < elements.length; i++) { if (value == 'list') spt.show(elements[i]); else spt.hide(elements[i]); } var elements = top.getElements(".spt_scan_rule"); for (var i = 0; i < elements.length; i++) { if (value == 'rule') spt.show(elements[i]); else spt.hide(elements[i]); } var elements = top.getElements(".spt_scan_script"); for (var i = 0; i < elements.length; i++) { if (value == 'script') spt.show(elements[i]); else spt.hide(elements[i]); } ''' } ) # add in a list of stuff tbody = table.add_tbody() tbody.add_class("spt_scan_list") if scan_type != 'list': tbody.add_style("display: none") tr = table.add_row() td = table.add_cell() td.add("List of files: ") td = table.add_cell() text = TextAreaWdg(name="file_list") td.add(text) text.add_style("width: 400px") #text.set_readonly() #text.add_color("background", "background", -10) text.set_value(file_list) table.close_tbody() # add rule scan mode tbody = table.add_tbody() tbody.add_class("spt_scan_rule") if scan_type != 'rule': tbody.add_style("display: none") # add the path tr = table.add_row() td = table.add_cell() td.add("Starting Path: ") td = table.add_cell() hidden = HiddenWdg("session_code", session.get_code() ) td.add(hidden) text = TextInputWdg(name="base_dir") td.add(text) text.set_value(base_dir) text.add_style("width: 400px") #text.set_readonly() #text.add_color("background", "background", -10) text.set_value(base_dir) # add rule tr = table.add_row() td = table.add_cell() td.add("Tag Rule: ") td = table.add_cell() text = TextInputWdg(name="rule") td.add(text) text.add_style("width: 400px") text.set_value(rule) tr = table.add_row() td = table.add_cell() td.add("Filter: ") td = table.add_cell() text = TextWdg("filter") td.add(text) text.set_value( my.get_value("filter") ) text.add_style("width: 400px") text.add_style("padding: 2px") text.add_style("-moz-border-radius: 5px") tr = table.add_row() td = table.add_cell() td.add("Ignore: ") td = table.add_cell() text = TextWdg("ignore") td.add(text) text.set_value( my.get_value("ignore") ) text.set_value(ignore) text.add_style("width: 400px") text.add_style("padding: 2px") text.add_style("-moz-border-radius: 5px") table.add_row() td = table.add_cell() td.add("Validation script: ") td.add_style("vertical-align: top") td.add_style("padding-top: 5px") td = table.add_cell() text = TextInputWdg(name="validation_script") text.set_value( my.get_value("validation_script") ) text.add_style("width: 400px") td.add(text) icon = IconButtonWdg(title='Edit Validation Script', icon=IconWdg.EDIT) icon.add_style("float: right") td.add(icon) icon.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.named_events.fire_event("show_script_editor"); var top = bvr.src_el.getParent(".spt_ingestion_top"); var values = spt.api.Utility.get_input_values(top, null, false); var kwargs = { script_path: values.validation_script } setTimeout( function() { spt.js_edit.display_script_cbk(evt, kwargs) }, 500 ); ''' } ) table.close_tbody() # add the script path tbody = table.add_tbody() tbody.add_class("spt_scan_script") if scan_type != 'script': tbody.add_style("display: none") tr = table.add_row() td = table.add_cell() td.add("Script Path: ") td = table.add_cell() text = TextInputWdg(name="script_path") td.add(text) text.add_style("width: 400px") table.close_tbody() table.add_row() td = table.add_cell("<hr/>") table.add_row() td = table.add_cell() td.add("<b>Action</b><br/>") td.add("The following information define the actions that will be used on each matched path<br/><br/>") # pick the type of action table.add_row() td = table.add_cell() td.add("Type: ") select = SelectWdg("action_type") td = table.add_cell() td.add(select) labels = ['Checkin', 'Ignore'] values = ['checkin', 'ignore'] select.set_option("values", values) select.set_option("labels", labels) select.add_empty_option("-- Select --") if action_type: select.set_value(action_type) select.add_behavior( { 'type': 'change', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingestion_top"); value = bvr.src_el.value; var elements = top.getElements(".spt_action_ignore"); for (var i = 0; i < elements.length; i++) { if (value == 'ignore') spt.show(elements[i]); else spt.hide(elements[i]); } var elements = top.getElements(".spt_action_checkin"); for (var i = 0; i < elements.length; i++) { if (value == 'checkin') spt.show(elements[i]); else spt.hide(elements[i]); } ''' } ) table.add_row() td = table.add_cell("<br/>") # add the script path tbody = table.add_tbody() tbody.add_class("spt_action_checkin") if action_type != 'checkin': tbody.add_style("display: none") # add the checkin type table.add_row() td = table.add_cell() td.add("Action: ") select = SelectWdg("action") td = table.add_cell() td.add(select) select.set_value( my.get_value("action") ) labels = ['File Checkin', 'Directory Checkin', 'Sequence Checkin'] values = ['file', 'directory', 'sequence', 'ignore'] select.set_option("values", values) select.set_option("labels", labels) table.add_row() td = table.add_cell() td.add("Mode: ") select = SelectWdg("mode") td = table.add_cell() td.add(select) labels = ['Copy', 'Move', 'In Place'] values = ['copy', 'move', 'inplace'] select.set_option("values", values) select.set_option("labels", labels) # add the search_type table.add_row() td = table.add_cell() td.add("sType: ") td = table.add_cell() select = SelectWdg("search_type") td.add(select) search_types = Project.get().get_search_types() values = [x.get_value("search_type") for x in search_types] select.set_option("values", values) search_type = my.kwargs.get("search_type") if search_type: select.set_value(search_type) # add the search_type table.add_row() td = table.add_cell() td.add("Context: ") td = table.add_cell() select = SelectWdg("context") td.add(select) select.set_option("values", ['publish', 'by rule', 'custom']) # add extra values extra_div = DivWdg() text = TextWdg("extra_name") text.add_attr("spt_is_multiple", "true") extra_div.add(text) extra_div.add(" = ") text = TextWdg("extra_value") extra_div.add(text) text.add_attr("spt_is_multiple", "true") template_div = DivWdg() text = TextWdg("extra_name") text.add_attr("spt_is_multiple", "true") template_div.add(text) template_div.add(" = ") text = TextWdg("extra_value") template_div.add(text) text.add_attr("spt_is_multiple", "true") table.close_tbody() table.add_row() td = table.add_cell("<br/>") table.add_row() td = table.add_cell() td.add("Extra Keywords: ") td.add_style("vertical-align: top") td.add_style("padding-top: 5px") td = table.add_cell() text = TextWdg("keywords") text.add_style("width: 300px") td.add(text) table.add_row() td = table.add_cell() td.add("Extra Values: ") td.add_style("vertical-align: top") td.add_style("padding-top: 5px") td = table.add_cell() extra_list = DynamicListWdg() td.add(extra_list) extra_list.add_item(extra_div) extra_list.add_template(template_div) table.add_row() table.add_cell(" ") table.add_row() td = table.add_cell() td.add("Process script: ") td.add_style("vertical-align: top") td.add_style("padding-top: 5px") td = table.add_cell() text = TextWdg("process_script") text.add_style("width: 300px") td.add(text) text.set_value( my.get_value("process_script") ) icon = IconButtonWdg(title='Edit Process Script', icon=IconWdg.EDIT) icon.add_style("float: right") td.add(icon) icon.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.named_events.fire_event("show_script_editor"); var top = bvr.src_el.getParent(".spt_ingestion_top"); var values = spt.api.Utility.get_input_values(top, null, false); var kwargs = { script_path: values.process_script } // need to wait for this setTimeout( function() { spt.js_edit.display_script_cbk(evt, kwargs) }, 500 ); ''' } ) table.add_row() td = table.add_cell() td.add("Custom Naming: ") td.add_style("vertical-align: top") td.add_style("padding-top: 5px") td = table.add_cell() text = TextWdg("naming") text.add_style("width: 300px") td.add(text) table.add_row() td = table.add_cell() #td.add("<br clear='all'/>") td.add("<hr/>") behavior = { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingestion_top"); var values = spt.api.Utility.get_input_values(top, null, false); spt.app_busy.show("Scanning ...", values.base_dir); var class_name = 'tactic.ui.tools.IngestionProcessWdg'; var server = TacticServerStub.get(); values.mode = bvr.mode; values.is_local = 'true'; // scan client side if (values.is_local == 'true') { var base_dir = values.base_dir; var applet = spt.Applet.get(); var files = applet.list_recursive_dir(base_dir); // turn into a string var files_in_js = []; for (var i = 0; i < files.length; i++) { var file = files[i].replace(/\\\\/g, "/"); files_in_js.push( file ); } values.files = files_in_js; values.base_dir = base_dir; /* var server = TacticServerStub.get(); var handoff_dir = server.get_handoff_dir(); var applet = spt.Applet.get(); for (var i = 0; i < files_in_js.length; i++) { try { var parts = files_in_js[i].split("/"); var filename = parts[parts.length-1]; spt.app_busy.show("Copying files to handoff", filename); applet.copy_file(files_in_js[i], handoff_dir+"/"+filename); } catch(e) { log.error(e); } } */ } var info_el = top.getElement(".spt_info"); spt.panel.load(info_el, class_name, values); spt.app_busy.hide(); ''' } # Save button button = ActionButtonWdg(title="Save", tip="Save Rule") td.add(button) button.add_style("float: right") behavior['mode'] = 'save' button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingestion_top"); var values = spt.api.Utility.get_input_values(top, null, false); spt.app_busy.show("Saving ..."); var class_name = 'tactic.command.CheckinRuleSaveCmd'; var server = TacticServerStub.get(); server.execute_cmd(class_name, values); spt.panel.refresh(top, {}); spt.app_busy.hide(); ''' } ) # Scan button button = ActionButtonWdg(title="Scan", tip="Click to Scan") td.add(button) button.add_style("float: left") # set a limit #limit = TextWdg("limit") #td.add(limit) #text.add_style("float: left") behavior = behavior.copy() behavior['mode'] = 'scan' button.add_behavior(behavior) # Test button button = ActionButtonWdg(title="Test", tip="Do a test of this rule") td.add(button) behavior = behavior.copy() behavior['mode'] = 'test' button.add_behavior(behavior) button.add_style("float: left") # Ingest button button = ActionButtonWdg(title="Ingest", tip="Click to start ingesting") td.add(button) behavior = behavior.copy() behavior['mode'] = 'checkin' button.add_behavior(behavior) table.add_behavior( { 'type': 'listen', 'event_name': 'file_browser|select', 'cbjs_action': ''' var dirname = bvr.firing_data.dirname; var top = bvr.src_el.getParent(".spt_ingestion_top"); var kwargs = { base_dir: dirname }; spt.panel.load(top, top.getAttribute("spt_class_name"), kwargs); ''' }) top.add( my.get_info_wdg() ) return top
def get_nav_wdg(my): #base_dir = my.kwargs.get("base_dir") #location = my.kwargs.get("location") base_dir = my.session.get_value("base_dir") location = my.session.get_value("location") nav_wdg = DivWdg() nav_wdg.add("<b>Session 101 - Clean up my Crap</b><hr/>") nav_wdg.add_style("margin-bottom: 10px") nav_wdg.add_class("spt_file_nav") nav_wdg.add_style("width: 575px") nav_wdg.add_border() nav_wdg.set_round_corners() nav_wdg.add_style("padding: 5px") button = ActionButtonWdg(title="Scan", tip="Scan for files in specified folder") button.add_style("float: right") button.add_style("margin-top: -5px") nav_wdg.add(button) from tactic.ui.input import TextInputWdg title_wdg = "Session Title: " nav_wdg.add(title_wdg) text = TextInputWdg(name="title") text.add_class("spt_title") text.add_style("width: 300px") nav_wdg.add(text) nav_wdg.add("<br/><br/>") folder_wdg = "Base folder of this session: " nav_wdg.add(folder_wdg) text = TextInputWdg(name="base_dir") text.add_class("spt_base_dir") text.add_style("width: 300px") if base_dir: text.set_value(base_dir) nav_wdg.add(text) # add a hidden paths variable text = HiddenWdg("paths") text.add_class("spt_paths") nav_wdg.add(text) nav_wdg.add("<br/>") # add a hidden paths variable select = SelectWdg("location") if location: select.set_value(location) nav_wdg.add("<br/>") nav_wdg.add("Folder is on ") nav_wdg.add(select) select.set_option("values", "local|server") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingestion_top"); var nav = top.getElement(".spt_file_nav"); var nav_values = spt.api.Utility.get_input_values(nav,null,false); var base_dir = nav_values.base_dir; var location = nav_values.location; spt.app_busy.show("Scanning", base_dir); if (location == 'local') { var applet = spt.Applet.get(); var paths = applet.list_dir(base_dir, 2); var paths_el = nav.getElement(".spt_paths"); var js_paths = []; for (var i = 0; i < paths.length; i++) { var js_path = paths[i].replace(/\\\\/g,"/"); if (applet.is_dir(js_path) ) { js_path = js_path + '/'; js_paths.push(js_path); } //if (i > 100) break; else { js_paths.push(js_path); } } paths_el.value = js_paths.join("|"); } //var nav_values = spt.api.Utility.get_input_values(nav,null,false); //spt.panel.refresh(top, nav_values); spt.tab.set_tab_top(top); spt.tab.select("files") var class_name = "tactic.ui.tools.IngestionToolDirListWdg"; var kwargs = { base_dir: base_dir, location: location, paths: js_paths } spt.tab.load_selected("files", "Files", class_name, kwargs); spt.app_busy.hide(); ''' } ) return nav_wdg
def get_upload_wdg(my): '''get search type select and upload wdg''' key = 'csv_import' widget = DivWdg(css='spt_import_csv') widget.add_color('color','color') widget.add_color('background','background') widget.add_style('width: 600px') # get the search type stype_div = DivWdg() widget.add(stype_div) # DEPRECATED # handle new search_types """ new_search_type = CheckboxWdg("new_search_type_checkbox") new_search_type.add_event("onclick", "toggle_display('new_search_type_div')") new_search_type_div = DivWdg() new_search_type_div.set_id("new_search_type_div") name_input = TextWdg("asset_name") title = TextWdg("asset_title") description = TextAreaWdg("asset_description") table = Table() table.set_id('csv_main_body') table.add_style("margin: 10px 10px") table.add_col().set_attr('width','140') table.add_col().set_attr('width','400') table.add_row() table.add_header("Search Type: ").set_attr('align','left') table.add_cell(name_input) table.add_row() table.add_header("Title: ").set_attr('align','left') table.add_cell(title) table.add_row() table.add_header("Description: ").set_attr('align','left') table.add_cell(description) new_search_type_div.add(table) new_search_type_div.add_style("display: none") #widget.add(new_search_type_div) """ show_stype_select = my.kwargs.get("show_stype_select") if show_stype_select in ['true',True] or not my.search_type: title = DivWdg("<b>Select sType to import data into:</b> ") stype_div.add( title ) title.add_style("float: left") search_type_select = SearchTypeSelectWdg("search_type_filter", mode=SearchTypeSelectWdg.ALL) search_type_select.add_empty_option("-- Select --") if not search_type_select.get_value(): search_type_select.set_value(my.search_type) search_type_select.set_persist_on_submit() stype_div.add(search_type_select) search_type_select.add_behavior( {'type': 'change', \ 'cbjs_action': "spt.panel.load('csv_import_main','%s', {}, {\ 'search_type_filter': bvr.src_el.value});" %(Common.get_full_class_name(my)) } ) else: hidden = HiddenWdg("search_type_filter") stype_div.add(hidden) hidden.set_value(my.search_type) if my.search_type: sobj = None try: sobj = SObjectFactory.create(my.search_type) except ImportError: widget.add(HtmlElement.br()) widget.add(SpanWdg('WARNING: Import Error encountered. Please choose another search type.', css='warning')) return widget required_columns = sobj.get_required_columns() if required_columns: widget.add(HtmlElement.br()) req_span = SpanWdg("Required Columns: ", css='med') req_span.add_color('color','color') widget.add(req_span) #required_columns = ['n/a'] req_span.add(', '.join(required_columns)) widget.add( HtmlElement.br() ) if my.file_path: hidden = HiddenWdg("file_path", my.file_path) widget.add(hidden) if my.web_url: file_span = FloatDivWdg('URL: <i>%s</i> ' %my.web_url, css='med') else: if not my.data: file_span = FloatDivWdg('File uploaded: <i>%s</i> ' %os.path.basename(my.file_path), css='med') else: lines = len(my.data.split("\n")) file_span = FloatDivWdg("Uploaded [%s] lines of entries: " % lines) file_span.add_color('color','color') file_span.add_style('margin: 8px 0 0 10px') file_span.add_style('font-size: 14px') widget.add(file_span) button = ActionButtonWdg(title='Change') button.add_style('float','left') button.add_behavior( {'type': 'click_up', \ 'cbjs_action': "spt.panel.load('csv_import_main','%s', {}, {\ 'search_type_filter': '%s'});" %(Common.get_full_class_name(my), my.search_type) } ) widget.add(button) widget.add("<br clear='all'/>") widget.add(HtmlElement.br()) return widget widget.add_style("overflow-y: auto") msg = DivWdg() widget.add(msg) msg.add_border() msg.add_style("width: 500px") msg.add_color("background", "background3") msg.add_style("padding: 30px") msg.add_style("margin: 10 auto") #msg.add_style("text-align: center") msg.add( "<div style='float: left; padding-top: 6px; margin-right: 105px'><b>Upload a csv file: </b></div>") ticket = Environment.get_security().get_ticket_key() on_complete = '''var server = TacticServerStub.get(); var file = spt.html5upload.get_file(); if (file) { var file_name = file.name; // clean up the file name the way it is done in the server //file_name = spt.path.get_filesystem_name(file_name); var server = TacticServerStub.get(); var class_name = 'tactic.ui.widget.CsvImportWdg'; var values = spt.api.Utility.get_input_values('csv_import_main'); values['is_refresh'] = true; values['file_name'] = file_name; values['html5_ticket'] = '%s'; try { var info = spt.panel.load('csv_import_main', class_name, {}, values); spt.app_busy.hide(); } catch(e) { spt.alert(spt.exception.handler(e)); } } else { alert('Error: file object cannot be found.') } spt.app_busy.hide();'''%ticket from tactic.ui.input import UploadButtonWdg browse = UploadButtonWdg(name='new_csv_upload', title="Browse", tip="Click to choose a csv file",\ on_complete=on_complete, ticket=ticket) browse.add_style('float: left') msg.add(browse) # this is now only used in the copy and paste Upload button for backward-compatibility upload_wdg = SimpleUploadWdg(key=key, show_upload=False) upload_wdg.add_style('display: none') msg.add(upload_wdg) msg.add("<br/>") msg.add("<div style='margin: 30px; text-align: center'>-- OR --</div>") msg.add("<b>Published URL: </b><br/>") from tactic.ui.input import TextInputWdg text = TextInputWdg(name="web_url") text.add_style("width: 100%") msg.add(text) msg.add("<div style='margin: 30px; text-align: center'>-- OR --</div>") msg.add("<b>Copy and Paste from a Spreadsheet: </b><br/>") text = TextAreaWdg("data") text.add_style('width: 100%') text.add_style('height: 100px') text.add_class("spt_import_cut_paste") msg.add(text) msg.add("<br/>"*3) button = ActionButtonWdg(title="Parse") button.add_style("margin: 5px auto") msg.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_import_top"); var el = top.getElement(".spt_import_cut_paste"); var value = el.value; var csv = []; // convert to a csv file! lines = value.split("\\n"); for (var i = 0; i < lines.length; i++) { if (lines[i] == '') { continue; } var parts = lines[i].split("\\t"); var new_line = []; for (var j = 0; j < parts.length; j++) { if (parts[j] == '') { new_line.push(''); } else { new_line.push('"'+parts[j]+'"'); } } new_line = new_line.join(","); csv.push(new_line); } csv = csv.join("\\n") /* // FIXME: need to get a local temp directory var applet = spt.Applet.get(); var path = spt.browser.os_is_Windows() ? "C:/sthpw/copy_n_paste.csv" : "/tmp/sthpw/copy_n_paste.csv"; applet.create_file(path, csv); // upload the file applet.upload_file(path) applet.rmtree(path); var top = bvr.src_el.getParent(".spt_import_csv"); var hidden = top.getElement(".spt_upload_hidden"); hidden.value = path; var file_name = spt.path.get_basename(hidden.value); file_name = spt.path.get_filesystem_name(file_name); */ var class_name = 'tactic.ui.widget.CsvImportWdg'; var values = spt.api.Utility.get_input_values('csv_import_main'); values['is_refresh'] = true; //values['file_name'] = file_name; values['data'] = csv; var info = spt.panel.load('csv_import_main', class_name, {}, values); ''' } ) return widget
def get_data_wdg(my): div = DivWdg() from pyasm.biz import Pipeline from pyasm.widget import SelectWdg search_type_obj = SearchType.get(my.search_type) base_type = search_type_obj.get_base_key() search = Search("sthpw/pipeline") search.add_filter("search_type", base_type) pipelines = search.get_sobjects() if pipelines: pipeline = pipelines[0] process_names = pipeline.get_process_names() if process_names: table = Table() div.add(table) table.add_row() table.add_cell("Process: ") select = SelectWdg("process") table.add_cell(select) process_names.append("---") process_names.append("publish") process_names.append("icon") select.set_option("values", process_names) #### buttons = Table() div.add(buttons) buttons.add_row() #button = IconButtonWdg(title="Fill in Data", icon=IconWdg.EDIT) button = ActionButtonWdg(title="Metadata") button.add_style("float: left") button.add_style("margin-top: -3px") buttons.add_cell(button) select_label = DivWdg("Update mode"); select_label.add_style("float: left") select_label.add_style("margin-top: -3px") select_label.add_style("margin-left: 20px") buttons.add_cell(select_label) update_mode_option = my.kwargs.get("update_mode") if not update_mode_option: update_mode_option = "true" update_mode = SelectWdg(name="update mode") update_mode.add_class("spt_update_mode_select") update_mode.set_option("values", ["false", "true", "sequence"]) update_mode.set_option("labels", ["Off", "On", "Sequence"]) update_mode.set_option("default", update_mode_option) update_mode.add_style("float: left") update_mode.add_style("margin-top: -3px") update_mode.add_style("margin-left: 5px") update_mode.add_style("margin-right: 5px") buttons.add_cell(update_mode) update_info = DivWdg() update_info.add_class("glyphicon") update_info.add_class("glyphicon-info-sign") update_info.add_style("float: left") update_info.add_style("margin-top: -3px") update_info.add_style("margin-left: 10px") update_info.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.info("When update mode is on, if a file shares the name of one other file in the asset library, the file will update on ingest. If more than one file shares the name of an ingested asset, a new asset is created.<br> If sequence mode is selected, the system will update the sobject on ingest if a file sequence sharing the same name already exists.", {type: 'html'}); ''' } ) buttons.add_cell(update_info); dialog = DialogWdg(display="false", show_title=False) div.add(dialog) dialog.set_as_activator(button, offset={'x':-10,'y':10}) dialog_data_div = DivWdg() dialog_data_div.add_color("background", "background") dialog_data_div.add_style("padding", "20px") dialog.add(dialog_data_div) # Order folders by date name_div = DivWdg() dialog_data_div.add(name_div) name_div.add_style("margin: 15px 0px") if SearchType.column_exists(my.search_type, "relative_dir"): category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "none") category_div.add(checkbox) category_div.add(" No categories") category_div.add_style("margin-bottom: 5px") checkbox.set_option("checked", "true") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_day") category_div.add(checkbox) category_div.add(" Categorize files by Day") category_div.add_style("margin-bottom: 5px") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_week") category_div.add(checkbox) category_div.add(" Categorize files by Week") category_div.add_style("margin-bottom: 5px") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_year") category_div.add(checkbox) category_div.add(" Categorize files by Year") category_div.add_style("margin-bottom: 5px") """ checkbox = RadioWdg("category") checkbox.set_option("value", "custom") name_div.add(checkbox) name_div.add(" Custom") """ name_div.add("<br/>") ingest_data_view = my.kwargs.get('ingest_data_view') from tactic.ui.panel import EditWdg sobject = SearchType.create(my.search_type) edit = EditWdg(search_key =sobject.get_search_key(), mode='view', view=ingest_data_view ) dialog_data_div.add(edit) hidden = HiddenWdg(name="parent_key") dialog_data_div.add(hidden) hidden.add_class("spt_parent_key") parent_key = my.kwargs.get("parent_key") or "" if parent_key: hidden.set_value(parent_key) extra_data = my.kwargs.get("extra_data") if not isinstance(extra_data, basestring): extra_data = jsondumps(extra_data) if extra_data and extra_data != "null": # it needs a TextArea instead of Hidden because of JSON data text = TextAreaWdg(name="extra_data") text.add_style('display: none') text.set_value(extra_data) dialog_data_div.add(text) """ dialog_data_div.add("Keywords:<br/>") dialog.add(dialog_data_div) text = TextAreaWdg(name="keywords") dialog_data_div.add(text) text.add_class("spt_keywords") text.add_style("padding: 1px") dialog_data_div.add("<br/>"*2) text.add_class("spt_extra_data") text.add_style("padding: 1px") """ #### TEST Image options """ button = IconButtonWdg(title="Resize", icon=IconWdg.FILM) buttons.add_cell(button) dialog = DialogWdg(display="false", show_title=False) div.add(dialog) dialog.set_as_activator(button, offset={'x':-10,'y':10}) try: from spt.tools.convert import ConvertOptionsWdg convert_div = DivWdg() dialog.add(convert_div) convert_div.add_style("padding: 20px") convert_div.add_color("background", "background") convert_div.add_class("spt_image_convert") convert = ConvertOptionsWdg() convert_div.add(convert) except: pass """ # use base name for name """ name_div = DivWdg() dialog_data_div.add(name_div) name_div.add_style("margin: 15px 0px") checkbox = CheckboxWdg("use_file_name") name_div.add(checkbox) name_div.add(" Use name of file for name") name_div.add("<br/>") checkbox = CheckboxWdg("use_base_name") name_div.add(checkbox) name_div.add(" Remove extension") name_div.add("<br/>") checkbox = CheckboxWdg("file_keywords") name_div.add(checkbox) name_div.add(" Use file name for keywords") """ return div
def get_top(self): top = self.top top.add_color("background", "background", -5) top.add_style("margin-bottom: -2px") top.add_class("spt_filter_top") table = Table() top.add(table) tr, td = table.add_row_cell() td.add_class("spt_simple_search_title") # add the load wdg show_saved_search = True if show_saved_search: saved_button = ActionButtonWdg(title='Saved', tip='Load Saved Searches') saved_button.add_class("spt_simple_search_save_button") saved_button.add_behavior({ #'type': 'load', 'search_type': self.search_type, 'cbjs_action': ''' var popup = bvr.src_el.getParent(".spt_popup"); spt.popup.close(popup); var class_name = 'tactic.ui.app.LoadSearchWdg'; var kwargs = { search_type: bvr.search_type } var layout = spt.table.get_layout(); var panel = layout.getParent(".spt_view_panel_top"); var popup = spt.panel.load_popup("Saved Searches", class_name, kwargs); popup.activator = panel; ''' }) td.add(saved_button) saved_button.add_style("float: right") saved_button.add_style("margin: 10px") clear_button = ActionButtonWdg(title='Clear', tip='Clear all of the filters') td.add(clear_button) clear_button.add_class("spt_simple_search_clear_button") clear_button.add_style("float: right") clear_button.add_style("margin: 10px") clear_button.add_behavior({ 'type': 'click', 'cbjs_action': ''' spt.api.Utility.clear_inputs(bvr.src_el.getParent(".spt_filter_top")); ''' }) title_div = DivWdg() td.add(title_div) title_div.add("<div style='font-size: 16px'>Search Criteria</div>") title_div.add("<div>Select filters to refine your search</div>") title_div.add_style("padding: 20px 0px 0px 20px") table.add_style("margin-left: auto") table.add_style("margin-right: auto") table.add_style("margin-bottom: 15px") table.add_style("width: 100%") tr = table.add_row() if not self.content: self.content = DivWdg() self.content.add("No Content") td = table.add_cell() td.add(self.content) #self.content.add_style("margin: -2 -1 0 -1") show_search = self.kwargs.get("show_search") if show_search in [False, 'false']: show_search = False else: show_search = True show_search = True if show_search: search_wdg = self.get_search_wdg() table.add_row() search_wdg.add_style("float: right") search_wdg.add_class("spt_simple_search_button") search_wdg.add_style("padding-top: 6px") search_wdg.add_style("padding-left: 10px") search_wdg.add_style("height: 33px") td = table.add_cell() td.add(search_wdg) td.add_style("padding: 5px 10px") #td.add_border() #td.add_color("background", "background", -10) hidden = HiddenWdg("prefix", self.prefix) top.add(hidden) # this cannot be spt_search as it will confuse spt.dg_table.search_cbk() top.add_class("spt_simple_search") return top
def get_display(my): top = my.top top.add_class("spt_input_top") top.add_style("position: relative") top.add_style("width: 150px") top.add_style("margin-top: -1px") top.add_style("margin-left: -1px") top.add_color("background", "background", -20) top.add_border() title = "Big" div = DivWdg() top.add(div) icon_div = DivWdg() div.add(icon_div) icon_div.add_style("width: 20px") icon_div.add_style("height: 21px") icon_div.add_style("padding-left: 3px") icon_div.add_style("margin: -3 6 0 -3") icon_div.add_color("background", "background", [+15, 0, 0]) icon_div.add_style("float: left") icon_div.add_style("opacity: 0.5") icon = IconWdg("Select", IconWdg.FILM) icon_div.add(icon) div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_input_top"); var content = spt.get_element( top, ".spt_input_content"); spt.toggle_show_hide(content); spt.body.add_focus_element(content); content.position(top); ''' } ) div.add(title) div.add_class("hand") div.add_style("padding: 3px") #top.add( TextWdg("hello") ) select_div = DivWdg() top.add(select_div) select_div.add_style("position: absolute") select_div.add_class("spt_input_content") select_div.add_color("background", "background") select_div.add_style("top: 0px") select_div.add_style("left: 0px") select_div.add_style("display: none") select_div.add_style("z-index: 1000") select_div.set_box_shadow() select_div.add_border() select_div.add_class("SPT_PUW") for title in ("Big", "Fat", "Cow", "Horse", "Donkeys"): div = DivWdg() select_div.add(div) icon_div = DivWdg() div.add(icon_div) icon_div.add_style("width: 20px") icon_div.add_style("height: 21px") icon_div.add_style("margin: -3 6 0 -3") icon_div.add_color("background", "background", [+15, 0, 0]) icon_div.add_style("float: left") icon_div.add_style("opacity: 0.5") icon_div.add(" ") div.add(title) div.add_class("hand") div.add_style("padding: 3px") div.add_style("width: 100px") hover = div.get_color("background", [-30, -30, 20]) div.add_behavior( { 'type': 'hover', 'hover': hover, 'cbjs_action_over': ''' bvr.src_el.setStyle("background", bvr.hover); ''', 'cbjs_action_out': ''' bvr.src_el.setStyle("background", ""); ''' } ) div.add_behavior( { 'type': 'click_up', 'value': title, 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); var top_el = spt.get_parent(bvr.src_el, ".spt_input_top"); var value_wdg = top_el.getElement(".spt_input_data"); var content = spt.get_parent(bvr.src_el, ".spt_input_content"); spt.hide(content); value_wdg.value = bvr.value; spt.dg_table.simple_edit_cell_cbk(top_el); ''' } ) # generally, some real input widget is needed store and transport # the data input = HiddenWdg(my.get_input_name() ) input.add_class("spt_input_data") input.add_class("SPT_NO_RESIZE") input.add_behavior( { 'type': 'change', 'cbjs_action': ''' var top_el = bvr.src_el.getParent(".spt_input_top"); var value_wdg = top_el.getElement(".spt_input_data"); spt.dg_table.edit.widget = top_el; spt.dg_table.inline_edit_cell_cbk( value_wdg ); ''' } ) top.add(input) return top
def handle_dir_or_item(my, item_div, dirname, basename): spath = "%s/%s" % (dirname, basename) fspath = "%s/%s" % (dirname, File.get_filesystem_name(basename)) md5 = my.md5s.get(fspath) changed = False context = None error_msg = None snapshot = None file_obj = my.checked_in_paths.get(fspath) if not file_obj: if fspath.startswith(my.base_dir): rel = fspath.replace("%s/" % my.base_dir, "") file_obj = my.checked_in_paths.get(rel) if file_obj != None: snapshot_code = file_obj.get_value("snapshot_code") snapshot = my.snapshots_dict.get(snapshot_code) if not snapshot: # last resort snapshot = file_obj.get_parent() if snapshot: context = snapshot.get_value("context") item_div.add_attr("spt_snapshot_code", snapshot.get_code()) snapshot_md5 = file_obj.get_value("md5") item_div.add_attr("spt_md5", snapshot_md5) item_div.add_attr("title", "Checked-in as: %s" % file_obj.get_value("file_name")) if md5 and md5 != snapshot_md5: item_div.add_class("spt_changed") changed = True else: error_msg = 'snapshot not found' status = None if file_obj != None: if changed: check = IconWdg( "Checked-In", IconWdg.ERROR, width=12 ) status = "changed" else: check = IconWdg( "Checked-In", IconWdg.CHECK, width=12 ) status = "same" item_div.add_color("color", "color", [0, 0, 50]) else: check = None item_div.add_style("opacity: 0.8") status = "unversioned" if check: item_div.add(check) check.add_style("float: left") check.add_style("margin-left: -16px") check.add_style("margin-top: 4px") # add the file name filename_div = DivWdg() item_div.add(filename_div) filename_div.add(basename) file_info_div = None if snapshot and status != 'unversioned': file_info_div = SpanWdg() filename_div.add(file_info_div) if error_msg: filename_div.add(' (%s)'%error_msg) filename_div.add_style("float: left") filename_div.add_style("overflow: hidden") filename_div.add_style("width: 65%") # DEPRECATED from pyasm.widget import CheckboxWdg, TextWdg, SelectWdg, HiddenWdg checkbox = CheckboxWdg("check") checkbox.add_style("display: none") checkbox.add_class("spt_select") checkbox.add_style("float: right") checkbox.add_style("margin-top: 1px") item_div.add(checkbox) subcontext_val = '' cat_input = None is_select = True if my.context_options: context_sel = SelectWdg("context") context_sel.add_attr('title', 'context') context_sel.set_option("show_missing", False) context_sel.set_option("values", my.context_options) item_div.add_attr("spt_context", my.context_options[0]) cat_input = context_sel input_cls = 'spt_context' else: if my.subcontext_options in [['(main)'], ['(auto)'] , []]: is_select = False #subcontext = TextWdg("subcontext") subcontext = HiddenWdg("subcontext") subcontext.add_class("spt_subcontext") elif my.subcontext_options == ['(text)']: is_select = False subcontext = TextWdg("subcontext") subcontext.add_class("spt_subcontext") else: is_select = True subcontext = SelectWdg("subcontext") subcontext.set_option("show_missing", False) subcontext.set_option("values", my.subcontext_options) #subcontext.add_empty_option("----") cat_input = subcontext input_cls = 'spt_subcontext' if my.subcontext_options == ['(main)'] or my.subcontext_options == ['(auto)']: subcontext_val = my.subcontext_options[0] subcontext.set_value(subcontext_val) item_div.add_attr("spt_subcontext", subcontext_val) elif context: parts = context.split("/") if len(parts) > 1: # get the actual subcontext value subcontext_val = "/".join(parts[1:]) # identify a previous "auto" check-in and preselect the item in the select if is_select and subcontext_val not in my.subcontext_options: subcontext_val = '(auto)' elif isinstance(cat_input, HiddenWdg): subcontext_val = '' # the Text field will adopt the subcontext value of the last check-in subcontext.set_value(subcontext_val) item_div.add_attr("spt_subcontext", subcontext_val) else: if is_select: if my.subcontext_options: subcontext_val = my.subcontext_options[0] #subcontext_val = '(auto)' cat_input.set_value(subcontext_val) else: subcontext_val = '' item_div.add_attr("spt_subcontext", subcontext_val) item_div.add(cat_input) cat_input.add_behavior( { 'type': 'click_up', 'propagate_evt': False, 'cbjs_action': ''' bvr.src_el.focus(); ''' } ) cat_input.add_style("display: none") cat_input.add_class("spt_subcontext") cat_input.add_style("float: right") cat_input.add_style("width: 50px") cat_input.add_style("margin-top: -1px") cat_input.add_style("font-size: 10px") cat_input.add_style("height: 16px") # we depend on the attribute cuz sometimes we go by the initialized value # since they are not drawn cat_input.add_behavior( { 'type': 'change', 'cbjs_action': ''' var el = bvr.src_el.getParent('.spt_dir_list_item'); el.setAttribute("%s", bvr.src_el.value); ''' %input_cls } ) if file_info_div: if subcontext_val in ['(auto)','(main)', '']: file_info_div.add(" <i style='font-size: 9px; opacity: 0.6'>(v%s)</i>" % snapshot.get_value("version") ) else: file_info_div.add(" <i style='font-size: 9px; opacity: 0.6'>(v%s - %s)</i>" % (snapshot.get_value("version"), subcontext_val) )
def get_first_row_wdg(my): # read the csv file my.file_path = "" div = DivWdg() div.add( my.get_upload_wdg() ) if not my.search_type: return div if not my.file_path: return div if not my.file_path.endswith(".csv"): div.add( "Uploaded file [%s] is not a csv file"% my.file_path) return div if not os.path.exists(my.file_path): raise Exception("Path '%s' does not exists" % my.file_path) div.add(HtmlElement.br(2)) div.add( HtmlElement.b("The following is taken from first line in the uploaded csv file. Select the appropriate column to match.") ) div.add(HtmlElement.br()) div.add( HtmlElement.b("Make sure you have all the required columns** in the csv.")) option_div = DivWdg() option_div.add_style("float: left") option_div.add_style("margin-right: 30px") option_div.add("<p>3. Parsing Options:</p>") my.search_type_obj = SearchType.get(my.search_type) # first row and second row option_div.add( HtmlElement.br(2) ) option_div.add("Use Title Row: ") title_row_checkbox = FilterCheckboxWdg("has_title") title_row_checkbox.set_default_checked() option_div.add(title_row_checkbox) option_div.add( HintWdg("Set this to use the first row as a title row to match up columns in the database") ) option_div.add( HtmlElement.br(2) ) option_div.add("Sample Data Row: ") data_row_text = TextWdg("data_row") data_row_text.set_attr("size", "3") option_div.add(data_row_text) option_div.add( HintWdg("Set this as a sample data row to match the columns to the database") ) option_div.add( HtmlElement.br(2) ) div.add(option_div) my.has_title = title_row_checkbox.is_checked() # parse the first fow csv_parser = CsvParser(my.file_path) if my.has_title: csv_parser.set_has_title_row(True) else: csv_parser.set_has_title_row(False) csv_parser.parse() csv_titles = csv_parser.get_titles() csv_data = csv_parser.get_data() data_row = data_row_text.get_value() if not data_row: data_row = 0 else: try: data_row = int(data_row) except ValueError: data_row = 0 if data_row >= len(csv_data): data_row = len(csv_data)-1 data_row_text.set_value(data_row) table = Table() table.set_attr("cellpadding", "10") table.add_row() table.add_header("CSV Column Value") table.add_header("TACTIC Column") table.add_header("Create New Column") columns = my.search_type_obj.get_columns() search_type = my.search_type_obj.get_base_search_type() sobj = SObjectFactory.create(search_type) required_columns = sobj.get_required_columns() row = csv_data[data_row] labels = [] for column in columns: if column in required_columns: label = '%s**'%column else: label = column labels.append(label) for j, cell in enumerate(row): table.add_row() table.add_cell(cell) column_select = SelectWdg("column_%s" % j) column_select.add_event("onchange", "if (this.value!='') {set_display_off('new_column_div_%s')} else {set_display_on('new_column_div_%s')}" % (j,j)) column_select.add_empty_option("-- Select --") column_select.set_option("values", columns) column_select.set_option("labels", labels) # only set the value if it is actually in there if csv_titles[j] in columns: column_select.set_option("default", csv_titles[j]) column_select.set_persist_on_submit() column_select_value = column_select.get_value() display = column_select.get_buffer_display() td = table.add_cell( display ) if csv_titles[j] not in columns: td.add(" <b style='color: red'>*</b>") # new property new_column_div = DivWdg() if column_select_value: new_column_div.add_style("display", "none") else: new_column_div.add_style("display", "block") new_column_div.set_id("new_column_div_%s" % j) td = table.add_cell( new_column_div ) text = TextWdg("new_column_%s" % j) text.set_persist_on_submit() if my.has_title: text.set_value(csv_titles[j]) new_column_div.add( " ... or ..." ) new_column_div.add( text ) my.num_columns = len(row) hidden = HiddenWdg("num_columns", my.num_columns) # need to somehow specify defaults for columns div.add(table) div.add("<br/><br/>") div.add(my.get_preview_wdg()) return div
def get_page_two(my): '''let's browse an optional image here''' info_page = DivWdg() # add an icon for this project image_div = DivWdg() image_div.add_class("spt_image_top") image_div.add_color("background", "background") image_div.add_color("color", "color") image_div.add_style("padding: 20px") image_div.add(HtmlElement.b("Order Image:")) image_div.add("<br/>"*3) button = ActionButtonWdg(title="Browse") image_div.add(button) button.add_style("margin-left: auto") button.add_style("margin-right: auto") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var applet = spt.Applet.get(); spt.app_busy.show("Browsing for order image"); var path = applet.open_file_browser(); var top = bvr.src_el.getParent(".spt_image_top"); var text = top.getElement(".spt_image_path"); var display = top.getElement(".spt_path_display"); var check_icon = top.getElement(".spt_check_icon"); text.value = path; applet.upload_file(path); display.innerHTML = "Uploaded: " + path; display.setStyle("padding", "10px"); check_icon.setStyle("display", ""); path = path + ""; /* path = path.replace(/\\\\/g, "/"); var parts = path.split("/"); var filename = parts[parts.length-1]; */ var filename = spt.path.get_basename(path); filename = spt.path.get_filesystem_name(filename); var server = TacticServerStub.get(); var kwargs = { filename: filename } try { var ret_val = server.execute_cmd("tactic.command.CopyFileToAssetTempCmd", kwargs); var info = ret_val.info; var path = info.path; display.innerHTML = display.innerHTML + "<br/><br/><div style='text-align: center'><img style='width: 80px;' src='"+path+"'/></div>"; } catch(e) { spt.alert(spt.exception.handler(e)); } spt.app_busy.hide(); ''' } ) text = HiddenWdg("order_image_path") text.add_class("spt_image_path") image_div.add(text) check_div = DivWdg() image_div.add(check_div) check_div.add_class("spt_check_icon") check_icon = IconWdg("Image uploaded", IconWdg.CHECK) check_div.add(check_icon) check_div.add_style("display: none") check_div.add_style("float: left") check_div.add_style("padding-top: 8px") path_div = DivWdg() image_div.add(path_div) path_div.add_class("spt_path_display") image_div.add(HtmlElement.br(3)) span = DivWdg() image_div.add(span) span.add_style("padding: 20px 20px 20px 20px") span.add_color("background", "background3") span.add(IconWdg("INFO", IconWdg.CREATE)) span.add("This optional order image can be used in verious places as a visual representation of this order.") #info_page.add("<br/><br/>") return image_div
def get_display(self): top = self.top top.add_color("background", "background") top.add_class("spt_pipelines_top") self.set_as_panel(top) inner = DivWdg() top.add(inner) search_type = self.kwargs.get("search_type") pipeline_code = self.kwargs.get("pipeline_code") if search_type: search = Search("sthpw/pipeline") search.add_filter("search_type", search_type) pipelines = search.get_sobjects() else: pipeline = Pipeline.get_by_code(pipeline_code) if pipeline: pipelines = [pipeline] else: pipelines = [] if not pipelines: div = DivWdg() inner.add(div) inner.add_style("padding: 50px") div.add_border() div.add_color("color", "color3") div.add_color("background", "background3") div.add_style("width: 400px") div.add_style("height: 100px") div.add_style("padding: 30px") icon = IconWdg("WARNING", IconWdg.WARNING) div.add(icon) div.add("<b>This Searchable Type does not have pipelines defined.</b>") div.add("<br/>"*2) div.add("<b style='padding-left: 35px'>Click Create to add one...</b>") div.add("<br/>"*2) button_div = DivWdg() div.add(button_div) button = ActionButtonWdg(title="Create", tip="Create pipeline") button_div.add(button) button.add_style("margin: auto") button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'cbjs_action': ''' var server = TacticServerStub.get(); var cmd = 'tactic.ui.startup.PipelineCreateCbk'; var kwargs = { search_type: bvr.search_type } server.execute_cmd(cmd, kwargs) var top = bvr.src_el.getParent(".spt_pipelines_top"); spt.panel.refresh(top); ''' } ) return top # get the defalt task statuses task_pipeline = Pipeline.get_by_code("task") if task_pipeline: statuses = task_pipeline.get_process_names() else: statuses = ['Pending', 'In Progress', 'Complete'] statuses_str = ",".join(statuses) pipelines_div = DivWdg() inner.add( pipelines_div ) pipelines_div.add_style("font-size: 12px") pipelines_div.add_style("padding: 10px") buttons_div = DivWdg() pipelines_div.add(buttons_div) #button = SingleButtonWdg( title="Save Pipelines", icon=IconWdg.SAVE ) button = ActionButtonWdg( title="Save" ) buttons_div.add(button) button.add_behavior( { 'type': 'click_up', 'default_statuses': statuses_str, 'cbjs_action': ''' spt.app_busy.show("Saving Pipeline...") setTimeout(function() { try { var top = bvr.src_el.getParent(".spt_pipelines_top"); // get all the pipeline divs var pipeline_els = top.getElements(".spt_pipeline_top"); var data = {}; for ( var i = 0; i < pipeline_els.length; i++) { var pipeline_code = pipeline_els[i].getAttribute("spt_pipeline_code"); var values = spt.api.Utility.get_input_values(pipeline_els[i]); data[pipeline_code] = values; } var class_name = 'tactic.ui.startup.PipelineEditCbk'; var kwargs = { data: data } var server = TacticServerStub.get(); server.execute_cmd(class_name, kwargs); } catch(e) { spt.alert(spt.exception.handler(e)); } spt.app_busy.hide(); } , 100); ''' } ) buttons_div.add("<br clear='all'/>") buttons_div.add_style("margin-bottom: 5px") for pipeline in pipelines: pipeline_div = DivWdg() pipelines_div.add(pipeline_div) pipeline_div.add_class("spt_pipeline_top") code = pipeline.get_code() label = '%s (%s)' %(pipeline.get('name'), code) pipeline_div.add_attr("spt_pipeline_code", code) title = DivWdg() pipeline_div.add(title) title.add("Pipeline: ") title.add(label) title.add_style("padding: 8px 10px") title.add_color("background", "background3") title.add_style("font-weight: bold") title.add_style("margin: -10 -10 5 -10") header_wdg = DivWdg() pipeline_div.add(header_wdg) header_wdg.add_color("background", "background", -5) headers = ['Process', 'Description', 'Task Status'] widths = ['100px', '180px', '210px'] for header, width in zip(headers,widths): th = DivWdg() header_wdg.add(th) th.add("<b>%s</b>" % header) th.add_style("float: left") th.add_style("width: %s" % width) th.add_style("padding: 8px 3px") header_wdg.add("<br clear='all'/>") # get all of the process sobjects from this pipeline pipeline_code = pipeline.get_code() search = Search("config/process") search.add_filter("pipeline_code", pipeline.get_code() ) process_sobjs = search.get_sobjects() process_sobj_dict = {} for process_sobj in process_sobjs: process = process_sobj.get_value("process") process_sobj_dict[process] = process_sobj from tactic.ui.container import DynamicListWdg dyn_list = DynamicListWdg() pipeline_div.add(dyn_list) pipeline_div.add_style("width: 725px") processes = pipeline.get_process_names() if not processes: processes.append("") processes.append("") processes.append("") processes.insert(0, "") for i, process in enumerate(processes): if process == '': process_name = '' description = '' else: process_sobj = process_sobj_dict.get(process) if process_sobj: process_name = process_sobj.get_value("process") description = process_sobj.get_value("description") else: if isinstance(process,basestring): process_name = process else: process_name = process.get_name() deccription = '' process_type = 'manual' process_xpos = '' process_ypos = '' # get the task pipeline for this process if process_name: process = pipeline.get_process(process_name) process_type = process.get_type() process_xpos = process.get_attribute('xpos') process_ypos = process.get_attribute('ypos') task_pipeline_code = process.get_task_pipeline() if task_pipeline_code != "task": task_pipeline = Search.get_by_code("sthpw/pipeline", task_pipeline_code) else: task_pipeline = None else: task_pipeline_code = "task" task_pipeline = None process_div = DivWdg() process_div.add_style("float: left") process_div.add_class("spt_process_top") if i == 0: dyn_list.add_template(process_div) else: dyn_list.add_item(process_div) #process_div.add_style("padding-left: 10px") #process_div.add_style("margin: 5px") table = Table() process_div.add(table) table.add_row() text = TextInputWdg(name="process") process_cell = table.add_cell(text) text.add_style("width: 95px") text.add_style("margin: 5px") text.set_value(process_name) text.add_class("spt_process") # the template has a border if i == 0: text.add_style("border: solid 1px #AAA") hidden = HiddenWdg(name='process_type') hidden.set_value(process_type) process_cell.add(hidden) hidden = HiddenWdg(name='process_xpos') hidden.set_value(process_xpos) process_cell.add(hidden) hidden = HiddenWdg(name='process_ypos') hidden.set_value(process_ypos) process_cell.add(hidden) text = TextInputWdg(name="description") table.add_cell(text) text.add_style("width: 175px") text.add_style("margin: 5px") text.set_value(description) # the template has a border if i == 0: text.add_style("border: solid 1px #AAA") if process_type in ['manual','approval']: read_only = False else: read_only = True text = TextInputWdg(name="task_status", read_only=read_only) table.add_cell(text) text.add_style("width: 325px") text.add_style("margin: 5px") #text.set_value(statuses_str) #text.add_style("opacity: 0.5") text.add_style("border-style: none") if process_type in ['manual','approval']: if task_pipeline: statuses = task_pipeline.get_process_names() text.set_value(",".join(statuses)) else: text.set_value("(default)") text.add_behavior( { 'type': 'click_up', 'statuses': statuses_str, 'cbjs_action': ''' if (bvr.src_el.value == '(default)') { bvr.src_el.value = bvr.statuses; } ''' } ) table.add_cell(" "*2) button = IconButtonWdg(tip="Trigger", icon=IconWdg.ARROW_OUT) table.add_cell(button) button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'pipeline_code': pipeline_code, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_process_top"); var process_el = top.getElement(".spt_process"); var process = process_el.value; if (process == "") { alert("Process value is empty"); return; } var class_name = 'tactic.ui.tools.TriggerToolWdg'; var kwargs = { mode: "pipeline", process: process, pipeline_code: bvr.pipeline_code }; spt.panel.load_popup("Trigger", class_name, kwargs); ''' } ) """ button = IconButtonWdg(tip="Edit", icon=IconWdg.EDIT) table.add_cell(button) button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'pipeline_code': pipeline_code, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_process_top"); var process_el = top.getElement(".spt_process"); var process = process_el.value; if (process == "") { alert("Process value is empty"); return; } var class_name = 'tactic.ui.panel.EditWdg'; var kwargs = { expression: "@SOBJECT(config/process['process','"+process+"'])" } spt.panel.load_popup("Trigger", class_name, kwargs); ''' } ) """ table.add_cell(" "*3) pipeline_div.add("<br clear='all'/>") pipeline_div.add("<br clear='all'/>") if self.kwargs.get("is_refresh"): return inner else: return top
def get_upload_wdg(my): widget = Widget() # get the search type widget.add( "1. Select type of asset: ") # handle new search_types new_search_type = CheckboxWdg("new_search_type_checkbox") new_search_type.add_event("onclick", "toggle_display('new_search_type_div')") #span = SpanWdg(css="med") #span.add(new_search_type) #span.add("Create new type") #span.add(" ... or ... ") #widget.add(span) new_search_type_div = DivWdg() new_search_type_div.set_id("new_search_type_div") name_input = TextWdg("asset_name") title = TextWdg("asset_title") description = TextAreaWdg("asset_description") table = Table() table.add_style("margin: 10px 20px") table.add_col().set_attr('width','140') table.add_col().set_attr('width','400') table.add_row() table.add_header("Search Type: ").set_attr('align','left') table.add_cell(name_input) table.add_row() table.add_header("Title: ").set_attr('align','left') table.add_cell(title) table.add_row() table.add_header("Description: ").set_attr('align','left') table.add_cell(description) new_search_type_div.add(table) new_search_type_div.add_style("display: none") #widget.add(new_search_type_div) # or use a pre-existing one search_type_select = SearchTypeSelectWdg("filter|search_type") search_type_select.add_empty_option("-- Select --") search_type_select.set_persist_on_submit() search_type_select.set_submit_onchange() widget.add(search_type_select) my.search_type = search_type_select.get_value() if my.search_type: sobj = SObjectFactory.create(my.search_type) required_columns = sobj.get_required_columns() widget.add(SpanWdg("Required Columns: ", css='med')) if not required_columns: required_columns = ['n/a'] widget.add(SpanWdg(', '.join(required_columns), css='med')) widget.add( HtmlElement.br(2) ) widget.add( "2. Upload a csv file: ") upload_wdg = HtmlElement.upload("uploaded_file") widget.add(upload_wdg) submit = IconSubmitWdg("Upload", IconWdg.UPLOAD, True) widget.add(submit) web = WebContainer.get_web() field_storage = web.get_form_value("uploaded_file") if field_storage != "": upload = FileUpload() upload.set_field_storage(field_storage) upload.set_create_icon(False) upload.execute() files = upload.get_files() if files: my.file_path = files[0] else: my.file_path = web.get_form_value("file_path") if my.file_path: hidden = HiddenWdg("file_path", my.file_path) widget.add(hidden) return widget
def get_display(my): top = my.top my.set_as_panel(top) top.set_unique_id() top.add_class("spt_search_limit_top") # this info comes from the SearchLimit above (function get_info() ) count = my.kwargs.get("count") if count == 0: return top search_limit = my.kwargs.get("search_limit") # account for cases where this shouldn't even be called in a non search scenario if not search_limit: search_limit = 100 current_offset = my.kwargs.get("current_offset") num_pages = int( float(count-1) / float(search_limit) ) + 1 current_page = int (float(current_offset) / count * num_pages) + 1 if num_pages == 1: return top #print "current: ", current_offset #print "search_limit: ", search_limit #print "current_page: ", current_page top.add_color("background", "background3") top.add_color("color", "color3") top.add_style("margin: 15px -1px 10px -1px") top.add_border() table = Table() table.add_style("margin-left: 30px") top.add(table) table.add_row() top.add_smart_style("spt_link", "padding", "5px 10px 5px 10px") top.add_smart_style("spt_link", "margin", "0px 5px 0px 5x") top.add_smart_style("spt_link", "cursor", "pointer") #top.add_smart_style("spt_link", "border", "solid 1px blue") top.add_smart_style("spt_no_link", "padding", "5px 10px 5px 10px") top.add_smart_style("spt_no_link", "margin", "0px 5px 0px 5x") top.add_smart_style("spt_no_link", "opacity", "0.5") top.add_smart_style("spt_no_link", "font-style", "italic") top.add_relay_behavior( { 'type': 'mouseup', 'search_limit': search_limit, 'limit': search_limit, 'current_page': current_page, 'num_pages': num_pages, 'bvr_match_class': 'spt_link', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var page_el = top.getElement(".spt_page"); var value = bvr.src_el.getAttribute("spt_page"); if (value == 'next') { value = bvr.current_page + 1; if ( value < 1 ) value = 1; } else if (value == 'prev') { value = bvr.current_page - 1; if ( value > bvr.num_pages ) value = bvr.num_pages; } page_el.value = value; bvr.src_el = bvr.src_el.getParent('.spt_table_top'); //bvr.panel = bvr.src_el.getParent('.spt_view_panel'); spt.dg_table.search_cbk(evt, bvr); ''' } ) bgcolor = top.get_color("background3") bgcolor2 = top.get_color("background3", 10) top.add_relay_behavior( { 'type': 'mouseover', 'bgcolor': bgcolor2, 'bvr_match_class': 'spt_link', 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.bgcolor); ''' } ) top.add_relay_behavior( { 'type': 'mouseout', 'bgcolor': bgcolor, 'bvr_match_class': 'spt_link', 'cbjs_action': ''' if (!bvr.src_el.hasClass('spt_current_page')) bvr.src_el.setStyle("background", bvr.bgcolor); ''' } ) top.add_class("spt_table_search") hidden = HiddenWdg("prefix", "search_limit_simple") top.add(hidden) hidden = HiddenWdg("page", "") hidden.add_class("spt_page") top.add(hidden) td = table.add_cell() left = "< Prev" td.add(left) if current_page > 1: td.add_class("spt_link") else: td.add_class("spt_no_link") td.add_attr("spt_page", "prev") # find the range ... always show 10 pages max start_page = current_page - 5 if start_page < 1: start_page = 1 if start_page + 9 <= num_pages: end_page = start_page + 10 - 1 elif start_page > 5: end_page = current_page + 5 else: end_page = num_pages start_page = 1 # if end_pages for whatever reason, exceeds num_pages, limit it if end_page > num_pages: end_page = num_pages # if for whatever reason, end_page - 10 > 1, then limit it if end_page == num_pages and end_page - 10 > 1: start_page = end_page - 10 for i in range(start_page, end_page + 1): td = table.add_cell() td.add(i) td.add_class("spt_link") td.add_attr("spt_page", i) if i == current_page: td.add_color("color", "color") td.add_class("spt_current_page") td.add_color("background", "background3", 10) td.add_color("border-color", "border") td.add_style("border-width", "0px 1px 0px 1px") td.add_style("border-style", "solid") td = table.add_cell() right = "Next >" td.add(right) if current_page < num_pages: td.add_class("spt_link") else: td.add_class("spt_no_link") td.add_attr("spt_page", "next") return top
def get_display(my): if not my.search_type: return "No search type found" web = WebContainer.get_web() my.view = web.get_form_value("view") if not my.view: my.view = web.get_form_value("filter|view") if not my.view: my.view = get_template_view() widget = Widget() widget.add( HiddenWdg("search_type", my.search_type) ) element_names = [] # see if there is an override search_type_obj = SearchType.get(my.search_type) config = WidgetConfig.get_by_search_type(my.search_type,"browser_list") if config: element_names = config.get_element_names() search = Search("sthpw/widget_config") search.add_filter("search_type", my.search_type) search.add_filter("view", my.view) widget_config = search.get_sobject() if widget_config: edit_link_wdg = EditLinkWdg("sthpw/widget_config", widget_config.get_id(), text="Edit XML", long=True) edit_link_wdg.set_iframe_width(95) widget.add(edit_link_wdg) custom_config = WidgetConfigView.get_by_search_type(my.search_type,my.view) custom_element_names = custom_config.get_element_names() # get the custom properties search = Search("prod/custom_property") search.add_filter("search_type", my.search_type) custom_properties = search.get_sobjects() # action popup action_popup = PopupMenuWdg("table_action", multi=True, width='12em') action_popup.set_auto_hide(False) action_popup.set_submit(False) action_popup.add( HtmlElement.href("Add ...", "javascript:document.form.submit()") ) for custom_property in custom_properties: element_name = custom_property.get_name() if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) # if there is an override if element_names: for element_name in element_names: if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) # get all of the columns else: search_type_obj = SearchType.get(my.search_type) element_names = search_type_obj.get_columns() for element_name in element_names: if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) # add some standard properties if my.view in ["edit", "insert"]: for element_name in PREDEFINED_EDIT_ELEMENTS: if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) else: for element_name in PREDEFINED_ELEMENTS: if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) action_popup.add_separator() action_popup.add( HtmlElement.href("Remove ...", "javascript:document.form.submit()") ) for element_name in custom_element_names: action_popup.add( " %s" % element_name, "remove|%s" % element_name ) action_popup.add_separator() span = SpanWdg("New Custom ...", css="hand") iframe = WebContainer.get_iframe() url = WebContainer.get_web().get_widget_url() url.set_option("widget", "pyasm.widget.CustomAddPropertyWdg") url.set_option("search_type", my.search_type) url.set_option("view", my.view) action = iframe.get_on_script(url.to_string() ) span.add_event("onclick", action) action_popup.add( span ) # add the edit button edit = IconButtonWdg("Edit View", IconWdg.EDIT, True) edit.add_event("oncontextmenu", "%s;return false" % action_popup.get_on_script() ) edit.add_event("onclick", "%s" % action_popup.get_on_script() ) # lay it all out widget.add(SpanWdg(action_popup)) widget.add(edit) # add the edit button #save = IconButtonWdg("Save", IconWdg.SAVE, True) #widget.add(save) # add the add property button if my.mode == "admin": add = CustomAddPropertyLinkWdg(my.search_type, my.view) widget.add(add) #add_element = CustomAddElementLinkWdg(my.search_type, my.view) #widget.add(add_element) # add the clear button if my.mode == "admin" or my.view.startswith("custom_"): clear = IconSubmitWdg("Clear", IconWdg.DELETE, True) widget.add(clear) widget.add(SpanWdg(css="small")) WebContainer.register_cmd("pyasm.widget.CustomViewAction") return widget
def get_display(my): top = my.top view = my.kwargs.get("view") top.add_class("spt_help_edit_content") search = Search("config/widget_config") search.add_filter("category", "HelpWdg") search.add_filter("view", view) sobject = search.get_sobject() if not sobject: value = "" search_key = "" else: xml_value = sobject.get_xml_value("config") value = xml_value.get_value("config/%s/html/div" % (view) ) search_key = sobject.get_search_key() title_wdg = DivWdg() top.add(title_wdg) title_wdg.add("<b>View: %s</b>" % view) title_wdg.add_style("font-style: bold") title_wdg.add_style("padding: 5px") title_wdg.add_gradient("background", "background", 0, -10) hidden = HiddenWdg("view") top.add(hidden) hidden.set_value(view) text = TextAreaWdg("content") text_id = text.set_unique_id() text.set_value(value) from tactic.ui.widget import ActionButtonWdg if sobject: delete_button = ActionButtonWdg(title="Delete") top.add(delete_button) delete_button.add_style("float: right") delete_button.add_style("margin-top: -3px") delete_button.add_behavior( { 'type': 'click_up', 'search_key': search_key, 'cbjs_action': ''' if (!confirm("Are you sure you wish to delete this help page?")) { return; } var server = TacticServerStub.get(); server.delete_sobject(bvr.search_key); var top = bvr.src_el.getParent(".spt_help_edit_top"); spt.panel.refresh(top); ''' }) test_button = ActionButtonWdg(title="Preview") top.add(test_button) test_button.add_style("float: right") test_button.add_style("margin-top: -3px") test_button.add_behavior( { 'type': 'click_up', 'text_id': text_id, 'cbjs_action': ''' var js_file = "ckeditor/ckeditor.js"; var url = "/context/spt_js/" + js_file; var js_el = document.createElement("script"); js_el.setAttribute("type", "text/javascript"); js_el.setAttribute("src", url); var head = document.getElementsByTagName("head")[0]; head.appendChild(js_el); var cmd = "CKEDITOR.instances." + bvr.text_id + ".getData()"; var text_value = eval( cmd ); bvr.options = {}; bvr.options.html = text_value; spt.named_events.fire_event("show_help", bvr) ''' }) save_button = ActionButtonWdg(title="Save") top.add(save_button) save_button.add_style("float: right") save_button.add_style("margin-top: -3px") top.add("<br/>") save_button.add_behavior( { 'type': 'click_up', 'text_id': text_id, 'cbjs_action': ''' spt.app_busy.show("Saving Help", " ") var top = bvr.src_el.getParent(".spt_help_edit_content"); var values = spt.api.Utility.get_input_values(top, null, false); var cmd = "CKEDITOR.instances." + bvr.text_id + ".getData()"; var text_value = eval( cmd ); values.content = text_value; var command = "tactic.ui.app.HelpEditCbk"; var kwargs = values; var server = TacticServerStub.get(); server.execute_cmd(command, kwargs); setTimeout("spt.app_busy.hide()", 200) ''' } ) #top.add("Style: ") #select = SelectWdg("style") #top.add(select) #select.set_option("values", "text|html") top.add("<br/>") top.add(text) text.set_value(value) text.add_style("width: 100%") text.add_style("height: 100%") text.add_style("min-height: 500px") text.add_style("display: none") text.add_behavior( { 'type': 'load', 'color': text.get_color("background", -10), 'text_id': text_id, 'cbjs_action': ''' var js_file = "ckeditor/ckeditor.js"; var url = "/context/spt_js/" + js_file; var js_el = document.createElement("script"); js_el.setAttribute("type", "text/javascript"); js_el.setAttribute("src", url); var head = document.getElementsByTagName("head")[0]; head.appendChild(js_el); setTimeout( function() { CKEDITOR.on( 'instanceReady', function( ev ) { ev.editor.dataProcessor.writer.indentationChars = ' '; }); var config = { toolbar: 'Full', uiColor: bvr.color, height: '500px' }; config.toolbar_Full = [ ['Source'], ['Cut','Copy','Paste'], ['Undo','Redo','-','Find','Replace'], ['Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], '/', ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['HorizontalRule','SpecialChar'], ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['Maximize', 'ShowBlocks'] ]; CKEDITOR.replace(bvr.text_id, config ); bvr.src_el.setStyle("display", ""); }, 500); ''' } ) return top
def get_display(my): web = WebContainer.get_web() if not my.view: my.view = web.get_form_value("view") if not my.view: my.view = get_template_view() widget = Widget() widget.add( HiddenWdg("search_type", my.search_type) ) # get a list of all of the element names possible search_type_obj = SearchType.get(my.search_type) config = WidgetConfigView.get_by_search_type(my.search_type,DEFAULT_VIEW) if config: element_names = config.get_element_names() # FIXME: also get those from the default (not sure about this) config = WidgetConfigView.get_by_search_type(my.search_type,"default") if config: element_names.extend( config.get_element_names() ) if not element_names: element_names = [] # get the custom element names from config custom_config = WidgetConfigView.get_by_search_type(my.search_type,my.view) custom_element_names = custom_config.get_element_names() # get the custom properties search = Search("prod/custom_property") search.add_filter("search_type", my.search_type) custom_properties = search.get_sobjects() # action popup action_popup = my.action_popup action_popup.set_auto_hide(False) action_popup.set_submit(False) action_popup.add( HtmlElement.href("Add ...", "javascript:document.form.submit()") ) for custom_property in custom_properties: element_name = custom_property.get_name() if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) for element_name in element_names: if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) # add some standard properties if my.view in ["edit", "insert"]: for element_name in PREDEFINED_EDIT_ELEMENTS: if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) else: for element_name in PREDEFINED_ELEMENTS: if element_name not in custom_element_names: action_popup.add( " %s" % element_name, "add|%s" % element_name ) action_popup.add_separator() action_popup.add( HtmlElement.href("Remove ...", "javascript:document.form.submit()") ) for element_name in custom_element_names: action_popup.add( " %s" % element_name, "remove|%s" % element_name ) action_popup.add_separator() span = SpanWdg("New Custom ...", css="hand") iframe = WebContainer.get_iframe() url = WebContainer.get_web().get_widget_url() url.set_option("widget", "pyasm.widget.CustomAddPropertyWdg") url.set_option("search_type", my.search_type) url.set_option("view", my.view) action = iframe.get_on_script(url.to_string() ) span.add_event("onclick", action) action_popup.add( span ) WebContainer.register_cmd("pyasm.widget.CustomViewAction") widget.add(action_popup) return widget
def init(self): self.current_offset = 0 self.count = None #self.text = TextWdg(self.search_limit_name) self.text = HiddenWdg(self.search_limit_name) self.text.add_style("width: 23px") self.text.add_style("margin-bottom: -1px") self.text.add_class("spt_search_limit_text") self.text.set_persist_on_submit(prefix=self.prefix) behavior = { 'type': 'keydown', 'cbjs_action': ''' if (evt.key=='enter') { // register this as changed item var value = bvr.src_el.value; if (isNaN(value) || value.test(/[\.-]/)) { spt.error('You have to use an integer.'); } } '''} self.text.add_behavior(behavior) # get the search limit that is passed in filter_data = FilterData.get() values = filter_data.get_values_by_prefix(self.prefix) if not values: # check web for embedded table web = WebContainer.get_web() values = {} limit_value = web.get_form_value("search_limit") label_value = web.get_form_value(self.label) if limit_value: values['search_limit'] = limit_value if label_value: values[self.label] = label_value else: values = values[0] self.values2 = filter_data.get_values_by_prefix("search_limit_simple") if not len(self.values2): self.values2 = {} elif len(self.values2) == 2: if self.values2[0]['page']: self.values2 = self.values2[0] else: self.values2 = self.values2[1] else: self.values2 = self.values2[0] self.stated_search_limit = values.get("search_limit") """ if not self.stated_search_limit: self.stated_search_limit = values.get("limit_select") if not self.stated_search_limit: self.stated_search_limit = values.get("custom_limit") """ if self.stated_search_limit: self.stated_search_limit = int(self.stated_search_limit) else: self.stated_search_limit = 0 # reused for alter_search() later self.values = values
def get_display(self): web = WebContainer.get_web() login_name = web.get_form_value('login') hidden = HiddenWdg('login', login_name) box = DivWdg(css='login') if web.is_IE(): box.add_style("margin-top: 150px") box.add_style("margin-bottom: 150px") else: box.add_style("margin-top: auto") box.add_style("margin-bottom: auto") box.add_style("text-align: center") div = DivWdg() div.add_style("margin: 0px 0px") div.add_class("centered") div.add_style("padding-top: 95px") sthpw = SpanWdg("SOUTHPAW TECHNOLOGY INC", css="login_sthpw") sthpw.add_style("color: #CCCCCC") div.add(sthpw) div.add(HtmlElement.br()) div.add(hidden) box.add(div) # hidden element in the form to pass message that this was not # actually a typical submitted form, but rather the result # of a login page div.add(HiddenWdg("is_from_login", "yes")) div.add_style("font-size: 10px") table = Table(css="login") table.center() table.set_attr("cellpadding", "3px") table.add_row() table2 = Table(css="login") table2.center() table2.add_style("width: 240px") table2.add_row() td = table2.add_header( 'After reset, the new password will be sent to the email address for [ %s ].' % login_name) td.add_color('color', 'color', +80) table2.add_row_cell(' ') # build the button manually from tactic.ui.widget import ActionButtonWdg button = ActionButtonWdg(tip='Reset Password', title='Reset') button.add_style('margin: auto') button.add_event( 'onclick', "document.form.elements['reset_password'].value='true'; document.form.submit()" ) table2.add_row() td = table2.add_cell(button) hidden = HiddenWdg('reset_password') td.add(hidden) #th.add_class('center_content') table2.add_row() div.add(HtmlElement.br()) div.add(table) div.add(HtmlElement.spacer_div(1, 14)) div.add(table2) #div.add(HiddenWdg(self.LOGIN_MSG)) #box.add(script) widget = Widget() #widget.add( HtmlElement.br(3) ) table = Table() table.add_style("width: 100%") table.add_style("height: 85%") table.add_row() td = table.add_cell() td.add_style("vertical-align: middle") td.add_style("text-align: center") td.add_style("background: transparent") td.add(box) widget.add(table) return widget
def get_display(my): top = my.top my.set_as_panel(top) top.set_unique_id() top.add_class("spt_search_limit_top") # this info comes from the SearchLimit above (function get_info() ) count = my.kwargs.get("count") if count == 0: return top search_limit = my.kwargs.get("search_limit") # account for cases where this shouldn't even be called in a non search scenario if not search_limit: search_limit = 100 current_offset = my.kwargs.get("current_offset") num_pages = int(float(count - 1) / float(search_limit)) + 1 current_page = int(float(current_offset) / count * num_pages) + 1 # show even if there is only a single page #if num_pages == 1: # return top #print "current: ", current_offset #print "search_limit: ", search_limit #print "current_page: ", current_page table = Table() table.add_style("float: right") top.add(table) top.add_color("background", "background", -5) top.add_color("color", "color3") top.add_style("margin: -1px 0px 10px 0px") top.add_border(color="table_border") top.add_style("padding-right: 30px") top.add_style("padding-left: 8px") top.add_style("padding-top: 5px") top.add_style("padding-bottom: 5px") showing_div = DivWdg() showing_div.add_style("padding: 5px") top.add(showing_div) start_count = current_offset + 1 end_count = current_offset + search_limit if end_count > count: end_count = count total_count = count bgcolor = top.get_color("background", -5) bgcolor2 = top.get_color("background", 10) showing_div.add_color('background', bgcolor) if num_pages > 1: showing_div.add("Showing %s - %s of %s" % (start_count, end_count, total_count)) else: showing_div.add("Showing %s - %s of %s" % (start_count, count, count)) return top table.add_row() top.add_smart_style("spt_link", "padding", "5px 10px 5px 10px") top.add_smart_style("spt_link", "margin", "0px 5px 0px 5x") top.add_smart_style("spt_link", "cursor", "pointer") #top.add_smart_style("spt_link", "border", "solid 1px blue") top.add_smart_style("spt_no_link", "padding", "5px 10px 5px 10px") top.add_smart_style("spt_no_link", "margin", "0px 5px 0px 5x") top.add_smart_style("spt_no_link", "opacity", "0.5") top.add_smart_style("spt_no_link", "font-style", "italic") top.add_relay_behavior({ 'type': 'mouseup', 'search_limit': search_limit, 'limit': search_limit, 'current_page': current_page, 'num_pages': num_pages, 'bvr_match_class': 'spt_link', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var page_el = top.getElement(".spt_page"); var value = bvr.src_el.getAttribute("spt_page"); if (value == 'next') { value = bvr.current_page + 1; if ( value < 1 ) value = 1; } else if (value == 'prev') { value = bvr.current_page - 1; if ( value > bvr.num_pages ) value = bvr.num_pages; } page_el.value = value; bvr.src_el = bvr.src_el.getParent('.spt_table_top'); //bvr.panel = bvr.src_el.getParent('.spt_view_panel'); spt.dg_table.search_cbk(evt, bvr); ''' }) top.add_relay_behavior({ 'type': 'mouseover', 'bgcolor': bgcolor2, 'bvr_match_class': 'spt_link', 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.bgcolor); ''' }) top.add_relay_behavior({ 'type': 'mouseout', 'bgcolor': bgcolor, 'bvr_match_class': 'spt_link', 'cbjs_action': ''' if (!bvr.src_el.hasClass('spt_current_page')) bvr.src_el.setStyle("background", bvr.bgcolor); ''' }) top.add_class("spt_table_search") hidden = HiddenWdg("prefix", "search_limit_simple") top.add(hidden) hidden = HiddenWdg("page", "") hidden.add_class("spt_page") top.add(hidden) td = table.add_cell() left = "< Prev" td.add(left) if current_page > 1: td.add_class("spt_link") else: td.add_class("spt_no_link") td.add_attr("spt_page", "prev") # find the range ... always show 10 pages max start_page = current_page - 5 if start_page < 1: start_page = 1 if start_page + 9 <= num_pages: end_page = start_page + 10 - 1 elif start_page > 5: end_page = current_page + 5 else: end_page = num_pages start_page = 1 # if end_pages for whatever reason, exceeds num_pages, limit it if end_page > num_pages: end_page = num_pages # if for whatever reason, end_page - 10 > 1, then limit it if end_page == num_pages and end_page - 10 > 1: start_page = end_page - 10 for i in range(start_page, end_page + 1): td = table.add_cell() td.add(i) td.add_class("spt_link") td.add_attr("spt_page", i) if i == current_page: td.add_color("color", "color") td.add_class("spt_current_page") td.add_color("background", "background", 10) td.add_color("border-color", "border") td.add_style("border-width", "0px 1px 0px 1px") td.add_style("border-style", "solid") td = table.add_cell() right = "Next >" td.add(right) if current_page < num_pages: td.add_class("spt_link") else: td.add_class("spt_no_link") td.add_attr("spt_page", "next") return top
def get_display(my): relative_dir = my.kwargs.get("relative_dir") my.relative_dir = relative_dir div = DivWdg() div.add_class("spt_ingest_top") div.add_style("width: 100%px") div.add_style("min-width: 500px") div.add_style("padding: 20px") div.add_color("background", "background") my.search_type = my.kwargs.get("search_type") if not my.search_type: div.add("No search type specfied") return div if relative_dir: folder_div = DivWdg() div.add(folder_div) folder_div.add("Folder: %s" % relative_dir) folder_div.add_style("opacity: 0.5") folder_div.add_style("font-style: italic") folder_div.add_style("margin-bottom: 10px") data_div = my.get_data_wdg() data_div.add_style("float: left") data_div.add_style("float: left") div.add(data_div) # create the help button help_button_wdg = DivWdg() div.add(help_button_wdg) help_button_wdg.add_style("float: right") help_button = ActionButtonWdg(title="?", tip="Ingestion Widget Help", size='s') help_button_wdg.add(help_button) help_button.add_behavior({ 'type': 'click_up', 'cbjs_action': '''spt.help.load_alias("ingestion_widget")''' }) from tactic.ui.input import Html5UploadWdg upload = Html5UploadWdg(multiple=True) div.add(upload) button = ActionButtonWdg(title="Add") button.add_style("float: right") button.add_style("margin-top: -3px") div.add(button) button.add_behavior({ 'type': 'click_up', 'normal_ext': File.NORMAL_EXT, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var files_el = top.getElement(".spt_to_ingest_files"); var regex = new RegExp('(' + bvr.normal_ext.join('|') + ')$', 'i'); //clear upload progress var upload_bar = top.getElement('.spt_upload_progress'); if (upload_bar) { upload_bar.setStyle('width','0%'); upload_bar.innerHTML = ''; } var onchange = function (evt) { var files = spt.html5upload.get_files(); var delay = 0; for (var i = 0; i < files.length; i++) { var size = files[i].size; var file_name = files[i].name; var is_normal = regex.test(file_name); if (size >= 10*1024*1024 || is_normal) { spt.drag.show_file(files[i], files_el, 0, false); } else { spt.drag.show_file(files[i], files_el, delay, true); if (size < 100*1024) delay += 50; else if (size < 1024*1024) delay += 500; else if (size < 10*1024*1024) delay += 1000; } } } spt.html5upload.clear(); spt.html5upload.set_form( top ); spt.html5upload.select_file( onchange ); ''' }) button = ActionButtonWdg(title="Clear") button.add_style("float: right") button.add_style("margin-top: -3px") div.add(button) button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); }; ''' }) div.add("<br clear='all'/>") div.add("<br clear='all'/>") border_color_light = div.get_color("background2", 8) border_color_dark = div.get_color("background2", -15) background_mouseout = div.get_color("background3", 10) background_mouseenter = div.get_color("background3", 8) files_div = DivWdg() files_div.add_style("position: relative") files_div.add_class("spt_to_ingest_files") div.add(files_div) files_div.add_style("max-height: 300px") files_div.add_style("height: 300px") files_div.add_style("overflow-y: auto") files_div.add_style("padding: 3px") files_div.add_color("background", background_mouseout) files_div.add_style("border: 3px dashed %s" % border_color_light) files_div.add_style("border-radius: 20px 20px 20px 20px") files_div.add_style("z-index: 1") #files_div.add_style("display: none") bgcolor = div.get_color("background3") bgcolor2 = div.get_color("background3", -3) #style_text = "text-align: center; margin-top: 100px; color: #A0A0A0; font-size: 3.0em; z-index: 10;" background = DivWdg() background.add_class("spt_files_background") files_div.add(background) background.add_style("text-align: center") background.add_style("margin-top: 100px") background.add_style("opacity: 0.65") background.add_style("font-size: 3.0em") background.add_style("z-index: 10") background_text = DivWdg("<p>Drag Files Here</p>") background.add(background_text) files_div.add_behavior({ 'type': 'mouseover', 'cbjs_action': ''' bvr.src_el.setStyle("border","3px dashed %s") bvr.src_el.setStyle("background","%s") ''' % (border_color_dark, background_mouseenter) }) files_div.add_behavior({ 'type': 'mouseout', 'cbjs_action': ''' bvr.src_el.setStyle("border", "3px dashed %s") bvr.src_el.setStyle("background","%s") ''' % (border_color_light, background_mouseout) }) # Test drag and drop files files_div.add_attr("ondragenter", "return false") files_div.add_attr("ondragover", "return false") files_div.add_attr("ondrop", "spt.drag.noop(event, this)") files_div.add_behavior({ 'type': 'load', 'normal_ext': File.NORMAL_EXT, 'cbjs_action': ''' spt.drag = {} var background; spt.drag.show_file = function(file, top, delay, icon) { if (!background) { background = top.getElement(".spt_files_background"); if (background) background.setStyle("display", "none"); } var template = top.getElement(".spt_upload_file_template"); var clone = spt.behavior.clone(template); clone.removeClass("spt_upload_file_template"); clone.addClass("spt_upload_file"); clone.setStyle("display", ""); if (typeof(delay) == 'undefined') { delay = 0; } // remember the file handle clone.file = file; var name = file.name; var size = parseInt(file.size / 1024 * 10) / 10; var thumb_el = clone.getElement(".spt_thumb"); var date_label_el = clone.getElement(".spt_date_label"); var date_el = clone.getElement(".spt_date"); //var loadingImage = loadImage( setTimeout( function() { var draw_empty_icon = function() { var img = $(document.createElement("div")); img.setStyle("width", "58"); img.setStyle("height", "34"); //img.innerHTML = "MP4"; img.setStyle("border", "1px dotted #222") thumb_el.appendChild(img); }; if (icon) { var loadingImage = loadImage( file, function (img) { if (img.width) thumb_el.appendChild(img); else draw_empty_icon(); }, {maxWidth: 80, maxHeight: 60, canvas: true, contain: true} ); } else { draw_empty_icon(); } loadImage.parseMetaData( file, function(data) { if (data.exif) { var date = data.exif.get('DateTimeOriginal'); if (date) { date_label_el.innerHTML = date; if (date_el) { date_el.value = date; } } } } ); }, delay ); /* var reader = new FileReader(); reader.thumb_el = thumb_el; reader.onload = function(e) { this.thumb_el.innerHTML = [ '<img class="thumb" src="', e.target.result, '" title="', escape(name), '" width="60px"', '" padding="5px"', '"/>' ].join(''); } reader.readAsDataURL(file); */ clone.getElement(".spt_name").innerHTML = file.name; clone.getElement(".spt_size").innerHTML = size + " KB"; clone.inject(top); } spt.drag.noop = function(evt, el) { var top = $(el).getParent(".spt_ingest_top"); var files_el = top.getElement(".spt_to_ingest_files"); evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; var files = evt.dataTransfer.files; var delay = 0; var skip = false; var regex = new RegExp('(' + bvr.normal_ext.join('|') + ')$', 'i'); for (var i = 0; i < files.length; i++) { var size = files[i].size; var file_name = files[i].name; var is_normal = regex.test(file_name); if (size >= 10*1024*1024 || is_normal) { spt.drag.show_file(files[i], files_el, 0, false); } else { spt.drag.show_file(files[i], files_el, delay, true); if (size < 100*1024) delay += 50; else if (size < 1024*1024) delay += 500; else if (size < 10*1024*1024) delay += 1000; } } } ''' }) # create a template that will be filled in for each file files_div.add_relay_behavior({ 'type': 'mouseenter', 'color': files_div.get_color("background3", -5), 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.color); ''' }) files_div.add_relay_behavior({ 'type': 'mouseleave', 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); ''' }) files_div.add_relay_behavior({ 'type': 'mouseup', 'bvr_match_class': 'spt_remove', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_upload_file"); spt.behavior.destroy_element(top); ''' }) """ metadata_view = "test/wizard/metadata" files_div.add_relay_behavior( { 'type': 'mouseup', 'view': metadata_view, 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: bvr.view } spt.app_busy.show("Loading Metadata"); spt.panel.load_popup("Metadata", class_name, kwargs); spt.app_busy.hide(); ''' } ) """ # template for each file item file_template = DivWdg() file_template.add_class("spt_upload_file_template") files_div.add(file_template) file_template.add_style("margin-bottom: 3px") file_template.add_style("padding: 3px") file_template.add_style("height: 40px") file_template.add_style("display: none") thumb_div = DivWdg() file_template.add(thumb_div) thumb_div.add_style("float: left") thumb_div.add_style("width: 60") thumb_div.add_style("height: 40") thumb_div.add_style("overflow: hidden") thumb_div.add_style("margin: 3 10 3 0") thumb_div.add_class("spt_thumb") info_div = DivWdg() file_template.add(info_div) info_div.add_style("float: left") name_div = DivWdg() name_div.add_class("spt_name") info_div.add(name_div) name_div.add("image001.jpg") name_div.add_style("width: 150px") """ dialog = DialogWdg(display="false", show_title=False) info_div.add(dialog) dialog.set_as_activator(info_div, offset={'x':0,'y':10}) dialog_data_div = DivWdg() dialog_data_div.add_color("background", "background") dialog_data_div.add_style("padding", "10px") dialog.add(dialog_data_div) dialog_data_div.add("Category: ") text = TextInputWdg(name="category") dialog_data_div.add(text) text.add_class("spt_category") text.add_style("padding: 1px") """ date_div = DivWdg() date_div.add_class("spt_date_label") info_div.add(date_div) date_div.add("") date_div.add_style("opacity: 0.5") date_div.add_style("font-size: 0.8em") date_div.add_style("font-style: italic") date_div.add_style("margin-top: 3px") hidden_date_div = HiddenWdg("date") hidden_date_div.add_class("spt_date") info_div.add(date_div) size_div = DivWdg() size_div.add_class("spt_size") file_template.add(size_div) size_div.add("433Mb") size_div.add_style("float: left") size_div.add_style("width: 150px") size_div.add_style("text-align: right") remove_div = DivWdg() remove_div.add_class("spt_remove") file_template.add(remove_div) icon = IconButtonWdg(title="Remove", icon=IconWdg.DELETE) icon.add_style("float: right") remove_div.add(icon) #remove_div.add_style("text-align: right") div.add("<br/>") info = DivWdg() div.add(info) info.add_class("spt_upload_info") progress_div = DivWdg() progress_div.add_class("spt_upload_progress_top") div.add(progress_div) progress_div.add_style("width: 100%") progress_div.add_style("height: 15px") progress_div.add_style("margin-bottom: 10px") progress_div.add_border() #progress_div.add_style("display: none") progress = DivWdg() progress_div.add(progress) progress.add_class("spt_upload_progress") progress.add_style("width: 0px") progress.add_style("height: 100%") progress.add_gradient("background", "background3", -10) progress.add_style("text-align: right") progress.add_style("overflow: hidden") progress.add_style("padding-right: 3px") from tactic.ui.app import MessageWdg progress.add_behavior({ 'type': 'load', 'cbjs_action': MessageWdg.get_onload_js() }) # NOTE: files variable is passed in automatically upload_init = ''' server.start( {description: "Upload and check-in of ["+files.length+"] files"} ); var info_el = top.getElement(".spt_upload_info"); info_el.innerHTML = "Uploading ..."; ''' upload_progress = ''' var top = bvr.src_el.getParent(".spt_ingest_top"); progress_el = top.getElement(".spt_upload_progress"); var percent = Math.round(evt.loaded * 100 / evt.total); progress_el.setStyle("width", percent + "%"); progress_el.innerHTML = String(percent) + "%"; ''' oncomplete_script_path = my.kwargs.get("oncomplete_script_path") oncomplete_script = '' if oncomplete_script_path: script_folder, script_title = oncomplete_script_path.split("/") oncomplete_script_expr = "@GET(config/custom_script['folder','%s']['title','%s'].script)" % ( script_folder, script_title) server = TacticServerStub.get() oncomplete_script_ret = server.eval(oncomplete_script_expr, single=True) if oncomplete_script_ret: oncomplete_script = '''var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); };''' + oncomplete_script_ret script_found = True else: script_found = False oncomplete_script = "alert('Error: oncomplete script not found');" if not oncomplete_script: oncomplete_script = ''' var click_action = function() { var fade = true; var pop = spt.popup.get_popup(top) spt.popup.close(pop, fade); } spt.info("Ingest Completed", {click: click_action}); server.finish(); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); }; var background = top.getElement(".spt_files_background"); background.setStyle("display", ""); spt.message.stop_interval(key); var info_el = top.getElement(".spt_upload_info"); info_el.innerHTML = ''; if (spt.table) { spt.table.run_search(); } ''' script_found = True on_complete = ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var update_data_top = top.getElement(".spt_edit_top"); var progress_el = top.getElement(".spt_upload_progress"); progress_el.innerHTML = "100%"; progress_el.setStyle("width", "100%"); var info_el = top.getElement(".spt_upload_info"); var search_type = bvr.kwargs.search_type; var relative_dir = bvr.kwargs.relative_dir; var filenames = []; for (var i = 0; i != files.length;i++) { var name = files[i].name; filenames.push(name); } var key = spt.message.generate_key(); var values = spt.api.get_input_values(top); //var category = values.category[0]; //var keywords = values.keywords[0]; var extra_data = values.extra_data ? values.extra_data[0]: {}; var parent_key = values.parent_key[0]; var convert_el = top.getElement(".spt_image_convert") var convert = spt.api.get_input_values(convert_el); var processes = values.process; if (processes) { process = processes[0]; if (!process) { process = null; } } else { process = null; } var return_array = false; var update_data = spt.api.get_input_values(update_data_top, null, return_array); var kwargs = { search_type: search_type, relative_dir: relative_dir, filenames: filenames, key: key, parent_key: parent_key, //category: category, //keywords: keywords, extra_data: extra_data, update_data: update_data, process: process, convert: convert, } on_complete = function() { ''' + oncomplete_script + ''' }; var class_name = bvr.action_handler; // TODO: make the async_callback return throw an e so we can run // server.abort server.execute_cmd(class_name, kwargs, null, {on_complete:on_complete}); on_progress = function(message) { msg = JSON.parse(message.message); var percent = msg.progress; var description = msg.description; info_el.innerHTML = description; progress_el.setStyle("width", percent+"%"); progress_el.innerHTML = percent + "%"; } spt.message.set_interval(key, on_progress, 2000); ''' upload_div = DivWdg() div.add(upload_div) #button = UploadButtonWdg(**kwargs) button = ActionButtonWdg(title="Ingest") upload_div.add(button) button.add_style("float: right") upload_div.add_style("margin-bottom: 15px") upload_div.add("<br clear='all'/>") action_handler = my.kwargs.get("action_handler") if not action_handler: action_handler = 'tactic.ui.tools.IngestUploadCmd' button.add_behavior({ 'type': 'click_up', 'action_handler': action_handler, 'kwargs': { 'search_type': my.search_type, 'relative_dir': relative_dir, 'script_found': script_found }, 'cbjs_action': ''' if (bvr.kwargs.script_found != true) { spt.alert("Error: provided on_complete script not found"); return; } var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); // get the server that will be used in the callbacks var server = TacticServerStub.get(); // retrieved the stored file handles var files = []; for (var i = 0; i < file_els.length; i++) { files.push( file_els[i].file ); } if (files.length == 0) { alert("Either click 'Add' or drag some files over to ingest."); return; } // defined the callbacks var upload_start = function(evt) { } var upload_progress = function(evt) { %s; } var upload_complete = function(evt) { %s; spt.app_busy.hide(); } var upload_file_kwargs = { files: files, upload_start: upload_start, upload_complete: upload_complete, upload_progress: upload_progress }; if (bvr.ticket) upload_file_kwargs['ticket'] = bvr.ticket; %s; spt.html5upload.set_form( top ); spt.html5upload.upload_file(upload_file_kwargs); ''' % (upload_progress, on_complete, upload_init) }) return div
def get_title(my): div = DivWdg() div.add_behavior({'type': 'load', 'cbjs_action': my.get_onload_js()}) # for csv export hid = HiddenWdg('start_date', my.start_date) div.add(hid) mday = my.today.strftime("%d") mmonth = my.today.strftime("%m") my.weekday_dict = {} days = [] for idx, date in enumerate(my.dates): day_div = DivWdg() days.append(day_div) week_day = date.strftime("%a") day_div.add("%s<br/>%s" % (week_day, date.strftime("%d"))) my.weekday_dict[idx] = week_day table = Table() div.add(table) table.add_row() table.add_color("color", "color") table.add_style("width: %spx" % my.table_width) table.add_style("float: left") month_div = FloatDivWdg(my.start_date.strftime("%b")) month_div.add_style('font-weight: 600') td = table.add_cell(month_div) td.add_style('width', '%spx' % my.MONTH_WIDTH) icon = IconButtonWdg(tip="Previous Week", icon=IconWdg.LEFT) td = table.add_cell(icon) offset = 0 if not my.use_straight_time: offset = 12 td.add_style("width: %spx" % (my.LEFT_WIDTH + offset)) display_days = my.days_per_page next_start_date = my.start_date + datetime.timedelta(days=display_days) prev_start_date = my.start_date + datetime.timedelta( days=-display_days) icon.add_behavior({ 'type': 'click_up', 'start_date': prev_start_date.__str__(), 'cbjs_action': ''' spt.app_busy.show('Loading previous week...'); var header = bvr.src_el.getParent('.spt_table_header'); if (!header) { spt.alert('Work hour widget requires the new Fast Table Layout to scroll to previous week. You can do so in [Manage Side Bar].'); spt.app_busy.hide(); return; } var cur_name = spt.table.get_element_name_by_header(header); var values = {'start_date': bvr.start_date}; spt.table.refresh_column(cur_name, values); spt.app_busy.hide(); ''' }) for day in days: day_wdg = DivWdg() day_wdg.add(day) td = table.add_cell() td.add(day_wdg) td.add_styles( "text-align: center; padding-left: 2px;min-width: %spx" % my.day_width) icon = IconButtonWdg(tip="Next Week", icon=IconWdg.RIGHT) icon.add_behavior({ 'type': 'click_up', 'start_date': next_start_date.__str__(), 'cbjs_action': ''' spt.app_busy.show('Loading next week...'); var header = bvr.src_el.getParent('.spt_table_header'); if (!header) { spt.alert('Work hour widget requires the new Fast Table Layout to scroll to next week. You can do so in [Manage Side Bar].'); spt.app_busy.hide(); return; } var cur_name = spt.table.get_element_name_by_header(header); var values = {'start_date': bvr.start_date}; spt.table.refresh_column(cur_name, values); spt.app_busy.hide(); ''' }) td = table.add_cell(icon) td.add_style('width: %spx' % my.day_width) # empty total cell td = table.add_blank_cell() td.add_style('width: 100%') return div
def get_data_wdg(my): div = DivWdg() from pyasm.biz import Pipeline from pyasm.widget import SelectWdg search_type_obj = SearchType.get(my.search_type) base_type = search_type_obj.get_base_key() search = Search("sthpw/pipeline") search.add_filter("search_type", base_type) pipelines = search.get_sobjects() if pipelines: pipeline = pipelines[0] process_names = pipeline.get_process_names() if process_names: table = Table() div.add(table) table.add_row() table.add_cell("Process: ") select = SelectWdg("process") table.add_cell(select) process_names.append("---") process_names.append("publish") process_names.append("icon") select.set_option("values", process_names) #### buttons = Table() div.add(buttons) buttons.add_row() button = IconButtonWdg(title="Fill in Data", icon=IconWdg.EDIT) buttons.add_cell(button) dialog = DialogWdg(display="false", show_title=False) div.add(dialog) dialog.set_as_activator(button, offset={'x': -10, 'y': 10}) dialog_data_div = DivWdg() dialog_data_div.add_color("background", "background") dialog_data_div.add_style("padding", "20px") dialog.add(dialog_data_div) # Order folders by date name_div = DivWdg() dialog_data_div.add(name_div) name_div.add_style("margin: 15px 0px") if SearchType.column_exists(my.search_type, "relative_dir"): category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "none") category_div.add(checkbox) category_div.add(" No categories") category_div.add_style("margin-bottom: 5px") checkbox.set_option("checked", "true") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_day") category_div.add(checkbox) category_div.add(" Categorize files by Day") category_div.add_style("margin-bottom: 5px") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_week") category_div.add(checkbox) category_div.add(" Categorize files by Week") category_div.add_style("margin-bottom: 5px") category_div = DivWdg() name_div.add(category_div) checkbox = RadioWdg("category") checkbox.set_option("value", "by_year") category_div.add(checkbox) category_div.add(" Categorize files by Year") category_div.add_style("margin-bottom: 5px") """ checkbox = RadioWdg("category") checkbox.set_option("value", "custom") name_div.add(checkbox) name_div.add(" Custom") """ name_div.add("<br/>") ingest_data_view = my.kwargs.get('ingest_data_view') from tactic.ui.panel import EditWdg sobject = SearchType.create(my.search_type) edit = EditWdg(search_key=sobject.get_search_key(), mode='view', view=ingest_data_view) dialog_data_div.add(edit) hidden = HiddenWdg(name="parent_key") dialog_data_div.add(hidden) hidden.add_class("spt_parent_key") parent_key = my.kwargs.get("parent_key") or "" if parent_key: hidden.set_value(parent_key) extra_data = my.kwargs.get("extra_data") if not isinstance(extra_data, basestring): extra_data = jsondumps(extra_data) if extra_data and extra_data != "null": # it needs a TextArea instead of Hidden because of JSON data text = TextAreaWdg(name="extra_data") text.add_style('display: none') text.set_value(extra_data) dialog_data_div.add(text) """ dialog_data_div.add("Keywords:<br/>") dialog.add(dialog_data_div) text = TextAreaWdg(name="keywords") dialog_data_div.add(text) text.add_class("spt_keywords") text.add_style("padding: 1px") dialog_data_div.add("<br/>"*2) text.add_class("spt_extra_data") text.add_style("padding: 1px") """ #### TEST Image options """ button = IconButtonWdg(title="Resize", icon=IconWdg.FILM) buttons.add_cell(button) dialog = DialogWdg(display="false", show_title=False) div.add(dialog) dialog.set_as_activator(button, offset={'x':-10,'y':10}) try: from spt.tools.convert import ConvertOptionsWdg convert_div = DivWdg() dialog.add(convert_div) convert_div.add_style("padding: 20px") convert_div.add_color("background", "background") convert_div.add_class("spt_image_convert") convert = ConvertOptionsWdg() convert_div.add(convert) except: pass """ # use base name for name """ name_div = DivWdg() dialog_data_div.add(name_div) name_div.add_style("margin: 15px 0px") checkbox = CheckboxWdg("use_file_name") name_div.add(checkbox) name_div.add(" Use name of file for name") name_div.add("<br/>") checkbox = CheckboxWdg("use_base_name") name_div.add(checkbox) name_div.add(" Remove extension") name_div.add("<br/>") checkbox = CheckboxWdg("file_keywords") name_div.add(checkbox) name_div.add(" Use file name for keywords") """ return div
def get_display(self): # if no filters are defined, then display nothing if not self.filters: return Widget() top = self.top top.add_class("spt_search_top") filter_top = DivWdg() top.add(filter_top) filter_top.add_color("color", "color") filter_top.add_color("background", "background", -5) filter_top.add_style("padding: 5px") filter_top.add_style("min-width: 800px") filter_top.add_border() self.set_as_panel(filter_top) # TEST link to help for search widget help_button = ActionButtonWdg(title="?", tip="Search Documentation", size='small') filter_top.add(help_button) help_button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.help.set_top(); spt.help.load_alias("search-quickstart|what-is-searching|search-interface|search-compound|search-expressions"); ''' } ) help_button.add_style("float: right") # this id should be removed filter_top.set_id("%s_search" % self.prefix) filter_top.add_class("spt_search") for name, value in self.kwargs.items(): filter_top.set_attr("spt_%s" % name, value) display = self.kwargs.get('display') # Add a number of filters indicator div = DivWdg() div.add_class("spt_search_num_filters") div.add_style("float: right") div.add_style("font-size: 0.9em") div.add_style("margin: 0 10 0 10") #search_summary.add(div) filter_top.add(div) if self.num_filters_enabled: msg = "[%s] filter/s" % self.num_filters_enabled icon = IconWdg(msg, IconWdg.DOT_GREEN) div.add(icon) div.add("%s" % msg) filter_div = DivWdg() filter_div.set_id("search_filters") filter_div.add_class("spt_search_filters") # TODO: disabling for now # add the action buttons #action_wdg = self.get_action_wdg() #action_wdg.add_style("text-align: right") #filter_div.add( action_wdg ) # add the top display_str = 'block' if not display: display_str = 'none' filter_div.add_style("display: %s" % display_str) search_wdg = self.get_search_wdg() prefix = "filter_mode" if self.prefix_namespace: prefix = '%s_%s' %(self.prefix_namespace, prefix) hidden = HiddenWdg("prefix", prefix) match_div = DivWdg() match_div.add(hidden) match_div.add_class('spt_search_filter') palette = match_div.get_palette() bg_color = palette.color('background') light_bg_color = palette.color('background', modifier=+10) select = SelectWdg("filter_mode") select.add_style("width: 110px") select.add_class("spt_search_filter_mode") select.set_persist_on_submit(prefix) select.remove_empty_option() # for Local search, leave out compound search for now if self.kwargs.get('prefix_namespace'): select.set_option("labels", "Match all|Match any") select.set_option("values", "and|or") else: select.set_option("labels", "Match all|Match any|Compound") select.set_option("values", "and|or|custom") #select.set_option("labels", "all|any") #select.set_option("values", "and|or") select.add_behavior( { 'type': 'change', 'cbjs_action': ''' var display = bvr.src_el.value == 'custom';; var top = bvr.src_el.getParent(".spt_search"); var ops = top.getElements(".spt_op"); for (var i = 0; i < ops.length; i++) { var op = ops[i]; var element = op.getElement(".spt_op_display"); var value = op.getAttribute("spt_op"); if (display) { element.innerHTML = value; var level = op.getAttribute("spt_level"); if (level == 1) { element.setStyle("background", "%s") element.setStyle("padding", "4px") } } else { element.innerHTML = ' '; element.setStyle("background", "%s") element.setStyle("padding", "1px") } } ''' %(light_bg_color, bg_color) } ) match_div.add(select) match_div.add_color("color", "color2") #match_div.add(" on the following") #hint = HintWdg( "An 'AND' operation is always applied to each category below. " \ # "This controls only the filters within each category." ) #match_div.add(hint) #match_div.add('<br/>') #match_div.add_style("padding-top: 5px") filter_div.add( search_wdg) search_wdg.add_style("float: left") filter_div.add( match_div) filter_div.add(HtmlElement.br()) filters_div = DivWdg() filters_div.add_style("margin: 0 -6 0 -6") security = Environment.get_security() # add all the filters for filter in self.filters: element_name = filter.get_name() if not security.check_access("search", element_name, "view"): continue # no need to create it again #filter = self.config.get_display_widget(element_name) div = DivWdg() filters_div.add(div) div.add_class("hand") class_suffix = element_name.replace(' ', '_') cbjs_action = 'var el=spt.get_cousin(bvr.src_el,".spt_search",".spt_filter_%s");spt.simple_display_toggle(el);' % class_suffix div.add_behavior( { 'type': 'click_up', 'cbjs_action': cbjs_action } ) div.add_color("color", "color", +5) #div.add_gradient("background", "background", -5, -5) div.add_style("margin-top: -1px") div.add_style("height: 18px") div.add_border() div.add_style("padding: 8px 5px") div.add_style("white-space: nowrap") if element_name in ["Parent", 'Children']: swap = SwapDisplayWdg.get_triangle_wdg() else: swap = SwapDisplayWdg.get_triangle_wdg() swap.set_off() swap.add_action_script(cbjs_action) div.add_event("onclick", swap.get_swap_script() ) div.add(swap) div.add_class("SPT_DTS") div.add(element_name) div = DivWdg() div.add_class("spt_filter_%s" % class_suffix) if element_name in ["Parent", 'Children']: div.add_style("display: none") else: div.add_style("display: block") #div.add_style("background-color: #333") div.add_color("background", "background") div.add_border() div.add_style("padding: 10px 8px") div.add_style("margin-top: -1px") #div.add_style("margin-left: 20px") #div.add_style("width: 660") div.add(filter) filters_div.add(div) filter_div.add(filters_div) buttons_div = DivWdg() buttons_div.add_style("margin-top: 7px") buttons_div.add_style("margin-bottom: 7px") search_wdg = self.get_search_wdg() search_wdg.add_style("margin: 15px auto") buttons_div.add(search_wdg) filter_div.add(buttons_div) filter_top.add(filter_div) if self.kwargs.get("is_refresh"): return filter_top else: return top
def get_display(my): widget = Widget() my.search_type = my.options.get("search_type") if not my.search_type: my.search_type = my.kwargs.get("search_type") assert my.search_type my.load_options_class = my.kwargs.get('load_options_class') state = Container.get("global_state") if state: my.process = state.get("process") else: my.process = None # the filter for searching assets div = DivWdg(css='filter_box') div.add_color("background", "background2", -35) from app_init_wdg import PyMayaInit, PyXSIInit, PyHoudiniInit if WebContainer.get_web().get_selected_app() == 'Maya': app = PyMayaInit() elif WebContainer.get_web().get_selected_app() == 'XSI': app = PyXSIInit() elif WebContainer.get_web().get_selected_app() == 'Houdini': app = PyHoudiniInit() div.add(app) # add the possibility of a custom callback callback = my.options.get('callback') if callback: hidden = HiddenWdg("callback", callback) div.add(hidden) # or add the possiblity of a switch mode pipeline_type = "load" hidden = HiddenWdg("pipeline_type", pipeline_type) if my.process: process_div = DivWdg() process_div.add_style("margin: 10px") process_div.add("PROCESS: %s" % my.process) process_div.add_style("font-size: 20px") widget.add(process_div) hidden_wdg = HiddenWdg("process_select_%s" % my.search_type) hidden_wdg.set_value(my.process) widget.add(hidden_wdg) else: search_type = my.search_type if search_type == 'prod/shot_instance': search_type = 'prod/shot' process_filter = ProcessFilterWdg(my.get_context_data(search_type), search_type) span = SpanWdg(process_filter, css='med') div.add(span) widget.add(div) # load options for diff search type if my.load_options_class: load_options = Common.create_from_class_path(my.load_options_class) elif my.search_type == 'prod/asset': load_options = LoadOptionsWdg() elif my.search_type == 'prod/shot': load_options = ShotLoadOptionsWdg() elif my.search_type == 'prod/shot_instance': load_options = AnimLoadOptionsWdg() else: load_options = LoadOptionsWdg() load_options.set_prefix(my.search_type) widget.add(load_options) return widget
def get_display(self): element_data_dict = {} config = self.get_config() element_names = config.get_element_names() content_wdg = DivWdg() content_wdg.add_class("spt_simple_search_top") onload_js = DivWdg() content_wdg.add(onload_js) onload_js.add_behavior({ 'type': 'load', 'cbjs_action': self.get_onload_js() }) if not element_names: element_names = ['keywords'] self.set_content(content_wdg) # this is somewhat duplicated logic from alter_search, but since this is called # in ViewPanelWdg, it's a diff instance and needs to retrieve again filter_data = FilterData.get() filter_view = self.kwargs.get("filter_view") if filter_view: search = Search("config/widget_config") search.add_filter("view", filter_view) search.add_filter("category", "search_filter") search.add_filter("search_type", self.search_type) filter_config = search.get_sobject() if filter_config: filter_xml = filter_config.get_xml_value("config") filter_value = filter_xml.get_value("config/filter/values") if filter_value: data_list = jsonloads(filter_value) else: data_list = filter_data.get_values_by_prefix(self.prefix) for data in data_list: handler = data.get("handler") element_name = data.get("element_name") if not element_name: continue element_data_dict[element_name] = data elements_wdg = DivWdg() content_wdg.add(elements_wdg) elements_wdg.add_color("color", "color") elements_wdg.add_style("padding-top: 10px") elements_wdg.add_style("padding-bottom: 15px") #elements_wdg.add_color("background", "background3", 0) elements_wdg.add_color("background", "background", -3) elements_wdg.add_border() if len(element_names) == 1: elements_wdg.add_style("border-width: 0px 0px 0px 0px") elements_wdg.add_style("padding-right: 50px") else: elements_wdg.add_style("border-width: 0px 0px 0px 0px") table = Table() table.add_color("color", "color") elements_wdg.add(table) table.add_class("spt_simple_search_table") columns = self.kwargs.get("columns") if not columns: columns = 2 else: columns = int(columns) num_rows = int(len(element_names) / columns) + 1 tot_rows = int(len(element_names) / columns) + 1 project_code = Project.get_project_code() # self.search_type could be the same as self.base_search_type full_search_type = SearchType.build_search_type( self.search_type, project_code) visible_rows = self.kwargs.get("visible_rows") if visible_rows: visible_rows = int(visible_rows) num_rows = visible_rows else: visible_rows = 0 titles = config.get_element_titles() row_count = 0 for i, element_name in enumerate(element_names): attrs = config.get_element_attributes(element_name) if i % columns == 0: if visible_rows and row_count == visible_rows: tr, td = table.add_row_cell("+ more ...") td.add_class("hand") td.add_class("SPT_DTS") td.add_class("spt_toggle") td.add_style("padding-left: 10px") td.add_behavior({ 'type': 'click_up', 'visible_rows': visible_rows, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_simple_search_table"); var expand = true; var rows = top.getElements(".spt_simple_search_row"); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.getStyle("display") == "none") { row.setStyle("display", ""); } else { row.setStyle("display", "none"); expand = false; } } var spacer = top.getElements(".spt_spacer"); var cell = top.getElement(".spt_toggle"); if (expand) { spacer.setStyle("height", (rows.length+bvr.visible_rows)*20); cell.innerHTML = "- less ..."; } else { spacer.setStyle("height", bvr.visible_rows*20); cell.innerHTML = "+ more ..."; } ''' }) tr = table.add_row() if visible_rows and row_count >= visible_rows: tr.add_class("spt_simple_search_row") tr.add_style("display: none") tr.add_style("height: 0px") row_count += 1 icon_td = table.add_cell() title_td = table.add_cell() element_td = table.add_cell() # need to add these to all the elements because it is all separated # by table tds icon_td.add_class("spt_element_item") icon_td.add_attr("spt_element_name", element_name) title_td.add_class("spt_element_item") title_td.add_attr("spt_element_name", element_name) element_td.add_class("spt_element_item") element_td.add_attr("spt_element_name", element_name) # show the title title_td.add_style("text-align: left") title_td.add_style("padding-right: 5px") title_td.add_style("min-width: 60px") element_wdg = DivWdg() if attrs.get('view') == 'false': element_wdg.add_style('display: none') element_td.add(element_wdg) if i >= 0 and i < columns - 1 and len(element_names) > 1: spacer = DivWdg() spacer.add_class("spt_spacer") spacer.add_style("border-style: solid") spacer.add_style("border-width: 0 0 0 0") #spacer.add_style("height: %spx" % (num_rows*20)) spacer.add_style("height: %spx" % (num_rows * 10)) spacer.add_style("width: 10px") spacer.add_style("border-color: %s" % spacer.get_color("border")) spacer.add(" ") td = table.add_cell(spacer) td.add_attr("rowspan", tot_rows) element_wdg.add_style("padding: 4px 10px 4px 5px") element_wdg.add_class("spt_table_search") element_wdg.add_style("margin: 1px") element_wdg.add_style("min-height: 20px") element_wdg.add_style("min-width: 250px") # this is done at get_top() #element_wdg.add_class("spt_search") element_wdg.add(HiddenWdg("prefix", self.prefix)) display_handler = config.get_display_handler(element_name) element_wdg.add(HiddenWdg("handler", display_handler)) element_wdg.add(HiddenWdg("element_name", element_name)) from pyasm.widget import ExceptionWdg try: widget = config.get_display_widget(element_name) if widget: widget.set_title(titles[i]) except Exception as e: element_wdg.add(ExceptionWdg(e)) continue if not widget: # the default for KeywordFilterElementWdg is mode=keyword if not self.column_choice: self.column_choice = self.get_search_col(self.search_type) widget = KeywordFilterElementWdg(column=self.column_choice) widget.set_name(element_name) from pyasm.widget import IconWdg icon_div = DivWdg() icon_td.add(icon_div) icon_div.add_style("width: 20px") icon_div.add_style("margin-top: -2px") icon_div.add_style("padding-left: 6px") icon_div.add_class("spt_filter_top") widget.set_show_title(False) #element_wdg.add("%s: " % title) data = element_data_dict.get(element_name) view_panel_keywords = self.kwargs.get("keywords") #user data takes precedence over view_panel_keywords if isinstance(widget, KeywordFilterElementWdg): if view_panel_keywords: widget.set_value("value", view_panel_keywords) if data: widget.set_values(data) if isinstance( widget, KeywordFilterElementWdg ) and not full_search_type.startswith('sthpw/sobject_list'): widget.set_option('filter_search_type', full_search_type) try: if attrs.get('view') != 'false': title_td.add(widget.get_title_wdg()) element_wdg.add(widget.get_buffer_display()) except Exception as e: element_wdg.add(ExceptionWdg(e)) continue icon = IconWdg("Filter Set", "BS_ASTERISK") #icon.add_style("color", "#393") icon_div.add(icon) icon.add_class("spt_filter_set") icon.add_class("hand") icon.add_attr("spt_element_name", element_name) icon.add_behavior({ 'type': 'click', 'cbjs_action': ''' var element_name = bvr.src_el.getAttribute("spt_element_name"); spt.simple_search.clear_element(element_name); ''' }) if not widget.is_set(): icon.add_style("display: none") else: color = icon_div.get_color("background", -10) icon_td.add_style("background-color", color) title_td.add_style("background-color", color) element_td.add_style("background-color", color) #elements_wdg.add("<br clear='all'/>") top = self.get_top() return top
def get_display(my): # add the detail widget from tactic.ui.container import RoundedCornerDivWdg detail_wdg = DivWdg(css='spt_detail_panel') if not my.name_string and not my.config_string: detail_wdg.add("<br/>" * 3) detail_wdg.add('<- Click on an item on the left for modification.') detail_wdg.add_style("padding: 10px") detail_wdg.add_color("background", "background", -5) detail_wdg.add_style("width: 350px") detail_wdg.add_style("height: 400px") detail_wdg.add_border() return detail_wdg if my.kwargs.get("mode") == "empty": overlay = DivWdg() detail_wdg.add(overlay) detail_wdg.add_border() detail_wdg.add_color("color", "black") detail_wdg.add_style("padding: 10px") detail_wdg.add_color("background", "background", -5) detail_wdg.set_id('search_type_detail') # put in the selection for simple or advanced select = SelectWdg("config_mode", label='Mode: ') select.set_persistence() values = ['simple', 'advanced'] select.set_option("values", values) config_mode = select.get_value() #select.add_behavior({"type": "change", "cbjs_action": "spt.simple_display_toggle( spt.get_cousin(bvr.src_el, '.spt_detail_panel','.config_simple') )"}) select.add_behavior({"type": "change", "cbjs_action": \ "spt.simple_display_toggle( spt.get_cousin(bvr.src_el, '.spt_detail_panel','.config_advanced')); %s" %select.get_save_script()}) select.add_class('spt_config_mode') title_div = DivWdg("Column Detail") title_div.add_class("maq_search_bar") detail_wdg.add(title_div) detail_wdg.add("<br/>") detail_wdg.add(select) detail_wdg.add(HtmlElement.br(2)) #simple_mode_wdg = WidgetDetailSimpleModeWdg() #detail_wdg.add(simple_mode_wdg) #detail_wdg.add(HtmlElement.br(2)) if my.is_new_column: detail_wdg.add(my.get_new_definition_wdg()) else: simple_wdg = my.get_simple_definition_wdg() simple_wdg.add_class("config_simple") detail_wdg.add(simple_wdg) adv_wdg = my.get_advanced_definition_wdg() adv_wdg.add_class("config_advanced") if config_mode == 'simple': adv_wdg.add_style('display: none') detail_wdg.add(HtmlElement.br(2)) detail_wdg.add(adv_wdg) detail_wdg.add(HtmlElement.br(2)) security_wdg = my.get_security_wdg() detail_wdg.add(security_wdg) # add hidden input for view for panel refreshing # we are only interested in whether it is project_view or definition # sub-views of project_view is not of our interest #if my.view != 'project_view': # my.view = 'custom_definition' detail_wdg.add(HiddenWdg('view', my.view)) return detail_wdg
def get_new_definition_wdg(my): detail_wdg = DivWdg() detail_wdg.add_style("color: black") detail_wdg.add_style("width: 350px") detail_wdg.add_style("margin-top: 10px") detail_wdg.add_style("padding: 10px") detail_wdg.add_border() title = DivWdg() title.add_style("color: black") title.add("Column Definition") title.add_style("margin-top: -22px") detail_wdg.add(title) # add a name entry title = SpanWdg() detail_wdg.add("Name: ") detail_wdg.add(title) input = SpanWdg() input.add_style('padding-top: 6px') input.set_id("config_element_name") text = TextWdg('column_name') text.set_value(my.name_string) input.add(text) detail_wdg.add(input) hidden = HiddenWdg('target_search_type', my.search_type) detail_wdg.add(hidden) detail_wdg.add(HtmlElement.br(2)) # add data_type entry data_type = SpanWdg() default_data_types = [ 'varchar(256)', 'varchar', 'character', 'text', 'integer', 'float', 'boolean', 'timestamp', 'Other...' ] select = SelectWdg('config_data_type', label='Data Type: ') #detail_wdg.add(": ") select.set_option('values', default_data_types) select.set_value(my.data_type_string) select.add_behavior({ 'type': 'change', 'cbjs_action': "if (bvr.src_el.value=='Other...') {spt.show('config_data_type_custom');}\ else {spt.hide('config_data_type_custom');}" }) data_type.add(select) text = TextWdg('config_data_type_custom') span = SpanWdg("Other: ", css='med') span.add(text) span.set_id('config_data_type_custom') span.add_style('display', 'none') text.set_value(my.data_type_string) data_type.add("<br/>") data_type.add(span) detail_wdg.add(data_type) detail_wdg.add("<br/>") # add a nullable entry nullable = DivWdg() checkbox = CheckboxWdg('config_nullable', label='Allow null(empty) value: ') nullable.add(checkbox) if my.nullable_string in ['True', 'true']: checkbox.set_checked() detail_wdg.add(nullable) return detail_wdg
def get_simple_definition_wdg(my): detail_wdg = DivWdg() detail_wdg.add_color("color", "color") detail_wdg.add_style("width: 350px") detail_wdg.add_style("margin-top: 10px") detail_wdg.add_style("padding: 10px") detail_wdg.add_border() title = DivWdg() title.add_style("margin-top: -23px") detail_wdg.add(title) if not my.name_string: title.add('No database column') return detail_wdg title.add("Column Definition") # add a name entry detail_wdg.add("<br/>") title = SpanWdg() detail_wdg.add("Name: ") detail_wdg.add(title) input = SpanWdg() input.add_style('padding-top: 6px') input.set_id("config_element_name") input.add(HtmlElement.b(my.name_string)) detail_wdg.add(input) hidden = HiddenWdg('column_name', my.name_string) detail_wdg.add(hidden) hidden = HiddenWdg('target_search_type', my.search_type) detail_wdg.add(hidden) detail_wdg.add(HtmlElement.br(2)) # add data_type entry data_type = SpanWdg() default_data_types = [ 'varchar(256)', 'varchar', 'character', 'text', 'integer', 'float', 'boolean', 'timestamp', 'Other...' ] select = SelectWdg('config_data_type', label='Data Type: ') #detail_wdg.add(": ") select.set_option('values', default_data_types) select.set_value(my.data_type_string) select.add_behavior({ 'type': 'change', 'cbjs_action': "if (bvr.src_el.value=='Other...') {spt.show('config_data_type_custom');}\ else {spt.hide('config_data_type_custom');}" }) data_type.add(select) text = TextWdg('config_data_type_custom') span = SpanWdg("Other: ", css='med') span.add(text) span.set_id('config_data_type_custom') span.add_style('display', 'none') text.set_value(my.data_type_string) data_type.add("<br/>") data_type.add(span) detail_wdg.add(data_type) detail_wdg.add("<br/>") # add a nullable entry nullable = SpanWdg() checkbox = CheckboxWdg('config_nullable', label='Allow null(empty) value: ') #detail_wdg.add(": ") nullable.add(checkbox) if my.nullable_string in ['True', 'true']: checkbox.set_checked() detail_wdg.add(nullable) #constraint = DivWdg() #detail_wdg.add(constraint) #constraint.add_style("margin-top: 10px") #constraint.add("Constraint: ") #select = SelectWdg("config_constraint") #constraint.add(select) #select.set_option("values", "unique|indexed") #select.add_empty_option("-- None --") button_div = DivWdg() button_div.add_style("text-align: center") button_div.add_behavior({ 'type': 'load', 'cbjs_action': ''' spt.manage_search_type = {}; spt.manage_search_type.change_column_cbk = function(bvr) { var class_name = 'tactic.ui.panel.AlterSearchTypeCbk'; var options ={ 'alter_mode': bvr.alter_mode, 'title': bvr.title }; try { var server = TacticServerStub.get(); var panel = $('search_type_detail'); if (! panel.getAttribute("spt_class_name") ) { panel = panel.getParent(".spt_panel"); } var values = spt.api.Utility.get_input_values(panel); rtn = server.execute_cmd(class_name, options, values); if (bvr.alter_mode == 'Remove Column') spt.info("Column [" + bvr.column + "] has been deleted."); else if (bvr.alter_mode == 'Modify Column') spt.notify.show_message("Column [" + bvr.column + "] has been modified."); } catch (e) { spt.alert(spt.exception.handler(e)); } var view = 'db_column'; spt.panel.refresh("ManageSearchTypeMenuWdg_" + view); var view = 'definition'; spt.panel.refresh("ManageSearchTypeMenuWdg_" + view); } ''' }) detail_wdg.add(button_div) button_div.add("<hr/><br/>") if my.is_new_column: button = ActionButtonWdg(title="Commit") #button = ProdIconButtonWdg("Commit New Column") button.add_behavior({"type": "click_up", "cbjs_action": "spt.manage_search_type.change_column_cbk(bvr)", \ "alter_mode": my.ADD_COLUMN}) button_div.add(button) else: table = Table() button_div.add(table) table.add_row() table.center() button = ActionButtonWdg(title="Modify") #button = ProdIconButtonWdg("Modify Column") button.add_behavior({ "type": "click_up", "cbjs_action": '''spt.manage_search_type.change_column_cbk(bvr); ''', "alter_mode": my.MODIFY_COLUMN, "column": my.name_string, "title": my.title_string }) table.add_cell(button) button = ActionButtonWdg(title="Delete") #button = ProdIconButtonWdg("Delete Column") #button.add_style('background-color: #BF462E') button.add_behavior({ "type": "click_up", "cbjs_action": ''' var yes = function() { spt.manage_search_type.change_column_cbk(bvr); } spt.confirm("Are you sure you wish to delete this column?", yes) ''', "alter_mode": my.REMOVE_COLUMN, "column": my.name_string }) table.add_cell(button) button_div.add(HiddenWdg('delete_column')) button_div.add(HiddenWdg('modify_column')) return detail_wdg
def get_display(self): current = self.get_current_sobject() if current.is_insert(): widget = Widget() parent_key = self.get_option('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) if parent: widget.add(SpanWdg(parent.get_code())) else: # use the project as the parent parent = Project.get() widget.add(SpanWdg("Project: %s" % parent.get_code())) #raise TacticException('Task creation aborted since parent is undetermined. Please check the configuration that generates this table.') text = HiddenWdg(self.get_input_name()) text.set_option('size','40') text.set_value(parent_key) widget.add(text) return widget else: search_type = current.get_value('search_type') if not search_type: return "No parent type" widget = Widget() parent = current.get_parent() if parent: widget.add(parent.get_code()) return widget # What is this look up code for? text = TextWdg(self.get_input_name()) behavior = { 'type': 'keyboard', 'kbd_handler_name': 'DgTableMultiLineTextEdit' } text.add_behavior(behavior) widget.add(text) icon = IconButtonWdg("Look up", IconWdg.ZOOM) icon.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var options = { title: '%s', class_name: 'tactic.ui.panel.ViewPanelWdg' }; var args = { search_type: '%s', view: 'list' }; spt.popup.get_widget( {}, {options: options, args: args} ); ''' % (search_type, search_type) } ) widget.add(icon) return widget
def get_display(my): top_wdg = DivWdg() top_wdg.add_style("color: black") top_wdg.add_style("width: 350px") top_wdg.add_style("margin-top: 10px") top_wdg.add_style("padding: 10px") top_wdg.add_border() title = DivWdg() title.add_style("color: black") title.add_style("margin-top: -22px") top_wdg.add(title) #if not my.name_string: # title.add('No database column') # return top_wdg title.add("Widget Definition") widget_types = { 'foreign_key': 'tactic.ui.table.ForeignKeyElementWdg', 'button': 'tactic.ui.table.ButtonElementWdg', 'expression': 'tactic.ui.table.ExpressionElementWdg' } web = WebContainer.get_web() config_string = web.get_form_value("config_xml") if not config_string: config_string = '<config/>' xml = Xml() xml.read_string(config_string) #print "config_string: ", config_string # get values from the config file element_name = xml.get_value('element/@name') config = WidgetConfig.get( view='element', xml='<config><element>%s</element></config>' % config_string) display_options = config.get_display_options(element_name) title = xml.get_value('element/@title') display_handler = xml.get_value('element/display/@class') if not display_handler: display_handler = 'tactic.ui.panel.TypeTableElementWdg' widget_name = xml.get_value('element/display/@widget') if not widget_name: widget_name = 'custom' custom_table = Table() custom_table.add_style("color: black") top_wdg.add(custom_table) name_text = DivWdg() name_text.add_style("color: black") name_text.add(element_name) custom_table.add_row() custom_table.add_cell("Name: ") custom_table.add_cell(name_text) # add title custom_table.add_row() title_wdg = TextWdg("custom_title") title_wdg.set_value(title) title_wdg.add_attr("size", "50") custom_table.add_cell("Title: ") custom_table.add_cell(title_wdg) # add description #custom_table.add_row() #description_wdg = TextAreaWdg("custom_description") #td = custom_table.add_cell( "Description: " ) #td.add_style("vertical-align: top") #custom_table.add_cell( description_wdg ) type_select = SelectWdg("custom_type") #type_select.add_empty_option("-- Select --") type_select.set_option( "values", "string|integer|float|boolean|currency|date|foreign_key|link|list|button|custom" ) type_select.set_option( "labels", "String(db)|Integer(db)|Float(db)|Boolean(db)|Currency(db)|Date(db)|Foreign Key|Link|List|Button|Custom" ) type_select.set_value(widget_name) #type_select.set_option("values", "string|integer|float|boolean|currency|date|link|list|foreign_key|button|empty") #type_select.set_option("labels", "String|Integer|Float|Boolean|Currency|Date|Link|List|Foreign Key|Button|Empty") custom_table.add_row() td = custom_table.add_cell("Widget Type: ") td.add_style("vertical-align: top") td = custom_table.add_cell(type_select) type_select.add_event( "onchange", "spt.CustomProject.property_type_select_cbk(this)") td.add(HtmlElement.br()) display_handler_text = TextWdg("display_handler") display_handler_text.add_attr("size", "50") display_handler_text.set_value(display_handler) td.add(display_handler_text) # extra info for foreign key custom_table.add_row() div = DivWdg() div.add_class("foreign_key_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # extra info for foreign key custom_table.add_row() div = DivWdg() div.add_class("foreign_key_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Relate to: ") search_type_select = SearchTypeSelectWdg( "foreign_key_search_select", mode=SearchTypeSelectWdg.CURRENT_PROJECT) div.add(search_type_select) td.add(div) # extra info for list custom_table.add_row() div = DivWdg() div.add_class("list_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Values: ") search_type_text = TextWdg("list_values") div.add(search_type_text) td.add(div) # extra info for button custom_table.add_row() div = DivWdg() div.add_style("color: black") div.add_class("button_options") div.add_style("display: none") div.add_style("margin-top: 10px") #class_path = "tactic.ui.table.ButtonElementWdg" class_path = display_handler button = Common.create_from_class_path(class_path) args_keys = button.get_args_keys() div.add("Options") div.add(HtmlElement.br()) for key in args_keys.keys(): option_name_text = HiddenWdg("option_name") option_name_text.set_value(key) div.add(option_name_text) div.add("%s: " % key) div.add(" ") input = button.get_input_by_arg_key(key) value = display_options.get(key) if value: input.set_value(value) div.add(input) div.add(HtmlElement.br()) td.add(div) # is searchable checkbox #custom_table.add_row() #current_searchable_wdg = CheckboxWdg("is_searchable") #current_view_wdg.set_checked() #custom_table.add_cell("Searchable? ") #td = custom_table.add_cell(current_searchable_wdg) custom_table.close_tbody() return top_wdg
class DropElementWdg(SimpleTableElementWdg): ARGS_KEYS = { 'accepted_drop_type': { 'description': 'This will enforce the SType that can be accepted on this drop', 'category': 'Options', 'order': 1 }, 'cbjs_drop_action': { 'description': 'Custom javascript callback to call when a drop has occured. This is optional', 'type': 'TextAreaWdg', 'category': 'Options', 'order': 3 }, 'instance_type': { 'description': 'The SType name for the table that carries out the association', 'category': 'Options', 'order': 2 }, 'display_expr': { 'description': 'Display Expression for the dropped item. e.g. @GET(.code)', 'category': 'Options', 'order': 4 } #'cbpy_drop_action': 'Custom python callback when save is done' } """ def get_args_keys(cls): return cls.ARGS_KEYS get_args_keys = classmethod(get_args_keys) """ def get_width(self): return 150 def _get_sorted_instances(self): sobject = self.get_current_sobject() instance_type = self.get_option("instance_type") instances = sobject.get_related_sobjects(instance_type) # sorting now name_dict ={} for inst in instances: name_dict[inst] = inst.get_display_value() return sorted(instances, key=name_dict.__getitem__) def is_editable(cls): return False is_editable = classmethod(is_editable) def handle_layout_behaviors(self, layout): #self.menu.set_activator_over(layout, "spt_drop_item") #self.menu.set_activator_out(layout, "spt_drop_item") layout.add_behavior( { 'type': 'load', 'cbjs_action': get_onload_js() } ) def handle_td(self, td): # FIXME: this is some hackery borrowed from the work to make gantt widget not commit on change # ... need to clean this up at some point! version = self.parent_wdg.get_layout_version() if version != "2": td.add_attr('spt_input_type', 'gantt') td.add_class("spt_input_inline") super(DropElementWdg, self).handle_td(td) def get_value_wdg(self): return self.value_wdg def handle_tr(self, tr): # define the drop zone version = self.parent_wdg.get_layout_version() def handle_th(self, th, wdg_idx=None): th.add_attr('spt_input_type', 'inline') """ # handle finger menu self.top_class = "spt_drop_element_menu" from tactic.ui.container import MenuWdg, MenuItem self.menu = MenuWdg(mode='horizontal', width = 25, height=20, top_class=self.top_class) menu_item = MenuItem('action', label=IconWdg("Add User", IconWdg.ADD)) self.menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' ''' } ) widget = DivWdg() widget.add_class(self.top_class) widget.add_styles('position: absolute; display: none; z-index: 1000') widget.add(self.menu) th.add(widget) """ """ FIXME: Waiting until this is implemented def handle_th(self, th, wdg_idx=None): from tactic.ui.container import MenuWdg, MenuItem self.menu = MenuWdg(mode='horizontal', width = 40) th.add(self.menu) menu_item = MenuItem('action', label='delete') self.menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': '''alert('cow');''' } ) menu_item = MenuItem('action', label='kill') self.menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': '''alert('cow');''' } ) """ def add_drop_behavior(self, widget, accepted_search_type=''): js_callback = self.get_option("cbjs_drop_action") if not js_callback: js_callback = 'spt.drop.sobject_drop_action(evt,bvr)' py_callback = self.get_option("cbpy_drop_action") #assert(py_callback) # define the drop zone widget.set_attr('SPT_ACCEPT_DROP', 'DROP_ROW') widget.add_behavior( { 'type': 'accept_drop', 'drop_code': 'DROP_ROW', 'accepted_search_type': accepted_search_type, 'cbjs_action': js_callback, 'cbpy_action': py_callback, } ) widget.add_behavior( { 'type': 'mouseleave', 'cbjs_action': ''' var orig_border_color = bvr.src_el.getAttribute('orig_border_color'); var orig_border_style = bvr.src_el.getAttribute('orig_border_style'); bvr.src_el.setStyle('border-color', orig_border_color) bvr.src_el.setStyle('border-style', orig_border_style) ''' }) def get_text_value(self): sorted_instances = self._get_sorted_instances() names = '' for inst in sorted_instances: names += '%s ' % inst.get_display_value() return names def get_display(self): self.display_expr = self.kwargs.get('display_expr') self.values = [] instance_type = self.get_option("instance_type") accepted_type = self.get_option("accepted_drop_type") div = DivWdg() div.add_class("spt_drop_element_top") div.add_style("width: 100%") div.add_style("min-height: 70px") div.add_style("height: auto") div.add_style("min-width: 100px") div.add_style("max-height: 300px") div.add_style("overflow-y: auto") div.add_style("overflow-x: hidden") self.value_wdg = HiddenWdg(self.get_name()) self.value_wdg.add_class("spt_drop_element_value") div.add( self.value_wdg ) version = self.parent_wdg.get_layout_version() #if version != "2": self.add_drop_behavior(div, accepted_type) # add the hidden div which holds containers info for the sobject template_div = DivWdg() template_div.add_style("display: none") template_item = self.get_item_div(None) # float left for the new icon beside it item_div = template_item.get_widget('item_div') #item_div.add_style('float: left') template_item.add_class("spt_drop_template") new_icon = IconWdg("New", IconWdg.NEW) new_icon.add_style('padding-left','3px') #TODO: insert the new_icon at add(new_icon, index=0) and make sure # the js-side sobject_drop_action cloning align the template div properly #template_item.add(new_icon) template_div.add(template_item) div.add(template_div) content_div = DivWdg() div.add(content_div) content_div.add_class("spt_drop_content") if instance_type: instance_wdg = self.get_instance_wdg(instance_type) content_div.add(instance_wdg) return div def get_instance_wdg(self, instance_type): sorted_instances = self._get_sorted_instances() content_div = Widget() for instance in sorted_instances: item_div = self.get_item_div(instance) item_div.add_attr( "spt_search_key", SearchKey.get_by_sobject(instance) ) item_div.add_class("spt_drop_item") # no need for that #item_div.add(' ') content_div.add(item_div) value_wdg = self.get_value_wdg() json = jsondumps(self.values) json = json.replace('"', '"') value_wdg.set_value(json) return content_div def get_item_div(self, sobject): ''' get the item div the sobject''' top = DivWdg() top.add_style("padding: 3px 2px") top.add_class("spt_drop_item") top.add_class("SPT_DROP_ITEM") item_div = DivWdg() top.add(item_div, "item_div") item_div.add_style("text-overflow: ellipsis") item_div.add_style("white-space: nowrap") item_div.add_style("width: 80%") item_div.add_attr('title','Click to remove') item_div.add_style("display", "inline-block") item_div.add_style("vertical-align", "top") item_div.add_style("overflow", "hidden") icon_div = DivWdg() top.add(icon_div) icon = IconWdg(icon="BS_REMOVE") icon_div.add(icon) icon_div.add_behavior( { 'type': 'click_up', #'cbjs_action': '''spt.dg_table_action.sobject_drop_remove(evt,bvr)''' 'cbjs_action': '''spt.drop.sobject_drop_remove(evt,bvr)''' } ) icon.add_style("opacity: 0.3") icon_div.add_class("hand") icon_div.add_style("display", "inline-block") icon_div.add_style("vertical-align", "top") #icon_div.add_border() #self.menu.set_over(item_div, event="mousein") #self.menu.set_out(top, event="mouseleave") # set this as the place for the display value to go item_div.add_class("spt_drop_display_value") add_icon = True ExpressionParser.clear_cache() if sobject: if add_icon: self._add_icon(sobject, item_div) if self.display_expr: display_value = Search.eval(self.display_expr, sobjects = sobject, single=True) else: display_value = sobject.get_display_value() if isinstance(display_value, list): display_value = display_value[0] item_div.add( display_value ) self.values.append( SearchKey.get_by_sobject(sobject) ) return top def _add_icon(self, sobject, item_div): '''add icon to the item_div''' if sobject.get_base_search_type() == 'sthpw/login_in_group': icon = IconWdg(icon=IconWdg.USER) item_div.add(icon)
def get_display(self): top = self.top top.add_class("spt_input_top") top.add_style("position: relative") top.add_style("width: 150px") top.add_style("margin-top: -1px") top.add_style("margin-left: -1px") top.add_color("background", "background", -20) top.add_border() title = "Big" div = DivWdg() top.add(div) icon_div = DivWdg() div.add(icon_div) icon_div.add_style("width: 20px") icon_div.add_style("height: 21px") icon_div.add_style("padding-left: 3px") icon_div.add_style("margin: -3 6 0 -3") icon_div.add_color("background", "background", [+15, 0, 0]) icon_div.add_style("float: left") icon_div.add_style("opacity: 0.5") icon = IconWdg("Select", IconWdg.FILM) icon_div.add(icon) div.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_input_top"); var content = spt.get_element( top, ".spt_input_content"); spt.toggle_show_hide(content); spt.body.add_focus_element(content); content.position(top); ''' }) div.add(title) div.add_class("hand") div.add_style("padding: 3px") #top.add( TextWdg("hello") ) select_div = DivWdg() top.add(select_div) select_div.add_style("position: absolute") select_div.add_class("spt_input_content") select_div.add_color("background", "background") select_div.add_style("top: 0px") select_div.add_style("left: 0px") select_div.add_style("display: none") select_div.add_style("z-index: 1000") select_div.set_box_shadow() select_div.add_border() select_div.add_class("SPT_PUW") for title in ("Big", "Fat", "Cow", "Horse", "Donkeys"): div = DivWdg() select_div.add(div) icon_div = DivWdg() div.add(icon_div) icon_div.add_style("width: 20px") icon_div.add_style("height: 21px") icon_div.add_style("margin: -3 6 0 -3") icon_div.add_color("background", "background", [+15, 0, 0]) icon_div.add_style("float: left") icon_div.add_style("opacity: 0.5") icon_div.add(" ") div.add(title) div.add_class("hand") div.add_style("padding: 3px") div.add_style("width: 100px") hover = div.get_color("background", [-30, -30, 20]) div.add_behavior({ 'type': 'hover', 'hover': hover, 'cbjs_action_over': ''' bvr.src_el.setStyle("background", bvr.hover); ''', 'cbjs_action_out': ''' bvr.src_el.setStyle("background", ""); ''' }) div.add_behavior({ 'type': 'click_up', 'value': title, 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); var top_el = spt.get_parent(bvr.src_el, ".spt_input_top"); var value_wdg = top_el.getElement(".spt_input_data"); var content = spt.get_parent(bvr.src_el, ".spt_input_content"); spt.hide(content); value_wdg.value = bvr.value; spt.dg_table.simple_edit_cell_cbk(top_el); ''' }) # generally, some real input widget is needed store and transport # the data input = HiddenWdg(self.get_input_name()) input.add_class("spt_input_data") input.add_class("SPT_NO_RESIZE") input.add_behavior({ 'type': 'change', 'cbjs_action': ''' var top_el = bvr.src_el.getParent(".spt_input_top"); var value_wdg = top_el.getElement(".spt_input_data"); spt.dg_table.edit.widget = top_el; spt.dg_table.inline_edit_cell_cbk( value_wdg ); ''' }) top.add(input) return top
def get_display(my): if not my.preprocessed: my.preprocess() if my.is_refresh: top = Widget() else: top = DivWdg() top.add_class("spt_work_hours_top") hidden = HiddenWdg('workhour_data') hidden.add_class('spt_workhour_data') header_data = {'start_date': str(my.start_date)} header_data = jsondumps(header_data).replace('"', """) hidden.set_value(header_data, set_form_value=False ) top.add(hidden) days = [] for date in my.dates: days.append( date.strftime("%Y_%m_%d") ) today = my.today.strftime("%Y_%m_%d") task = my.get_current_sobject() if not my.is_refresh: my.set_as_panel(top) entries = my.entries.get(task.get_code()) if isinstance(task, Task): parent = task.get_parent() if not parent: disabled = True else: disabled = False else: disabled = False if not entries: entries = {} table = Table() top.add(table) if my.use_straight_time: row_list = [my.ST_ROW] if my.show_overtime: row_list.append(my.OT_ROW) prefix_list = ['','ot'] else: row_list = [my.STT_ROW, my.ENT_ROW] prefix_list = ['stt','ent'] text = HiddenWdg(my.get_name() ) text.add_class("spt_data") table.add_color("color", "color") table.add_styles("width: %spx; float: left"%my.table_width) for row_to_draw in row_list: tr = table.add_row() tr.add_style('line-height','8px') td = table.add_blank_cell() offset_width = my.MONTH_WIDTH + my.LEFT_WIDTH+8 td.add_style("min-width: %spx" % offset_width) td.add(text) # go through each day and draw an input for overtime total_hours_st = 0 total_hours_ot = 0 search_key = task.get_search_key() # Add a label to indicate if the row is straight time or overtime time_prefix = '' if row_to_draw == my.OT_ROW: time_prefix = 'ot' div = DivWdg() div.add("OT") div.add_styles('text-align: right; margin-right: 4px') td.add(div) elif row_to_draw == my.STT_ROW: time_prefix = 'stt' div = DivWdg() div.add("ST") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) elif row_to_draw == my.ENT_ROW: time_prefix = 'ent' div = DivWdg() div.add("ET") div.add_styles('text-align: right; margin: 0 4px 4px 0') td.add(div) for idx, day in enumerate(days): day_wdg = DivWdg() day_wdg.add(day) td = table.add_cell() td.add_style("width: %spx" % my.day_width) text = TextWdg('%sday_%s' % (time_prefix, day)) if disabled: text.set_option('read_only','true') text.set_attr('disabled','disabled') td.add(text) text.add_class('spt_day%s' % (time_prefix)) text.add_styles("width: %spx;text-align: right;padding-left: 2px" %(my.day_width-2)) #text.add_styles("width: 100%;text-align: right;padding-left: 2px") if day == today: text.add_style("border: solid 1px black") else: text.add_border() week_day = my.weekday_dict[idx] if week_day in ['Sat','Sun']: # MAIN: Overtime, weekend if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[-15,0,5]) else: text.add_color("background", "background2", modifier= [0,15,20]) text.add_style("margin: 0px 1px") if row_to_draw == my.OT_ROW: text.add_attr('input_field_type', 'ot') else: text.add_attr('input_field_type', 'st') if my.kwargs.get('show_all_users')=='true': text.set_option('read_only','true') #TODO: while we may have multiple entries per task, we will only use the latest one here # for now, making the UI cleaner # if a corresponding entry exists, display its value entry_list_dict = entries.get(day) daily_sum = 0 value = 0 entry_list = [] if entry_list_dict: row_key = my.ROW_DICT.get(row_to_draw) entry_list = entry_list_dict.get(row_key) if entry_list: for entry in entry_list: # Check if there is something in the category column. category = entry.get_value("category") if row_to_draw == my.OT_ROW: # Skip if the category field does not have a 'ot' indicated. if not category: print "Warning this work_hour entry has no category [%s]" % entry.get_code() continue # Check if there exist a value in the straight_time column value, delta = my.get_time_value(entry, row_to_draw) if value: text.set_value(value) text.add_attr('orig_input_value', value) if row_to_draw == my.OT_ROW: total_hours_ot += float(delta) else: total_hours_st += float(delta) daily_sum += delta # we only use value instead of the sum "daily_sum" for now if row_to_draw == my.OT_ROW: my.summary_ot[idx].update({search_key: daily_sum}) else: my.summary_st[idx].update({search_key: daily_sum}) script = ''' var orig_value = bvr.src_el.getAttribute("orig_input_value"); var input_field_type = bvr.src_el.getAttribute("input_field_type"); bvr.src_el.value = bvr.src_el.value.strip(); if (bvr.src_el.value == '') { if (orig_value) { bvr.src_el.value = 0; } else { return; } } else if (bvr.src_el.value == orig_value) { return; } bvr.prefix_list.splice( bvr.prefix_list.indexOf(bvr.time_prefix),1) var other_time_prefix = bvr.prefix_list[0]; spt.work_hour.update_total(bvr, '.spt_day' + bvr.time_prefix); // register this as changed item var all_top_el = bvr.src_el.getParent(".spt_work_hours_top"); var values1 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ bvr.time_prefix, false); var values2 = spt.api.Utility.get_input_values(all_top_el, '.spt_day'+ other_time_prefix, false); // Merge values from straight time and overtime fields in values variable. for (var attr in values2) { values1[attr] = values2[attr]; } for (val in values1) { if (values1[val] && isNaN(values1[val])) { spt.error('You have non-numeric values in your work hours. Please correct it: ' + values[val]); return; } } delete values1.data; var value_wdg = all_top_el.getElement(".spt_data"); var value = JSON.stringify(values1); value_wdg.value = value; var layout = bvr.src_el.getParent(".spt_layout"); var version = layout.getAttribute("spt_version"); if (version == "2") { spt.table.set_layout(layout); spt.table.accept_edit(all_top_el, value, false); } else { var cached_data = {}; spt.dg_table.edit.widget = all_top_el; spt.dg_table.inline_edit_cell_cbk( value_wdg, cached_data ); } ''' # accept on pressing Enter behavior = { 'type': 'keydown', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' if (evt.key=='enter') { %s } '''%script} text.add_behavior(behavior) behavior = { 'type': 'blur', 'time_prefix': time_prefix, 'prefix_list': prefix_list, 'cbjs_action': ''' %s '''%script} text.add_behavior(behavior) text = TextWdg("total") td = table.add_cell(text) td.add_style("width: 35px") text.add_border() text.add_attr('spt_total', '.spt_total%s' % (time_prefix)) text.add_class('spt_total%s' % (time_prefix)) text.add_styles("width: %spx; text-align: right; padding-right: 3px"%my.day_width) text.set_attr("readonly", "readonly") # MAIN: Overtime, total. if row_to_draw == my.OT_ROW: text.add_color("background", "background2", modifier=[5,-15,0]) if total_hours_ot: text.set_value("%0.1f" % total_hours_ot) my.summary_ot[7].update({search_key: total_hours_ot}) else: text.add_color("background", "background2", modifier=[20,0,15]) if total_hours_st: text.set_value("%0.1f" % total_hours_st) my.summary_st[7].update({search_key: total_hours_st}) td = table.add_blank_cell() td.add_style('width: 100%') return top
def get_display(my): top = my.top top.add_class("spt_upload_top") title = my.kwargs.get("title") name = my.kwargs.get("name") if not name: name = "upload" if not title: title = Common.get_display_title(name) search_key = my.kwargs.get("search_key") hidden = HiddenWdg(name) top.add(hidden) multiple = my.kwargs.get("multiple") if multiple in [True, 'true']: multiple = True else: multiple = False if my.upload_id: upload_id = my.upload_id else: upload = Html5UploadWdg(name=name, multiple=multiple) top.add(upload) upload_id = upload.get_upload_id() from tactic.ui.widget import ActionButtonWdg button = ActionButtonWdg(title=title) button_id = my.kwargs.get("id") if button_id: button.set_id(button_id) top.add(button) upload_init = my.kwargs.get("upload_init") if not upload_init: upload_init = "" upload_start = my.kwargs.get("upload_start") if not upload_start: upload_start = ''' var top = bvr.src_el.getParent(".spt_upload_top"); var hidden = top.getElement(".spt_input"); var file = spt.html5upload.get_file(); if (!file) { return; } hidden.value = file.name; ''' on_complete = my.get_on_complete() if not on_complete: on_complete = ''' var files = spt.html5upload.get_files(); if (files.length == 0) { alert('Error: files cannot be found.') spt.app_busy.hide(); return; } spt.notify.show_message("Uploaded "+files.length+" files"); spt.app_busy.hide(); ''' upload_progress = my.kwargs.get("upload_progress") if not upload_progress: upload_progress = ''' var percent = Math.round(evt.loaded * 100 / evt.total); spt.app_busy.show("Uploading ["+percent+"%% complete]"); ''' reader_load = my.kwargs.get("reader_load") if not reader_load: reader_load = "" button.add_behavior({ 'type': 'click_up', 'upload_id': upload_id, 'search_key': search_key, 'ticket': my.ticket, 'multiple': multiple, 'kwargs': my.on_complete_kwargs, 'cbjs_action': ''' var search_key = bvr.search_key; // set the form if (!spt.html5upload.form) { spt.html5upload.set_form( $(bvr.upload_id) ); } spt.html5upload.clear(); spt.html5upload.kwargs = bvr.kwargs; var file_obj = spt.html5upload.form.getElement(".spt_file"); var is_multiple = bvr.multiple == true; var upload_start = function(evt) { %s; } var upload_progress = function(evt) { %s; } // set an action for completion var upload_complete = function(evt) { %s; spt.app_busy.hide(); } var reader_load = function(file) { %s; } var upload_file_kwargs = { reader_load: reader_load, upload_start: upload_start, upload_complete: upload_complete, upload_progress: upload_progress }; if (bvr.ticket) upload_file_kwargs['ticket'] = bvr.ticket; var onchange = function () { %s; spt.html5upload.upload_file(upload_file_kwargs); } if (is_multiple) { file_obj.setAttribute('multiple','multiple'); spt.html5upload.select_files(onchange); } else spt.html5upload.select_file(onchange); ''' % (upload_start, upload_progress, on_complete, reader_load, upload_init) }) return top
def get_display(self): top_wdg = DivWdg() top_wdg.add_style("color: black") top_wdg.add_style("width: 350px") top_wdg.add_style("margin-top: 10px") top_wdg.add_style("padding: 10px") top_wdg.add_border() title = DivWdg() title.add_style("color: black") title.add_style("margin-top: -22px") top_wdg.add(title) #if not self.name_string: # title.add('No database column') # return top_wdg title.add("Widget Definition") widget_types = { 'foreign_key': 'tactic.ui.table.ForeignKeyElementWdg', 'button': 'tactic.ui.table.ButtonElementWdg', 'expression': 'tactic.ui.table.ExpressionElementWdg' } web = WebContainer.get_web() config_string = web.get_form_value("config_xml") if not config_string: config_string = '<config/>' xml = Xml() xml.read_string(config_string) #print "config_string: ", config_string # get values from the config file element_name = xml.get_value('element/@name') config = WidgetConfig.get(view='element',xml='<config><element>%s</element></config>' % config_string) display_options = config.get_display_options(element_name) title = xml.get_value('element/@title') display_handler = xml.get_value('element/display/@class') if not display_handler: display_handler = 'tactic.ui.panel.TypeTableElementWdg' widget_name = xml.get_value('element/display/@widget') if not widget_name: widget_name = 'custom' custom_table = Table() custom_table.add_style("color: black") top_wdg.add(custom_table) name_text = DivWdg() name_text.add_style("color: black") name_text.add(element_name) custom_table.add_row() custom_table.add_cell("Name: ") custom_table.add_cell(name_text) # add title custom_table.add_row() title_wdg = TextWdg("custom_title") title_wdg.set_value(title) title_wdg.add_attr("size", "50") custom_table.add_cell( "Title: " ) custom_table.add_cell( title_wdg ) # add description #custom_table.add_row() #description_wdg = TextAreaWdg("custom_description") #td = custom_table.add_cell( "Description: " ) #td.add_style("vertical-align: top") #custom_table.add_cell( description_wdg ) type_select = SelectWdg("custom_type") #type_select.add_empty_option("-- Select --") type_select.set_option("values", "string|integer|float|boolean|currency|date|foreign_key|link|list|button|custom") type_select.set_option("labels", "String(db)|Integer(db)|Float(db)|Boolean(db)|Currency(db)|Date(db)|Foreign Key|Link|List|Button|Custom") type_select.set_value(widget_name) #type_select.set_option("values", "string|integer|float|boolean|currency|date|link|list|foreign_key|button|empty") #type_select.set_option("labels", "String|Integer|Float|Boolean|Currency|Date|Link|List|Foreign Key|Button|Empty") custom_table.add_row() td = custom_table.add_cell("Widget Type: ") td.add_style("vertical-align: top") td = custom_table.add_cell(type_select) type_select.add_event("onchange", "spt.CustomProject.property_type_select_cbk(this)") td.add(HtmlElement.br()) display_handler_text = TextWdg("display_handler") display_handler_text.add_attr("size", "50") display_handler_text.set_value(display_handler) td.add(display_handler_text) # extra info for foreign key custom_table.add_row() div = DivWdg() div.add_class("foreign_key_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # extra info for foreign key custom_table.add_row() div = DivWdg() div.add_class("foreign_key_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Relate to: ") search_type_select = SearchTypeSelectWdg("foreign_key_search_select", mode=SearchTypeSelectWdg.CURRENT_PROJECT) div.add(search_type_select) td.add(div) # extra info for list custom_table.add_row() div = DivWdg() div.add_class("list_options") div.add_style("display: none") div.add_style("margin-top: 10px") div.add("Options") div.add(HtmlElement.br()) # TODO: this class should not be in prod!! from pyasm.prod.web import SearchTypeSelectWdg div.add("Values: ") search_type_text = TextWdg("list_values") div.add(search_type_text) td.add(div) # extra info for button custom_table.add_row() div = DivWdg() div.add_style("color: black") div.add_class("button_options") div.add_style("display: none") div.add_style("margin-top: 10px") #class_path = "tactic.ui.table.ButtonElementWdg" class_path = display_handler button = Common.create_from_class_path(class_path) args_keys = button.get_args_keys() div.add("Options") div.add(HtmlElement.br()) for key in args_keys.keys(): option_name_text = HiddenWdg("option_name") option_name_text.set_value(key) div.add(option_name_text) div.add("%s: " % key) div.add(" ") input = button.get_input_by_arg_key(key) value = display_options.get(key) if value: input.set_value(value) div.add(input) div.add(HtmlElement.br()) td.add(div) # is searchable checkbox #custom_table.add_row() #current_searchable_wdg = CheckboxWdg("is_searchable") #current_view_wdg.set_checked() #custom_table.add_cell("Searchable? ") #td = custom_table.add_cell(current_searchable_wdg) custom_table.close_tbody() return top_wdg
def get_display(my): top = my.top view = my.kwargs.get("view") top.add_class("spt_help_edit_content") search = Search("config/widget_config") search.add_filter("category", "HelpWdg") search.add_filter("view", view) sobject = search.get_sobject() if not sobject: value = "" search_key = "" else: xml_value = sobject.get_xml_value("config") value = xml_value.get_value("config/%s/html/div" % (view)) search_key = sobject.get_search_key() title_wdg = DivWdg() top.add(title_wdg) title_wdg.add("<b>View: %s</b>" % view) title_wdg.add_style("font-style: bold") title_wdg.add_style("padding: 5px") title_wdg.add_gradient("background", "background", 0, -10) hidden = HiddenWdg("view") top.add(hidden) hidden.set_value(view) text = TextAreaWdg("content") text_id = text.set_unique_id() text.set_value(value) from tactic.ui.widget import ActionButtonWdg if sobject: delete_button = ActionButtonWdg(title="Delete") top.add(delete_button) delete_button.add_style("float: right") delete_button.add_style("margin-top: -3px") delete_button.add_behavior({ 'type': 'click_up', 'search_key': search_key, 'cbjs_action': ''' if (!confirm("Are you sure you wish to delete this help page?")) { return; } var server = TacticServerStub.get(); server.delete_sobject(bvr.search_key); var top = bvr.src_el.getParent(".spt_help_edit_top"); spt.panel.refresh(top); ''' }) test_button = ActionButtonWdg(title="Preview") top.add(test_button) test_button.add_style("float: right") test_button.add_style("margin-top: -3px") test_button.add_behavior({ 'type': 'click_up', 'text_id': text_id, 'cbjs_action': ''' var js_file = "ckeditor/ckeditor.js"; var url = "/context/spt_js/" + js_file; var js_el = document.createElement("script"); js_el.setAttribute("type", "text/javascript"); js_el.setAttribute("src", url); var head = document.getElementsByTagName("head")[0]; head.appendChild(js_el); var cmd = "CKEDITOR.instances." + bvr.text_id + ".getData()"; var text_value = eval( cmd ); bvr.options = {}; bvr.options.html = text_value; spt.named_events.fire_event("show_help", bvr) ''' }) save_button = ActionButtonWdg(title="Save") top.add(save_button) save_button.add_style("float: right") save_button.add_style("margin-top: -3px") top.add("<br/>") save_button.add_behavior({ 'type': 'click_up', 'text_id': text_id, 'cbjs_action': ''' spt.app_busy.show("Saving Help", " ") var top = bvr.src_el.getParent(".spt_help_edit_content"); var values = spt.api.Utility.get_input_values(top, null, false); var cmd = "CKEDITOR.instances." + bvr.text_id + ".getData()"; var text_value = eval( cmd ); values.content = text_value; var command = "tactic.ui.app.HelpEditCbk"; var kwargs = values; var server = TacticServerStub.get(); server.execute_cmd(command, kwargs); setTimeout("spt.app_busy.hide()", 200) ''' }) #top.add("Style: ") #select = SelectWdg("style") #top.add(select) #select.set_option("values", "text|html") top.add("<br/>") top.add(text) text.set_value(value) text.add_style("width: 100%") text.add_style("height: 100%") text.add_style("min-height: 500px") text.add_style("display: none") text.add_behavior({ 'type': 'load', 'color': text.get_color("background", -10), 'text_id': text_id, 'cbjs_action': ''' var js_file = "ckeditor/ckeditor.js"; var url = "/context/spt_js/" + js_file; var js_el = document.createElement("script"); js_el.setAttribute("type", "text/javascript"); js_el.setAttribute("src", url); var head = document.getElementsByTagName("head")[0]; head.appendChild(js_el); setTimeout( function() { CKEDITOR.on( 'instanceReady', function( ev ) { ev.editor.dataProcessor.writer.indentationChars = ' '; }); var config = { toolbar: 'Full', uiColor: bvr.color, height: '500px' }; config.toolbar_Full = [ ['Source'], ['Cut','Copy','Paste'], ['Undo','Redo','-','Find','Replace'], ['Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], '/', ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['HorizontalRule','SpecialChar'], ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['Maximize', 'ShowBlocks'] ]; CKEDITOR.replace(bvr.text_id, config ); bvr.src_el.setStyle("display", ""); }, 500); ''' }) return top
def get_display(my): web = WebContainer.get_web() widget = DivWdg() widget.add_class("spt_search_limit_top") #widget.add_style("border", "solid 1px blue") widget.add_color("background", "background") widget.add_color("color", "color") widget.add_style("padding: 5px") hidden = HiddenWdg("prefix", my.prefix) widget.add(hidden) if not my.search and not my.sobjects: widget.add("No search or sobjects found") return widget # my.count should have been set in alter_search() # which can be called explicitly thru this instance, my. if not my.count: my.count = my.search.get_count(no_exception=True) # if my.sobjects exist thru inheriting from parent widgets # or explicitly set, (this is not mandatory though) if my.sobjects and len(my.sobjects) < my.search_limit: limit = len(my.sobjects) elif my.search and my.count < my.search_limit: # this is only true if the total result of the search is # less than the limit and so this wdg will not display limit = my.count else: limit = my.search_limit if not limit: limit = 50 my.search_limit = limit if my.refresh: prev = SpanWdg( IconButtonWdg("Prev", IconWdg.LEFT, False ) ) prev.add_style("margin-left: 8px") prev.add_style("margin-right: 6px") prev.add_style("margin-top: -2px") next = IconButtonWdg("Next", IconWdg.RIGHT, False, icon_pos="right" ) next.add_style("margin-left: 6px") prev.add_behavior( { 'type': 'click_up', 'cbjs_action': my.refresh_script } ) next.add_behavior( { 'type': 'click_up', 'cbjs_action': my.refresh_script } ) else: # the old code pre 2.5 prev = IconButtonWdg("Prev", IconWdg.LEFT, False ) hidden_name = my.prev_hidden_name hidden = HiddenWdg(hidden_name,"") prev.add(hidden) prev.add_event('onclick'," spt.api.Utility.get_input(document,'%s').value ='Prev';%s"\ %(hidden_name, my.refresh_script)) next = IconButtonWdg("Next", IconWdg.RIGHT, False, icon_pos="right" ) hidden_name = my.next_hidden_name hidden = HiddenWdg(hidden_name,"") next.add(hidden) next.add_event('onclick',"spt.api.Utility.get_input(document,'%s').value ='Next';%s" \ %(hidden_name, my.refresh_script)) showing_wdg = DivWdg() widget.add(showing_wdg) showing_wdg.add_style("padding: 10px") showing_wdg.add_style("margin: 10px") showing_wdg.add_color("background", "background", -5) showing_wdg.add_border() label_span = SpanWdg("Showing: ") showing_wdg.add(label_span) showing_wdg.add( prev ) # this min calculation is used so that if my.sobjects is not set # above for the calculation of the limit, which will make the last # set of range numbers too big left_bound = my.current_offset+1 if not limit: # prevent error in ItemsNavigatorWdg if a search encounters query error limit = 50 my.search_limit = limit right_bound = min(my.current_offset+limit, my.count) if left_bound > right_bound: left_bound = 1 current_value = "%d - %d" % (left_bound, right_bound) if my.style == my.SIMPLE: showing_wdg.add( current_value ) else: # add a range selector using ItemsNavigatorWdg from pyasm.widget import ItemsNavigatorWdg selector = ItemsNavigatorWdg(my.label, my.count, my.search_limit) selector.select.add_behavior( { 'type': 'change', 'cbjs_action': my.refresh_script } ) selector.set_style(my.style) selector.set_value(current_value) selector.set_display_label(False) showing_wdg.add( selector) showing_wdg.add( next ) #showing_wdg.add( " x ") showing_wdg.add(my.text) my.text.add_style("margin-top: -3px") my.text.set_attr("size", "1") my.text.add_attr("title", "Set number of items per page") widget.add("<hr/>") # set the limit set_limit_wdg = my.get_set_limit_wdg() widget.add(set_limit_wdg) from tactic.ui.widget.button_new_wdg import ActionButtonWdg button = ActionButtonWdg(title='Search') widget.add(button) button.add_style("float: right") button.add_style("margin-top: 8px") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var select = top.getElement(".spt_search_limit_select"); var value = select.value; if (value == 'Custom') { custom = top.getElement(".spt_search_limit_custom_text"); value = custom.value; } if (value == '') { value = 20; } var text = top.getElement(".spt_search_limit_text"); text.value = value; spt.dg_table.search_cbk({}, bvr) ''' } ) offset_wdg = HiddenWdg("%s_last_search_offset" %my.label) offset_wdg.set_value(my.current_offset) widget.add(offset_wdg) widget.add("<br clear='all'/>") return widget
def get_display(my): search_type_obj = SearchType.get(my.search_type) sobj_title = search_type_obj.get_title() my.color_mode = my.kwargs.get("color_mode") if not my.color_mode: my.color_mode = "default" top_div = my.top top_div.add_class("spt_edit_top") if not my.is_refresh: my.set_as_panel(top_div) content_div = DivWdg() content_div.add_class("spt_edit_top") content_div.add_class("spt_edit_form_top") content_div.set_attr("spt_search_key", my.search_key) if not Container.get_dict("JSLibraries", "spt_edit"): content_div.add_behavior( { 'type': 'load', 'cbjs_action': my.get_onload_js() } ) layout_view = my.kwargs.get("layout_view") if layout_view: layout_wdg = my.get_custom_layout_wdg(layout_view) content_div.add(layout_wdg) return content_div # add close listener # NOTE: this is an absolute search, but is here for backwards # compatibility content_div.add_named_listener('close_EditWdg', ''' var popup = bvr.src_el.getParent( ".spt_popup" ); if (popup) spt.popup.close(popup); ''') attrs = my.config.get_view_attributes() default_access = attrs.get("access") if not default_access: default_access = "edit" project_code = Project.get_project_code() security = Environment.get_security() base_key = search_type_obj.get_base_key() key = { 'search_type': base_key, 'project': project_code } access = security.check_access("sobject", key, "edit", default=default_access) if not access: my.is_disabled = True else: my.is_disabled = False disable_wdg = None if my.is_disabled: # TODO: This overlay doesn't work in IE, size, position, # and transparency all fail. disable_wdg = DivWdg(id='edit_wdg') disable_wdg.add_style("position: absolute") disable_wdg.add_style("height: 90%") disable_wdg.add_style("width: 100%") disable_wdg.add_style("left: 0px") #disable_wdg.add_style("bottom: 0px") #disable_wdg.add_style("top: 0px") disable_wdg.add_style("opacity: 0.2") disable_wdg.add_style("background: #fff") #disable_wdg.add_style("-moz-opacity: 0.2") disable_wdg.add_style("filter: Alpha(opacity=20)") disable_wdg.add("<center>EDIT DISABLED</center>") content_div.add(disable_wdg) attrs = my.config.get_view_attributes() inner = DivWdg() content_div.add(inner) menu = my.get_header_context_menu() menus = [menu.get_data()] menus_in = { 'HEADER_CTX': menus, } SmartMenu.attach_smart_context_menu( inner, menus_in, False ) table = Table() inner.add(table) if my.color_mode == "default": table.add_color("background", "background") elif my.color_mode == "transparent": table.add_style("background", "transparent") table.add_color("color", "color") width = attrs.get('width') if not width: width = my.kwargs.get("width") if not width: width = 600 table.add_style("width: %s" % width) height = attrs.get('height') if height: table.add_style("height: %s" % height) tr = table.add_row() show_header = my.kwargs.get("show_header") if show_header not in ['false', False]: my.add_header(table, sobj_title) single = my.kwargs.get("single") if single in ['false', False] and my.mode == 'insert': multi_div = DivWdg() multi_div.add_style("text-align: left") multi_div.add("Specify the number of items that will be added with this form:<br/><br/>") multi_div.add("<b># of new items to add: </b>") multi_div.add(" "*4) multi_text = TextWdg("multiplier") multi_text.add_style("width: 30px") multi_div.add(multi_text) tr, td = table.add_row_cell( multi_div ) if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1px") td.add_style("border-style: solid") td.add_style("padding: 8 3 8 3") td.add_color("background", "background3") td.add_color("color", "color3") security = Environment.get_security() # break the widgets up in columns num_columns = attrs.get('num_columns') if not num_columns: num_columns = my.kwargs.get('num_columns') if not num_columns: num_columns = 1 else: num_columns = int(num_columns) # go through each widget and draw it for i, widget in enumerate(my.widgets): # since a widget name called code doesn't necessariy write to code column, it is commented out for now """ key = { 'search_type' : search_type_obj.get_base_key(), 'column' : widget.get_name(), 'project': project_code} # check security on widget if not security.check_access( "sobject_column",\ key, "edit"): my.skipped_element_names.append(widget.get_name()) continue """ if not hasattr(widget, 'set_input_prefix'): msg = DivWdg("Warning: The widget definition for [%s] uses [%s] and is not meant for use in Edit Layout. Please revise the edit_definition in widget config."% (widget.get_name(), widget.__class__.__name__ )) msg.add_style('color: orange') content_div.add(msg) content_div.add(HtmlElement.br()) continue if my.input_prefix: widget.set_input_prefix(my.input_prefix) # Bootstrap widget.add_class("form-control") widget.add_style("width: 100%") class EditTitleWdg(BaseRefreshWdg): pass #if isinstance(widget, EditTitleWdg): """ has_title = True if has_title and i % 3 == 0: tr, td = table.add_row_cell() tr.add_color("background", "background", -5) td.add("TITLE") td.add_style("height", "30px") td.add_style("padding", "0px 10px") """ if isinstance(widget, HiddenWdg): content_div.add(widget) continue # Set up any validations configured on the widget ... from tactic.ui.app import ValidationUtil v_util = ValidationUtil( widget=widget ) v_bvr = v_util.get_validation_bvr() if v_bvr: if (isinstance(widget, CalendarInputWdg)): widget.set_validation( v_bvr.get('cbjs_validation'), v_bvr.get('validation_warning') ); else: widget.add_behavior( v_bvr ) widget.add_behavior( v_util.get_input_onchange_bvr() ) new_row = i % num_columns == 0 if new_row: tr = table.add_row() if my.color_mode == "default": if i % 2 == 0: tr.add_color("background", "background") else: tr.add_color("background", "background", -2 ) show_title = widget.get_option("show_title") if not show_title: show_title = my.kwargs.get("show_title") if show_title in ['false', False]: show_title = False else: show_title = True if show_title: title = widget.get_title() td = table.add_cell(title) td.add_style("padding: 10px 15px 10px 5px") td.add_style("vertical-align: top") title_width = my.kwargs.get("title_width") if title_width: td.add_style("width: %s" % title_width) else: td.add_style("width: 150px") security = Environment.get_security() if security.check_access("builtin", "view_site_admin", "allow"): SmartMenu.assign_as_local_activator( td, 'HEADER_CTX' ) if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) td.add_style("text-align: right" ) hint = widget.get_option("hint") if hint: #hint_wdg = HintWdg(hint) #hint_wdg.add_style("float: right") #td.add( hint_wdg ) td.add_attr("title", hint) if not show_title: th, td = table.add_row_cell( widget ) continue else: td = table.add_cell( widget ) #td = table.add_cell( widget.get_value() ) td.add_style("min-width: 300px") td.add_style("padding: 10px 15px 10px 5px") td.add_style("vertical-align: top") if my.color_mode == "default": td.add_color("border-color", "table_border", default="border") td.add_style("border-width: 1" ) td.add_style("border-style: solid" ) if not my.is_disabled and not my.mode == 'view': tr, td = table.add_row_cell( my.get_action_html() ) if my.input_prefix: prefix = HiddenWdg("input_prefix", my.input_prefix) tr, td = table.add_row_cell() td.add(prefix) top_div.add(content_div) return top_div
def get_display(my): my.search_key = my.kwargs.get("search_key") my.process = my.kwargs.get("process") my.sobject = Search.get_by_search_key(my.search_key) my.pipeline_code = my.kwargs.get("pipeline_code") top = DivWdg() top.add_class("spt_file_selector") top.add_style("position: relative") hidden = HiddenWdg("mode") #hidden = TextWdg("mode") hidden.add_class("spt_mode") top.add(hidden) top.add_style("padding: 5px") top.add_style("min-width: 500px") top.add_style("min-height: 400px") top.add_color("background", "background") top.add_color("color", "color") #top.add_border() logo_wdg = DivWdg() logo = HtmlElement.img(src="/context/icons/logo/perforce_logo.gif") logo_wdg.add(logo) top.add(logo_wdg) logo_wdg.add_style("opacity: 0.2") logo_wdg.add_style("position: absolute") logo_wdg.add_style("bottom: 0px") logo_wdg.add_style("right: 5px") # get some info from the config file """ client_env_var = Config.get_value("perforce", "client_env_var") if not client_env_var: client_env_var = "P4Client" port_env_var = Config.get_value("perforce", "port_env_var") if not port_env_var: port_env_var = "P4Port" user_env_var = Config.get_value("perforce", "user_env_var") if not user_env_var: user_env_var = "P4User" password_env_var = Config.get_value("perforce", "password_env_var") if not password_env_var: password_env_var = "P4Passwd" """ # {GET(sthpw/login)}_user host = "" client = "" user = "" password = "" port = "" project = my.sobject.get_project() depot = project.get_value("location", no_exception=True) if not depot: depot = "" top.add_behavior( { 'type': 'load', #'client_env_var': client_env_var, #'port_env_var': port_env_var, #'user_env_var': user_env_var, #'password_env_var': password_env_var, 'client': client, 'user': user, 'password': password, 'host': host, 'port': port, 'depot': depot, 'cbjs_action': get_onload_js() } ) list_wdg = DivWdg() top.add(list_wdg) list_wdg.add_style("height: 32px") from tactic.ui.widget import SingleButtonWdg, ButtonNewWdg, ButtonRowWdg button_row = ButtonRowWdg() list_wdg.add(button_row) button_row.add_style("float: left") button = ButtonNewWdg(title="Refresh", icon=IconWdg.REFRESH, long=False) button_row.add(button) button.add_style("float: left") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.app_busy.show("Reading file system ...") var top = bvr.src_el.getParent(".spt_checkin_top"); spt.panel.refresh(top); spt.app_busy.hide(); ''' } ) button = ButtonNewWdg(title="Check-out", icon=IconWdg.CHECK_OUT, long=False) button_row.add(button) my.sandbox_dir = my.kwargs.get("sandbox_dir") # what are we trying to do here??? #my.root_sandbox_dir = Environment.get_sandbox_dir() #project = my.sobject.get_project() #my.root_sandbox_dir = "%s/%s" % (my.root_sandbox_dir, project.get_code()) #repo_dir = my.sandbox_dir.replace("%s/" % my.root_sandbox_dir, "") #repo_dir = "%s/%s" % (project.get_code(), repo_dir) # checkout command requires either starting with //<depot>/ or just # the relative path to the root. The following removes # the root of the sandbox folder assuming that this is mapped # to the base of the depot my.root_sandbox_dir = Environment.get_sandbox_dir() repo_dir = my.sandbox_dir repo_dir = my.sandbox_dir.replace("%s/" % my.root_sandbox_dir, "") #button.add_style("padding-right: 14px") button.add_style("float: left") button.add_behavior( { 'type': 'click_up', 'repo_dir': repo_dir, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_checkin_top"); spt.app_busy.show("Reading file system ...") var data = spt.scm.checkout(bvr.repo_dir) spt.panel.refresh(top); spt.app_busy.hide(); ''' } ) button = ButtonNewWdg(title="Perforce Actions", icon=IconWdg.PERFORCE, show_arrow=True) #button.set_show_arrow_menu(True) button_row.add(button) menu = Menu(width=220) menu_item = MenuItem(type='title', label='Perforce') menu.add(menu_item) menu_item = MenuItem(type='action', label='Show Workspaces') menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var activator = spt.smenu.get_activator(bvr); var class_name = 'tactic.ui.checkin.WorkspaceWdg'; var top = activator.getParent(".spt_checkin_top"); var content = top.getElement(".spt_checkin_content"); var el = top.getElement(".spt_mode"); el.value = "workspace"; var kwargs = {}; spt.panel.load(content, class_name, kwargs); ''' } ) menu_item = MenuItem(type='action', label='Show Changelists') menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var activator = spt.smenu.get_activator(bvr); var class_name = 'tactic.ui.checkin.ChangelistWdg'; var top = activator.getParent(".spt_checkin_top"); var content = top.getElement(".spt_checkin_content"); var el = top.getElement(".spt_mode"); el.value = "changelist"; var kwargs = {}; spt.panel.load(content, class_name, kwargs); ''' } ) menu_item = MenuItem(type='action', label='Show Branches') menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var activator = spt.smenu.get_activator(bvr); var class_name = 'tactic.ui.checkin.branch_wdg.BranchWdg'; var top = activator.getParent(".spt_checkin_top"); var content = top.getElement(".spt_checkin_content"); var el = top.getElement(".spt_mode"); el.value = "branch"; var kwargs = {}; spt.panel.load(content, class_name, kwargs); ''' } ) menu_item = MenuItem(type='title', label='Actions') menu.add(menu_item) menu_item = MenuItem(type='action', label='Add New Changelist') menu.add(menu_item) menu_item.add_behavior( { 'type': 'load', 'cbjs_action': ''' var activator = spt.smenu.get_activator(bvr); spt.scm.run("add_changelist", ["New Changelist"]); var class_name = 'tactic.ui.checkin.ChangelistWdg'; var top = activator.getParent(".spt_checkin_top"); var content = top.getElement(".spt_checkin_content"); spt.panel.load(content, class_name); ''' } ) menu_item = MenuItem(type='separator') menu.add(menu_item) menu_item = MenuItem(type='action', label='Sign Out of Perforce') menu.add(menu_item) menu_item.add_behavior( { 'type': 'load', 'cbjs_action': ''' if (!confirm("Are you sure you wish to sign out of Perforce?")) { return; } spt.scm.host = null; spt.scm.user = null; spt.scm.password = null; var activator = spt.smenu.get_activator(bvr); var top = activator.getParent(".spt_checkin_top"); spt.panel.refresh(top); ''' } ) #SmartMenu.add_smart_menu_set( button.get_arrow_wdg(), { 'BUTTON_MENU': menu } ) #SmartMenu.assign_as_local_activator( button.get_arrow_wdg(), "BUTTON_MENU", True ) SmartMenu.add_smart_menu_set( button.get_button_wdg(), { 'BUTTON_MENU': menu } ) SmartMenu.assign_as_local_activator( button.get_button_wdg(), "BUTTON_MENU", True ) # Perforce script editor. (nice because it should run as the user # in the appopriate environment """ button = ButtonNewWdg(title="P4 Script Editor", icon=IconWdg.CREATE, show_arrow=True) #button_row.add(button) button.add_style("padding-right: 14px") button.add_style("float: left") """ button = ButtonNewWdg(title="Changelists Counter", icon=IconWdg.CHECK_OUT_SM, show_arrow=True) #button_row.add(button) #button.add_style("padding-right: 14px") button.add_style("float: left") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' // find any changelists that were missed var changelists = spt.scm.run("get_changelists", []); for (var i = 0; i < changelists.length; i++) { var changelist = changelists[i]; var info = spt.scm.run("get_changelist_info",[changelist.change]); console.log(info); } ''' } ) # Hiding this for now button = ButtonNewWdg(title="Create", icon=IconWdg.NEW, show_arrow=True) #button_row.add(button) button.add_style("padding-right: 14px") button.add_style("float: left") menu = Menu(width=220) menu_item = MenuItem(type='title', label='New ...') menu.add(menu_item) menu_item = MenuItem(type='action', label='Text File') menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'sandbox_dir': my.sandbox_dir, 'cbjs_action': ''' var path = bvr.sandbox_dir + "/" + "new_text_file.txt"; var env = spt.Environment.get(); var url = env.get_server_url() + "/context/VERSION_API"; var applet = spt.Applet.get(); applet.download_file(url, path); var activator = spt.smenu.get_activator(bvr); var top = activator.getParent(".spt_checkin_top"); spt.panel.refresh(top); ''' } ) #create_sobj = SObject.create("sthpw/virtual") #create_sobj.set_value("title", "Maya Project") #create_sobj.set_value("script_path", "create/maya_project") script_path = 'create/maya_project' menu_item = MenuItem(type='action', label='Maya Project') menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'sandbox_dir': my.sandbox_dir, 'process': my.process, 'script_path': script_path, 'cbjs_action': ''' var script = spt.CustomProject.get_script_by_path(bvr.script_path); var options = {}; options.script = script; // add some data to options options.sandbox_dir = bvr.sandbox_dir; options.process = bvr.process; spt.CustomProject.exec_custom_script({}, options); var activator = spt.smenu.get_activator(bvr); var top = activator.getParent(".spt_checkin_top"); spt.panel.refresh(top); ''' } ) template_path = '/context/template/maya_project.zip' menu_item = MenuItem(type='action', label='Zipped Template') menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'sandbox_dir': my.sandbox_dir, 'template_path': template_path, 'cbjs_action': ''' var path = bvr.sandbox_dir + "/" + "_template.zip"; var env = spt.Environment.get(); var url = env.get_server_url() + bvr.template_path; var applet = spt.Applet.get(); applet.download_file(url, path); applet.unzip_file(path, bvr.sandbox_dir); applet.rmtree(path); var activator = spt.smenu.get_activator(bvr); var top = activator.getParent(".spt_checkin_top"); spt.panel.refresh(top); ''' } ) SmartMenu.add_smart_menu_set( button, { 'BUTTON_MENU': menu } ) SmartMenu.assign_as_local_activator( button, "BUTTON_MENU", True ) # Browse button for browsing files and dirs directly """ browse_div = DivWdg() list_wdg.add(browse_div) browse_div.add_style("float: left") button = ActionButtonWdg(title="Browse", tip="Select Files or Folder to Check-In") browse_div.add(button) behavior = { 'type': 'click_up', 'base_dir': my.sandbox_dir, 'cbjs_action': ''' var current_dir = bvr.base_dir; var is_sandbox = false; spt.checkin.browse_folder(current_dir, is_sandbox); ''' } button.add_behavior( behavior ) """ from tactic.ui.widget import SandboxButtonWdg, CheckoutButtonWdg, ExploreButtonWdg, GearMenuButtonWdg button_row = ButtonRowWdg() list_wdg.add(button_row) button_row.add_style("float: right") #button = SandboxButtonWdg(base_dir=my.sandbox_dir, process=my.process) #button_row.add(button) #button = CheckoutButtonWdg(base_dir=my.sandbox_dir, sobject=my.sobject, proces=my.process) #button_row.add(button) button = ExploreButtonWdg(base_dir=my.sandbox_dir) button_row.add(button) button = GearMenuButtonWdg(base_dir=my.sandbox_dir, process=my.process, pipeline_code=my.pipeline_code) button_row.add(button) list_wdg.add("<br clear='all'/>") top.add("<hr/>") content_div = DivWdg() top.add(content_div) content_div.add_class("spt_checkin_content") content = my.get_content_wdg() content_div.add(content) return top
def handle_dir_or_item(my, item_div, dirname, basename): spath = "%s/%s" % (dirname, basename) #fspath = "%s/%s" % (dirname, File.get_filesystem_name(basename)) fspath = "%s/%s" % (dirname, basename) md5 = my.md5s.get(fspath) changed = False context = None error_msg = None snapshot = None file_obj = my.checked_in_paths.get(fspath) if not file_obj: if fspath.startswith(my.base_dir): rel = fspath.replace("%s/" % my.base_dir, "") file_obj = my.checked_in_paths.get(rel) if file_obj != None: snapshot_code = file_obj.get_value("snapshot_code") snapshot = my.snapshots_dict.get(snapshot_code) if not snapshot: # last resort snapshot = file_obj.get_parent() if snapshot: context = snapshot.get_value("context") item_div.add_attr("spt_snapshot_code", snapshot.get_code()) snapshot_md5 = file_obj.get_value("md5") item_div.add_attr("spt_md5", snapshot_md5) item_div.add_attr( "title", "Checked-in as: %s" % file_obj.get_value("file_name")) if md5 and md5 != snapshot_md5: item_div.add_class("spt_changed") changed = True else: error_msg = 'snapshot not found' status = None if file_obj != None: if changed: check = IconWdg("Checked-In", IconWdg.ERROR, width=12) status = "changed" else: check = IconWdg("Checked-In", IconWdg.CHECK, width=12) status = "same" item_div.add_color("color", "color", [0, 0, 50]) else: check = None item_div.add_style("opacity: 0.8") status = "unversioned" if check: item_div.add(check) check.add_style("float: left") check.add_style("margin-left: -16px") check.add_style("margin-top: 4px") # add the file name filename_div = DivWdg() item_div.add(filename_div) filename_div.add(basename) file_info_div = None if snapshot and status != 'unversioned': file_info_div = SpanWdg() filename_div.add(file_info_div) if error_msg: filename_div.add(' (%s)' % error_msg) filename_div.add_style("float: left") filename_div.add_style("overflow: hidden") filename_div.add_style("width: 65%") # DEPRECATED """ checkbox = CheckboxWdg("check") checkbox.add_style("display: none") checkbox.add_class("spt_select") checkbox.add_style("float: right") checkbox.add_style("margin-top: 1px") item_div.add(checkbox) """ subcontext_val = '' cat_input = None is_select = True if my.context_options: context_sel = SelectWdg("context") context_sel.add_attr('title', 'context') context_sel.set_option("show_missing", False) context_sel.set_option("values", my.context_options) item_div.add_attr("spt_context", my.context_options[0]) cat_input = context_sel input_cls = 'spt_context' else: if my.subcontext_options in [['(main)'], ['(auto)'], []]: is_select = False #subcontext = TextWdg("subcontext") subcontext = HiddenWdg("subcontext") subcontext.add_class("spt_subcontext") elif my.subcontext_options == ['(text)']: is_select = False subcontext = TextWdg("subcontext") subcontext.add_class("spt_subcontext") else: is_select = True subcontext = SelectWdg("subcontext") subcontext.set_option("show_missing", False) subcontext.set_option("values", my.subcontext_options) #subcontext.add_empty_option("----") cat_input = subcontext input_cls = 'spt_subcontext' if my.subcontext_options == [ '(main)' ] or my.subcontext_options == ['(auto)']: subcontext_val = my.subcontext_options[0] subcontext.set_value(subcontext_val) item_div.add_attr("spt_subcontext", subcontext_val) elif context: parts = context.split("/") if len(parts) > 1: # get the actual subcontext value subcontext_val = "/".join(parts[1:]) # identify a previous "auto" check-in and preselect the item in the select if is_select and subcontext_val not in my.subcontext_options: subcontext_val = '(auto)' elif isinstance(cat_input, HiddenWdg): subcontext_val = '' # the Text field will adopt the subcontext value of the last check-in subcontext.set_value(subcontext_val) item_div.add_attr("spt_subcontext", subcontext_val) else: if is_select: if my.subcontext_options: subcontext_val = my.subcontext_options[0] #subcontext_val = '(auto)' cat_input.set_value(subcontext_val) else: subcontext_val = '' item_div.add_attr("spt_subcontext", subcontext_val) item_div.add(cat_input) cat_input.add_behavior({ 'type': 'click_up', 'propagate_evt': False, 'cbjs_action': ''' bvr.src_el.focus(); ''' }) cat_input.add_style("display: none") cat_input.add_class("spt_subcontext") cat_input.add_style("float: right") cat_input.add_style("width: 50px") cat_input.add_style("margin-top: -1px") cat_input.add_style("font-size: 10px") cat_input.add_style("height: 16px") # we depend on the attribute cuz sometimes we go by the initialized value # since they are not drawn cat_input.add_behavior({ 'type': 'change', 'cbjs_action': ''' var el = bvr.src_el.getParent('.spt_dir_list_item'); el.setAttribute("%s", bvr.src_el.value); ''' % input_cls }) if file_info_div: if subcontext_val in ['(auto)', '(main)', '']: file_info_div.add( " <i style='font-size: 9px; opacity: 0.6'>(v%s)</i>" % snapshot.get_value("version")) else: file_info_div.add( " <i style='font-size: 9px; opacity: 0.6'>(v%s - %s)</i>" % (snapshot.get_value("version"), subcontext_val))
def get_display(self): top = DivWdg() top.add_class("ad_input_top") name = self.get_name() text = TextWdg(self.get_input_name()) # get the login sobject = self.get_current_sobject() client = sobject.get_value("contact_name") print "client: ", client if client: login_sobj = Login.get_by_code(client) else: login_sobj = Environment.get_login() # build the display_name login = login_sobj.get_value("login") display_name = login_sobj.get_value("display_name") if not display_name: display_name = "%s %s" % (user.get('first_name'), user.get('last_name')) display_name = display_name.replace('"', "'") print "login: "******"spt_ad_input") if login: hidden.set_value(login) top.add(hidden) # copy over some options #text.set_options( self.options.copy() ) if login: text.set_value(display_name) text.set_option("read_only", "true") text.add_class("spt_ad_display") top.add(text) top.add(" ") groups_str = self.get_option("groups_allowed_to_search") if groups_str: stmt = 'groups_list = %s' % groups_str exec stmt else: groups_list = None allow_search = True if groups_list: allow_search = False login_in_group_list = Search.eval("@SOBJECT(sthpw/login_in_group['login','=','%s'])" % login) for login_in_group in login_in_group_list: group = login_in_group.get_value("login_group") if group in groups_list: allow_search = True break if login == 'admin': allow_search = True if allow_search: button = IconButtonWdg('Search for User', IconWdg.USER) #button = ButtonWdg() button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent('.ad_input_top'); var content = top.getElement('.ad_input_content'); spt.toggle_show_hide(content); ''' } ) top.add(button) ad_top = DivWdg() ad_top.add_class("ad_input_content") ad_top.add_style("display: none") ad_top.add_style("position: absolute") ad_top.add_style("background: #222") ad_top.add_style("min-width: 300px") ad_top.add_style("border: solid 1px #000") ad_top.add_style("padding: 20px") cbjs_action = ''' var value = bvr.src_el.getAttribute('spt_input_value'); var display_value = bvr.src_el.getAttribute('spt_display_value'); var phone_number = bvr.src_el.getAttribute('spt_phone_number'); var email = bvr.src_el.getAttribute('spt_mail'); var top = bvr.src_el.getParent('.ad_input_top'); var content = top.getElement('.ad_input_content'); var input = top.getElement('.spt_ad_input'); var display = top.getElement('.spt_ad_display'); input.value = value; display.value = display_value; server = TacticServerStub.get() server.execute_cmd("tactic.active_directory.ADCacheUserCbk", {login: value}) spt.toggle_show_hide(content); ''' ad_search_wdg = ADSearchWdg(cbjs_action=cbjs_action) ad_top.add(ad_search_wdg) top.add(ad_top) return top
def get_display(my): widget = Widget() my.search_type = my.options.get("search_type") if not my.search_type: my.search_type = my.kwargs.get("search_type") assert my.search_type my.load_options_class = my.kwargs.get('load_options_class') state = Container.get("global_state") if state: my.process = state.get("process") else: my.process = None # the filter for searching assets div = DivWdg(css='filter_box') div.add_color("background", "background2", -35) from app_init_wdg import PyMayaInit, PyXSIInit, PyHoudiniInit if WebContainer.get_web().get_selected_app() == 'Maya': app = PyMayaInit() elif WebContainer.get_web().get_selected_app() == 'XSI': app = PyXSIInit() elif WebContainer.get_web().get_selected_app() == 'Houdini': app = PyHoudiniInit() div.add(app) # add the possibility of a custom callback callback = my.options.get('callback') if callback: hidden = HiddenWdg("callback", callback) div.add(hidden) # or add the possiblity of a switch mode pipeline_type = "load" hidden = HiddenWdg("pipeline_type", pipeline_type) if my.process: process_div = DivWdg() process_div.add_style("margin: 10px") process_div.add("PROCESS: %s" % my.process) process_div.add_style("font-size: 20px") widget.add(process_div) hidden_wdg = HiddenWdg("process_select_%s" %my.search_type) hidden_wdg.set_value(my.process) widget.add(hidden_wdg) else: search_type = my.search_type if search_type =='prod/shot_instance': search_type = 'prod/shot' process_filter = ProcessFilterWdg(my.get_context_data(search_type), search_type) span = SpanWdg(process_filter, css='med') div.add(span) widget.add(div) # load options for diff search type if my.load_options_class: load_options = Common.create_from_class_path(my.load_options_class) elif my.search_type=='prod/asset': load_options = LoadOptionsWdg() elif my.search_type == 'prod/shot': load_options = ShotLoadOptionsWdg() elif my.search_type == 'prod/shot_instance': load_options = AnimLoadOptionsWdg() else: load_options = LoadOptionsWdg() load_options.set_prefix(my.search_type) widget.add(load_options) return widget
def get_display(my): relative_dir = my.kwargs.get("relative_dir") my.relative_dir = relative_dir div = DivWdg() div.add_class("spt_ingest_top") div.add_style("width: 100%px") div.add_style("min-width: 500px") div.add_style("padding: 20px") div.add_color("background", "background") title_div = DivWdg() div.add(title_div) title_div.add("Ingest Files") title_div.add_style("font-size: 14px") title_div.add_style("font-weight: bold") title_div.add_style("padding: 10px") title_div.add_color("background", "background3") title_div.add_border() my.search_type = my.kwargs.get("search_type") if not my.search_type: div.add("No search type specfied") return div if relative_dir: folder_div = DivWdg() div.add(folder_div) folder_div.add("Folder: %s" % relative_dir) folder_div.add_style("opacity: 0.5") folder_div.add_style("font-style: italic") folder_div.add_style("margin-bottom: 10px") title_div.add_style("margin: -20px -21px 5px -21px") else: title_div.add_style("margin: -20px -21px 15px -21px") div.add("Add files or drag/drop files to be uploaded and ingested:") div.add("<br/>"*2) data_div = my.get_data_wdg() data_div.add_style("float: left") data_div.add_style("float: left") div.add(data_div) # create the help button help_button_wdg = DivWdg() div.add(help_button_wdg) help_button_wdg.add_style("margin-top: -3px") help_button_wdg.add_style("float: right") help_button = ActionButtonWdg(title="?", tip="Ingestion Widget Help", size='s') help_button_wdg.add(help_button) help_button.add_behavior( { 'type': 'click_up', 'cbjs_action': '''spt.help.load_alias("ingestion_widget")''' } ) from tactic.ui.input import Html5UploadWdg upload = Html5UploadWdg(multiple=True) div.add(upload) button = ActionButtonWdg(title="Add") button.add_style("float: right") button.add_style("margin-top: -3px") div.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var files_el = top.getElement(".spt_upload_files"); var onchange = function (evt) { var files = spt.html5upload.get_files(); for (var i = 0; i < files.length; i++) { spt.drag.show_file(files[i], files_el, 0, true); } } spt.html5upload.set_form( top ); spt.html5upload.select_file( onchange ); ''' } ) button = ActionButtonWdg(title="Clear") button.add_style("float: right") button.add_style("margin-top: -3px") div.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); }; ''' } ) div.add("<br clear='all'/>") files_div = DivWdg() files_div.add_style("position: relative") files_div.add_class("spt_upload_files") div.add(files_div) files_div.add_style("max-height: 300px") files_div.add_style("height: 300px") files_div.add_style("overflow-y: auto") files_div.add_border() files_div.add_style("padding: 3px") files_div.add_color("background", "background3") #files_div.add_style("display: none") bgcolor = div.get_color("background3") bgcolor2 = div.get_color("background3", -3) files_div.add_behavior( { 'type': 'mouseenter', 'bgcolor': bgcolor2, 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.bgcolor) ''' } ) files_div.add_behavior( { 'type': 'mouseout', 'bgcolor': bgcolor, 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.bgcolor) ''' } ) background = DivWdg() background.add_class("spt_files_background") files_div.add(background) background.add_style("font-size: 4.0em") background.add_style("font-weight: bold") background.add_style("opacity: 0.1") background.add_style("position: absolute") background.add_style("left: 50%") background.add_style("top: 100px") background.add_border() inner_background = DivWdg("Drag Files Here") background.add(inner_background) inner_background.set_style("position: absolute") inner_background.set_style("margin-left: -50%") # Test drag and drop files files_div.add_attr("ondragenter", "return false") files_div.add_attr("ondragover", "return false") files_div.add_attr("ondrop", "spt.drag.noop(event, this)") files_div.add_behavior( { 'type': 'load', 'cbjs_action': ''' spt.drag = {} var background; spt.drag.show_file = function(file, top, delay, icon) { if (!background) { background = top.getElement(".spt_files_background"); background.setStyle("display", "none"); } var template = top.getElement(".spt_upload_file_template"); var clone = spt.behavior.clone(template); clone.removeClass("spt_upload_file_template"); clone.addClass("spt_upload_file"); clone.setStyle("display", ""); if (typeof(delay) == 'undefined') { delay = 0; } // remember the file handle clone.file = file; var name = file.name; var size = parseInt(file.size / 1024 * 10) / 10; var thumb_el = clone.getElement(".spt_thumb"); var date_label_el = clone.getElement(".spt_date_label"); var date_el = clone.getElement(".spt_date"); //var loadingImage = loadImage( setTimeout( function() { if (icon) { var loadingImage = loadImage( file, function (img) { thumb_el.appendChild(img); }, {maxWidth: 80, maxHeight: 60, canvas: true, contain: true} ); } else { var img = $(document.createElement("div")); img.setStyle("width", "60"); img.setStyle("height", "40"); //img.innerHTML = "MP4"; img.setStyle("border", "solid 1px black") thumb_el.appendChild(img); } loadImage.parseMetaData( file, function(data) { if (data.exif) { var date = data.exif.get('DateTimeOriginal'); if (date) { date_label_el.innerHTML = date; if (date_el) { date_el.value = date; } } } } ); }, delay ); /* var reader = new FileReader(); reader.thumb_el = thumb_el; reader.onload = function(e) { this.thumb_el.innerHTML = [ '<img class="thumb" src="', e.target.result, '" title="', escape(name), '" width="60px"', '" padding="5px"', '"/>' ].join(''); } reader.readAsDataURL(file); */ clone.getElement(".spt_name").innerHTML = file.name; clone.getElement(".spt_size").innerHTML = size + " KB"; clone.inject(top); } spt.drag.noop = function(evt, el) { var top = $(el).getParent(".spt_ingest_top"); var files_el = top.getElement(".spt_upload_files"); evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; var files = evt.dataTransfer.files; var delay = 0; var skip = false; for (var i = 0; i < files.length; i++) { var size = files[i].size; if (size >= 10*1024*1024) { spt.drag.show_file(files[i], files_el, 0, false); } else { spt.drag.show_file(files[i], files_el, delay, true); if (size < 100*1024) delay += 50; else if (size < 1024*1024) delay += 500; else if (size < 10*1024*1024) delay += 1000; } } } ''' } ) # create a template that will be filled in for each file files_div.add_relay_behavior( { 'type': 'mouseenter', 'color': files_div.get_color("background3", -5), 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.color); ''' } ) files_div.add_relay_behavior( { 'type': 'mouseleave', 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); ''' } ) files_div.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_remove', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_upload_file"); spt.behavior.destroy_element(top); ''' } ) """ metadata_view = "test/wizard/metadata" files_div.add_relay_behavior( { 'type': 'mouseup', 'view': metadata_view, 'bvr_match_class': 'spt_upload_file', 'cbjs_action': ''' var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: bvr.view } spt.app_busy.show("Loading Metadata"); spt.panel.load_popup("Metadata", class_name, kwargs); spt.app_busy.hide(); ''' } ) """ # template for each file item file_template = DivWdg() file_template.add_class("spt_upload_file_template") files_div.add(file_template) file_template.add_style("margin-bottom: 3px") file_template.add_style("padding: 3px") file_template.add_style("height: 40px") file_template.add_style("display: none") thumb_div = DivWdg() file_template.add(thumb_div) thumb_div.add_style("float: left") thumb_div.add_style("width: 60"); thumb_div.add_style("height: 40"); thumb_div.add_style("overflow: hidden"); thumb_div.add_style("margin: 3 10 3 0"); thumb_div.add_class("spt_thumb") info_div = DivWdg() file_template.add(info_div) info_div.add_style("float: left") name_div = DivWdg() name_div.add_class("spt_name") info_div.add(name_div) name_div.add("image001.jpg") name_div.add_style("width: 150px") """ dialog = DialogWdg(display="false", show_title=False) info_div.add(dialog) dialog.set_as_activator(info_div, offset={'x':0,'y':10}) dialog_data_div = DivWdg() dialog_data_div.add_color("background", "background") dialog_data_div.add_style("padding", "10px") dialog.add(dialog_data_div) dialog_data_div.add("Category: ") text = TextInputWdg(name="category") dialog_data_div.add(text) text.add_class("spt_category") text.add_style("padding: 1px") """ date_div = DivWdg() date_div.add_class("spt_date_label") info_div.add(date_div) date_div.add("") date_div.add_style("opacity: 0.5") date_div.add_style("font-size: 0.8em") date_div.add_style("font-style: italic") date_div.add_style("margin-top: 3px") hidden_date_div = HiddenWdg("date") hidden_date_div.add_class("spt_date") info_div.add(date_div) size_div = DivWdg() size_div.add_class("spt_size") file_template.add(size_div) size_div.add("433Mb") size_div.add_style("float: left") size_div.add_style("width: 150px") size_div.add_style("text-align: right") remove_div = DivWdg() remove_div.add_class("spt_remove") file_template.add(remove_div) icon = IconButtonWdg(title="Remove", icon=IconWdg.DELETE) icon.add_style("float: right") remove_div.add(icon) #remove_div.add_style("text-align: right") div.add("<br/>") info = DivWdg() div.add(info) info.add_class("spt_upload_info") progress_div = DivWdg() progress_div.add_class("spt_upload_progress_top") div.add(progress_div) progress_div.add_style("width: 100%") progress_div.add_style("height: 15px") progress_div.add_style("margin-bottom: 10px") progress_div.add_border() #progress_div.add_style("display: none") progress = DivWdg() progress_div.add(progress) progress.add_class("spt_upload_progress") progress.add_style("width: 0px") progress.add_style("height: 100%") progress.add_gradient("background", "background3", -10) progress.add_style("text-align: right") progress.add_style("overflow: hidden") progress.add_style("padding-right: 3px") from tactic.ui.app import MessageWdg progress.add_behavior( { 'type': 'load', 'cbjs_action': MessageWdg.get_onload_js() } ) # NOTE: files variable is passed in automatically upload_init = ''' var server = TacticServerStub.get(); server.start( {description: "Upload and check-in of ["+files.length+"] files"} ); var info_el = top.getElement(".spt_upload_info"); info_el.innerHTML = "Uploading ..."; ''' upload_progress = ''' var top = bvr.src_el.getParent(".spt_ingest_top"); progress_el = top.getElement(".spt_upload_progress"); var percent = Math.round(evt.loaded * 100 / evt.total); progress_el.setStyle("width", percent + "%"); progress_el.innerHTML = String(percent) + "%"; ''' on_complete = ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var progress_el = top.getElement(".spt_upload_progress"); progress_el.innerHTML = "100%"; progress_el.setStyle("width", "100%"); var info_el = top.getElement(".spt_upload_info"); var search_type = bvr.kwargs.search_type; var relative_dir = bvr.kwargs.relative_dir; var filenames = []; for (var i = 0; i != files.length;i++) { var name = files[i].name; filenames.push(name); } var key = spt.message.generate_key(); var values = spt.api.get_input_values(top); //var category = values.category[0]; var keywords = values.keywords[0]; var extra_data = values.extra_data[0]; var parent_key = values.parent_key[0]; var convert_el = top.getElement(".spt_image_convert") var convert = spt.api.get_input_values(convert_el); var processes = values.process; if (processes) { process = processes[0]; if (!process) { process = null; } } else { process = null; } var kwargs = { search_type: search_type, relative_dir: relative_dir, filenames: filenames, key: key, parent_key: parent_key, //category: category, keywords: keywords, extra_data: extra_data, process: process, convert: convert, } on_complete = function() { spt.info("Ingest complete"); server.finish(); var file_els = top.getElements(".spt_upload_file"); for ( var i = 0; i < file_els.length; i++) { spt.behavior.destroy( file_els[i] ); }; var background = top.getElement(".spt_files_background"); background.setStyle("display", ""); spt.message.stop_interval(key); }; var class_name = bvr.action_handler; server.execute_cmd(class_name, kwargs, null, {on_complete:on_complete}); on_progress = function(message) { msg = JSON.parse(message.message); var percent = msg.progress; var description = msg.description; info_el.innerHTML = description; progress_el.setStyle("width", percent+"%"); progress_el.innerHTML = percent + "%"; } spt.message.set_interval(key, on_progress, 2000); ''' upload_div = DivWdg() div.add(upload_div) #button = UploadButtonWdg(**kwargs) button = ActionButtonWdg(title="Ingest") upload_div.add(button) button.add_style("float: right") upload_div.add_style("margin-bottom: 15px") upload_div.add("<br clear='all'/>") action_handler = my.kwargs.get("action_handler") if not action_handler: action_handler = 'tactic.ui.tools.IngestUploadCmd'; button.add_behavior( { 'type': 'click_up', 'action_handler': action_handler, 'kwargs': { 'search_type': my.search_type, 'relative_dir': relative_dir }, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_ingest_top"); var file_els = top.getElements(".spt_upload_file"); // get the server that will be used in the callbacks var server = TacticServerStub.get(); // retrieved the stored file handles var files = []; for (var i = 0; i < file_els.length; i++) { files.push( file_els[i].file ); } if (files.length == 0) { alert("No files selected"); return; } // defined the callbacks var upload_start = function(evt) { } var upload_progress = function(evt) { %s; } var upload_complete = function(evt) { %s; spt.app_busy.hide(); } var upload_file_kwargs = { files: files, upload_start: upload_start, upload_complete: upload_complete, upload_progress: upload_progress }; if (bvr.ticket) upload_file_kwargs['ticket'] = bvr.ticket; %s; spt.html5upload.set_form( top ); spt.html5upload.upload_file(upload_file_kwargs); ''' % (upload_progress, on_complete, upload_init) } ) return div
class DropElementWdg(SimpleTableElementWdg): ARGS_KEYS = { 'accepted_drop_type': { 'description': 'This will enforce the SType that can be accepted on this drop', 'category': 'Options', 'order': 1 }, 'cbjs_drop_action': { 'description': 'Custom javascript callback to call when a drop has occured. This is optional', 'type': 'TextAreaWdg', 'category': 'Options', 'order': 3 }, 'instance_type': { 'description': 'The SType name for the table that carries out the association', 'category': 'Options', 'order': 2 }, 'display_expr': { 'description': 'Display Expression for the dropped item. e.g. @GET(.code)', 'category': 'Options', 'order': 4 } #'cbpy_drop_action': 'Custom python callback when save is done' } """ def get_args_keys(cls): return cls.ARGS_KEYS get_args_keys = classmethod(get_args_keys) """ def get_width(self): return 150 def _get_sorted_instances(self): sobject = self.get_current_sobject() instance_type = self.get_option("instance_type") instances = sobject.get_related_sobjects(instance_type) # sorting now name_dict = {} for inst in instances: name_dict[inst] = inst.get_display_value() return sorted(instances, key=name_dict.__getitem__) def is_editable(cls): return False is_editable = classmethod(is_editable) def handle_layout_behaviors(self, layout): #self.menu.set_activator_over(layout, "spt_drop_item") #self.menu.set_activator_out(layout, "spt_drop_item") layout.add_behavior({'type': 'load', 'cbjs_action': get_onload_js()}) def handle_td(self, td): # FIXME: this is some hackery borrowed from the work to make gantt widget not commit on change # ... need to clean this up at some point! version = self.parent_wdg.get_layout_version() if version != "2": td.add_attr('spt_input_type', 'gantt') td.add_class("spt_input_inline") super(DropElementWdg, self).handle_td(td) def get_value_wdg(self): return self.value_wdg def handle_tr(self, tr): # define the drop zone version = self.parent_wdg.get_layout_version() def handle_th(self, th, wdg_idx=None): th.add_attr('spt_input_type', 'inline') """ # handle finger menu self.top_class = "spt_drop_element_menu" from tactic.ui.container import MenuWdg, MenuItem self.menu = MenuWdg(mode='horizontal', width = 25, height=20, top_class=self.top_class) menu_item = MenuItem('action', label=IconWdg("Add User", IconWdg.ADD)) self.menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' ''' } ) widget = DivWdg() widget.add_class(self.top_class) widget.add_styles('position: absolute; display: none; z-index: 1000') widget.add(self.menu) th.add(widget) """ """ FIXME: Waiting until this is implemented def handle_th(self, th, wdg_idx=None): from tactic.ui.container import MenuWdg, MenuItem self.menu = MenuWdg(mode='horizontal', width = 40) th.add(self.menu) menu_item = MenuItem('action', label='delete') self.menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': '''alert('cow');''' } ) menu_item = MenuItem('action', label='kill') self.menu.add(menu_item) menu_item.add_behavior( { 'type': 'click_up', 'cbjs_action': '''alert('cow');''' } ) """ def add_drop_behavior(self, widget, accepted_search_type=''): js_callback = self.get_option("cbjs_drop_action") if not js_callback: js_callback = 'spt.drop.sobject_drop_action(evt,bvr)' py_callback = self.get_option("cbpy_drop_action") #assert(py_callback) # define the drop zone widget.set_attr('SPT_ACCEPT_DROP', 'DROP_ROW') widget.add_behavior({ 'type': 'accept_drop', 'drop_code': 'DROP_ROW', 'accepted_search_type': accepted_search_type, 'cbjs_action': js_callback, 'cbpy_action': py_callback, }) widget.add_behavior({ 'type': 'mouseleave', 'cbjs_action': ''' var orig_border_color = bvr.src_el.getAttribute('orig_border_color'); var orig_border_style = bvr.src_el.getAttribute('orig_border_style'); bvr.src_el.setStyle('border-color', orig_border_color) bvr.src_el.setStyle('border-style', orig_border_style) ''' }) def get_text_value(self): sorted_instances = self._get_sorted_instances() names = '' for inst in sorted_instances: names += '%s ' % inst.get_display_value() return names def get_display(self): self.display_expr = self.kwargs.get('display_expr') self.values = [] instance_type = self.get_option("instance_type") accepted_type = self.get_option("accepted_drop_type") div = DivWdg() div.add_class("spt_drop_element_top") div.add_style("width: 100%") div.add_style("min-height: 70px") div.add_style("height: auto") div.add_style("min-width: 100px") div.add_style("max-height: 300px") div.add_style("overflow-y: auto") div.add_style("overflow-x: hidden") self.value_wdg = HiddenWdg(self.get_name()) self.value_wdg.add_class("spt_drop_element_value") div.add(self.value_wdg) version = self.parent_wdg.get_layout_version() #if version != "2": self.add_drop_behavior(div, accepted_type) # add the hidden div which holds containers info for the sobject template_div = DivWdg() template_div.add_style("display: none") template_item = self.get_item_div(None) # float left for the new icon beside it item_div = template_item.get_widget('item_div') #item_div.add_style('float: left') template_item.add_class("spt_drop_template") new_icon = IconWdg("New", IconWdg.NEW) new_icon.add_style('padding-left', '3px') #TODO: insert the new_icon at add(new_icon, index=0) and make sure # the js-side sobject_drop_action cloning align the template div properly #template_item.add(new_icon) template_div.add(template_item) div.add(template_div) content_div = DivWdg() div.add(content_div) content_div.add_class("spt_drop_content") if instance_type: instance_wdg = self.get_instance_wdg(instance_type) content_div.add(instance_wdg) return div def get_instance_wdg(self, instance_type): sorted_instances = self._get_sorted_instances() content_div = Widget() for instance in sorted_instances: item_div = self.get_item_div(instance) item_div.add_attr("spt_search_key", SearchKey.get_by_sobject(instance)) item_div.add_class("spt_drop_item") # no need for that #item_div.add(' ') content_div.add(item_div) value_wdg = self.get_value_wdg() json = jsondumps(self.values) json = json.replace('"', '"') value_wdg.set_value(json) return content_div def get_item_div(self, sobject): ''' get the item div the sobject''' top = DivWdg() top.add_style("padding: 3px 2px") top.add_class("spt_drop_item") top.add_class("SPT_DROP_ITEM") item_div = DivWdg() top.add(item_div, "item_div") item_div.add_style("text-overflow: ellipsis") item_div.add_style("white-space: nowrap") item_div.add_style("width: 80%") item_div.add_attr('title', 'Click to remove') item_div.add_style("display", "inline-block") item_div.add_style("vertical-align", "top") item_div.add_style("overflow", "hidden") icon_div = DivWdg() top.add(icon_div) icon = IconWdg(icon="BS_REMOVE") icon_div.add(icon) icon_div.add_behavior({ 'type': 'click_up', #'cbjs_action': '''spt.dg_table_action.sobject_drop_remove(evt,bvr)''' 'cbjs_action': '''spt.drop.sobject_drop_remove(evt,bvr)''' }) icon.add_style("opacity: 0.3") icon_div.add_class("hand") icon_div.add_style("display", "inline-block") icon_div.add_style("vertical-align", "top") #icon_div.add_border() #self.menu.set_over(item_div, event="mousein") #self.menu.set_out(top, event="mouseleave") # set this as the place for the display value to go item_div.add_class("spt_drop_display_value") add_icon = True ExpressionParser.clear_cache() if sobject: if add_icon: self._add_icon(sobject, item_div) if self.display_expr: display_value = Search.eval(self.display_expr, sobjects=sobject, single=True) else: display_value = sobject.get_display_value() if isinstance(display_value, list): display_value = display_value[0] item_div.add(display_value) self.values.append(SearchKey.get_by_sobject(sobject)) return top def _add_icon(self, sobject, item_div): '''add icon to the item_div''' if sobject.get_base_search_type() == 'sthpw/login_in_group': icon = IconWdg(icon=IconWdg.USER) item_div.add(icon)
def get_display(self): #return None div = DivWdg() div.add_class("spt_gantt_top") value_wdg = HiddenWdg(self.get_name()) value_wdg.add_class("spt_gantt_value") div.add( value_wdg ) content_div = DivWdg() content_div.add_style("width: 100%") content_div.add_style("height: 100%") content_div.add_behavior( { 'type': 'accept_drop', 'drop_code': 'DROP_ROW', 'cbjs_action': ''' var src_el = bvr._drop_source_bvr.src_el; var src_table_top = src_el.getParent(".spt_table_top"); var src_table = src_table_top.getElement(".spt_table"); var src_search_keys = spt.dg_table.get_selected_search_keys(src_table); if (src_search_keys.length == 0) { var tbody = src_el.getParent(".spt_table_tbody"); var src_search_key = tbody.getAttribute("spt_search_key"); src_search_keys = [ src_search_key ]; } var src_search_key = src_search_keys[0]; var drop_el = bvr.src_el; var top_wdg = drop_el.getParent('.spt_gantt_top'); var value_wdg = top_wdg.getElement('.spt_gantt_value'); value_wdg.value = src_search_key; var content_wdg = top_wdg.getElement('.spt_content'); var server = TacticServerStub.get(); var sobject = server.get_by_search_key(src_search_key); var code = sobject['code']; content_wdg.innerHTML = code; spt.dg_table.edit.widget = top_wdg; var key_code = spt.kbd.special_keys_map.ENTER; spt.dg_table.edit_cell_cbk( value_wdg, key_code ); ''' } ) sobject = self.get_current_sobject() try: parent = sobject.get_parent() if parent: value = parent.get_code() else: value = " " except SearchException as e: # skips unknown search_type/project print e.__str__() search_type = sobject.get_search_type() if search_type in ['sthpw/task','sthpw/note','sthpw/snapshot']: value = "Parent cannot be found for this parent key [%s&id=%s]" %(sobject.get_value('search_type'), sobject.get_value('search_id')) else: search_key = sobject.get_search_key() value = "Invalid parent for [%s]" % search_key content_div.add_class('spt_content') content_div.add(value) div.add(content_div) return div
class SearchLimitWdg(Widget): DETAIL = "detail_style" LESS_DETAIL = "less_detail_style" SIMPLE = "simple_style" def __init__(self, name='search_limit', label="Showing", limit=None, refresh=True): self.search_limit_name = name self.label = label if limit: self.search_limit = int(limit) else: self.search_limit = None self.fixed_offset = False self.style = self.DETAIL self.prefix = "search_limit" self.refresh = refresh self.refresh_script = 'spt.dg_table.search_cbk(evt, bvr)' if self.refresh: self.prev_hidden_name = 'Prev' self.next_hidden_name = 'Next' else: self.prev_hidden_name = '%s_Prev' %self.label self.next_hidden_name = '%s_Next' %self.label self.chunk_size = 0 self.chunk_num = 0 super(SearchLimitWdg, self).__init__() def init(self): self.current_offset = 0 self.count = None #self.text = TextWdg(self.search_limit_name) self.text = HiddenWdg(self.search_limit_name) self.text.add_style("width: 23px") self.text.add_style("margin-bottom: -1px") self.text.add_class("spt_search_limit_text") self.text.set_persist_on_submit(prefix=self.prefix) behavior = { 'type': 'keydown', 'cbjs_action': ''' if (evt.key=='enter') { // register this as changed item var value = bvr.src_el.value; if (isNaN(value) || value.test(/[\.-]/)) { spt.error('You have to use an integer.'); } } '''} self.text.add_behavior(behavior) # get the search limit that is passed in filter_data = FilterData.get() values = filter_data.get_values_by_prefix(self.prefix) if not values: # check web for embedded table web = WebContainer.get_web() values = {} limit_value = web.get_form_value("search_limit") label_value = web.get_form_value(self.label) if limit_value: values['search_limit'] = limit_value if label_value: values[self.label] = label_value else: values = values[0] self.values2 = filter_data.get_values_by_prefix("search_limit_simple") if not len(self.values2): self.values2 = {} elif len(self.values2) == 2: if self.values2[0]['page']: self.values2 = self.values2[0] else: self.values2 = self.values2[1] else: self.values2 = self.values2[0] self.stated_search_limit = values.get("search_limit") """ if not self.stated_search_limit: self.stated_search_limit = values.get("limit_select") if not self.stated_search_limit: self.stated_search_limit = values.get("custom_limit") """ if self.stated_search_limit: self.stated_search_limit = int(self.stated_search_limit) else: self.stated_search_limit = 0 # reused for alter_search() later self.values = values def set_refresh_script(self, script): self.refresh_script = script def set_label(self, label): self.label = label def get_limit(self): return self.search_limit def get_stated_limit(self): return self.stated_search_limit def get_count(self): return self.count def set_limit(self, limit): self.search_limit = limit # this is user defined, should be set in init() instead #self.stated_search_limit = limit def set_offset(self, offset): self.fixed_offset = True self.current_offset = offset def set_style(self, style): self.style = style def set_chunk(self, chunk_size, chunk_num, limit=None): self.chunk_size = chunk_size self.chunk_num = chunk_num if limit: self.search_limit = limit else: # avoid undefined chunk_size if chunk_size: self.search_limit = chunk_size # to avoid 0 limit on undefined search limit in fast table if self.search_limit == 0: self.search_limit = 50 def alter_search(self, search): if not search: return self.set_search(search) security = Environment.get_security() # allow security to alter the search security.alter_search(search) search.set_security_filter() self.count = search.get_count() web = WebContainer.get_web() values = self.values # look at the stated search limit only if there is no chunk_size if not self.chunk_size: search_limit = self.stated_search_limit if search_limit and self.search_limit != -1: try: self.search_limit = int(search_limit) except ValueError: self.search_limit = 20 if self.search_limit <= 0: self.search_limit = 1 elif self.search_limit: # this usually happens with search_limit set in side bar or kwarg for TableLayoutWdg pass else: # for backward compatibility with the default chunk size of 100 self.search_limit = 100 # find out what the last offset was #last_search_offset = web.get_form_value("last_search_offset") last_search_offset = values.get("%s_last_search_offset"%self.label) if last_search_offset: last_search_offset = int(last_search_offset) else: last_search_offset = 0 # based on the action, set the new offset #if web.get_form_value("Next"): # FIXME: Next Prev not working for embedded tables yet # look at various values to change the search criteria page = self.values2.get("page") if page: current_offset = self.search_limit * (int(page)-1) elif values.get("Next"): current_offset = last_search_offset + self.search_limit if current_offset >= self.count: current_offset = 0 #elif web.get_form_value("Prev"): elif values.get("Prev"): current_offset = last_search_offset - self.search_limit if current_offset < 0: current_offset = int(self.count/self.search_limit) * self.search_limit # this happens when the user jumps from Page 3 of a tab to a tab that # doesn't really need this widget elif last_search_offset > self.count: current_offset = 0 elif values.get(self.label): value = values.get(self.label) if not value.startswith("+"): current_offset, tmp = value.split(" - ") current_offset = int(current_offset) - 1 else: current_offset = 0 else: current_offset = 0 if self.fixed_offset == False: self.current_offset = current_offset # add ability to break search limit search into chunks self.current_offset = self.current_offset if self.chunk_num: self.current_offset = last_search_offset + (self.chunk_num*self.chunk_size) if self.search_limit >= 0: self.search.set_limit(self.search_limit) self.search.set_offset(self.current_offset) def get_info(self): return { "count": self.count, "current_offset": self.current_offset, "search_limit": self.search_limit, } def get_display(self): web = WebContainer.get_web() widget = DivWdg() widget.add_class("spt_search_limit_top") #widget.add_style("border", "solid 1px blue") widget.add_color("background", "background") widget.add_color("color", "color") widget.add_style("padding: 10px") hidden = HiddenWdg("prefix", self.prefix) widget.add(hidden) if not self.search and not self.sobjects: widget.add("No search or sobjects found") return widget # self.count should have been set in alter_search() # which can be called explicitly thru this instance, self. if not self.count: self.count = self.search.get_count(no_exception=True) # if self.sobjects exist thru inheriting from parent widgets # or explicitly set, (this is not mandatory though) if self.sobjects and len(self.sobjects) < self.search_limit: limit = len(self.sobjects) elif self.search and self.count < self.search_limit: # this is only true if the total result of the search is # less than the limit and so this wdg will not display limit = self.count else: limit = self.search_limit if not limit: limit = 50 self.search_limit = limit if self.refresh: prev = SpanWdg( IconButtonWdg(title="Prev", icon="BS_CHEVRON_LEFT") ) prev.add_style("margin-left: 8px") prev.add_style("margin-right: 6px") prev.add_style("margin-top: 5px") hidden_name = self.prev_hidden_name hidden = HiddenWdg(hidden_name, "") prev.add(hidden) prev.add_behavior( { 'type': 'click_up', 'cbjs_action': " bvr.src_el.getElement('input[name=%s]').value ='Prev';%s"\ % (hidden_name, self.refresh_script) } ) next = SpanWdg( IconButtonWdg(title="Next", icon="BS_CHEVRON_RIGHT" ) ) next.add_style("margin-left: 6px") next.add_style("margin-top: 5px") hidden_name = self.next_hidden_name hidden = HiddenWdg(hidden_name, "") next.add(hidden) next.add_behavior( { 'type': 'click_up', 'cbjs_action': " bvr.src_el.getElement('input[name=%s]').value ='Next';%s"\ % (hidden_name, self.refresh_script) } ) prev.add_style("float: left") next.add_style("float: left") else: # the old code pre 2.5 prev = IconButtonWdg(title="Prev", icon="BS_CHEVRON_LEFT" ) hidden_name = self.prev_hidden_name hidden = HiddenWdg(hidden_name,"") prev.add(hidden) prev.add_event('onclick'," spt.api.Utility.get_input(document,'%s').value ='Prev';%s"\ %(hidden_name, self.refresh_script)) next = IconButtonWdg(title="Next", icon="BS_CHEVRON_RIGHT" ) hidden_name = self.next_hidden_name hidden = HiddenWdg(hidden_name,"") next.add(hidden) next.add_event('onclick',"spt.api.Utility.get_input(document,'%s').value ='Next';%s" \ %(hidden_name, self.refresh_script)) showing_wdg = DivWdg() widget.add(showing_wdg) showing_wdg.add_style("padding: 20px") showing_wdg.add_style("margin: 10px") showing_wdg.add_color("background", "background", -5) #showing_wdg.add_color("text-align", "center") showing_wdg.add_border() label_span = SpanWdg("Showing: ") showing_wdg.add(label_span) showing_wdg.add("<br clear='all'/>") showing_wdg.add("<br/>") showing_wdg.add( prev ) # this min calculation is used so that if self.sobjects is not set # above for the calculation of the limit, which will make the last # set of range numbers too big left_bound = self.current_offset+1 if not limit: # prevent error in ItemsNavigatorWdg if a search encounters query error limit = 50 self.search_limit = limit right_bound = min(self.current_offset+limit, self.count) if left_bound > right_bound: left_bound = 1 current_value = "%d - %d" % (left_bound, right_bound) if self.style == self.SIMPLE: showing_wdg.add( current_value ) else: # add a range selector using ItemsNavigatorWdg from pyasm.widget import ItemsNavigatorWdg selector = ItemsNavigatorWdg(self.label, self.count, self.search_limit) selector.select.add_behavior( { 'type': 'change', 'cbjs_action': self.refresh_script } ) selector.set_style(self.style) selector.select.add_style("width: 100px") #selector.add_style("display: inline") selector.add_style("float: left") selector.set_value(current_value) selector.set_display_label(False) showing_wdg.add( selector) showing_wdg.add( next ) showing_wdg.add("<br clear='all'/>") showing_wdg.add("<br clear='all'/>") #showing_wdg.add( " x ") showing_wdg.add(self.text) self.text.add_style("margin-top: -3px") self.text.set_attr("size", "1") self.text.add_attr("title", "Set number of items per page") # set the limit set_limit_wdg = self.get_set_limit_wdg() widget.add(set_limit_wdg) from tactic.ui.widget.button_new_wdg import ActionButtonWdg button = ActionButtonWdg(title='Search') widget.add(button) button.add_style("float: right") button.add_style("margin-top: 8px") button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var select = top.getElement(".spt_search_limit_select"); var value = select.value; if (value == 'Custom') { custom = top.getElement(".spt_search_limit_custom_text"); value = custom.value; } if (value == '') { value = 20; } var text = top.getElement(".spt_search_limit_text"); text.value = value; spt.dg_table.search_cbk({}, bvr) ''' } ) offset_wdg = HiddenWdg("%s_last_search_offset" %self.label) offset_wdg.set_value(self.current_offset) widget.add(offset_wdg) widget.add("<br clear='all'/>") return widget def get_set_limit_wdg(self): limit_content = DivWdg() limit_content.add_style("font-size: 10px") limit_content.add_style("padding", "15px") #limit_content.add_border() limit_content.add("Show ") limit_select = SelectWdg("limit_select") limit_select.add_class("spt_search_limit_select") limit_select.set_option("values", "10|20|50|100|200|Custom") limit_select.add_style("font-size: 10px") limit_content.add(limit_select) limit_content.add(" items per page<br/>") if self.search_limit in [10,20,50,100,200]: limit_select.set_value(self.search_limit) is_custom = False else: limit_select.set_value("Custom") is_custom = True limit_select.add_behavior( { 'type': 'change', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_search_limit_top"); var value = bvr.src_el.value; var custom = top.getElement(".spt_search_limit_custom"); if (value == 'Custom') { custom.setStyle("display", ""); } else { custom.setStyle("display", "none"); } ''' } ) custom_limit = DivWdg() limit_content.add(custom_limit) custom_limit.add_class("spt_search_limit_custom") custom_limit.add("<br/>Custom: ") text = TextWdg("custom_limit") text.add_class("spt_search_limit_custom_text") text.add_style("width: 50px") if not is_custom: custom_limit.add_style("display: none") else: text.set_value(self.search_limit) custom_limit.add(text) text.add(" items") behavior = { 'type': 'keydown', 'cbjs_action': ''' if (evt.key=='enter') { // register this as changed item var value = bvr.src_el.value; if (isNaN(value) || value.test(/[\.-]/)) { spt.error('You have to use an integer.'); } } '''} text.add_behavior(behavior) return limit_content