def get_display(my): #assert my.template top = DivWdg() top.add_class("spt_list_top") top.add_relay_behavior({ 'type': 'mouseup', 'bvr_match_class': 'spt_remove', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_list_top"); var items = top.getElements(".spt_list_item"); if (items.length > 1) { var item = bvr.src_el.getParent(".spt_list_item"); item.destroy(); } ''' }) top.add_relay_behavior({ 'type': 'mouseup', 'bvr_match_class': 'spt_add', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_list_top"); var template = top.getElement(".spt_list_template_item"); var new_item = spt.behavior.clone(template); var item = bvr.src_el.getParent(".spt_list_item"); new_item.removeClass("spt_list_template_item"); new_item.addClass("spt_list_item") new_item.setStyle("display", "") //new_item.inject(top, 'bottom'); new_item.inject(item, 'after'); ''' }) if my.template: template_wdg = my.get_item_wdg(my.template, is_template=True) top.add(template_wdg) for item in my.items: item_wdg = my.get_item_wdg(item) top.add(item_wdg) return top
def get_display(self): #assert self.template top = DivWdg() top.add_class("spt_list_top") top.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_remove', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_list_top"); var items = top.getElements(".spt_list_item"); if (items.length > 1) { var item = bvr.src_el.getParent(".spt_list_item"); item.destroy(); } ''' } ) top.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_add', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_list_top"); var template = top.getElement(".spt_list_template_item"); var new_item = spt.behavior.clone(template); var item = bvr.src_el.getParent(".spt_list_item"); new_item.removeClass("spt_list_template_item"); new_item.addClass("spt_list_item") new_item.setStyle("display", "") //new_item.inject(top, 'bottom'); new_item.inject(item, 'after'); ''' } ) if self.template: template_wdg = self.get_item_wdg(self.template, is_template=True) top.add(template_wdg ) for item in self.items: item_wdg = self.get_item_wdg(item) top.add( item_wdg ) return top
def get_templates_wdg(self): div = DivWdg() div.add_style("padding: 5px") div.add_color("background", "background3") div.add_style("height: 100%") title_div = DivWdg() button = ActionButtonWdg(title="+", tip="Choose a Project Template file to install", size="small") title_div.add(button) button.add_style("float: right") button.add_style("margin-top: -6px") button.add_style("margin-right: -4px") button.add_behavior( { 'type': 'click_up', 'cbjs_action': r''' var applet = spt.Applet.get(); spt.app_busy.show('Choose a Project Template file'); var paths = applet.open_file_browser(); var server = TacticServerStub.get(); var cmd = "tactic.ui.app.ProjectTemplateInstallCmd"; if (!paths.length) { return; } try { for (var i = 0; i < paths.length; i++) { if (!paths[i].test(/\.zip/)) { spt.alert('A template file should be a zip file'); return; } server.upload_file(paths[i]); } var kwargs = { paths: paths }; server.execute_cmd(cmd, kwargs); var path = paths[0] path = path.replace(/\\/g, "/"); var parts = path.split("/"); var name = parts[parts.length-1]; var parts2 = name.split("-"); var name = parts2[0]; var top = bvr.src_el.getParent(".spt_project_template_top"); top.setAttribute("spt_template", name); spt.panel.refresh(top); spt.app_busy.hide(); spt.notify.show_message("Project Template ["+name+"] has been installed."); }catch (e) { spt.app_busy.hide(); spt.alert(spt.exception.handler(e)); } ''' } ) div.add(title_div) title_div.add("<b>Installed Templates</b>") title_div.add_gradient("background", "background", 0, -10) title_div.add_color("color", "color3") title_div.add_style("margin: -5px -5px 5px -5px") title_div.add_style("font-weight: bold") title_div.add_style("padding: 8px") templates_div = DivWdg() div.add(templates_div) templates_div.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_template', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_project_template_top"); var content = top.getElement(".spt_project_template_content") var class_name = 'tactic.ui.app.ProjectTemplateEditWdg'; var template_dir = bvr.src_el.getAttribute("spt_template_dir"); var kwargs = { template_dir: template_dir }; spt.panel.load(content, class_name, kwargs); ''' } ) templates_div.add_class("hand") bgcolor = title_div.get_color("background3") bgcolor2 = title_div.get_color("background3", -10) templates_div.add_relay_behavior( { 'type': 'mouseover', 'bvr_match_class': 'spt_template', 'cbjs_action': ''' bvr.src_el.setStyle("background", "%s") ''' % bgcolor2 } ) templates_div.add_relay_behavior( { 'type': 'mouseout', 'bvr_match_class': 'spt_template', 'cbjs_action': ''' bvr.src_el.setStyle("background", "%s") ''' % bgcolor } ) template_dir = Environment.get_template_dir() if not template_dir: raise Exception("No template dir defined") #template_dir = "/home/apache/project_templates" dirnames = os.listdir(template_dir) #templates = ['scrum', 'tickets', 'vfx', 'game'] for template in dirnames: path = "%s/%s" % (template_dir, template) if not os.path.isdir(path): continue template_div = DivWdg() templates_div.add(template_div) icon = IconWdg("View Template [%s]" % template, IconWdg.DETAILS) template_div.add(icon) template_div.add(template) template_div.add_style("padding: 5px 3px 5px 3px") template_div.add_class("spt_template") template_div.add_attr("spt_template_dir", path) return div
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
def get_display(my): my.doc_mode = my.kwargs.get("doc_mode") path = my.kwargs.get("path") my.search_type = my.kwargs.get("search_type") my.last_path = None doc_key = my.kwargs.get("doc_key") if doc_key: my.doc = Search.get_by_search_key(doc_key) snapshot = Snapshot.get_latest_by_sobject(my.doc) if snapshot: my.last_path = snapshot.get_lib_path_by_type('main') path = my.doc.get_value("link") # TEST TEST TEST if not path: #path = "/home/apache/pdf/mongodb.txt" #path = "/home/apache/assets/google_docs.html" #path = "/home/apache/pdf/star_wars.txt" path = "https://docs.google.com/document/d/1AC_YR8X8wbKsshkJ1h8EjZuFIr41guvqXq3_PXgaqJ0/pub?embedded=true" path = "https://docs.google.com/document/d/1WPUmXYoSkR2cz0NcyM2vqQYO6OGZW8BAiDL31YEj--M/pub" #path = "https://docs.google.com/spreadsheet/pub?key=0Al0xl-XktnaNdExraEE4QkxVQXhaOFh1SHIxZmZMQ0E&single=true&gid=0&output=html" path = "/home/apache/tactic/doc/alias.json" if not my.search_type: my.search_type = "test3/shot" my.column = "description" top = my.top top.add_class("spt_document_top") my.set_as_panel(top) #table = Table() table = ResizableTableWdg() top.add(table) table.add_row() table.set_max_width() left_td = table.add_cell() left_td.add_style("vertical-align: top") title = DivWdg() left_td.add(title) title.add_style("padding: 10px") title.add_color("background", "background3") button = IconButtonWdg(title="Refresh", icon=IconWdg.REFRESH) title.add(button) button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' spt.app_busy.show("Reloading Document"); var top = bvr.src_el.getParent(".spt_document_top"); spt.panel.refresh(top); spt.app_busy.hide(); ''' }) button.add_style("float: left") button = IconButtonWdg(title="Save", icon=IconWdg.SAVE) title.add(button) button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' ''' }) button.add_style("float: left") if not my.doc_mode: my.doc_mode = "text" select = SelectWdg("doc_mode") select.set_option("values", "text|formatted") title.add(select) select.set_value(my.doc_mode) select.add_behavior({ 'type': 'change', 'cbjs_action': ''' spt.app_busy.show("Reloading Document"); var top = bvr.src_el.getParent(".spt_document_top"); var value = bvr.src_el.value; top.setAttribute("spt_doc_mode", value); spt.panel.refresh(top); spt.app_busy.hide(); ''' }) title.add("<br clear='all'/>") #title.add(path) text_wdg = DivWdg() text_wdg.add_class("spt_document_content") left_td.add(text_wdg) #if path.startswith("https://docs.google.com/spreadsheet"): # #path = "http://www.southpawtech.com.com" # text_wdg.add(''' # <iframe class="spt_document_iframe" style="width: 100%%; height: auto; min-height: 600px; font-size: 1.0em" src="%s"></iframe> # ''' % path) # text_wdg.add_style("overflow-x: hidden") if True: if not my.last_path and my.doc: tmp_dir = Environment.get_tmp_dir() tmp_path = '%s/last_path.txt' % tmp_dir f = open(tmp_path, 'w') text = my.get_text(path, highlight=False) f.write(text) f.close() cmd = FileCheckin(my.doc, tmp_path) Command.execute_cmd(cmd) else: save = False if save: # open up the last path f = open(my.last_path, 'r') last_text = f.read() text = my.get_text(path, None, highlight=False) if last_text != text: tmp_dir = Environment.get_tmp_dir() tmp_path = '%s/last_path.txt' % tmp_dir f = open(tmp_path, 'w') f.write(text) f.write(text) f.close() cmd = FileCheckin(my.doc, tmp_path) Command.execute_cmd(cmd) text = my.get_text(path, my.last_path) lines = text.split("\n") if my.doc_mode == "text": num_lines = len(lines) """ line_div = HtmlElement.pre() text_wdg.add(line_div) line_div.add_style("width: 20px") line_div.add_style("float: left") line_div.add_style("text-align: right") line_div.add_style("opacity: 0.3") line_div.add_style("padding-right: 10px") for i in range(0, num_lines*2): line_div.add(i+1) line_div.add("<br/>") """ if my.doc_mode == "text": pre = HtmlElement.pre() pre.add_style("white-space: pre-wrap") else: pre = DivWdg() pre = DivWdg() text_wdg.add(pre) text_wdg.add_style("padding: 10px 5px") text_wdg.add_style("max-height: 600px") text_wdg.add_style("overflow-y: auto") text_wdg.add_style("width: 600px") text_wdg.add_class("spt_resizable") pre.add_style("font-family: courier") if my.doc_mode == "formatted": pre.add(text) else: line_table = Table() pre.add(line_table) line_table.add_style("width: 100%") count = 1 for line in lines: #line = line.replace(" ", " ") tr = line_table.add_row() if count % 2 == 0: tr.add_color("background", "background", -2) td = line_table.add_cell() # FIXME: hacky if line.startswith('''<span style='background: #CFC'>'''): is_new = True else: td.add_style("vertical-align: top") text = TextWdg() text.add_style("border", "none") text.add_style("text-align", "right") text.add_style("width", "25px") text.add_style("margin", "0 10 0 0") text.add_style("opacity", "0.5") text.set_value(count) td.add(text) count += 1 is_new = False td = line_table.add_cell() if not is_new: SmartMenu.assign_as_local_activator(td, 'TEXT_CTX') tr.add_class("spt_line") else: SmartMenu.assign_as_local_activator(td, 'TEXT_NEW_CTX') tr.add_class("spt_new_line") td.add_class("spt_line_content") td.add(line) #from tactic.ui.app import AceEditorWdg #editor = AceEditorWdg(code=text, show_options=False, readonly=True, height="600px") #text_wdg.add(editor) # add a click on spt_item text_wdg.add_relay_behavior({ 'type': 'mouseup', 'bvr_match_class': 'spt_document_item', 'search_type': my.search_type, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_document_top"); var data_el = top.getElement(".spt_document_data"); var search_key = bvr.src_el.getAttribute("spt_search_key"); var class_name = 'tactic.ui.panel.ViewPanelWdg'; var kwargs = { 'search_type': bvr.search_type, 'search_key': search_key, } spt.panel.load(data_el, class_name, kwargs); ''' }) # add a double click on spt_item bgcolor = text_wdg.get_color("background", -10) text_wdg.add_relay_behavior({ 'type': 'mouseover', 'bvr_match_class': 'spt_document_item', 'search_type': my.search_type, 'bgcolor': bgcolor, 'cbjs_action': ''' bvr.src_el.setStyle("opacity", "1.0"); //bvr.src_el.setStyle("font-weight", "normal"); bvr.src_el.setStyle("background", bvr.bgcolor); ''' }) # add a double click on spt_item text_wdg.add_relay_behavior({ 'type': 'mouseout', 'bvr_match_class': 'spt_document_item', 'search_type': my.search_type, 'cbjs_action': ''' bvr.src_el.setStyle("opacity", "1.0"); //bvr.src_el.setStyle("font-weight", "bold"); bvr.src_el.setStyle("background", ""); ''' }) # add a context menu ctx_menu = my.get_text_context_menu() ctx_new_menu = my.get_text_new_context_menu() menus_in = { 'TEXT_CTX': ctx_menu, 'TEXT_NEW_CTX': ctx_new_menu, } SmartMenu.attach_smart_context_menu(text_wdg, menus_in, False) panel = ViewPanelWdg(search_type=my.search_type, layout="blah") right_td = table.add_cell() right_td.add_style("vertical-align: top") panel_div = DivWdg() panel_div.add_class("spt_document_data") right_td.add(panel_div) panel_div.add(panel) text_wdg.add_behavior({ 'type': 'load', 'cbjs_action': r''' spt.document = {}; spt.document.selected_text = null; spt.document.get_selected_text = function(frame) { var t = ''; if (frame) { var rng = frame.contentWindow.getSelection().getRangeAt(0); spt.document.expandtoword(rng); t = rng.toString(); } else if (window.getSelection) // FF4 with one tab open? { var rng = window.getSelection().getRangeAt(0); spt.document.expandtoword(rng); t = rng.toString(); } else if (document.getSelection) // FF4 with multiple tabs open? { var rng = document.getSelection().getRangeAt(0); spt.document.expandtoword(rng); t = rng.toString(); } else if (document.selection) // IE8 { var rng = document.selection.createRange(); // expand range to enclose any word partially enclosed in it rng.expand("word"); t = rng.text; } // convert newline chars to spaces, collapse whitespace, and trim non-word chars return t.replace(/^\W+|\W+$/g, ''); //return t.replace(/\r?\n/g, " ").replace(/\s+/g, " ").replace(/^\W+|\W+$/g, ''); } // expand FF range to enclose any word partially enclosed in it spt.document.expandtoword = function(range) { if (range.collapsed) { return; } while (range.startOffset > 0 && range.toString()[0].match(/\w/)) { range.setStart(range.startContainer, range.startOffset - 1); } while (range.endOffset < range.endContainer.length && range.toString()[range.toString().length - 1].match(/\w/)) { range.setEnd(range.endContainer, range.endOffset + 1); } } ''' }) top.add_relay_behavior({ 'type': 'mouseup', 'bvr_match_class': 'spt_document_content', 'cbjs_action': r''' //spt.ace_editor.set_editor_top(bvr.src_el); //var text = spt.ace_editor.get_selection(); var text = spt.document.get_selected_text(); text = text.replace(/\n\n/mg, "\n"); text = text.replace(/\n\n/mg, "\n"); spt.document.selected_text = text + ""; ''' }) return top
def get_templates_wdg(my): div = DivWdg() div.add_style("padding: 5px") div.add_color("background", "background3") div.add_style("height: 100%") title_div = DivWdg() button = ActionButtonWdg(title="+", tip="Choose a Project Template file to install", size="small") title_div.add(button) button.add_style("float: right") button.add_style("margin-top: -6px") button.add_style("margin-right: -4px") button.add_behavior( { 'type': 'click_up', 'cbjs_action': r''' var applet = spt.Applet.get(); spt.app_busy.show('Choose a Project Template file'); var paths = applet.open_file_browser(); var server = TacticServerStub.get(); var cmd = "tactic.ui.app.ProjectTemplateInstallCmd"; if (!paths.length) { return; } try { for (var i = 0; i < paths.length; i++) { if (!paths[i].test(/\.zip/)) { spt.alert('A template file should be a zip file'); return; } server.upload_file(paths[i]); } var kwargs = { paths: paths }; server.execute_cmd(cmd, kwargs); var path = paths[0] path = path.replace(/\\/g, "/"); var parts = path.split("/"); var name = parts[parts.length-1]; var parts2 = name.split("-"); var name = parts2[0]; var top = bvr.src_el.getParent(".spt_project_template_top"); top.setAttribute("spt_template", name); spt.panel.refresh(top); spt.app_busy.hide(); spt.notify.show_message("Project Template ["+name+"] has been installed."); }catch (e) { spt.app_busy.hide(); spt.alert(spt.exception.handler(e)); } ''' } ) div.add(title_div) title_div.add("<b>Installed Templates</b>") title_div.add_gradient("background", "background", 0, -10) title_div.add_color("color", "color3") title_div.add_style("margin: -5px -5px 5px -5px") title_div.add_style("font-weight: bold") title_div.add_style("padding: 8px") templates_div = DivWdg() div.add(templates_div) templates_div.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_template', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_project_template_top"); var content = top.getElement(".spt_project_template_content") var class_name = 'tactic.ui.app.ProjectTemplateEditWdg'; var template_dir = bvr.src_el.getAttribute("spt_template_dir"); var kwargs = { template_dir: template_dir }; spt.panel.load(content, class_name, kwargs); ''' } ) templates_div.add_class("hand") bgcolor = title_div.get_color("background3") bgcolor2 = title_div.get_color("background3", -10) templates_div.add_relay_behavior( { 'type': 'mouseover', 'bvr_match_class': 'spt_template', 'cbjs_action': ''' bvr.src_el.setStyle("background", "%s") ''' % bgcolor2 } ) templates_div.add_relay_behavior( { 'type': 'mouseout', 'bvr_match_class': 'spt_template', 'cbjs_action': ''' bvr.src_el.setStyle("background", "%s") ''' % bgcolor } ) template_dir = Environment.get_template_dir() if not template_dir: raise Exception("No template dir defined") #template_dir = "/home/apache/project_templates" dirnames = os.listdir(template_dir) #templates = ['scrum', 'tickets', 'vfx', 'game'] for template in dirnames: path = "%s/%s" % (template_dir, template) if not os.path.isdir(path): continue template_div = DivWdg() templates_div.add(template_div) icon = IconWdg("View Template [%s]" % template, IconWdg.DETAILS) template_div.add(icon) template_div.add(template) template_div.add_style("padding: 5px 3px 5px 3px") template_div.add_class("spt_template") template_div.add_attr("spt_template_dir", path) return div
def get_display(self): top = self.top top.add_style("margin: 10px") search = Search("config/widget_config") search.add_column("view") search.add_filter("category", "CustomLayoutWdg") search.add_filter("view", "pages.%", op="like") sobjects = search.get_sobjects() self.pages = SObject.get_values(sobjects, "view") top.add("<div style='font-size: 16px'>Select page to load</div>") top.add("<hr/>") pages_div = DivWdg() top.add(pages_div) pages_div.add_style("margin: 20px") pages_div.add_relay_behavior( { 'type': 'click', 'bvr_match_class': "spt_user_page_item", 'cbjs_action': ''' var popup = bvr.src_el.getParent(".spt_popup"); var activator = popup.activator; var page = bvr.src_el.getAttribute("spt_page"); var top = activator.getParent(".spt_panel_top"); var content = top.getElement(".spt_panel_content"); var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: page, } spt.panel.load(content, class_name, kwargs); spt.popup.close(popup); ''' } ) if self.pages: last_parts = self.pages[0].split(".")[:-1] self.pages.sort() last_parts = [] for count, page in enumerate(self.pages): page = page.replace(".", "/") page_div = DivWdg() pages_div.add(page_div) page_div.add_class("spt_user_page_item") page_div.add_style("padding: 3px") page_div.add_class("tactic_hover") page_div.add_attr("spt_page", page) page_div.add_class("hand") page_div.add_style("min-width: 400px") new_parts = [] parts = page.split("/") parts = parts[1:] index = 0 for part in parts: if index < len(last_parts): last_part = last_parts[index] if part == last_part: part = "<i style='opacity: 0.0'>%s</i>" % part index += 1 new_parts.append(part) last_parts = parts #parts = ["<b>%s</b>" % x for x in parts] display_path = " <i style='opacity: 1.0'>/</i> ".join(new_parts) page_div.add("<div style='margin-right: 10px;display: inline-block; width: 20px; text-align: right'>%s: </div>" % count) page_div.add(display_path) return top
def get_collection_wdg(my): div = DivWdg() div.add_style("margin: 15px 0px") title_div = DivWdg("Collection Manager") div.add(title_div) div.add_class("spt_collection_left") title_div.add_style("font-size: 1.2em") title_div.add_style("font-weight: bold") div.add("<hr/>") # Shelf shelf_div = DivWdg() div.add(shelf_div) shelf_div.add_style("float: right") shelf_div.add_style("margin-bottom: 15px") #button = IconButtonWdg(title='Delete Selected Collection', icon="BS_TRASH") #shelf_div.add(button) #button.add_style("display: inline-block") #button.add_style("width: auto") button = IconButtonWdg(title='Add New Collection', icon="BS_PLUS") shelf_div.add(button) button.add_style("display: inline-block") button.add_style("vertical-align: top") insert_view = "edit_collection" button.add_behavior( { 'type': 'click_up', 'insert_view': insert_view, 'search_type': my.search_type, 'cbjs_action': ''' kwargs = { search_type: bvr.search_type, mode: 'insert', view: bvr.insert_view, save_event: bvr.event_name, show_header: false, num_columns: 2, default: { _is_collection: true } }; var popup = spt.panel.load_popup('Add New Collection', 'tactic.ui.panel.EditWdg', kwargs); ''' } ) text_div = DivWdg() shelf_div.add(text_div) custom_cbk = {} custom_cbk['enter'] = ''' var top = bvr.src_el.getParent(".spt_collection_left"); var input = top.getElement(".spt_main_search"); var search_value = input.value.toLowerCase(); var collections = top.getElements(".spt_collection_div"); var num_result = 0; for (i = 0; i < collections.length; i++) { // Access the Collection title (without number count) var collection_title = collections[i].attributes[0].value.toLowerCase(); if (collection_title.indexOf(search_value) != '-1') { collections[i].style.display = "block"; num_result += 1; } else { collections[i].style.display = "none"; } } // if no search results, display all if (num_result == 0) { for (i = 0; i < collections.length; i++) { collections[i].style.display = "block"; } } ''' filters = [] filters.append(("_is_collection",True)) filters.append(("status","Verified")) text = LookAheadTextInputWdg( search_type = "workflow/asset", column="name", width="100%", hint_text="Enter terms to filter collections...", value_column="name", filters=filters, custom_cbk=custom_cbk, is_collection=True ) text.add_class("spt_main_search") text_div.add(text) text_div.add_style("width: 270px") text_div.add_style("display: inline-block") # Asset Library folder access div.add("<br clear='all'/>") asset_lib_div = DivWdg() div.add(asset_lib_div) folder_icon = IconWdg(icon="FOLDER_2", width='30px') asset_lib_div.add(folder_icon) asset_lib_div.add_style("margin: 5px 0px 5px -5px") asset_lib_div.add_style("height: 20px") asset_lib_div.add_style("padding-top: 5px") asset_lib_div.add_style("padding-bottom: 5px") asset_lib_div.add_style("font-weight: bold") asset_lib_div.add("Asset Library") asset_lib_div.add_class("tactic_hover") asset_lib_div.add_class("hand") asset_lib_div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElements(".spt_collection_content"); spt.panel.refresh(top); ''' } ) # collection search = Search(my.search_type) search.add_filter("_is_collection", True) collections = search.get_sobjects() collections_div = DivWdg() collections_div.add_class("spt_collection_list") div.add(collections_div) collections_div.add_style("margin: 5px 0px 5px -5px") from tactic.ui.panel import ThumbWdg2 parts = my.search_type.split("/") collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1]) collections_div.add_relay_behavior( { 'type': 'mouseup', 'search_type': my.search_type, 'collection_type': collection_type, 'bvr_match_class': 'spt_collection_item', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElement(".spt_collection_content"); var list = bvr.src_el.getParent(".spt_collection_list"); var items = list.getElements(".spt_collection_item"); for (var i = 0; i < items.length; i++) { items[i].setStyle("background", ""); items[i].setStyle("box-shadow", ""); } bvr.src_el.setStyle("background", "#EEE"); var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_code = bvr.src_el.getAttribute("spt_collection_code"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var expr = "@SEARCH("+bvr.collection_type+"['parent_code','"+collection_code+"']."+bvr.search_type+")"; var parent_dict = {}; var parent_collection = bvr.src_el.getParent(".spt_subcollection_wdg"); var path = collection_path.substring(0, collection_path.lastIndexOf("/")); if (parent_collection) { for (var i = 0; i < collection_path.split("/").length - 1; i++) { var n = path.lastIndexOf("/"); var collection_name = path.substring(n+1); path = path.substring(0, n); var parent_key = parent_collection.getAttribute("spt_parent_key"); parent_dict[collection_name] = parent_key; parent_collection = parent_collection.getParent(".spt_subcollection_wdg"); } } var cls = "tactic.ui.panel.CollectionContentWdg"; var kwargs = { collection_key: collection_key, path: collection_path, search_type: bvr.search_type, show_shelf: false, show_search_limit: true, expression: expr, parent_dict: parent_dict } spt.panel.load(content, cls, kwargs); bvr.src_el.setStyle("box-shadow", "0px 0px 3px rgba(0,0,0,0.5)"); // hide the bottom show_search_limit when clicking into a collection var panel = bvr.src_el.getParent(".spt_panel"); var search_limit_div = panel.getElements(".spt_search_limit_top"); if (search_limit_div.length == 2){ search_limit_div[1].setStyle("visibility", "hidden"); } ''' } ) collections_div.add_relay_behavior( { 'type': 'mouseup', 'search_type': my.search_type, 'bvr_match_class': 'spt_collection_open', 'cbjs_action': ''' var item = bvr.src_el.getParent(".spt_collection_div_top"); var next = item.getNext(); if (bvr.src_el.hasClass("spt_open")) { next.innerHTML = ""; bvr.src_el.setStyle("opacity", 1.0); bvr.src_el.removeClass("spt_open"); } else { var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var cls = "tactic.ui.panel.CollectionListWdg"; var kwargs = { parent_key: collection_key, path: collection_path, } spt.panel.load(next, cls, kwargs, null, {show_loading: false}); bvr.src_el.setStyle("opacity", 0.3); bvr.src_el.addClass("spt_open"); evt.stopPropagation(); } ''' } ) for collection in collections: collection_wdg = CollectionItemWdg(collection=collection, path=collection.get_value("name")) collections_div.add(collection_wdg) collection_wdg.add_class("spt_collection_div") subcollection_wdg = DivWdg() collections_div.add(subcollection_wdg) subcollection_wdg.add_class("spt_subcollection_wdg") subcollection_wdg.add_style("padding-left: 15px") return div
def get_collection_wdg(my): div = DivWdg() div.add_style("margin: 15px 0px") title_div = DivWdg("Collection Manager") div.add(title_div) div.add_class("spt_collection_left") title_div.add_style("font-size: 1.2em") title_div.add_style("font-weight: bold") div.add("<hr/>") # Shelf shelf_div = DivWdg() div.add(shelf_div) shelf_div.add_style("float: right") shelf_div.add_style("margin-bottom: 15px") #button = IconButtonWdg(title='Delete Selected Collection', icon="BS_TRASH") #shelf_div.add(button) #button.add_style("display: inline-block") #button.add_style("width: auto") button = IconButtonWdg(title='Add New Collection', icon="BS_PLUS") shelf_div.add(button) button.add_style("display: inline-block") button.add_style("vertical-align: top") insert_view = "edit_collection" button.add_behavior({ 'type': 'click_up', 'insert_view': insert_view, 'search_type': my.search_type, 'cbjs_action': ''' kwargs = { search_type: bvr.search_type, mode: 'insert', view: bvr.insert_view, save_event: bvr.event_name, show_header: false, num_columns: 2, default: { _is_collection: true } }; var popup = spt.panel.load_popup('Add New Collection', 'tactic.ui.panel.EditWdg', kwargs); ''' }) text_div = DivWdg() shelf_div.add(text_div) custom_cbk = {} custom_cbk['enter'] = ''' var top = bvr.src_el.getParent(".spt_collection_left"); var input = top.getElement(".spt_main_search"); var search_value = input.value.toLowerCase(); var collections = top.getElements(".spt_collection_div"); var num_result = 0; for (i = 0; i < collections.length; i++) { // Access the Collection title (without number count) var collection_title = collections[i].attributes[0].value.toLowerCase(); if (collection_title.indexOf(search_value) != '-1') { collections[i].style.display = "block"; num_result += 1; } else { collections[i].style.display = "none"; } } // if no search results, display all if (num_result == 0) { for (i = 0; i < collections.length; i++) { collections[i].style.display = "block"; } } ''' filters = [] filters.append(("_is_collection", True)) filters.append(("status", "Verified")) text = LookAheadTextInputWdg( search_type="workflow/asset", column="name", width="100%", hint_text="Enter terms to filter collections...", value_column="name", filters=filters, custom_cbk=custom_cbk, is_collection=True) text.add_class("spt_main_search") text_div.add(text) text_div.add_style("width: 270px") text_div.add_style("display: inline-block") # Asset Library folder access div.add("<br clear='all'/>") asset_lib_div = DivWdg() div.add(asset_lib_div) folder_icon = IconWdg(icon="FOLDER_2", width='30px') asset_lib_div.add(folder_icon) asset_lib_div.add_style("margin: 5px 0px 5px -5px") asset_lib_div.add_style("height: 20px") asset_lib_div.add_style("padding-top: 5px") asset_lib_div.add_style("padding-bottom: 5px") asset_lib_div.add_style("font-weight: bold") asset_lib_div.add("Asset Library") asset_lib_div.add_class("tactic_hover") asset_lib_div.add_class("hand") asset_lib_div.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElements(".spt_collection_content"); spt.panel.refresh(top); ''' }) # collection search = Search(my.search_type) search.add_filter("_is_collection", True) collections = search.get_sobjects() collections_div = DivWdg() collections_div.add_class("spt_collection_list") div.add(collections_div) collections_div.add_style("margin: 5px 0px 5px -5px") from tactic.ui.panel import ThumbWdg2 parts = my.search_type.split("/") collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1]) collections_div.add_relay_behavior({ 'type': 'mouseup', 'search_type': my.search_type, 'collection_type': collection_type, 'bvr_match_class': 'spt_collection_item', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElement(".spt_collection_content"); var list = bvr.src_el.getParent(".spt_collection_list"); var items = list.getElements(".spt_collection_item"); for (var i = 0; i < items.length; i++) { items[i].setStyle("background", ""); items[i].setStyle("box-shadow", ""); } bvr.src_el.setStyle("background", "#EEE"); var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_code = bvr.src_el.getAttribute("spt_collection_code"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var expr = "@SEARCH("+bvr.collection_type+"['parent_code','"+collection_code+"']."+bvr.search_type+")"; var parent_dict = {}; var parent_collection = bvr.src_el.getParent(".spt_subcollection_wdg"); var path = collection_path.substring(0, collection_path.lastIndexOf("/")); if (parent_collection) { for (var i = 0; i < collection_path.split("/").length - 1; i++) { var n = path.lastIndexOf("/"); var collection_name = path.substring(n+1); path = path.substring(0, n); var parent_key = parent_collection.getAttribute("spt_parent_key"); parent_dict[collection_name] = parent_key; parent_collection = parent_collection.getParent(".spt_subcollection_wdg"); } } var cls = "tactic.ui.panel.CollectionContentWdg"; var kwargs = { collection_key: collection_key, path: collection_path, search_type: bvr.search_type, show_shelf: false, show_search_limit: true, expression: expr, parent_dict: parent_dict } spt.panel.load(content, cls, kwargs); bvr.src_el.setStyle("box-shadow", "0px 0px 3px rgba(0,0,0,0.5)"); // hide the bottom show_search_limit when clicking into a collection var panel = bvr.src_el.getParent(".spt_panel"); var search_limit_div = panel.getElements(".spt_search_limit_top"); if (search_limit_div.length == 2){ search_limit_div[1].setStyle("visibility", "hidden"); } ''' }) collections_div.add_relay_behavior({ 'type': 'mouseup', 'search_type': my.search_type, 'bvr_match_class': 'spt_collection_open', 'cbjs_action': ''' var item = bvr.src_el.getParent(".spt_collection_div_top"); var next = item.getNext(); if (bvr.src_el.hasClass("spt_open")) { next.innerHTML = ""; bvr.src_el.setStyle("opacity", 1.0); bvr.src_el.removeClass("spt_open"); } else { var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var cls = "tactic.ui.panel.CollectionListWdg"; var kwargs = { parent_key: collection_key, path: collection_path, } spt.panel.load(next, cls, kwargs, null, {show_loading: false}); bvr.src_el.setStyle("opacity", 0.3); bvr.src_el.addClass("spt_open"); evt.stopPropagation(); } ''' }) for collection in collections: collection_wdg = CollectionItemWdg( collection=collection, path=collection.get_value("name")) collections_div.add(collection_wdg) collection_wdg.add_class("spt_collection_div") subcollection_wdg = DivWdg() collections_div.add(subcollection_wdg) subcollection_wdg.add_class("spt_subcollection_wdg") subcollection_wdg.add_style("padding-left: 15px") return div
class BaseRefreshWdg(Widget): def __init__(self, **kwargs): # get the them from cgi self.handle_args(kwargs) self.top = DivWdg() super(BaseRefreshWdg,self).__init__() # # Define a standard format for widgets # # Get it from web_form_values() ARGS_KEYS = {} def get_args_keys(cls): '''external settings which populate the widget''' return cls.ARGS_KEYS get_args_keys = classmethod(get_args_keys) CATEGORY_KEYS = {} def get_category_keys(cls): return cls.CATEGORY_KEYS get_category_keys = classmethod(get_category_keys) # DEPRECATED: use ARGS_KEYS ARGS_OPTIONS = [] def get_args_options(cls): '''external settings which populate the widget''' return cls.ARGS_OPTIONS get_args_options = classmethod(get_args_options) def handle_args(self, kwargs): # verify the args #args_keys = self.get_args_keys() if kwargs.get("include_form_values") in [True, 'true']: web = WebContainer.get_web() args_keys = self.get_args_keys() for key in args_keys.keys(): if web and not kwargs.has_key(key): value = web.get_form_value(key) kwargs[key] = value else: args_keys = self.get_args_keys() for key in args_keys.keys(): if not kwargs.has_key(key): kwargs[key] = '' self.kwargs = kwargs def set_arg(self, name, value): self.kwargs[name] = value def get_top(self): return self.top def add_class(self, class_name): self.top.add_class(class_name) def add_attr(self, name, value): self.top.add_attr(name, value) def set_attr(self, name, value): self.top.set_attr(name, value) def add_style(self, name, value=None): self.top.add_style(name, value) def get_style(self, name): self.top.get_style(name) def add_behavior(self, behavior): self.top.add_behavior(behavior) def add_color(self, name, palette_key, modifier=0, default=None): self.top.add_color(name, palette_key, modifier=modifier, default=default) def get_kwargs(self): return self.kwargs def get_sobject_from_kwargs(self): sobject = None search_key = self.kwargs.get('search_key') parent_key = self.kwargs.get('parent_key') # sometimes None is passed as a string if search_key == "None": return None if search_key: sobject = Search.get_by_search_key( search_key ) elif parent_key: sobject = Search.get_by_search_key( parent_key ) else: search_type = self.kwargs.get("search_type") code = self.kwargs.get("code") id = self.kwargs.get("id") if search_type and (code or id): search = Search(search_type) if code: search.add_filter("code", code) try: id = int(code) search.add_filter("id", id) search.add_where("or") except ValueError as e: pass elif id: try: #id = int(code) search.add_filter("id", id) except ValueError as e: pass #search.add_filter("code", code) sobject = search.get_sobject() return sobject def serialize(self): '''provide the ability for a widget to serialize itself''' xml = Xml() xml.create_doc("config") # create the top element element = xml.create_element("element") xml.set_attribute(element, "name", self.name) # create the display handler display = xml.create_element("display") xml.set_attribute(display, "class", Common.get_full_class_name(self) ) element.appendChild(display) # create the options for name, value in self.kwargs.items(): if value: option = xml.create_text_element(name, value) else: # avoid the \n in the textContent of the textNode option = xml.create_element(name) display.appendChild(option) return xml.to_string(element) def get_top(self): return self.top def add_style(self, name, value=None): return self.top.add_style(name, value=value) def add_class(self, class_name): return self.top.add_class(class_name) def has_class(self, class_name): return self.top.has_class(class_name) def add_behavior(self, behavior): return self.top.add_behavior(behavior) def add_relay_behavior(self, behavior): return self.top.add_relay_behavior(behavior) def set_option(self, name, value): self.kwargs[name] = value def get_option(self, name): return self.kwargs.get(name) def get_persistent_key(self): return "whatever" def commit(self): # store the widget persistently config_xml = self.serialize() key = self.get_persistent_key() WidgetSettings.set_key_values(key, [config.xml.to_string()]) def get_by_key(self, key): key = self.get_persistent_key() return WidgetSettings.set_key_values(key, [config.xml.to_string()]) def set_as_panel(self, widget, class_name='spt_panel', kwargs=None): self.top = widget widget.add_class(class_name) widget.add_attr("spt_class_name", Common.get_full_class_name(self) ) if not kwargs: kwargs = self.kwargs for name, value in kwargs.items(): if name == 'class_name': continue if value == None: continue if type(value) not in types.StringTypes: value = str(value) # replace " with ' in case the kwargs is a dict value = value.replace('"', "'") if value: widget.add_attr("spt_%s" % name, value) def get_top_wdg(self): return self.top def process_state(state): '''process the state object for use with a widget. Usually a dictionary or a string version of it''' if not state: state = {} elif isinstance(state, basestring): # FIXME: SECURITY HOLE: NOT SURE ABOUT THIS if state != 'null': try: state = eval(state) except Exception as e: print("WARNING: ", str(e)) state = {} return state process_state = staticmethod(process_state)
def get_display(self): top = self.top top.add_style("margin: 10px") search = Search("config/widget_config") search.add_column("view") search.add_filter("category", "CustomLayoutWdg") search.add_filter("view", "pages.%", op="like") sobjects = search.get_sobjects() self.pages = SObject.get_values(sobjects, "view") top.add("<div style='font-size: 16px'>Select page to load</div>") top.add("<hr/>") pages_div = DivWdg() top.add(pages_div) pages_div.add_style("margin: 20px") pages_div.add_relay_behavior({ 'type': 'click', 'bvr_match_class': "spt_user_page_item", 'cbjs_action': ''' var popup = bvr.src_el.getParent(".spt_popup"); var activator = popup.activator; var page = bvr.src_el.getAttribute("spt_page"); var top = activator.getParent(".spt_panel_top"); var content = top.getElement(".spt_panel_content"); var class_name = 'tactic.ui.panel.CustomLayoutWdg'; var kwargs = { view: page, } spt.panel.load(content, class_name, kwargs); spt.popup.close(popup); ''' }) if self.pages: last_parts = self.pages[0].split(".")[:-1] self.pages.sort() last_parts = [] for count, page in enumerate(self.pages): page = page.replace(".", "/") page_div = DivWdg() pages_div.add(page_div) page_div.add_class("spt_user_page_item") page_div.add_style("padding: 3px") page_div.add_class("tactic_hover") page_div.add_attr("spt_page", page) page_div.add_class("hand") page_div.add_style("min-width: 400px") new_parts = [] parts = page.split("/") parts = parts[1:] index = 0 for part in parts: if index < len(last_parts): last_part = last_parts[index] if part == last_part: part = "<i style='opacity: 0.0'>%s</i>" % part index += 1 new_parts.append(part) last_parts = parts #parts = ["<b>%s</b>" % x for x in parts] display_path = " <i style='opacity: 1.0'>/</i> ".join( new_parts) page_div.add( "<div style='margin-right: 10px;display: inline-block; width: 20px; text-align: right'>%s: </div>" % count) page_div.add(display_path) 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
class BaseRefreshWdg(Widget): def __init__(self, **kwargs): # get the them from cgi self.handle_args(kwargs) self.top = DivWdg() super(BaseRefreshWdg, self).__init__() # # Define a standard format for widgets # # Get it from web_form_values() ARGS_KEYS = {} def get_args_keys(cls): '''external settings which populate the widget''' return cls.ARGS_KEYS get_args_keys = classmethod(get_args_keys) CATEGORY_KEYS = {} def get_category_keys(cls): return cls.CATEGORY_KEYS get_category_keys = classmethod(get_category_keys) # DEPRECATED: use ARGS_KEYS ARGS_OPTIONS = [] def get_args_options(cls): '''external settings which populate the widget''' return cls.ARGS_OPTIONS get_args_options = classmethod(get_args_options) def handle_args(self, kwargs): # verify the args #args_keys = self.get_args_keys() if kwargs.get("include_form_values") in [True, 'true']: web = WebContainer.get_web() args_keys = self.get_args_keys() for key in args_keys.keys(): if web and not kwargs.has_key(key): value = web.get_form_value(key) kwargs[key] = value else: args_keys = self.get_args_keys() for key in args_keys.keys(): if not kwargs.has_key(key): kwargs[key] = '' self.kwargs = kwargs def set_arg(self, name, value): self.kwargs[name] = value def get_top(self): return self.top def add_class(self, class_name): self.top.add_class(class_name) def add_attr(self, name, value): self.top.add_attr(name, value) def set_attr(self, name, value): self.top.set_attr(name, value) def add_style(self, name, value=None): self.top.add_style(name, value) def get_style(self, name): self.top.get_style(name) def add_behavior(self, behavior): self.top.add_behavior(behavior) def add_color(self, name, palette_key, modifier=0, default=None): self.top.add_color(name, palette_key, modifier=modifier, default=default) def get_kwargs(self): return self.kwargs def get_sobject_from_kwargs(self): sobject = None search_key = self.kwargs.get('search_key') parent_key = self.kwargs.get('parent_key') # sometimes None is passed as a string if search_key == "None": return None if search_key: sobject = Search.get_by_search_key(search_key) elif parent_key: sobject = Search.get_by_search_key(parent_key) else: search_type = self.kwargs.get("search_type") code = self.kwargs.get("code") id = self.kwargs.get("id") if search_type and (code or id): search = Search(search_type) if code: search.add_filter("code", code) try: id = int(code) search.add_filter("id", id) search.add_where("or") except ValueError as e: pass elif id: try: #id = int(code) search.add_filter("id", id) except ValueError as e: pass #search.add_filter("code", code) sobject = search.get_sobject() return sobject def serialize(self): '''provide the ability for a widget to serialize itself''' xml = Xml() xml.create_doc("config") # create the top element element = xml.create_element("element") xml.set_attribute(element, "name", self.name) # create the display handler display = xml.create_element("display") xml.set_attribute(display, "class", Common.get_full_class_name(self)) element.appendChild(display) # create the options for name, value in self.kwargs.items(): if value: option = xml.create_text_element(name, value) else: # avoid the \n in the textContent of the textNode option = xml.create_element(name) display.appendChild(option) return xml.to_string(element) def get_top(self): return self.top def add_style(self, name, value=None): return self.top.add_style(name, value=value) def add_class(self, class_name): return self.top.add_class(class_name) def has_class(self, class_name): return self.top.has_class(class_name) def add_behavior(self, behavior): return self.top.add_behavior(behavior) def add_relay_behavior(self, behavior): return self.top.add_relay_behavior(behavior) def set_option(self, name, value): self.kwargs[name] = value def get_option(self, name): return self.kwargs.get(name) def get_persistent_key(self): return "whatever" def commit(self): # store the widget persistently config_xml = self.serialize() key = self.get_persistent_key() WidgetSettings.set_key_values(key, [config.xml.to_string()]) def get_by_key(self, key): key = self.get_persistent_key() return WidgetSettings.set_key_values(key, [config.xml.to_string()]) def set_as_panel(self, widget, class_name='spt_panel', kwargs=None): self.top = widget widget.add_class(class_name) widget.add_attr("spt_class_name", Common.get_full_class_name(self)) if not kwargs: kwargs = self.kwargs for name, value in kwargs.items(): if name == 'class_name': continue if value == None: continue if type(value) not in types.StringTypes: value = str(value) # replace " with ' in case the kwargs is a dict value = value.replace('"', "'") if value: widget.add_attr("spt_%s" % name, value) def get_top_wdg(self): return self.top def process_state(state): '''process the state object for use with a widget. Usually a dictionary or a string version of it''' if not state: state = {} elif isinstance(state, basestring): # FIXME: SECURITY HOLE: NOT SURE ABOUT THIS if state != 'null': try: state = eval(state) except Exception as e: print("WARNING: ", str(e)) state = {} return state process_state = staticmethod(process_state)
def get_display(self): top = self.top inner = DivWdg() top.add(inner) inner.add_behavior( { 'type': 'load', 'cbjs_action': self.get_onload_js() } ) width = "100%" height = "100%" inner.add_style("width: %s" % width) inner.add_style("height: %s" % height) inner.add_style("overflow: hidden") inner.add_class("spt_container") content = DivWdg() inner.add(content) content.add_class("spt_content") content.add_style("width: %s" % width) content.add_style("height: %s" % height) content.add_style("position: relative") content.add_behavior( { 'type': 'load', 'cbjs_action': ''' spt.drag.load(bvr.src_el); ''' } ) content.add_behavior( { 'type': 'wheel', 'cbjs_action': ''' spt.drag.wheel(evt, bvr); ''' } ) inner.add_relay_behavior( { 'type': 'dblclick', 'bvr_match_class': 'spt_content', 'cbjs_action': ''' spt.drag.dblclick(evt, bvr); ''' } ) src = self.kwargs.get("src") if not src: src = DivWdg() src.add("No Content") img = HtmlElement.img(src=src) content.add(img) img.add_style("width: 100%") img.add_style("height: 100%") return top
def get_share_wdg(self): div = DivWdg() div.add_style("padding: 20px") msg = '''<p>Before starting to work on a project that you are sharing, you should import the starting point.</p>''' div.add(msg) button = ActionButtonWdg(title="Import") div.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var class_name = 'tactic.ui.sync.SyncImportWdg'; var top = bvr.src_el.getParent(".spt_share_top"); var content = top.getElement(".spt_share_content"); spt.panel.load(content, class_name); //spt.panel.load_popup("Sync Import", class_name); ''' } ) msg = '''<p>This allows you to create a share for this project. This will allow you to share this project with others.</p>''' div.add(msg) button = ActionButtonWdg(title="Share") div.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var class_name = 'tactic.ui.sync.SyncServerAddWdg'; spt.panel.load_popup("Sync Share", class_name); ''' } ) title_wdg = DivWdg() div.add( title_wdg ) title_wdg.add( "Local" ) title_wdg.add_style("padding: 5px") title_wdg.add_color("background", "background", -10) title_wdg.add_border() title_wdg.add_style("margin: 5px -22px 10px -22px") local_code = Config.get_value("install", "server") or "" local_div = DivWdg() div.add(local_div) local_div.add_class("spt_share_item") local_div.add_attr("spt_server_code", local_code) local_div.add_class("hand") local_div.add(local_code) local_div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var class_name = 'tactic.ui.startup.LocalItemWdg'; var top = bvr.src_el.getParent(".spt_share_top"); var content = top.getElement(".spt_share_content"); spt.panel.load(content, class_name); //spt.panel.load_popup("Sync Import", class_name); ''' } ) div.add("<br/>") search = Search("sthpw/sync_server") shares = search.get_sobjects() title_wdg = DivWdg() div.add( title_wdg ) title_wdg.add( "Share List" ) title_wdg.add_style("padding: 5px") title_wdg.add_color("background", "background", -10) title_wdg.add_border() title_wdg.add_style("margin: 5px -22px 10px -22px") shares_div = DivWdg() div.add(shares_div) shares_div.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_share_item', 'cbjs_action': ''' var server_code = bvr.src_el.getAttribute("spt_server_code"); var class_name = 'tactic.ui.startup.ShareItemWdg'; var kwargs = { server_code: server_code } var top = bvr.src_el.getParent(".spt_share_top"); var content = top.getElement(".spt_share_content"); spt.panel.load(content, class_name, kwargs); ''' } ) bgcolor = shares_div.get_color("background", -5) shares_div.add_relay_behavior( { 'type': 'mouseover', 'bvr_match_class': 'spt_share_item', 'bgcolor': bgcolor, 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.bgcolor); ''' } ) shares_div.add_relay_behavior( { 'type': 'mouseout', 'bvr_match_class': 'spt_share_item', 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); ''' } ) from pyasm.security import AccessManager access_manager = AccessManager() project = Project.get() project_code = project.get_code() # add in a context menu menu = self.get_context_menu() menus = [menu.get_data()] menus_in = { 'SHARE_ITEM_CTX': menus, } SmartMenu.attach_smart_context_menu( shares_div, menus_in, False ) count = 0 for share in shares: # hide the shares that are not in this project rules = share.get_value("access_rules"); access_manager.add_xml_rules(rules) key1 = { 'code': project_code } key2 = { 'code': '*' } keys = [key1, key2] if not access_manager.check_access("project", keys, "allow", default="deny"): continue share_div = DivWdg() shares_div.add(share_div) share_div.add_class("spt_share_item") share_div.add_attr("spt_server_code", share.get_code()) share_div.add_class("hand") share_div.add(share.get_code()) share_div.add_attr("title", share.get_value("description") ) share_div.add_style("padding: 5px") base_dir = share.get_value("base_dir") if base_dir: base_div = SpanWdg() share_div.add(base_div) base_div.add_style("font-size: 0.9em") base_div.add_style("font-style: italic") base_div.add_style("opacity: 0.5") base_div.add(" (%s)" % base_dir) share_div.add_attr("spt_share_code", share.get_code() ) SmartMenu.assign_as_local_activator( share_div, 'SHARE_ITEM_CTX' ) count += 1 if not count: share_div = DivWdg() shares_div.add(share_div) share_div.add("<i>No shares</i>") share_div.add_style("padding: 5px") return div
def get_versions_wdg(my): div = DivWdg() div.add_class("spt_imports") title_wdg = DivWdg() div.add(title_wdg) title_wdg.add("Imports found:") title_wdg.add_style("padding: 0px 0px 8px 0px") base_dir = my.kwargs.get("base_dir") imports_dir = "%s/imports" % base_dir if not os.path.exists(imports_dir): imports_dir = base_dir basenames = os.listdir(imports_dir) basenames.sort() basenames.reverse() div.add_relay_behavior({ 'type': 'mouseup', 'bvr_match_class': "spt_import_item", 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_imports"); var els = top.getElements(".spt_import_info"); for ( var i = 0; i < els.length; i++) { spt.hide(els[i]); } var el = bvr.src_el.getElement(".spt_import_info"); spt.show(el); ''' }) # find all the zip files count = 0 for basename in basenames: if not basename.endswith(".txt"): continue if basename.find("-files-") != -1: continue if basename.find("-data-") != -1: continue version_wdg = DivWdg() div.add(version_wdg) version_wdg.add_style("padding: 3px 3px 3px 12px") version_wdg.add_class("spt_import_item") radio = RadioWdg("basename") version_wdg.add(radio) radio.set_option("value", basename) if not count: radio.set_checked() version_wdg.add(basename) version_wdg.add("<br/>") # add info path = "%s/%s" % (imports_dir, basename) f = open(path) data = f.read() f.close() data = jsonloads(data) table = Table() version_wdg.add(table) table.add_class("spt_import_info") if count: table.add_style("display: none") table.set_max_width() table.add_style("margin-left: 40px") table.add_style("margin-right: 20px") version_wdg.add(table) for name, value in my.data.items(): name = Common.get_display_title(name) table.add_row() table.add_cell(name) table.add_cell(value) count += 1 if count == 0: msg_wdg = DivWdg() div.add(msg_wdg) msg_wdg.add("<i>No imports found</i>") msg_wdg.add_border() msg_wdg.add_style("padding: 20px") msg_wdg.add_style("padding: 10px") msg_wdg.add_style("text-align: center") msg_wdg.add_color("background", "background", -10) return div
def get_share_wdg(my): div = DivWdg() div.add_style("padding: 20px") msg = '''<p>Before starting to work on a project that you are sharing, you should import the starting point.</p>''' div.add(msg) button = ActionButtonWdg(title="Import") div.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var class_name = 'tactic.ui.sync.SyncImportWdg'; var top = bvr.src_el.getParent(".spt_share_top"); var content = top.getElement(".spt_share_content"); spt.panel.load(content, class_name); //spt.panel.load_popup("Sync Import", class_name); ''' } ) msg = '''<p>This allows you to create a share for this project. This will allow you to share this project with others.</p>''' div.add(msg) button = ActionButtonWdg(title="Share") div.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var class_name = 'tactic.ui.sync.SyncServerAddWdg'; spt.panel.load_popup("Sync Share", class_name); ''' } ) title_wdg = DivWdg() div.add( title_wdg ) title_wdg.add( "Local" ) title_wdg.add_style("padding: 5px") title_wdg.add_color("background", "background", -10) title_wdg.add_border() title_wdg.add_style("margin: 5px -22px 10px -22px") local_code = Config.get_value("install", "server") or "" local_div = DivWdg() div.add(local_div) local_div.add_class("spt_share_item") local_div.add_attr("spt_server_code", local_code) local_div.add_class("hand") local_div.add(local_code) local_div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var class_name = 'tactic.ui.startup.LocalItemWdg'; var top = bvr.src_el.getParent(".spt_share_top"); var content = top.getElement(".spt_share_content"); spt.panel.load(content, class_name); //spt.panel.load_popup("Sync Import", class_name); ''' } ) div.add("<br/>") search = Search("sthpw/sync_server") shares = search.get_sobjects() title_wdg = DivWdg() div.add( title_wdg ) title_wdg.add( "Share List" ) title_wdg.add_style("padding: 5px") title_wdg.add_color("background", "background", -10) title_wdg.add_border() title_wdg.add_style("margin: 5px -22px 10px -22px") shares_div = DivWdg() div.add(shares_div) shares_div.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_share_item', 'cbjs_action': ''' var server_code = bvr.src_el.getAttribute("spt_server_code"); var class_name = 'tactic.ui.startup.ShareItemWdg'; var kwargs = { server_code: server_code } var top = bvr.src_el.getParent(".spt_share_top"); var content = top.getElement(".spt_share_content"); spt.panel.load(content, class_name, kwargs); ''' } ) bgcolor = shares_div.get_color("background", -5) shares_div.add_relay_behavior( { 'type': 'mouseover', 'bvr_match_class': 'spt_share_item', 'bgcolor': bgcolor, 'cbjs_action': ''' bvr.src_el.setStyle("background", bvr.bgcolor); ''' } ) shares_div.add_relay_behavior( { 'type': 'mouseout', 'bvr_match_class': 'spt_share_item', 'cbjs_action': ''' bvr.src_el.setStyle("background", ""); ''' } ) from pyasm.security import AccessManager access_manager = AccessManager() project = Project.get() project_code = project.get_code() # add in a context menu menu = my.get_context_menu() menus = [menu.get_data()] menus_in = { 'SHARE_ITEM_CTX': menus, } SmartMenu.attach_smart_context_menu( shares_div, menus_in, False ) count = 0 for share in shares: # hide the shares that are not in this project rules = share.get_value("access_rules"); access_manager.add_xml_rules(rules) key1 = { 'code': project_code } key2 = { 'code': '*' } keys = [key1, key2] if not access_manager.check_access("project", keys, "allow", default="deny"): continue share_div = DivWdg() shares_div.add(share_div) share_div.add_class("spt_share_item") share_div.add_attr("spt_server_code", share.get_code()) share_div.add_class("hand") share_div.add(share.get_code()) share_div.add_attr("title", share.get_value("description") ) share_div.add_style("padding: 5px") base_dir = share.get_value("base_dir") if base_dir: base_div = SpanWdg() share_div.add(base_div) base_div.add_style("font-size: 0.9em") base_div.add_style("font-style: italic") base_div.add_style("opacity: 0.5") base_div.add(" (%s)" % base_dir) share_div.add_attr("spt_share_code", share.get_code() ) SmartMenu.assign_as_local_activator( share_div, 'SHARE_ITEM_CTX' ) count += 1 if not count: share_div = DivWdg() shares_div.add(share_div) share_div.add("<i>No shares</i>") share_div.add_style("padding: 5px") return div
def get_display(my): my.collection_key = my.kwargs.get("collection_key") collection = Search.get_by_search_key(my.collection_key) top = my.top my.kwargs["scale"] = 75; my.kwargs["show_scale"] = False; my.kwargs["expand_mode"] = "plain" from tile_layout_wdg import TileLayoutWdg tile = TileLayoutWdg( **my.kwargs ) parent_dict = my.kwargs.get("parent_dict") has_parent=False if parent_dict: has_parent = True path = my.kwargs.get("path") if collection and path: title_div = DivWdg() top.add(title_div) title_div.add_style("float: left") title_div.add_style("margin: 15px 0px 15px 30px") asset_lib_span_div = SpanWdg() title_div.add(asset_lib_span_div) icon = IconWdg(name="Asset Library", icon="BS_FOLDER_OPEN") asset_lib_span_div.add(icon) asset_lib_span_div.add(" <a><b>Asset Library</b></a> ") path = path.strip("/") parts = path.split("/") for idx, part in enumerate(parts): title_div.add(" / ") # the last spt_collection_link does not need a search_key if has_parent and (idx is not len(parts) - 1): search_key = parent_dict.get(part) title_div.add(" <a class='spt_collection_link' search_key=%s><b>%s</b></a> " % (search_key, part)) else: title_div.add(" <a class='spt_collection_link'><b>%s</b></a> " % part) title_div.add_style("margin-top: 10px") # Adding behavior to collections link parts = my.kwargs.get("search_type").split("/") collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1]) exists = SearchType.get(collection_type, no_exception=True) if not exists: title_div.add("SearchType %s is not registered." % collection_type) return top # These behaviors are only activated if the view is within collection layout, # "is_new_tab" is a kwargs set to true, if opening a new tab if not my.kwargs.get("is_new_tab"): icon.add_class("hand") icon.add_behavior( { 'type': 'mouseover', 'cbjs_action': ''' bvr.src_el.setStyle('opacity', 1.0); ''' } ) icon.add_behavior( { 'type': 'mouseout', 'cbjs_action': ''' bvr.src_el.setStyle('opacity', 0.6); ''' } ) # make icon and All Assets title clickable to return to view all assets asset_lib_span_div.add_class("hand") asset_lib_span_div.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElements(".spt_collection_content"); spt.panel.refresh(top); ''' } ) title_div.add_class("hand") title_div.add_relay_behavior( { 'type': 'mouseup', 'search_type': my.kwargs.get("search_type"), 'collection_type': collection_type, 'bvr_match_class': 'spt_collection_link', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElement(".spt_collection_content"); var collection_key = bvr.src_el.getAttribute("search_key"); if (!collection_key) { spt.notify.show_message("Already in the Collection."); } else { var collection_code = collection_key.split("workflow/asset?project=workflow&code=")[1]; var collection_path = bvr.src_el.innerText; var expr = "@SEARCH("+bvr.collection_type+"['parent_code','"+collection_code+"']."+bvr.search_type+")"; var cls = "tactic.ui.panel.CollectionContentWdg"; var kwargs = { collection_key: collection_key, path: collection_path, search_type: bvr.search_type, show_shelf: false, show_search_limit: true, expression: expr } spt.panel.load(content, cls, kwargs); bvr.src_el.setStyle("box-shadow", "0px 0px 3px rgba(0,0,0,0.5)"); } ''' } ) #title_div.add("/ %s" % collection.get_value("name") ) #scale_wdg = tile.get_scale_wdg() #top.add(scale_wdg) #scale_wdg.add_style("float: right") top.add(my.get_header_wdg()) top.add(tile) return top
def get_versions_wdg(self): div = DivWdg() div.add_class("spt_imports") title_wdg = DivWdg() div.add(title_wdg) title_wdg.add("Imports found:") title_wdg.add_style("padding: 0px 0px 8px 0px") base_dir = self.kwargs.get("base_dir") imports_dir = "%s/imports" % base_dir if not os.path.exists(imports_dir): imports_dir = base_dir basenames = os.listdir(imports_dir) basenames.sort() basenames.reverse() div.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': "spt_import_item", 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_imports"); var els = top.getElements(".spt_import_info"); for ( var i = 0; i < els.length; i++) { spt.hide(els[i]); } var el = bvr.src_el.getElement(".spt_import_info"); spt.show(el); ''' } ) # find all the zip files count = 0 for basename in basenames: if not basename.endswith(".txt"): continue if basename.find("-files-") != -1: continue if basename.find("-data-") != -1: continue version_wdg = DivWdg() div.add(version_wdg) version_wdg.add_style("padding: 3px 3px 3px 12px") version_wdg.add_class("spt_import_item") radio = RadioWdg("basename") version_wdg.add(radio) radio.set_option("value", basename) if not count: radio.set_checked() version_wdg.add(basename) version_wdg.add("<br/>") # add info path = "%s/%s" % (imports_dir, basename) f = open(path) data = f.read() f.close() data = jsonloads(data) table = Table() version_wdg.add(table) table.add_class("spt_import_info") if count: table.add_style("display: none") table.set_max_width() table.add_style("margin-left: 40px") table.add_style("margin-right: 20px") version_wdg.add(table) for name, value in self.data.items(): name = Common.get_display_title(name) table.add_row() table.add_cell(name) table.add_cell(value) count += 1 if count == 0: msg_wdg = DivWdg() div.add(msg_wdg) msg_wdg.add("<i>No imports found</i>") msg_wdg.add_border() msg_wdg.add_style("padding: 20px") msg_wdg.add_style("padding: 10px") msg_wdg.add_style("text-align: center") msg_wdg.add_color("background", "background", -10) return div
class BaseConfigWdg(BaseRefreshWdg): def __init__(self, search_type, config_base, input_prefix='', config=None): if type(search_type) in types.StringTypes: self.search_type_obj = SearchType.get(search_type) self.search_type = search_type elif isinstance(search_type, SearchType): self.search_type_obj = search_type self.search_type = self.search_type_obj.get_base_key() elif inspect.isclass(search_type) and issubclass(search_type, SObject): self.search_type_obj = SearchType.get(search_type.SEARCH_TYPE) self.search_type = self.search_type_obj.get_base_key() else: raise LayoutException('search_type must be a string or an sobject') self.config = config self.config_base = config_base self.input_prefix = input_prefix self.element_names = [] self.element_titles = [] from pyasm.web import DivWdg self.top = DivWdg() # Layout widgets compartmentalize their widgets in sections for drawing self.sections = {} super(BaseConfigWdg,self).__init__() # NEED to add these because this is derived from HtmlElement and not # BaseRefreshWdg def add_style(self, name, value=None): return self.top.add_style(name, value=value) def add_class(self, class_name): return self.top.add_class(class_name) def has_class(self, class_name): return self.top.has_class(class_name) def add_behavior(self, behavior): return self.top.add_behavior(behavior) def add_relay_behavior(self, behavior): return self.top.add_relay_behavior(behavior) def get_default_display_handler(cls, element_name): raise Exception("Must override 'get_default_display_handler()'") get_default_display_handler = classmethod(get_default_display_handler) def get_config_base(self): return self.config_base def get_config(self): return self.config def get_view(self): return self.config_base def remap_display_handler(self, display_handler): '''Provide an opportunity to remap a display handler for newer layouts engines using older configs''' return display_handler def init(self): # create all of the display elements if not self.config: # it shouldn't use the self.search_type_obj here as it would absorb the project info self.config = WidgetConfigView.get_by_search_type(self.search_type, self.config_base) self.element_names = self.config.get_element_names() self.element_titles = self.config.get_element_titles() # TODO: should probably be all the attrs self.element_widths = self.config.get_element_widths() simple_view = self.kwargs.get("show_simple_view") if simple_view == "true": simple_view = True else: simple_view = False self.extra_data = self.kwargs.get("extra_data") if self.extra_data and isinstance(self.extra_data, basestring): try: self.extra_data = jsonloads(self.extra_data) except: self.extra_data = self.extra_data.replace("'", '"') self.extra_data = jsonloads(self.extra_data) # go through each element name and construct the handlers for idx, element_name in enumerate(self.element_names): # check to see if these are removed for this production #if element_name in invisible_elements: # continue simple_element = None display_handler = self.config.get_display_handler(element_name) new_display_handler = self.remap_display_handler(display_handler) if new_display_handler: display_handler = new_display_handler if not display_handler: # else get it from default of this type display_handler = self.get_default_display_handler(element_name) # get the display options display_options = self.config.get_display_options(element_name) # add in extra_data if self.extra_data: for key, value in self.extra_data.items(): display_options[key] = value try: if not display_handler: element = self.config.get_display_widget(element_name) else: display_options['element_name'] = element_name element = WidgetConfig.create_widget( display_handler, display_options=display_options ) except Exception as e: from tactic.ui.common import WidgetTableElementWdg element = WidgetTableElementWdg() # FIXME: not sure why this doesn't work #from pyasm.widget import ExceptionWdg #log = ExceptionWdg(e) #element.add(log) # FIXME: not sure why this doesn't work from pyasm.widget import IconWdg icon = IconWdg("Error", IconWdg.ERROR) element.add(icon) element.add(e) # skip the empty elements like ThumbWdg if simple_element and not element.is_simple_viewable(): continue # make simple_element the element if it exists if simple_element: element = simple_element # if the element failed to create, then continue if element == None: continue element.set_name(element_name) title = self.element_titles[idx] element.set_title(title) # FIXME: this causes a circular reference which means the # Garbage collector can't clean it up # make sure the element knows about its layout engine element.set_layout_wdg(self) # TODO: should convert this to ATTRS or someting like that. Not # just width if idx >= len(self.element_widths): element.width = 150 else: element.width = self.element_widths[idx] if self.input_prefix: element.set_input_prefix(self.input_prefix) # get the display options #display_options = self.config.get_display_options(element_name) #for key in display_options.keys(): element.set_options(display_options) self.add_widget(element,element_name) # layout widgets also categorize their widgets based on type if element_name == "Filter": section_name = 'filter' else: section_name = 'default' section = self.sections.get(section_name) if not section: section = [] self.sections[section_name] = section section.append(element) # go through each widget and pass them the filter_data object from tactic.ui.filter import FilterData filter_data = FilterData.get() if not filter_data: filter_data = {} for widget in self.widgets: widget.set_filter_data(filter_data) # initialize all of the child widgets super(BaseConfigWdg,self).init() def rename_widget(self,name, new_name): widget = self.get_widget(name) widget.set_name(new_name) def remove_widget(self,name): widget = self.get_widget(name) try: self.widgets.remove(widget) except: print "WARNING: cannot remove widget"
def get_display(my): my.search_type = my.kwargs.get("search_type") search = Search(my.search_type) search.add_filter("_is_collection", True) collections = search.get_sobjects() collections_div = DivWdg() is_refresh = my.kwargs.get("is_refresh") if is_refresh: div = Widget() else: div = DivWdg() my.set_as_panel(div) div.add_class("spt_collection_left_side") div.add(collections_div) collections_div.add_class("spt_collection_list") collections_div.add_style("margin: 5px 0px 5px -5px") from tactic.ui.panel import ThumbWdg2 parts = my.search_type.split("/") collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1]) collections_div.add_relay_behavior({ 'type': 'mouseup', 'search_type': my.search_type, 'collection_type': collection_type, 'bvr_match_class': 'spt_collection_item', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElement(".spt_collection_content"); var list = bvr.src_el.getParent(".spt_collection_list"); var items = list.getElements(".spt_collection_item"); for (var i = 0; i < items.length; i++) { items[i].setStyle("background", ""); items[i].setStyle("box-shadow", ""); } bvr.src_el.setStyle("background", "#EEE"); var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_code = bvr.src_el.getAttribute("spt_collection_code"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var expr = "@SEARCH("+bvr.collection_type+"['parent_code','"+collection_code+"']."+bvr.search_type+")"; var parent_dict = {}; var parent_collection = bvr.src_el.getParent(".spt_subcollection_wdg"); var path = collection_path.substring(0, collection_path.lastIndexOf("/")); if (parent_collection) { for (var i = 0; i < collection_path.split("/").length - 1; i++) { var n = path.lastIndexOf("/"); var collection_name = path.substring(n+1); path = path.substring(0, n); var parent_key = parent_collection.getAttribute("spt_parent_key"); parent_dict[collection_name] = parent_key; parent_collection = parent_collection.getParent(".spt_subcollection_wdg"); } } var cls = "tactic.ui.panel.CollectionContentWdg"; var kwargs = { collection_key: collection_key, path: collection_path, search_type: bvr.search_type, show_shelf: false, show_search_limit: true, expression: expr, parent_dict: parent_dict } spt.panel.load(content, cls, kwargs); bvr.src_el.setStyle("box-shadow", "0px 0px 3px rgba(0,0,0,0.5)"); // hide the bottom show_search_limit when clicking into a collection var panel = bvr.src_el.getParent(".spt_panel"); var search_limit_div = panel.getElements(".spt_search_limit_top"); if (search_limit_div.length == 2){ search_limit_div[1].setStyle("visibility", "hidden"); } ''' }) collections_div.add_relay_behavior({ 'type': 'mouseup', 'search_type': my.search_type, 'bvr_match_class': 'spt_collection_open', 'cbjs_action': ''' var item = bvr.src_el.getParent(".spt_collection_div_top"); var next = item.getNext(); if (bvr.src_el.hasClass("spt_open")) { next.innerHTML = ""; bvr.src_el.setStyle("opacity", 1.0); bvr.src_el.removeClass("spt_open"); } else { var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var cls = "tactic.ui.panel.CollectionListWdg"; var kwargs = { parent_key: collection_key, path: collection_path, } spt.panel.load(next, cls, kwargs, null, {show_loading: false}); bvr.src_el.setStyle("opacity", 0.3); bvr.src_el.addClass("spt_open"); evt.stopPropagation(); } ''' }) for collection in collections: collection_wdg = CollectionItemWdg( collection=collection, path=collection.get_value("name")) collections_div.add(collection_wdg) collection_wdg.add_class("spt_collection_div") subcollection_wdg = DivWdg() collections_div.add(subcollection_wdg) subcollection_wdg.add_class("spt_subcollection_wdg") subcollection_wdg.add_style("padding-left: 15px") return div
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): my.collection_key = my.kwargs.get("collection_key") collection = Search.get_by_search_key(my.collection_key) top = my.top top.add_style("min-height: 400px") my.kwargs["scale"] = 75 my.kwargs["show_scale"] = False my.kwargs["expand_mode"] = "plain" my.kwargs["show_search_limit"] = False from tile_layout_wdg import TileLayoutWdg tile = TileLayoutWdg(**my.kwargs) parent_dict = my.kwargs.get("parent_dict") has_parent = False if parent_dict: has_parent = True path = my.kwargs.get("path") if collection and path: title_div = DivWdg() top.add(title_div) title_div.add_style("float: left") title_div.add_style("margin: 15px 0px 15px 30px") asset_lib_span_div = SpanWdg() title_div.add(asset_lib_span_div) icon = IconWdg(name="Asset Library", icon="BS_FOLDER_OPEN") asset_lib_span_div.add(icon) asset_lib_span_div.add(" <a><b>Asset Library</b></a> ") path = path.strip("/") parts = path.split("/") for idx, part in enumerate(parts): title_div.add(" / ") # the last spt_collection_link does not need a search_key if has_parent and (idx is not len(parts) - 1): search_key = parent_dict.get(part) title_div.add( " <a class='spt_collection_link' search_key=%s><b>%s</b></a> " % (search_key, part)) else: title_div.add( " <a class='spt_collection_link'><b>%s</b></a> " % part) title_div.add_style("margin-top: 10px") # Adding behavior to collections link parts = my.kwargs.get("search_type").split("/") collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1]) exists = SearchType.get(collection_type, no_exception=True) if not exists: title_div.add("SearchType %s is not registered." % collection_type) return top # These behaviors are only activated if the view is within collection layout, # "is_new_tab" is a kwargs set to true, if opening a new tab if not my.kwargs.get("is_new_tab"): icon.add_class("hand") icon.add_behavior({ 'type': 'mouseover', 'cbjs_action': ''' bvr.src_el.setStyle('opacity', 1.0); ''' }) icon.add_behavior({ 'type': 'mouseout', 'cbjs_action': ''' bvr.src_el.setStyle('opacity', 0.6); ''' }) # make icon and All Assets title clickable to return to view all assets asset_lib_span_div.add_class("hand") asset_lib_span_div.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var view_panel = top.getParent(".spt_view_panel"); spt.panel.refresh(view_panel); ''' }) title_div.add_class("hand") title_div.add_relay_behavior({ 'type': 'mouseup', 'search_type': my.kwargs.get("search_type"), 'collection_type': collection_type, 'bvr_match_class': 'spt_collection_link', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElement(".spt_collection_content"); var collection_key = bvr.src_el.getAttribute("search_key"); if (!collection_key) { spt.notify.show_message("Already in the Collection."); } else { var collection_code = collection_key.split("workflow/asset?project=workflow&code=")[1]; var collection_path = bvr.src_el.innerText; var expr = "@SEARCH("+bvr.collection_type+"['parent_code','"+collection_code+"']."+bvr.search_type+")"; var cls = "tactic.ui.panel.CollectionContentWdg"; var kwargs = { collection_key: collection_key, path: collection_path, search_type: bvr.search_type, show_shelf: false, show_search_limit: true, expression: expr } spt.panel.load(content, cls, kwargs); bvr.src_el.setStyle("box-shadow", "0px 0px 3px rgba(0,0,0,0.5)"); } ''' }) #title_div.add("/ %s" % collection.get_value("name") ) #scale_wdg = tile.get_scale_wdg() #top.add(scale_wdg) #scale_wdg.add_style("float: right") top.add(my.get_header_wdg()) top.add(tile) return top
def get_display(self): self.doc_mode = self.kwargs.get("doc_mode") path = self.kwargs.get("path") self.search_type = self.kwargs.get("search_type") self.last_path = None doc_key = self.kwargs.get("doc_key") if doc_key: self.doc = Search.get_by_search_key(doc_key) snapshot = Snapshot.get_latest_by_sobject(self.doc) if snapshot: self.last_path = snapshot.get_lib_path_by_type('main') path = self.doc.get_value("link") # TEST TEST TEST if not path: #path = "/home/apache/pdf/mongodb.txt" #path = "/home/apache/assets/google_docs.html" #path = "/home/apache/pdf/star_wars.txt" path = "https://docs.google.com/document/d/1AC_YR8X8wbKsshkJ1h8EjZuFIr41guvqXq3_PXgaqJ0/pub?embedded=true" path = "https://docs.google.com/document/d/1WPUmXYoSkR2cz0NcyM2vqQYO6OGZW8BAiDL31YEj--M/pub" #path = "https://docs.google.com/spreadsheet/pub?key=0Al0xl-XktnaNdExraEE4QkxVQXhaOFh1SHIxZmZMQ0E&single=true&gid=0&output=html" path = "/home/apache/tactic/doc/alias.json" if not self.search_type: self.search_type = "test3/shot" self.column = "description" top = self.top top.add_class("spt_document_top") self.set_as_panel(top) #table = Table() table = ResizableTableWdg() top.add(table) table.add_row() table.set_max_width() left_td = table.add_cell() left_td.add_style("vertical-align: top") title = DivWdg() left_td.add(title) title.add_style("padding: 10px") title.add_color("background", "background3") button = IconButtonWdg(title="Refresh", icon=IconWdg.REFRESH) title.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.app_busy.show("Reloading Document"); var top = bvr.src_el.getParent(".spt_document_top"); spt.panel.refresh(top); spt.app_busy.hide(); ''' } ) button.add_style("float: left") button = IconButtonWdg(title="Save", icon=IconWdg.SAVE) title.add(button) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' ''' } ) button.add_style("float: left") if not self.doc_mode: self.doc_mode = "text" select = SelectWdg("doc_mode") select.set_option("values", "text|formatted") title.add(select) select.set_value(self.doc_mode) select.add_behavior( { 'type': 'change', 'cbjs_action': ''' spt.app_busy.show("Reloading Document"); var top = bvr.src_el.getParent(".spt_document_top"); var value = bvr.src_el.value; top.setAttribute("spt_doc_mode", value); spt.panel.refresh(top); spt.app_busy.hide(); ''' } ) title.add("<br clear='all'/>") #title.add(path) text_wdg = DivWdg() text_wdg.add_class("spt_document_content") left_td.add(text_wdg) #if path.startswith("https://docs.google.com/spreadsheet"): # #path = "http://www.southpawtech.com.com" # text_wdg.add(''' # <iframe class="spt_document_iframe" style="width: 100%%; height: auto; min-height: 600px; font-size: 1.0em" src="%s"></iframe> # ''' % path) # text_wdg.add_style("overflow-x: hidden") if True: if not self.last_path and self.doc: tmp_dir = Environment.get_tmp_dir() tmp_path = '%s/last_path.txt' % tmp_dir f = open(tmp_path, 'w') text = self.get_text(path, highlight=False) f.write(text) f.close() cmd = FileCheckin(self.doc, tmp_path) Command.execute_cmd(cmd) else: save = False if save: # open up the last path f = open(self.last_path, 'r') last_text = f.read() text = self.get_text(path, None, highlight=False) if last_text != text: tmp_dir = Environment.get_tmp_dir() tmp_path = '%s/last_path.txt' % tmp_dir f = open(tmp_path, 'w') f.write(text) f.write(text) f.close() cmd = FileCheckin(self.doc, tmp_path) Command.execute_cmd(cmd) text = self.get_text(path, self.last_path) lines = text.split("\n") if self.doc_mode == "text": num_lines = len(lines) """ line_div = HtmlElement.pre() text_wdg.add(line_div) line_div.add_style("width: 20px") line_div.add_style("float: left") line_div.add_style("text-align: right") line_div.add_style("opacity: 0.3") line_div.add_style("padding-right: 10px") for i in range(0, num_lines*2): line_div.add(i+1) line_div.add("<br/>") """ if self.doc_mode == "text": pre = HtmlElement.pre() pre.add_style("white-space: pre-wrap") else: pre = DivWdg() pre = DivWdg() text_wdg.add(pre) text_wdg.add_style("padding: 10px 5px") text_wdg.add_style("max-height: 600px") text_wdg.add_style("overflow-y: auto") text_wdg.add_style("width: 600px") text_wdg.add_class("spt_resizable") pre.add_style("font-family: courier") if self.doc_mode == "formatted": pre.add(text) else: line_table = Table() pre.add(line_table) line_table.add_style("width: 100%") count = 1 for line in lines: #line = line.replace(" ", " ") tr = line_table.add_row() if count % 2 == 0: tr.add_color("background", "background", -2) td = line_table.add_cell() # FIXME: hacky if line.startswith('''<span style='background: #CFC'>'''): is_new = True else: td.add_style("vertical-align: top") text = TextWdg() text.add_style("border", "none") text.add_style("text-align", "right") text.add_style("width", "25px") text.add_style("margin", "0 10 0 0") text.add_style("opacity", "0.5") text.set_value(count) td.add(text) count += 1 is_new = False td = line_table.add_cell() if not is_new: SmartMenu.assign_as_local_activator( td,'TEXT_CTX' ) tr.add_class("spt_line"); else: SmartMenu.assign_as_local_activator( td,'TEXT_NEW_CTX' ) tr.add_class("spt_new_line"); td.add_class("spt_line_content"); td.add(line) #from tactic.ui.app import AceEditorWdg #editor = AceEditorWdg(code=text, show_options=False, readonly=True, height="600px") #text_wdg.add(editor) # add a click on spt_item text_wdg.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_document_item', 'search_type': self.search_type, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_document_top"); var data_el = top.getElement(".spt_document_data"); var search_key = bvr.src_el.getAttribute("spt_search_key"); var class_name = 'tactic.ui.panel.ViewPanelWdg'; var kwargs = { 'search_type': bvr.search_type, 'search_key': search_key, } spt.panel.load(data_el, class_name, kwargs); ''' } ) # add a double click on spt_item bgcolor = text_wdg.get_color("background", -10) text_wdg.add_relay_behavior( { 'type': 'mouseover', 'bvr_match_class': 'spt_document_item', 'search_type': self.search_type, 'bgcolor': bgcolor, 'cbjs_action': ''' bvr.src_el.setStyle("opacity", "1.0"); //bvr.src_el.setStyle("font-weight", "normal"); bvr.src_el.setStyle("background", bvr.bgcolor); ''' } ) # add a double click on spt_item text_wdg.add_relay_behavior( { 'type': 'mouseout', 'bvr_match_class': 'spt_document_item', 'search_type': self.search_type, 'cbjs_action': ''' bvr.src_el.setStyle("opacity", "1.0"); //bvr.src_el.setStyle("font-weight", "bold"); bvr.src_el.setStyle("background", ""); ''' } ) # add a context menu ctx_menu = self.get_text_context_menu() ctx_new_menu = self.get_text_new_context_menu() menus_in = { 'TEXT_CTX': ctx_menu, 'TEXT_NEW_CTX': ctx_new_menu, } SmartMenu.attach_smart_context_menu( text_wdg, menus_in, False ) panel = ViewPanelWdg( search_type=self.search_type, layout="blah" ) right_td = table.add_cell() right_td.add_style("vertical-align: top") panel_div = DivWdg() panel_div.add_class("spt_document_data") right_td.add(panel_div) panel_div.add(panel) text_wdg.add_behavior( { 'type': 'load', 'cbjs_action': r''' spt.document = {}; spt.document.selected_text = null; spt.document.get_selected_text = function(frame) { var t = ''; if (frame) { var rng = frame.contentWindow.getSelection().getRangeAt(0); spt.document.expandtoword(rng); t = rng.toString(); } else if (window.getSelection) // FF4 with one tab open? { var rng = window.getSelection().getRangeAt(0); spt.document.expandtoword(rng); t = rng.toString(); } else if (document.getSelection) // FF4 with multiple tabs open? { var rng = document.getSelection().getRangeAt(0); spt.document.expandtoword(rng); t = rng.toString(); } else if (document.selection) // IE8 { var rng = document.selection.createRange(); // expand range to enclose any word partially enclosed in it rng.expand("word"); t = rng.text; } // convert newline chars to spaces, collapse whitespace, and trim non-word chars return t.replace(/^\W+|\W+$/g, ''); //return t.replace(/\r?\n/g, " ").replace(/\s+/g, " ").replace(/^\W+|\W+$/g, ''); } // expand FF range to enclose any word partially enclosed in it spt.document.expandtoword = function(range) { if (range.collapsed) { return; } while (range.startOffset > 0 && range.toString()[0].match(/\w/)) { range.setStart(range.startContainer, range.startOffset - 1); } while (range.endOffset < range.endContainer.length && range.toString()[range.toString().length - 1].match(/\w/)) { range.setEnd(range.endContainer, range.endOffset + 1); } } ''' } ) top.add_relay_behavior( { 'type': 'mouseup', 'bvr_match_class': 'spt_document_content', 'cbjs_action': r''' //spt.ace_editor.set_editor_top(bvr.src_el); //var text = spt.ace_editor.get_selection(); var text = spt.document.get_selected_text(); text = text.replace(/\n\n/mg, "\n"); text = text.replace(/\n\n/mg, "\n"); spt.document.selected_text = text + ""; ''' } ) return top
def get_display(my): my.search_type = my.kwargs.get("search_type") search = Search(my.search_type) search.add_filter("_is_collection", True) collections = search.get_sobjects() collections_div = DivWdg() is_refresh = my.kwargs.get("is_refresh") if is_refresh: div = Widget() else: div = DivWdg() my.set_as_panel(div) div.add_class("spt_collection_left_side") div.add(collections_div) collections_div.add_class("spt_collection_list") collections_div.add_style("margin: 5px 0px 5px -5px") from tactic.ui.panel import ThumbWdg2 parts = my.search_type.split("/") collection_type = "%s/%s_in_%s" % (parts[0], parts[1], parts[1]) collections_div.add_relay_behavior( { 'type': 'mouseup', 'search_type': my.search_type, 'collection_type': collection_type, 'bvr_match_class': 'spt_collection_item', 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_collection_top"); var content = top.getElement(".spt_collection_content"); var list = bvr.src_el.getParent(".spt_collection_list"); var items = list.getElements(".spt_collection_item"); for (var i = 0; i < items.length; i++) { items[i].setStyle("background", ""); items[i].setStyle("box-shadow", ""); } bvr.src_el.setStyle("background", "#EEE"); var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_code = bvr.src_el.getAttribute("spt_collection_code"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var expr = "@SEARCH("+bvr.collection_type+"['parent_code','"+collection_code+"']."+bvr.search_type+")"; var parent_dict = {}; var parent_collection = bvr.src_el.getParent(".spt_subcollection_wdg"); var path = collection_path.substring(0, collection_path.lastIndexOf("/")); if (parent_collection) { for (var i = 0; i < collection_path.split("/").length - 1; i++) { var n = path.lastIndexOf("/"); var collection_name = path.substring(n+1); path = path.substring(0, n); var parent_key = parent_collection.getAttribute("spt_parent_key"); parent_dict[collection_name] = parent_key; parent_collection = parent_collection.getParent(".spt_subcollection_wdg"); } } var cls = "tactic.ui.panel.CollectionContentWdg"; var kwargs = { collection_key: collection_key, path: collection_path, search_type: bvr.search_type, show_shelf: false, show_search_limit: true, expression: expr, parent_dict: parent_dict } spt.panel.load(content, cls, kwargs); bvr.src_el.setStyle("box-shadow", "0px 0px 3px rgba(0,0,0,0.5)"); // hide the bottom show_search_limit when clicking into a collection var panel = bvr.src_el.getParent(".spt_panel"); var search_limit_div = panel.getElements(".spt_search_limit_top"); if (search_limit_div.length == 2){ search_limit_div[1].setStyle("visibility", "hidden"); } ''' } ) collections_div.add_relay_behavior( { 'type': 'mouseup', 'search_type': my.search_type, 'bvr_match_class': 'spt_collection_open', 'cbjs_action': ''' var item = bvr.src_el.getParent(".spt_collection_div_top"); var next = item.getNext(); if (bvr.src_el.hasClass("spt_open")) { next.innerHTML = ""; bvr.src_el.setStyle("opacity", 1.0); bvr.src_el.removeClass("spt_open"); } else { var collection_key = bvr.src_el.getAttribute("spt_collection_key"); var collection_path = bvr.src_el.getAttribute("spt_collection_path"); var cls = "tactic.ui.panel.CollectionListWdg"; var kwargs = { parent_key: collection_key, path: collection_path, } spt.panel.load(next, cls, kwargs, null, {show_loading: false}); bvr.src_el.setStyle("opacity", 0.3); bvr.src_el.addClass("spt_open"); evt.stopPropagation(); } ''' } ) for collection in collections: collection_wdg = CollectionItemWdg(collection=collection, path=collection.get_value("name")) collections_div.add(collection_wdg) collection_wdg.add_class("spt_collection_div") subcollection_wdg = DivWdg() collections_div.add(subcollection_wdg) subcollection_wdg.add_class("spt_subcollection_wdg") subcollection_wdg.add_style("padding-left: 15px") return div
def get_display(my): top = my.top top.add_class("spt_sandbox_select_top") sandbox_options = [ { 'name': 'fast', 'base_dir': 'C:/Fast', }, { 'name': 'faster', 'base_dir': 'C:/Faster', }, { 'name': 'slow', 'base_dir': 'Z:/Slow', } ] process = my.kwargs.get("process") search_key = my.kwargs.get("search_key") sobject = Search.get_by_search_key(search_key) search_type = sobject.get_base_search_type() client_os = Environment.get_env_object().get_client_os() if client_os == 'nt': prefix = "win32" else: prefix = "linux" alias_dict = Config.get_dict_value("checkin", "%s_sandbox_dir" % prefix) search_key = sobject.get_search_key() key = "sandbox_dir:%s" % search_key from pyasm.web import WidgetSettings value = WidgetSettings.get_value_by_key(key) sandboxes_div = DivWdg() top.add(sandboxes_div) sandboxes_div.add_relay_behavior( { 'type': 'mouseenter', 'bvr_match_class': 'spt_sandbox_option', 'cbjs_action': ''' var last_background = bvr.src_el.getStyle("background-color"); bvr.src_el.setAttribute("spt_last_background", last_background); bvr.src_el.setStyle("background-color", "#E0E0E0"); bvr.src_el.setStyle("opacity", "1.0"); ''' } ) sandboxes_div.add_relay_behavior( { 'type': 'mouseleave', 'bvr_match_class': 'spt_sandbox_option', 'cbjs_action': ''' var last_background = bvr.src_el.getAttribute("spt_last_background"); bvr.src_el.setStyle("background-color", last_background); if (!bvr.src_el.hasClass("spt_selected")) { bvr.src_el.setStyle("opacity", "0.5"); } ''' } ) sandboxes_div.add_relay_behavior( { 'type': 'mouseup', 'key': key, 'bvr_match_class': 'spt_sandbox_option', 'cbjs_action': ''' var sandbox_dir = bvr.src_el.getAttribute("spt_sandbox_dir"); var server = TacticServerStub.get(); server.set_widget_setting(bvr.key, sandbox_dir); var applet = spt.Applet.get(); applet.makedirs(sandbox_dir); //var top = bvr.src_el.getParent(".spt_sandbox_select_top"); var top = bvr.src_el.getParent(".spt_checkin_top"); spt.panel.refresh(top); ''' } ) #search = Search("config/naming") #search.add_filter("search_type", search_type) #search.add_filter("process", process) #namings = search.get_sobjects() #naming = namings[0] from pyasm.biz import Snapshot, Naming virtual_snapshot = Snapshot.create_new() virtual_snapshot.set_value("process", process) # for purposes of the sandbox folder for the checkin widget, # the context is the process virtual_snapshot.set_value("context", process) naming = Naming.get(sobject, virtual_snapshot) if naming: naming_expr = naming.get_value("sandbox_dir_naming") alias_options = naming.get_value("sandbox_dir_alias") else: naming_expr = None alias_options = None if alias_options == "__all__": alias_options = alias_dict.keys() elif alias_options: alias_options = alias_options.split("|") else: alias_options = ['default'] for alias in alias_options: from pyasm.biz import DirNaming dir_naming = DirNaming(sobject=sobject, snapshot=virtual_snapshot) dir_naming.set_protocol("sandbox") dir_naming.set_naming(naming_expr) base_dir = dir_naming.get_dir(alias=alias) sandbox_div = DivWdg() sandboxes_div.add(sandbox_div) sandbox_div.add_class("spt_sandbox_option") sandbox_div.add_attr("spt_sandbox_dir", base_dir) if value == base_dir: sandbox_div.add_color("background", "background3") #sandbox_div.set_box_shadow() sandbox_div.add_class("spt_selected") else: sandbox_div.add_style("opacity", "0.5") sandbox_div.add_style("width: auto") sandbox_div.add_style("height: 55px") sandbox_div.add_style("padding: 5px") #sandbox_div.add_style("float: left") sandbox_div.add_style("margin: 15px") sandbox_div.add_border() if alias: alias_div = DivWdg() sandbox_div.add(alias_div) alias_div.add(alias) alias_div.add_style("font-size: 1.5em") alias_div.add_style("font-weight: bold") alias_div.add_style("margin-bottom: 15px") icon_wdg = IconWdg("Folder", IconWdg.FOLDER) sandbox_div.add(icon_wdg) sandbox_div.add(base_dir) return top
def get_display(my): top = my.top inner = DivWdg() top.add(inner) inner.add_behavior( { 'type': 'load', 'cbjs_action': my.get_onload_js() } ) width = "100%" height = "100%" inner.add_style("width: %s" % width) inner.add_style("height: %s" % height) inner.add_style("overflow: hidden") inner.add_class("spt_container") content = DivWdg() inner.add(content) content.add_class("spt_content") content.add_style("width: %s" % width) content.add_style("height: %s" % height) content.add_style("position: relative") content.add_behavior( { 'type': 'load', 'cbjs_action': ''' spt.drag.load(bvr.src_el); ''' } ) content.add_behavior( { 'type': 'wheel', 'cbjs_action': ''' spt.drag.wheel(evt, bvr); ''' } ) inner.add_relay_behavior( { 'type': 'dblclick', 'bvr_match_class': 'spt_content', 'cbjs_action': ''' spt.drag.dblclick(evt, bvr); ''' } ) src = my.kwargs.get("src") if not src: src = DivWdg() src.add("No Content") img = HtmlElement.img(src=src) content.add(img) img.add_style("width: 100%") img.add_style("height: 100%") return top