1,0 → 0,0 |
Ext.namespace("Ext.ux.Utils");Ext.ux.Utils.EventQueue=function(handler,scope){if(!handler){throw"Handler is required."}this.handler=handler;this.scope=scope||window;this.queue=[];this.is_processing=false;this.postEvent=function(event,data){data=data||null;this.queue.push({event:event,data:data});if(!this.is_processing){this.process()}};this.flushEventQueue=function(){this.queue=[]},this.process=function(){while(this.queue.length>0){this.is_processing=true;var event_data=this.queue.shift();this.handler.call(this.scope,event_data.event,event_data.data)}this.is_processing=false}};Ext.ux.Utils.FSA=function(initial_state,trans_table,trans_table_scope){this.current_state=initial_state;this.trans_table=trans_table||{};this.trans_table_scope=trans_table_scope||window;Ext.ux.Utils.FSA.superclass.constructor.call(this,this.processEvent,this)};Ext.extend(Ext.ux.Utils.FSA,Ext.ux.Utils.EventQueue,{current_state:null,trans_table:null,trans_table_scope:null,state:function(){return this.current_state},processEvent:function(event,data){var transitions=this.currentStateEventTransitions(event);if(!transitions){throw"State '"+this.current_state+"' has no transition for event '"+event+"'."}for(var i=0,len=transitions.length;i<len;i++){var transition=transitions[i];var predicate=transition.predicate||transition.p||true;var action=transition.action||transition.a||Ext.emptyFn;var new_state=transition.state||transition.s||this.current_state;var scope=transition.scope||this.trans_table_scope;if(this.computePredicate(predicate,scope,data,event)){this.callAction(action,scope,data,event);this.current_state=new_state;return }}throw"State '"+this.current_state+"' has no transition for event '"+event+"' in current context"},currentStateEventTransitions:function(event){return this.trans_table[this.current_state]?this.trans_table[this.current_state][event]||false:false},computePredicate:function(predicate,scope,data,event){var result=false;switch(Ext.type(predicate)){case"function":result=predicate.call(scope,data,event,this);break;case"array":result=true;for(var i=0,len=predicate.length;result&&(i<len);i++){if(Ext.type(predicate[i])=="function"){result=predicate[i].call(scope,data,event,this)}else{throw ["Predicate: ",predicate[i],' is not callable in "',this.current_state,'" state for event "',event].join("")}}break;case"boolean":result=predicate;break;default:throw ["Predicate: ",predicate,' is not callable in "',this.current_state,'" state for event "',event].join("")}return result},callAction:function(action,scope,data,event){switch(Ext.type(action)){case"array":for(var i=0,len=action.length;i<len;i++){if(Ext.type(action[i])=="function"){action[i].call(scope,data,event,this)}else{throw ["Action: ",action[i],' is not callable in "',this.current_state,'" state for event "',event].join("")}}break;case"function":action.call(scope,data,event,this);break;default:throw ["Action: ",action,' is not callable in "',this.current_state,'" state for event "',event].join("")}}});Ext.namespace("Ext.ux.UploadDialog");Ext.ux.UploadDialog.BrowseButton=Ext.extend(Ext.Button,{input_name:"file",input_file:null,original_handler:null,original_scope:null,initComponent:function(){Ext.ux.UploadDialog.BrowseButton.superclass.initComponent.call(this);this.original_handler=this.handler||null;this.original_scope=this.scope||window;this.handler=null;this.scope=null},onRender:function(ct,position){Ext.ux.UploadDialog.BrowseButton.superclass.onRender.call(this,ct,position);this.createInputFile()},createInputFile:function(){var button_container=this.el.child(".x-btn-center");button_container.position("relative");this.input_file=Ext.DomHelper.append(button_container,{tag:"input",type:"file",size:1,name:this.input_name||Ext.id(this.el),style:"position: absolute; display: block; border: none; cursor: pointer"},true);var button_box=button_container.getBox();this.input_file.setStyle("font-size",(button_box.width*0.5)+"px");var input_box=this.input_file.getBox();var adj={x:3,y:3};if(Ext.isIE){adj={x:0,y:3}}this.input_file.setLeft(button_box.width-input_box.width+adj.x+"px");this.input_file.setTop(button_box.height-input_box.height+adj.y+"px");this.input_file.setOpacity(0);if(this.handleMouseEvents){this.input_file.on("mouseover",this.onMouseOver,this);this.input_file.on("mousedown",this.onMouseDown,this)}if(this.tooltip){if(typeof this.tooltip=="object"){Ext.QuickTips.register(Ext.apply({target:this.input_file},this.tooltip))}else{this.input_file.dom[this.tooltipType]=this.tooltip}}this.input_file.on("change",this.onInputFileChange,this);this.input_file.on("click",function(e){e.stopPropagation()})},detachInputFile:function(no_create){var result=this.input_file;no_create=no_create||false;if(typeof this.tooltip=="object"){Ext.QuickTips.unregister(this.input_file)}else{this.input_file.dom[this.tooltipType]=null}this.input_file.removeAllListeners();this.input_file=null;if(!no_create){this.createInputFile()}return result},getInputFile:function(){return this.input_file},disable:function(){Ext.ux.UploadDialog.BrowseButton.superclass.disable.call(this);this.input_file.dom.disabled=true},enable:function(){Ext.ux.UploadDialog.BrowseButton.superclass.enable.call(this);this.input_file.dom.disabled=false},destroy:function(){var input_file=this.detachInputFile(true);input_file.remove();input_file=null;Ext.ux.UploadDialog.BrowseButton.superclass.destroy.call(this)},onInputFileChange:function(){if(this.original_handler){this.original_handler.call(this.original_scope,this)}}});Ext.ux.UploadDialog.TBBrowseButton=Ext.extend(Ext.ux.UploadDialog.BrowseButton,{hideParent:true,onDestroy:function(){Ext.ux.UploadDialog.TBBrowseButton.superclass.onDestroy.call(this);if(this.container){this.container.remove()}}});Ext.ux.UploadDialog.FileRecord=Ext.data.Record.create([{name:"filename"},{name:"state",type:"int"},{name:"note"},{name:"input_element"}]);Ext.ux.UploadDialog.FileRecord.STATE_QUEUE=0;Ext.ux.UploadDialog.FileRecord.STATE_FINISHED=1;Ext.ux.UploadDialog.FileRecord.STATE_FAILED=2;Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING=3;Ext.ux.UploadDialog.Dialog=function(config){var default_config={border:false,width:450,height:300,minWidth:450,minHeight:300,plain:true,constrainHeader:true,draggable:true,closable:true,maximizable:false,minimizable:false,resizable:true,autoDestroy:true,closeAction:"hide",title:this.i18n.title,cls:"ext-ux-uploaddialog-dialog",url:"",base_params:{},permitted_extensions:[],reset_on_hide:true,allow_close_on_upload:false,upload_autostart:false,post_var_name:"file"};config=Ext.applyIf(config||{},default_config);config.layout="absolute";Ext.ux.UploadDialog.Dialog.superclass.constructor.call(this,config)};Ext.extend(Ext.ux.UploadDialog.Dialog,Ext.Window,{fsa:null,state_tpl:null,form:null,grid_panel:null,progress_bar:null,is_uploading:false,initial_queued_count:0,upload_frame:null,initComponent:function(){Ext.ux.UploadDialog.Dialog.superclass.initComponent.call(this);var tt={created:{"window-render":[{action:[this.createForm,this.createProgressBar,this.createGrid],state:"rendering"}],destroy:[{action:this.flushEventQueue,state:"destroyed"}]},rendering:{"grid-render":[{action:[this.fillToolbar,this.updateToolbar],state:"ready"}],destroy:[{action:this.flushEventQueue,state:"destroyed"}]},ready:{"file-selected":[{predicate:[this.fireFileTestEvent,this.isPermittedFile],action:this.addFileToUploadQueue,state:"adding-file"},{}],"grid-selection-change":[{action:this.updateToolbar}],"remove-files":[{action:[this.removeFiles,this.fireFileRemoveEvent]}],"reset-queue":[{action:[this.resetQueue,this.fireResetQueueEvent]}],"start-upload":[{predicate:this.hasUnuploadedFiles,action:[this.setUploadingFlag,this.saveInitialQueuedCount,this.updateToolbar,this.updateProgressBar,this.prepareNextUploadTask,this.fireUploadStartEvent],state:"uploading"},{}],"stop-upload":[{}],hide:[{predicate:[this.isNotEmptyQueue,this.getResetOnHide],action:[this.resetQueue,this.fireResetQueueEvent]},{}],destroy:[{action:this.flushEventQueue,state:"destroyed"}]},"adding-file":{"file-added":[{predicate:this.isUploading,action:[this.incInitialQueuedCount,this.updateProgressBar,this.fireFileAddEvent],state:"uploading"},{predicate:this.getUploadAutostart,action:[this.startUpload,this.fireFileAddEvent],state:"ready"},{action:[this.updateToolbar,this.fireFileAddEvent],state:"ready"}]},uploading:{"file-selected":[{predicate:[this.fireFileTestEvent,this.isPermittedFile],action:this.addFileToUploadQueue,state:"adding-file"},{}],"grid-selection-change":[{}],"start-upload":[{}],"stop-upload":[{predicate:this.hasUnuploadedFiles,action:[this.resetUploadingFlag,this.abortUpload,this.updateToolbar,this.updateProgressBar,this.fireUploadStopEvent],state:"ready"},{action:[this.resetUploadingFlag,this.abortUpload,this.updateToolbar,this.updateProgressBar,this.fireUploadStopEvent,this.fireUploadCompleteEvent],state:"ready"}],"file-upload-start":[{action:[this.uploadFile,this.findUploadFrame,this.fireFileUploadStartEvent]}],"file-upload-success":[{predicate:this.hasUnuploadedFiles,action:[this.resetUploadFrame,this.updateRecordState,this.updateProgressBar,this.prepareNextUploadTask,this.fireUploadSuccessEvent]},{action:[this.resetUploadFrame,this.resetUploadingFlag,this.updateRecordState,this.updateToolbar,this.updateProgressBar,this.fireUploadSuccessEvent,this.fireUploadCompleteEvent],state:"ready"}],"file-upload-error":[{predicate:this.hasUnuploadedFiles,action:[this.resetUploadFrame,this.updateRecordState,this.updateProgressBar,this.prepareNextUploadTask,this.fireUploadErrorEvent]},{action:[this.resetUploadFrame,this.resetUploadingFlag,this.updateRecordState,this.updateToolbar,this.updateProgressBar,this.fireUploadErrorEvent,this.fireUploadCompleteEvent],state:"ready"}],"file-upload-failed":[{predicate:this.hasUnuploadedFiles,action:[this.resetUploadFrame,this.updateRecordState,this.updateProgressBar,this.prepareNextUploadTask,this.fireUploadFailedEvent]},{action:[this.resetUploadFrame,this.resetUploadingFlag,this.updateRecordState,this.updateToolbar,this.updateProgressBar,this.fireUploadFailedEvent,this.fireUploadCompleteEvent],state:"ready"}],hide:[{predicate:this.getResetOnHide,action:[this.stopUpload,this.repostHide]},{}],destroy:[{predicate:this.hasUnuploadedFiles,action:[this.resetUploadingFlag,this.abortUpload,this.fireUploadStopEvent,this.flushEventQueue],state:"destroyed"},{action:[this.resetUploadingFlag,this.abortUpload,this.fireUploadStopEvent,this.fireUploadCompleteEvent,this.flushEventQueue],state:"destroyed"}]},destroyed:{}};this.fsa=new Ext.ux.Utils.FSA("created",tt,this);this.addEvents({filetest:true,fileadd:true,fileremove:true,resetqueue:true,uploadsuccess:true,uploaderror:true,uploadfailed:true,uploadstart:true,uploadstop:true,uploadcomplete:true,fileuploadstart:true});this.on("render",this.onWindowRender,this);this.on("beforehide",this.onWindowBeforeHide,this);this.on("hide",this.onWindowHide,this);this.on("destroy",this.onWindowDestroy,this);this.state_tpl=new Ext.Template("<div class='ext-ux-uploaddialog-state ext-ux-uploaddialog-state-{state}'> </div>").compile()},createForm:function(){this.form=Ext.DomHelper.append(this.body,{tag:"form",method:"post",action:this.url,style:"position: absolute; left: -100px; top: -100px; width: 100px; height: 100px"})},createProgressBar:function(){this.progress_bar=this.add(new Ext.ProgressBar({x:0,y:0,anchor:"0",value:0,text:this.i18n.progress_waiting_text}))},createGrid:function(){var store=new Ext.data.Store({proxy:new Ext.data.MemoryProxy([]),reader:new Ext.data.JsonReader({},Ext.ux.UploadDialog.FileRecord),sortInfo:{field:"state",direction:"DESC"},pruneModifiedRecords:true});var cm=new Ext.grid.ColumnModel([{header:this.i18n.state_col_title,width:this.i18n.state_col_width,resizable:false,dataIndex:"state",sortable:true,renderer:this.renderStateCell.createDelegate(this)},{header:this.i18n.filename_col_title,width:this.i18n.filename_col_width,dataIndex:"filename",sortable:true,renderer:this.renderFilenameCell.createDelegate(this)},{header:this.i18n.note_col_title,width:this.i18n.note_col_width,dataIndex:"note",sortable:true,renderer:this.renderNoteCell.createDelegate(this)}]);this.grid_panel=new Ext.grid.GridPanel({ds:store,cm:cm,x:0,y:22,anchor:"0 -22",border:true,viewConfig:{autoFill:true,forceFit:true},bbar:new Ext.Toolbar()});this.grid_panel.on("render",this.onGridRender,this);this.add(this.grid_panel);this.grid_panel.getSelectionModel().on("selectionchange",this.onGridSelectionChange,this)},fillToolbar:function(){var tb=this.grid_panel.getBottomToolbar();tb.x_buttons={};tb.x_buttons.add=tb.addItem(new Ext.ux.UploadDialog.TBBrowseButton({input_name:this.post_var_name,text:this.i18n.add_btn_text,tooltip:this.i18n.add_btn_tip,iconCls:"ext-ux-uploaddialog-addbtn",handler:this.onAddButtonFileSelected,scope:this}));tb.x_buttons.remove=tb.addButton({text:this.i18n.remove_btn_text,tooltip:this.i18n.remove_btn_tip,iconCls:"ext-ux-uploaddialog-removebtn",handler:this.onRemoveButtonClick,scope:this});tb.x_buttons.reset=tb.addButton({text:this.i18n.reset_btn_text,tooltip:this.i18n.reset_btn_tip,iconCls:"ext-ux-uploaddialog-resetbtn",handler:this.onResetButtonClick,scope:this});tb.add("-");tb.x_buttons.upload=tb.addButton({text:this.i18n.upload_btn_start_text,tooltip:this.i18n.upload_btn_start_tip,iconCls:"ext-ux-uploaddialog-uploadstartbtn",handler:this.onUploadButtonClick,scope:this});tb.add("-");tb.x_buttons.indicator=tb.addItem(new Ext.Toolbar.Item(Ext.DomHelper.append(tb.getEl(),{tag:"div",cls:"ext-ux-uploaddialog-indicator-stoped",html:" "})));tb.add("->");tb.x_buttons.close=tb.addButton({text:this.i18n.close_btn_text,tooltip:this.i18n.close_btn_tip,handler:this.onCloseButtonClick,scope:this})},renderStateCell:function(data,cell,record,row_index,column_index,store){return this.state_tpl.apply({state:data})},renderFilenameCell:function(data,cell,record,row_index,column_index,store){var view=this.grid_panel.getView();var f=function(){try{Ext.fly(view.getCell(row_index,column_index)).child(".x-grid3-cell-inner").dom.qtip=data}catch(e){}};f.defer(1000);return data},renderNoteCell:function(data,cell,record,row_index,column_index,store){var view=this.grid_panel.getView();var f=function(){try{Ext.fly(view.getCell(row_index,column_index)).child(".x-grid3-cell-inner").dom.qtip=data}catch(e){}};f.defer(1000);return data},getFileExtension:function(filename){var result=null;var parts=filename.split(".");if(parts.length>1){result=parts.pop()}return result},isPermittedFileType:function(filename){var result=true;if(this.permitted_extensions.length>0){result=this.permitted_extensions.indexOf(this.getFileExtension(filename))!=-1}return result},isPermittedFile:function(browse_btn){var result=false;var filename=browse_btn.getInputFile().dom.value;if(this.isPermittedFileType(filename)){result=true}else{Ext.Msg.alert(this.i18n.error_msgbox_title,String.format(this.i18n.err_file_type_not_permitted,filename,this.permitted_extensions.join(this.i18n.permitted_extensions_join_str)));result=false}return result},fireFileTestEvent:function(browse_btn){return this.fireEvent("filetest",this,browse_btn.getInputFile().dom.value)!==false},addFileToUploadQueue:function(browse_btn){var input_file=browse_btn.detachInputFile();input_file.appendTo(this.form);input_file.setStyle("width","100px");input_file.dom.disabled=true;var store=this.grid_panel.getStore();store.add(new Ext.ux.UploadDialog.FileRecord({state:Ext.ux.UploadDialog.FileRecord.STATE_QUEUE,filename:input_file.dom.value,note:this.i18n.note_queued_to_upload,input_element:input_file}));this.fsa.postEvent("file-added",input_file.dom.value)},fireFileAddEvent:function(filename){this.fireEvent("fileadd",this,filename)},updateProgressBar:function(){if(this.is_uploading){var queued=this.getQueuedCount(true);var value=1-queued/this.initial_queued_count;this.progress_bar.updateProgress(value,String.format(this.i18n.progress_uploading_text,this.initial_queued_count-queued,this.initial_queued_count))}else{this.progress_bar.updateProgress(0,this.i18n.progress_waiting_text)}},updateToolbar:function(){var tb=this.grid_panel.getBottomToolbar();if(this.is_uploading){tb.x_buttons.remove.disable();tb.x_buttons.reset.disable();tb.x_buttons.upload.enable();if(!this.getAllowCloseOnUpload()){tb.x_buttons.close.disable()}Ext.fly(tb.x_buttons.indicator.getEl()).replaceClass("ext-ux-uploaddialog-indicator-stoped","ext-ux-uploaddialog-indicator-processing");tb.x_buttons.upload.setIconClass("ext-ux-uploaddialog-uploadstopbtn");tb.x_buttons.upload.setText(this.i18n.upload_btn_stop_text);tb.x_buttons.upload.getEl().child(tb.x_buttons.upload.buttonSelector).dom[tb.x_buttons.upload.tooltipType]=this.i18n.upload_btn_stop_tip}else{tb.x_buttons.remove.enable();tb.x_buttons.reset.enable();tb.x_buttons.close.enable();Ext.fly(tb.x_buttons.indicator.getEl()).replaceClass("ext-ux-uploaddialog-indicator-processing","ext-ux-uploaddialog-indicator-stoped");tb.x_buttons.upload.setIconClass("ext-ux-uploaddialog-uploadstartbtn");tb.x_buttons.upload.setText(this.i18n.upload_btn_start_text);tb.x_buttons.upload.getEl().child(tb.x_buttons.upload.buttonSelector).dom[tb.x_buttons.upload.tooltipType]=this.i18n.upload_btn_start_tip;if(this.getQueuedCount()>0){tb.x_buttons.upload.enable()}else{tb.x_buttons.upload.disable()}if(this.grid_panel.getSelectionModel().hasSelection()){tb.x_buttons.remove.enable()}else{tb.x_buttons.remove.disable()}if(this.grid_panel.getStore().getCount()>0){tb.x_buttons.reset.enable()}else{tb.x_buttons.reset.disable()}}},saveInitialQueuedCount:function(){this.initial_queued_count=this.getQueuedCount()},incInitialQueuedCount:function(){this.initial_queued_count++},setUploadingFlag:function(){this.is_uploading=true},resetUploadingFlag:function(){this.is_uploading=false},prepareNextUploadTask:function(){var store=this.grid_panel.getStore();var record=null;store.each(function(r){if(!record&&r.get("state")==Ext.ux.UploadDialog.FileRecord.STATE_QUEUE){record=r}else{r.get("input_element").dom.disabled=true}});record.get("input_element").dom.disabled=false;record.set("state",Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING);record.set("note",this.i18n.note_processing);record.commit();this.fsa.postEvent("file-upload-start",record)},fireUploadStartEvent:function(){this.fireEvent("uploadstart",this)},removeFiles:function(file_records){var store=this.grid_panel.getStore();for(var i=0,len=file_records.length;i<len;i++){var r=file_records[i];r.get("input_element").remove();store.remove(r)}},fireFileRemoveEvent:function(file_records){for(var i=0,len=file_records.length;i<len;i++){this.fireEvent("fileremove",this,file_records[i].get("filename"))}},resetQueue:function(){var store=this.grid_panel.getStore();store.each(function(r){r.get("input_element").remove()});store.removeAll()},fireResetQueueEvent:function(){this.fireEvent("resetqueue",this)},uploadFile:function(record){Ext.Ajax.request({url:this.url,params:this.base_params||this.baseParams||this.params,method:"POST",form:this.form,isUpload:true,success:this.onAjaxSuccess,failure:this.onAjaxFailure,scope:this,record:record})},fireFileUploadStartEvent:function(record){this.fireEvent("fileuploadstart",this,record.get("filename"))},updateRecordState:function(data){if("success" in data.response&&data.response.success){data.record.set("state",Ext.ux.UploadDialog.FileRecord.STATE_FINISHED);data.record.set("note",data.response.message||data.response.error||this.i18n.note_upload_success)}else{data.record.set("state",Ext.ux.UploadDialog.FileRecord.STATE_FAILED);data.record.set("note",data.response.message||data.response.error||this.i18n.note_upload_error)}data.record.commit()},fireUploadSuccessEvent:function(data){this.fireEvent("uploadsuccess",this,data.record.get("filename"),data.response)},fireUploadErrorEvent:function(data){this.fireEvent("uploaderror",this,data.record.get("filename"),data.response)},fireUploadFailedEvent:function(data){this.fireEvent("uploadfailed",this,data.record.get("filename"))},fireUploadCompleteEvent:function(){this.fireEvent("uploadcomplete",this)},findUploadFrame:function(){this.upload_frame=Ext.getBody().child("iframe.x-hidden:last")},resetUploadFrame:function(){this.upload_frame=null},removeUploadFrame:function(){if(this.upload_frame){this.upload_frame.removeAllListeners();this.upload_frame.dom.src="about:blank";this.upload_frame.remove()}this.upload_frame=null},abortUpload:function(){this.removeUploadFrame();var store=this.grid_panel.getStore();var record=null;store.each(function(r){if(r.get("state")==Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING){record=r;return false}});record.set("state",Ext.ux.UploadDialog.FileRecord.STATE_FAILED);record.set("note",this.i18n.note_aborted);record.commit()},fireUploadStopEvent:function(){this.fireEvent("uploadstop",this)},repostHide:function(){this.fsa.postEvent("hide")},flushEventQueue:function(){this.fsa.flushEventQueue()},onWindowRender:function(){this.fsa.postEvent("window-render")},onWindowBeforeHide:function(){return this.isUploading()?this.getAllowCloseOnUpload():true},onWindowHide:function(){this.fsa.postEvent("hide")},onWindowDestroy:function(){this.fsa.postEvent("destroy")},onGridRender:function(){this.fsa.postEvent("grid-render")},onGridSelectionChange:function(){this.fsa.postEvent("grid-selection-change")},onAddButtonFileSelected:function(btn){this.fsa.postEvent("file-selected",btn)},onUploadButtonClick:function(){if(this.is_uploading){this.fsa.postEvent("stop-upload")}else{this.fsa.postEvent("start-upload")}},onRemoveButtonClick:function(){var selections=this.grid_panel.getSelectionModel().getSelections();this.fsa.postEvent("remove-files",selections)},onResetButtonClick:function(){this.fsa.postEvent("reset-queue")},onCloseButtonClick:function(){this[this.closeAction].call(this)},onAjaxSuccess:function(response,options){var json_response={success:false,error:this.i18n.note_upload_error};try{var rt=response.responseText;var filter=rt.match(/^<[^>]+>((?:.|\n)*)<\/[^>]+>$/);if(filter){rt=filter[1]}json_response=Ext.util.JSON.decode(rt)}catch(e){}var data={record:options.record,response:json_response};if("success" in json_response&&json_response.success){this.fsa.postEvent("file-upload-success",data)}else{this.fsa.postEvent("file-upload-error",data)}},onAjaxFailure:function(response,options){var data={record:options.record,response:{success:false,error:this.i18n.note_upload_failed}};this.fsa.postEvent("file-upload-failed",data)},startUpload:function(){this.fsa.postEvent("start-upload")},stopUpload:function(){this.fsa.postEvent("stop-upload")},getUrl:function(){return this.url},setUrl:function(url){this.url=url},getBaseParams:function(){return this.base_params},setBaseParams:function(params){this.base_params=params},getUploadAutostart:function(){return this.upload_autostart},setUploadAutostart:function(value){this.upload_autostart=value},getAllowCloseOnUpload:function(){return this.allow_close_on_upload},setAllowCloseOnUpload:function(value){this.allow_close_on_upload},getResetOnHide:function(){return this.reset_on_hide},setResetOnHide:function(value){this.reset_on_hide=value},getPermittedExtensions:function(){return this.permitted_extensions},setPermittedExtensions:function(value){this.permitted_extensions=value},isUploading:function(){return this.is_uploading},isNotEmptyQueue:function(){return this.grid_panel.getStore().getCount()>0},getQueuedCount:function(count_processing){var count=0;var store=this.grid_panel.getStore();store.each(function(r){if(r.get("state")==Ext.ux.UploadDialog.FileRecord.STATE_QUEUE){count++}if(count_processing&&r.get("state")==Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING){count++}});return count},hasUnuploadedFiles:function(){return this.getQueuedCount()>0}});var p=Ext.ux.UploadDialog.Dialog.prototype;p.i18n={title:"File upload dialog",state_col_title:"State",state_col_width:70,filename_col_title:"Filename",filename_col_width:230,note_col_title:"Note",note_col_width:150,add_btn_text:"Add",add_btn_tip:"Add file into upload queue.",remove_btn_text:"Remove",remove_btn_tip:"Remove file from upload queue.",reset_btn_text:"Reset",reset_btn_tip:"Reset queue.",upload_btn_start_text:"Upload",upload_btn_stop_text:"Abort",upload_btn_start_tip:"Upload queued files to the server.",upload_btn_stop_tip:"Stop upload.",close_btn_text:"Close",close_btn_tip:"Close the dialog.",progress_waiting_text:"Waiting...",progress_uploading_text:"Uploading: {0} of {1} files complete.",error_msgbox_title:"Error",permitted_extensions_join_str:",",err_file_type_not_permitted:"Selected file extension isn't permitted.<br/>Please select files with following extensions: {1}",note_queued_to_upload:"Queued for upload.",note_processing:"Uploading...",note_upload_failed:"Server is unavailable or internal server error occured.",note_upload_success:"OK.",note_upload_error:"Upload error.",note_aborted:"Aborted by user."}; |
/** |
* This namespace should be in another file but I dicided to put it here for consistancy. |
*/ |
Ext.namespace('Ext.ux.Utils'); |
|
/** |
* This class implements event queue behaviour. |
* |
* @class Ext.ux.Utils.EventQueue |
* @param function handler Event handler. |
* @param object scope Handler scope. |
*/ |
Ext.ux.Utils.EventQueue = function(handler, scope) |
{ |
if (!handler) { |
throw 'Handler is required.'; |
} |
this.handler = handler; |
this.scope = scope || window; |
this.queue = []; |
this.is_processing = false; |
|
/** |
* Posts event into the queue. |
* |
* @access public |
* @param mixed event Event identificator. |
* @param mixed data Event data. |
*/ |
this.postEvent = function(event, data) |
{ |
data = data || null; |
this.queue.push({event: event, data: data}); |
if (!this.is_processing) { |
this.process(); |
} |
} |
|
this.flushEventQueue = function() |
{ |
this.queue = []; |
}, |
|
/** |
* @access private |
*/ |
this.process = function() |
{ |
while (this.queue.length > 0) { |
this.is_processing = true; |
var event_data = this.queue.shift(); |
this.handler.call(this.scope, event_data.event, event_data.data); |
} |
this.is_processing = false; |
} |
} |
|
/** |
* This class implements Mili's finite state automata behaviour. |
* |
* Transition / output table format: |
* { |
* 'state_1' : { |
* 'event_1' : [ |
* { |
* p|predicate: function, // Transition predicate, optional, default to true. |
* // If array then conjunction will be applyed to the operands. |
* // Predicate signature is (data, event, this). |
* a|action: function|array, // Transition action, optional, default to Ext.emptyFn. |
* // If array then methods will be called sequentially. |
* // Action signature is (data, event, this). |
* s|state: 'state_x', // New state - transition destination, optional, default to |
* // current state. |
* scope: object // Predicate and action scope, optional, default to |
* // trans_table_scope or window. |
* } |
* ] |
* }, |
* |
* 'state_2' : { |
* ... |
* } |
* ... |
* } |
* |
* @param mixed initial_state Initial state. |
* @param object trans_table Transition / output table. |
* @param trans_table_scope Transition / output table's methods scope. |
*/ |
Ext.ux.Utils.FSA = function(initial_state, trans_table, trans_table_scope) |
{ |
this.current_state = initial_state; |
this.trans_table = trans_table || {}; |
this.trans_table_scope = trans_table_scope || window; |
Ext.ux.Utils.FSA.superclass.constructor.call(this, this.processEvent, this); |
} |
|
Ext.extend(Ext.ux.Utils.FSA, Ext.ux.Utils.EventQueue, { |
|
current_state : null, |
trans_table : null, |
trans_table_scope : null, |
|
/** |
* Returns current state |
* |
* @access public |
* @return mixed Current state. |
*/ |
state : function() |
{ |
return this.current_state; |
}, |
|
/** |
* @access public |
*/ |
processEvent : function(event, data) |
{ |
var transitions = this.currentStateEventTransitions(event); |
if (!transitions) { |
throw "State '" + this.current_state + "' has no transition for event '" + event + "'."; |
} |
for (var i = 0, len = transitions.length; i < len; i++) { |
var transition = transitions[i]; |
|
var predicate = transition.predicate || transition.p || true; |
var action = transition.action || transition.a || Ext.emptyFn; |
var new_state = transition.state || transition.s || this.current_state; |
var scope = transition.scope || this.trans_table_scope; |
|
if (this.computePredicate(predicate, scope, data, event)) { |
this.callAction(action, scope, data, event); |
this.current_state = new_state; |
return; |
} |
} |
|
throw "State '" + this.current_state + "' has no transition for event '" + event + "' in current context"; |
}, |
|
/** |
* @access private |
*/ |
currentStateEventTransitions : function(event) |
{ |
return this.trans_table[this.current_state] ? |
this.trans_table[this.current_state][event] || false |
: |
false; |
}, |
|
/** |
* @access private |
*/ |
computePredicate : function(predicate, scope, data, event) |
{ |
var result = false; |
|
switch (Ext.type(predicate)) { |
case 'function': |
result = predicate.call(scope, data, event, this); |
break; |
case 'array': |
result = true; |
for (var i = 0, len = predicate.length; result && (i < len); i++) { |
if (Ext.type(predicate[i]) == 'function') { |
result = predicate[i].call(scope, data, event, this); |
} |
else { |
throw [ |
'Predicate: ', |
predicate[i], |
' is not callable in "', |
this.current_state, |
'" state for event "', |
event |
].join(''); |
} |
} |
break; |
case 'boolean': |
result = predicate; |
break; |
default: |
throw [ |
'Predicate: ', |
predicate, |
' is not callable in "', |
this.current_state, |
'" state for event "', |
event |
].join(''); |
} |
return result; |
}, |
|
/** |
* @access private |
*/ |
callAction : function(action, scope, data, event) |
{ |
switch (Ext.type(action)) { |
case 'array': |
for (var i = 0, len = action.length; i < len; i++) { |
if (Ext.type(action[i]) == 'function') { |
action[i].call(scope, data, event, this); |
} |
else { |
throw [ |
'Action: ', |
action[i], |
' is not callable in "', |
this.current_state, |
'" state for event "', |
event |
].join(''); |
} |
} |
break; |
case 'function': |
action.call(scope, data, event, this); |
break; |
default: |
throw [ |
'Action: ', |
action, |
' is not callable in "', |
this.current_state, |
'" state for event "', |
event |
].join(''); |
} |
} |
}); |
|
// ---------------------------------------------------------------------------------------------- // |
|
/** |
* Ext.ux.UploadDialog namespace. |
*/ |
Ext.namespace('Ext.ux.UploadDialog'); |
|
/** |
* File upload browse button. |
* |
* @class Ext.ux.UploadDialog.BrowseButton |
*/ |
Ext.ux.UploadDialog.BrowseButton = Ext.extend(Ext.Button, |
{ |
input_name : 'file', |
|
input_file : null, |
|
original_handler : null, |
|
original_scope : null, |
|
/** |
* @access private |
*/ |
initComponent : function() |
{ |
Ext.ux.UploadDialog.BrowseButton.superclass.initComponent.call(this); |
this.original_handler = this.handler || null; |
this.original_scope = this.scope || window; |
this.handler = null; |
this.scope = null; |
}, |
|
/** |
* @access private |
*/ |
onRender : function(ct, position) |
{ |
Ext.ux.UploadDialog.BrowseButton.superclass.onRender.call(this, ct, position); |
this.createInputFile(); |
}, |
|
/** |
* @access private |
*/ |
createInputFile : function() |
{ |
var button_container = this.el.child('.x-btn-center'); |
button_container.position('relative'); |
this.input_file = Ext.DomHelper.append( |
button_container, |
{ |
tag: 'input', |
type: 'file', |
size: 1, |
name: this.input_name || Ext.id(this.el), |
style: 'position: absolute; display: block; border: none; cursor: pointer' |
}, |
true |
); |
|
var button_box = button_container.getBox(); |
this.input_file.setStyle('font-size', (button_box.width * 0.5) + 'px'); |
|
var input_box = this.input_file.getBox(); |
var adj = {x: 3, y: 3} |
if (Ext.isIE) { |
adj = {x: 0, y: 3} |
} |
|
this.input_file.setLeft(button_box.width - input_box.width + adj.x + 'px'); |
this.input_file.setTop(button_box.height - input_box.height + adj.y + 'px'); |
this.input_file.setOpacity(0.0); |
|
if (this.handleMouseEvents) { |
this.input_file.on('mouseover', this.onMouseOver, this); |
this.input_file.on('mousedown', this.onMouseDown, this); |
} |
|
if(this.tooltip){ |
if(typeof this.tooltip == 'object'){ |
Ext.QuickTips.register(Ext.apply({target: this.input_file}, this.tooltip)); |
} |
else { |
this.input_file.dom[this.tooltipType] = this.tooltip; |
} |
} |
|
this.input_file.on('change', this.onInputFileChange, this); |
this.input_file.on('click', function(e) { e.stopPropagation(); }); |
}, |
|
/** |
* @access public |
*/ |
detachInputFile : function(no_create) |
{ |
var result = this.input_file; |
|
no_create = no_create || false; |
|
if (typeof this.tooltip == 'object') { |
Ext.QuickTips.unregister(this.input_file); |
} |
else { |
this.input_file.dom[this.tooltipType] = null; |
} |
this.input_file.removeAllListeners(); |
this.input_file = null; |
|
if (!no_create) { |
this.createInputFile(); |
} |
return result; |
}, |
|
/** |
* @access public |
*/ |
getInputFile : function() |
{ |
return this.input_file; |
}, |
|
/** |
* @access public |
*/ |
disable : function() |
{ |
Ext.ux.UploadDialog.BrowseButton.superclass.disable.call(this); |
this.input_file.dom.disabled = true; |
}, |
|
/** |
* @access public |
*/ |
enable : function() |
{ |
Ext.ux.UploadDialog.BrowseButton.superclass.enable.call(this); |
this.input_file.dom.disabled = false; |
}, |
|
/** |
* @access public |
*/ |
destroy : function() |
{ |
var input_file = this.detachInputFile(true); |
input_file.remove(); |
input_file = null; |
Ext.ux.UploadDialog.BrowseButton.superclass.destroy.call(this); |
}, |
|
/** |
* @access private |
*/ |
onInputFileChange : function() |
{ |
if (this.original_handler) { |
this.original_handler.call(this.original_scope, this); |
} |
} |
}); |
|
/** |
* Toolbar file upload browse button. |
* |
* @class Ext.ux.UploadDialog.TBBrowseButton |
*/ |
Ext.ux.UploadDialog.TBBrowseButton = Ext.extend(Ext.ux.UploadDialog.BrowseButton, |
{ |
hideParent : true, |
|
onDestroy : function() |
{ |
Ext.ux.UploadDialog.TBBrowseButton.superclass.onDestroy.call(this); |
if(this.container) { |
this.container.remove(); |
} |
} |
}); |
|
/** |
* Record type for dialogs grid. |
* |
* @class Ext.ux.UploadDialog.FileRecord |
*/ |
Ext.ux.UploadDialog.FileRecord = Ext.data.Record.create([ |
{name: 'filename'}, |
{name: 'state', type: 'int'}, |
{name: 'note'}, |
{name: 'input_element'} |
]); |
|
Ext.ux.UploadDialog.FileRecord.STATE_QUEUE = 0; |
Ext.ux.UploadDialog.FileRecord.STATE_FINISHED = 1; |
Ext.ux.UploadDialog.FileRecord.STATE_FAILED = 2; |
Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING = 3; |
|
/** |
* Dialog class. |
* |
* @class Ext.ux.UploadDialog.Dialog |
*/ |
Ext.ux.UploadDialog.Dialog = function(config) |
{ |
var default_config = { |
border: false, |
width: 450, |
height: 300, |
minWidth: 450, |
minHeight: 300, |
plain: true, |
constrainHeader: true, |
draggable: true, |
closable: true, |
maximizable: false, |
minimizable: false, |
resizable: true, |
autoDestroy: true, |
closeAction: 'hide', |
title: this.i18n.title, |
cls: 'ext-ux-uploaddialog-dialog', |
// -------- |
url: '', |
base_params: {}, |
permitted_extensions: [], |
reset_on_hide: true, |
allow_close_on_upload: false, |
upload_autostart: false, |
post_var_name: 'file' |
} |
config = Ext.applyIf(config || {}, default_config); |
config.layout = 'absolute'; |
|
Ext.ux.UploadDialog.Dialog.superclass.constructor.call(this, config); |
} |
|
Ext.extend(Ext.ux.UploadDialog.Dialog, Ext.Window, { |
|
fsa : null, |
|
state_tpl : null, |
|
form : null, |
|
grid_panel : null, |
|
progress_bar : null, |
|
is_uploading : false, |
|
initial_queued_count : 0, |
|
upload_frame : null, |
|
/** |
* @access private |
*/ |
//--------------------------------------------------------------------------------------------- // |
initComponent : function() |
{ |
Ext.ux.UploadDialog.Dialog.superclass.initComponent.call(this); |
|
// Setting automata protocol |
var tt = { |
// -------------- |
'created' : { |
// -------------- |
'window-render' : [ |
{ |
action: [this.createForm, this.createProgressBar, this.createGrid], |
state: 'rendering' |
} |
], |
'destroy' : [ |
{ |
action: this.flushEventQueue, |
state: 'destroyed' |
} |
] |
}, |
// -------------- |
'rendering' : { |
// -------------- |
'grid-render' : [ |
{ |
action: [this.fillToolbar, this.updateToolbar], |
state: 'ready' |
} |
], |
'destroy' : [ |
{ |
action: this.flushEventQueue, |
state: 'destroyed' |
} |
] |
}, |
// -------------- |
'ready' : { |
// -------------- |
'file-selected' : [ |
{ |
predicate: [this.fireFileTestEvent, this.isPermittedFile], |
action: this.addFileToUploadQueue, |
state: 'adding-file' |
}, |
{ |
// If file is not permitted then do nothing. |
} |
], |
'grid-selection-change' : [ |
{ |
action: this.updateToolbar |
} |
], |
'remove-files' : [ |
{ |
action: [this.removeFiles, this.fireFileRemoveEvent] |
} |
], |
'reset-queue' : [ |
{ |
action: [this.resetQueue, this.fireResetQueueEvent] |
} |
], |
'start-upload' : [ |
{ |
predicate: this.hasUnuploadedFiles, |
action: [ |
this.setUploadingFlag, this.saveInitialQueuedCount, this.updateToolbar, |
this.updateProgressBar, this.prepareNextUploadTask, this.fireUploadStartEvent |
], |
state: 'uploading' |
}, |
{ |
// Has nothing to upload, do nothing. |
} |
], |
'stop-upload' : [ |
{ |
// We are not uploading, do nothing. Can be posted by user only at this state. |
} |
], |
'hide' : [ |
{ |
predicate: [this.isNotEmptyQueue, this.getResetOnHide], |
action: [this.resetQueue, this.fireResetQueueEvent] |
}, |
{ |
// Do nothing |
} |
], |
'destroy' : [ |
{ |
action: this.flushEventQueue, |
state: 'destroyed' |
} |
] |
}, |
// -------------- |
'adding-file' : { |
// -------------- |
'file-added' : [ |
{ |
predicate: this.isUploading, |
action: [this.incInitialQueuedCount, this.updateProgressBar, this.fireFileAddEvent], |
state: 'uploading' |
}, |
{ |
predicate: this.getUploadAutostart, |
action: [this.startUpload, this.fireFileAddEvent], |
state: 'ready' |
}, |
{ |
action: [this.updateToolbar, this.fireFileAddEvent], |
state: 'ready' |
} |
] |
}, |
// -------------- |
'uploading' : { |
// -------------- |
'file-selected' : [ |
{ |
predicate: [this.fireFileTestEvent, this.isPermittedFile], |
action: this.addFileToUploadQueue, |
state: 'adding-file' |
}, |
{ |
// If file is not permitted then do nothing. |
} |
], |
'grid-selection-change' : [ |
{ |
// Do nothing. |
} |
], |
'start-upload' : [ |
{ |
// Can be posted only by user in this state. |
} |
], |
'stop-upload' : [ |
{ |
predicate: this.hasUnuploadedFiles, |
action: [ |
this.resetUploadingFlag, this.abortUpload, this.updateToolbar, |
this.updateProgressBar, this.fireUploadStopEvent |
], |
state: 'ready' |
}, |
{ |
action: [ |
this.resetUploadingFlag, this.abortUpload, this.updateToolbar, |
this.updateProgressBar, this.fireUploadStopEvent, this.fireUploadCompleteEvent |
], |
state: 'ready' |
} |
], |
'file-upload-start' : [ |
{ |
action: [this.uploadFile, this.findUploadFrame, this.fireFileUploadStartEvent] |
} |
], |
'file-upload-success' : [ |
{ |
predicate: this.hasUnuploadedFiles, |
action: [ |
this.resetUploadFrame, this.updateRecordState, this.updateProgressBar, |
this.prepareNextUploadTask, this.fireUploadSuccessEvent |
] |
}, |
{ |
action: [ |
this.resetUploadFrame, this.resetUploadingFlag, this.updateRecordState, |
this.updateToolbar, this.updateProgressBar, this.fireUploadSuccessEvent, |
this.fireUploadCompleteEvent |
], |
state: 'ready' |
} |
], |
'file-upload-error' : [ |
{ |
predicate: this.hasUnuploadedFiles, |
action: [ |
this.resetUploadFrame, this.updateRecordState, this.updateProgressBar, |
this.prepareNextUploadTask, this.fireUploadErrorEvent |
] |
}, |
{ |
action: [ |
this.resetUploadFrame, this.resetUploadingFlag, this.updateRecordState, |
this.updateToolbar, this.updateProgressBar, this.fireUploadErrorEvent, |
this.fireUploadCompleteEvent |
], |
state: 'ready' |
} |
], |
'file-upload-failed' : [ |
{ |
predicate: this.hasUnuploadedFiles, |
action: [ |
this.resetUploadFrame, this.updateRecordState, this.updateProgressBar, |
this.prepareNextUploadTask, this.fireUploadFailedEvent |
] |
}, |
{ |
action: [ |
this.resetUploadFrame, this.resetUploadingFlag, this.updateRecordState, |
this.updateToolbar, this.updateProgressBar, this.fireUploadFailedEvent, |
this.fireUploadCompleteEvent |
], |
state: 'ready' |
} |
], |
'hide' : [ |
{ |
predicate: this.getResetOnHide, |
action: [this.stopUpload, this.repostHide] |
}, |
{ |
// Do nothing. |
} |
], |
'destroy' : [ |
{ |
predicate: this.hasUnuploadedFiles, |
action: [ |
this.resetUploadingFlag, this.abortUpload, |
this.fireUploadStopEvent, this.flushEventQueue |
], |
state: 'destroyed' |
}, |
{ |
action: [ |
this.resetUploadingFlag, this.abortUpload, |
this.fireUploadStopEvent, this.fireUploadCompleteEvent, this.flushEventQueue |
], |
state: 'destroyed' |
} |
] |
}, |
// -------------- |
'destroyed' : { |
// -------------- |
} |
} |
this.fsa = new Ext.ux.Utils.FSA('created', tt, this); |
|
// Registering dialog events. |
this.addEvents({ |
'filetest': true, |
'fileadd' : true, |
'fileremove' : true, |
'resetqueue' : true, |
'uploadsuccess' : true, |
'uploaderror' : true, |
'uploadfailed' : true, |
'uploadstart' : true, |
'uploadstop' : true, |
'uploadcomplete' : true, |
'fileuploadstart' : true |
}); |
|
// Attaching to window events. |
this.on('render', this.onWindowRender, this); |
this.on('beforehide', this.onWindowBeforeHide, this); |
this.on('hide', this.onWindowHide, this); |
this.on('destroy', this.onWindowDestroy, this); |
|
// Compiling state template. |
this.state_tpl = new Ext.Template( |
"<div class='ext-ux-uploaddialog-state ext-ux-uploaddialog-state-{state}'> </div>" |
).compile(); |
}, |
|
createForm : function() |
{ |
this.form = Ext.DomHelper.append(this.body, { |
tag: 'form', |
method: 'post', |
action: this.url, |
style: 'position: absolute; left: -100px; top: -100px; width: 100px; height: 100px' |
}); |
}, |
|
createProgressBar : function() |
{ |
this.progress_bar = this.add( |
new Ext.ProgressBar({ |
x: 0, |
y: 0, |
anchor: '0', |
value: 0.0, |
text: this.i18n.progress_waiting_text |
}) |
); |
}, |
|
createGrid : function() |
{ |
var store = new Ext.data.Store({ |
proxy: new Ext.data.MemoryProxy([]), |
reader: new Ext.data.JsonReader({}, Ext.ux.UploadDialog.FileRecord), |
sortInfo: {field: 'state', direction: 'DESC'}, |
pruneModifiedRecords: true |
}); |
|
var cm = new Ext.grid.ColumnModel([ |
{ |
header: this.i18n.state_col_title, |
width: this.i18n.state_col_width, |
resizable: false, |
dataIndex: 'state', |
sortable: true, |
renderer: this.renderStateCell.createDelegate(this) |
}, |
{ |
header: this.i18n.filename_col_title, |
width: this.i18n.filename_col_width, |
dataIndex: 'filename', |
sortable: true, |
renderer: this.renderFilenameCell.createDelegate(this) |
}, |
{ |
header: this.i18n.note_col_title, |
width: this.i18n.note_col_width, |
dataIndex: 'note', |
sortable: true, |
renderer: this.renderNoteCell.createDelegate(this) |
} |
]); |
|
this.grid_panel = new Ext.grid.GridPanel({ |
ds: store, |
cm: cm, |
|
x: 0, |
y: 22, |
anchor: '0 -22', |
border: true, |
|
viewConfig: { |
autoFill: true, |
forceFit: true |
}, |
|
bbar : new Ext.Toolbar() |
}); |
this.grid_panel.on('render', this.onGridRender, this); |
|
this.add(this.grid_panel); |
|
this.grid_panel.getSelectionModel().on('selectionchange', this.onGridSelectionChange, this); |
}, |
|
fillToolbar : function() |
{ |
var tb = this.grid_panel.getBottomToolbar(); |
tb.x_buttons = {} |
|
tb.x_buttons.add = tb.addItem(new Ext.ux.UploadDialog.TBBrowseButton({ |
input_name: this.post_var_name, |
text: this.i18n.add_btn_text, |
tooltip: this.i18n.add_btn_tip, |
iconCls: 'ext-ux-uploaddialog-addbtn', |
handler: this.onAddButtonFileSelected, |
scope: this |
})); |
|
tb.x_buttons.remove = tb.addButton({ |
text: this.i18n.remove_btn_text, |
tooltip: this.i18n.remove_btn_tip, |
iconCls: 'ext-ux-uploaddialog-removebtn', |
handler: this.onRemoveButtonClick, |
scope: this |
}); |
|
tb.x_buttons.reset = tb.addButton({ |
text: this.i18n.reset_btn_text, |
tooltip: this.i18n.reset_btn_tip, |
iconCls: 'ext-ux-uploaddialog-resetbtn', |
handler: this.onResetButtonClick, |
scope: this |
}); |
|
tb.add('-'); |
|
tb.x_buttons.upload = tb.addButton({ |
text: this.i18n.upload_btn_start_text, |
tooltip: this.i18n.upload_btn_start_tip, |
iconCls: 'ext-ux-uploaddialog-uploadstartbtn', |
handler: this.onUploadButtonClick, |
scope: this |
}); |
|
tb.add('-'); |
|
tb.x_buttons.indicator = tb.addItem( |
new Ext.Toolbar.Item( |
Ext.DomHelper.append(tb.getEl(), { |
tag: 'div', |
cls: 'ext-ux-uploaddialog-indicator-stoped', |
html: ' ' |
}) |
) |
); |
|
tb.add('->'); |
|
tb.x_buttons.close = tb.addButton({ |
text: this.i18n.close_btn_text, |
tooltip: this.i18n.close_btn_tip, |
handler: this.onCloseButtonClick, |
scope: this |
}); |
}, |
|
renderStateCell : function(data, cell, record, row_index, column_index, store) |
{ |
return this.state_tpl.apply({state: data}); |
}, |
|
renderFilenameCell : function(data, cell, record, row_index, column_index, store) |
{ |
var view = this.grid_panel.getView(); |
var f = function() { |
try { |
Ext.fly( |
view.getCell(row_index, column_index) |
).child('.x-grid3-cell-inner').dom['qtip'] = data; |
} |
catch (e) |
{} |
} |
f.defer(1000); |
return data; |
}, |
|
renderNoteCell : function(data, cell, record, row_index, column_index, store) |
{ |
var view = this.grid_panel.getView(); |
var f = function() { |
try { |
Ext.fly( |
view.getCell(row_index, column_index) |
).child('.x-grid3-cell-inner').dom['qtip'] = data; |
} |
catch (e) |
{} |
} |
f.defer(1000); |
return data; |
}, |
|
getFileExtension : function(filename) |
{ |
var result = null; |
var parts = filename.split('.'); |
if (parts.length > 1) { |
result = parts.pop(); |
} |
return result; |
}, |
|
isPermittedFileType : function(filename) |
{ |
var result = true; |
if (this.permitted_extensions.length > 0) { |
result = this.permitted_extensions.indexOf(this.getFileExtension(filename)) != -1; |
} |
return result; |
}, |
|
isPermittedFile : function(browse_btn) |
{ |
var result = false; |
var filename = browse_btn.getInputFile().dom.value; |
|
if (this.isPermittedFileType(filename)) { |
result = true; |
} |
else { |
Ext.Msg.alert( |
this.i18n.error_msgbox_title, |
String.format( |
this.i18n.err_file_type_not_permitted, |
filename, |
this.permitted_extensions.join(this.i18n.permitted_extensions_join_str) |
) |
); |
result = false; |
} |
|
return result; |
}, |
|
fireFileTestEvent : function(browse_btn) |
{ |
return this.fireEvent('filetest', this, browse_btn.getInputFile().dom.value) !== false; |
}, |
|
addFileToUploadQueue : function(browse_btn) |
{ |
var input_file = browse_btn.detachInputFile(); |
|
input_file.appendTo(this.form); |
input_file.setStyle('width', '100px'); |
input_file.dom.disabled = true; |
|
var store = this.grid_panel.getStore(); |
store.add( |
new Ext.ux.UploadDialog.FileRecord({ |
state: Ext.ux.UploadDialog.FileRecord.STATE_QUEUE, |
filename: input_file.dom.value, |
note: this.i18n.note_queued_to_upload, |
input_element: input_file |
}) |
); |
this.fsa.postEvent('file-added', input_file.dom.value); |
}, |
|
fireFileAddEvent : function(filename) |
{ |
this.fireEvent('fileadd', this, filename); |
}, |
|
updateProgressBar : function() |
{ |
if (this.is_uploading) { |
var queued = this.getQueuedCount(true); |
var value = 1 - queued / this.initial_queued_count; |
this.progress_bar.updateProgress( |
value, |
String.format( |
this.i18n.progress_uploading_text, |
this.initial_queued_count - queued, |
this.initial_queued_count |
) |
); |
} |
else { |
this.progress_bar.updateProgress(0, this.i18n.progress_waiting_text); |
} |
}, |
|
updateToolbar : function() |
{ |
var tb = this.grid_panel.getBottomToolbar(); |
if (this.is_uploading) { |
tb.x_buttons.remove.disable(); |
tb.x_buttons.reset.disable(); |
tb.x_buttons.upload.enable(); |
if (!this.getAllowCloseOnUpload()) { |
tb.x_buttons.close.disable(); |
} |
Ext.fly(tb.x_buttons.indicator.getEl()).replaceClass( |
'ext-ux-uploaddialog-indicator-stoped', |
'ext-ux-uploaddialog-indicator-processing' |
); |
tb.x_buttons.upload.setIconClass('ext-ux-uploaddialog-uploadstopbtn'); |
tb.x_buttons.upload.setText(this.i18n.upload_btn_stop_text); |
tb.x_buttons.upload.getEl() |
.child(tb.x_buttons.upload.buttonSelector) |
.dom[tb.x_buttons.upload.tooltipType] = this.i18n.upload_btn_stop_tip; |
} |
else { |
tb.x_buttons.remove.enable(); |
tb.x_buttons.reset.enable(); |
tb.x_buttons.close.enable(); |
Ext.fly(tb.x_buttons.indicator.getEl()).replaceClass( |
'ext-ux-uploaddialog-indicator-processing', |
'ext-ux-uploaddialog-indicator-stoped' |
); |
tb.x_buttons.upload.setIconClass('ext-ux-uploaddialog-uploadstartbtn'); |
tb.x_buttons.upload.setText(this.i18n.upload_btn_start_text); |
tb.x_buttons.upload.getEl() |
.child(tb.x_buttons.upload.buttonSelector) |
.dom[tb.x_buttons.upload.tooltipType] = this.i18n.upload_btn_start_tip; |
|
if (this.getQueuedCount() > 0) { |
tb.x_buttons.upload.enable(); |
} |
else { |
tb.x_buttons.upload.disable(); |
} |
|
if (this.grid_panel.getSelectionModel().hasSelection()) { |
tb.x_buttons.remove.enable(); |
} |
else { |
tb.x_buttons.remove.disable(); |
} |
|
if (this.grid_panel.getStore().getCount() > 0) { |
tb.x_buttons.reset.enable(); |
} |
else { |
tb.x_buttons.reset.disable(); |
} |
} |
}, |
|
saveInitialQueuedCount : function() |
{ |
this.initial_queued_count = this.getQueuedCount(); |
}, |
|
incInitialQueuedCount : function() |
{ |
this.initial_queued_count++; |
}, |
|
setUploadingFlag : function() |
{ |
this.is_uploading = true; |
}, |
|
resetUploadingFlag : function() |
{ |
this.is_uploading = false; |
}, |
|
prepareNextUploadTask : function() |
{ |
// Searching for first unuploaded file. |
var store = this.grid_panel.getStore(); |
var record = null; |
|
store.each(function(r) { |
if (!record && r.get('state') == Ext.ux.UploadDialog.FileRecord.STATE_QUEUE) { |
record = r; |
} |
else { |
r.get('input_element').dom.disabled = true; |
} |
}); |
|
record.get('input_element').dom.disabled = false; |
record.set('state', Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING); |
record.set('note', this.i18n.note_processing); |
record.commit(); |
|
this.fsa.postEvent('file-upload-start', record); |
}, |
|
fireUploadStartEvent : function() |
{ |
this.fireEvent('uploadstart', this); |
}, |
|
removeFiles : function(file_records) |
{ |
var store = this.grid_panel.getStore(); |
for (var i = 0, len = file_records.length; i < len; i++) { |
var r = file_records[i]; |
r.get('input_element').remove(); |
store.remove(r); |
} |
}, |
|
fireFileRemoveEvent : function(file_records) |
{ |
for (var i = 0, len = file_records.length; i < len; i++) { |
this.fireEvent('fileremove', this, file_records[i].get('filename')); |
} |
}, |
|
resetQueue : function() |
{ |
var store = this.grid_panel.getStore(); |
store.each( |
function(r) { |
r.get('input_element').remove(); |
} |
); |
store.removeAll(); |
}, |
|
fireResetQueueEvent : function() |
{ |
this.fireEvent('resetqueue', this); |
}, |
|
uploadFile : function(record) |
{ |
Ext.Ajax.request({ |
url : this.url, |
params : this.base_params || this.baseParams || this.params, |
method : 'POST', |
form : this.form, |
isUpload : true, |
success : this.onAjaxSuccess, |
failure : this.onAjaxFailure, |
scope : this, |
record: record |
}); |
}, |
|
fireFileUploadStartEvent : function(record) |
{ |
this.fireEvent('fileuploadstart', this, record.get('filename')); |
}, |
|
updateRecordState : function(data) |
{ |
if ('success' in data.response && data.response.success) { |
data.record.set('state', Ext.ux.UploadDialog.FileRecord.STATE_FINISHED); |
data.record.set( |
'note', data.response.message || data.response.error || this.i18n.note_upload_success |
); |
} |
else { |
data.record.set('state', Ext.ux.UploadDialog.FileRecord.STATE_FAILED); |
data.record.set( |
'note', data.response.message || data.response.error || this.i18n.note_upload_error |
); |
} |
|
data.record.commit(); |
}, |
|
fireUploadSuccessEvent : function(data) |
{ |
this.fireEvent('uploadsuccess', this, data.record.get('filename'), data.response); |
}, |
|
fireUploadErrorEvent : function(data) |
{ |
this.fireEvent('uploaderror', this, data.record.get('filename'), data.response); |
}, |
|
fireUploadFailedEvent : function(data) |
{ |
this.fireEvent('uploadfailed', this, data.record.get('filename')); |
}, |
|
fireUploadCompleteEvent : function() |
{ |
this.fireEvent('uploadcomplete', this); |
}, |
|
findUploadFrame : function() |
{ |
this.upload_frame = Ext.getBody().child('iframe.x-hidden:last'); |
}, |
|
resetUploadFrame : function() |
{ |
this.upload_frame = null; |
}, |
|
removeUploadFrame : function() |
{ |
if (this.upload_frame) { |
this.upload_frame.removeAllListeners(); |
this.upload_frame.dom.src = 'about:blank'; |
this.upload_frame.remove(); |
} |
this.upload_frame = null; |
}, |
|
abortUpload : function() |
{ |
this.removeUploadFrame(); |
|
var store = this.grid_panel.getStore(); |
var record = null; |
store.each(function(r) { |
if (r.get('state') == Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING) { |
record = r; |
return false; |
} |
}); |
|
record.set('state', Ext.ux.UploadDialog.FileRecord.STATE_FAILED); |
record.set('note', this.i18n.note_aborted); |
record.commit(); |
}, |
|
fireUploadStopEvent : function() |
{ |
this.fireEvent('uploadstop', this); |
}, |
|
repostHide : function() |
{ |
this.fsa.postEvent('hide'); |
}, |
|
flushEventQueue : function() |
{ |
this.fsa.flushEventQueue(); |
}, |
|
/** |
* @access private |
*/ |
// -------------------------------------------------------------------------------------------- // |
onWindowRender : function() |
{ |
this.fsa.postEvent('window-render'); |
}, |
|
onWindowBeforeHide : function() |
{ |
return this.isUploading() ? this.getAllowCloseOnUpload() : true; |
}, |
|
onWindowHide : function() |
{ |
this.fsa.postEvent('hide'); |
}, |
|
onWindowDestroy : function() |
{ |
this.fsa.postEvent('destroy'); |
}, |
|
onGridRender : function() |
{ |
this.fsa.postEvent('grid-render'); |
}, |
|
onGridSelectionChange : function() |
{ |
this.fsa.postEvent('grid-selection-change'); |
}, |
|
onAddButtonFileSelected : function(btn) |
{ |
this.fsa.postEvent('file-selected', btn); |
}, |
|
onUploadButtonClick : function() |
{ |
if (this.is_uploading) { |
this.fsa.postEvent('stop-upload'); |
} |
else { |
this.fsa.postEvent('start-upload'); |
} |
}, |
|
onRemoveButtonClick : function() |
{ |
var selections = this.grid_panel.getSelectionModel().getSelections(); |
this.fsa.postEvent('remove-files', selections); |
}, |
|
onResetButtonClick : function() |
{ |
this.fsa.postEvent('reset-queue'); |
}, |
|
onCloseButtonClick : function() |
{ |
this[this.closeAction].call(this); |
}, |
|
onAjaxSuccess : function(response, options) |
{ |
var json_response = { |
'success' : false, |
'message' : this.response |
} |
|
if(response.responseText == "OK" ) |
{ |
var data = { |
record : options.record, |
response : { |
'success' : true, |
'message' : this.response |
} |
} |
this.fsa.postEvent('file-upload-success', data); |
} |
else { |
this.fsa.postEvent('file-upload-error', data); |
} |
}, |
|
onAjaxFailure : function(response, options) |
{ |
var data = { |
record : options.record, |
response : { |
'success' : false, |
'error' : this.i18n.note_upload_error |
} |
} |
|
this.fsa.postEvent('file-upload-failed', data); |
}, |
|
/** |
* @access public |
*/ |
// -------------------------------------------------------------------------------------------- // |
startUpload : function() |
{ |
this.fsa.postEvent('start-upload'); |
}, |
|
stopUpload : function() |
{ |
this.fsa.postEvent('stop-upload'); |
}, |
|
getUrl : function() |
{ |
return this.url; |
}, |
|
setUrl : function(url) |
{ |
this.url = url; |
}, |
|
getBaseParams : function() |
{ |
return this.base_params; |
}, |
|
setBaseParams : function(params) |
{ |
this.base_params = params; |
}, |
|
getUploadAutostart : function() |
{ |
return this.upload_autostart; |
}, |
|
setUploadAutostart : function(value) |
{ |
this.upload_autostart = value; |
}, |
|
getAllowCloseOnUpload : function() |
{ |
return this.allow_close_on_upload; |
}, |
|
setAllowCloseOnUpload : function(value) |
{ |
this.allow_close_on_upload; |
}, |
|
getResetOnHide : function() |
{ |
return this.reset_on_hide; |
}, |
|
setResetOnHide : function(value) |
{ |
this.reset_on_hide = value; |
}, |
|
getPermittedExtensions : function() |
{ |
return this.permitted_extensions; |
}, |
|
setPermittedExtensions : function(value) |
{ |
this.permitted_extensions = value; |
}, |
|
isUploading : function() |
{ |
return this.is_uploading; |
}, |
|
isNotEmptyQueue : function() |
{ |
return this.grid_panel.getStore().getCount() > 0; |
}, |
|
getQueuedCount : function(count_processing) |
{ |
var count = 0; |
var store = this.grid_panel.getStore(); |
store.each(function(r) { |
if (r.get('state') == Ext.ux.UploadDialog.FileRecord.STATE_QUEUE) { |
count++; |
} |
if (count_processing && r.get('state') == Ext.ux.UploadDialog.FileRecord.STATE_PROCESSING) { |
count++; |
} |
}); |
return count; |
}, |
|
hasUnuploadedFiles : function() |
{ |
return this.getQueuedCount() > 0; |
} |
}); |
|
// ---------------------------------------------------------------------------------------------- // |
|
var p = Ext.ux.UploadDialog.Dialog.prototype; |
p.i18n = { |
title: 'Ajout simple de fichiers', |
state_col_title: 'Etat', |
state_col_width: 70, |
filename_col_title: 'Fichier', |
filename_col_width: 230, |
note_col_title: 'Note', |
note_col_width: 150, |
add_btn_text: 'Ajouter', |
add_btn_tip: 'Ajoute un fichier à la liste.', |
remove_btn_text: 'Supprimer', |
remove_btn_tip: 'Supprime un fichier de la liste.', |
reset_btn_text: 'Vider', |
reset_btn_tip: 'Vider la liste.', |
upload_btn_start_text: 'Envoyer', |
upload_btn_stop_text: 'Annuler', |
upload_btn_start_tip: 'Envoie les fichiers de la liste sur le serveur.', |
upload_btn_stop_tip: 'Stopper l\'envoi.', |
close_btn_text: 'Fermer', |
close_btn_tip: 'Ferme la fenêtre.', |
progress_waiting_text: 'En attente...', |
progress_uploading_text: 'Envoi de: {0} sur {1} fichiers terminé.', |
error_msgbox_title: 'Erreur', |
permitted_extensions_join_str: ',', |
err_file_type_not_permitted: 'Cette extension de fichier n\'est pas permise.<br/>Selectionnez un fichier portant une des extensions suivantes: {1}', |
note_queued_to_upload: 'Prêt à être envoyé.', |
note_processing: 'Envoi...', |
note_upload_failed: 'Le serveur est inaccessible ou bien une erreur serveur s\'est produite.', |
note_upload_success: 'OK.', |
note_upload_error: 'Erreur d\'envoi.', |
note_aborted: 'Annulé par l\'utilisateur.' |
} |