Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ListGrid make two requests at same time with same response

    Hi folks!

    We got an strange behavior on ListGrid. The ListGrid make two http request with same response any time I make a refresh or initial load. But, some times the first response comes blank and the grid doesn't show de records.

    Version: smartgwt-power-5.0-p20150828.jar

    This is the grid
    Click image for larger version

Name:	ListGrid.jpg
Views:	312
Size:	44.7 KB
ID:	239997

    This is the request. There are two request at the same time.
    Click image for larger version

Name:	DevTools.jpg
Views:	235
Size:	89.4 KB
ID:	239998

    We need a way to make only one request, but I don't know if this is a SmartGWT bug or it's a poor implementation. By the way, I made various tests with diferente ListGrid configurations but doesn't work properly.

    Take a look at the code

    Grid View
    Code:
        private BaseListGrid createGrid() {
            BaseListGrid grid = new BaseListGrid(false, 1) {
                @Override
                public Boolean willFetchData(Criteria newCriteria) {
                    return true;
                }
            };
            grid.setHeaderHeight(DesignConstants.GRID_HEADER_HEIGHT);
            grid.setCellHeight(32);
            grid.setDataFetchMode(FetchMode.PAGED);
            grid.setFilterButtonPrompt(CONSTANTS.filter());
            grid.setFetchDelay(500);
            grid.setHoverCustomizer(new VehiclePlateHoverCustomizer(HistoryEntryFieldsConstants.FIELD_VEHICLE_NAME,
                    HistoryEntryFieldsConstants.FIELD_VEHICLE_LICENSE_PLATE));
            grid.setCanSort(false);
            grid.setSortField(HistoryEntryFieldsConstants.FIELD_PERSISTED_DATE);
            grid.setSortDirection(SortDirection.DESCENDING);
    
            grid.setReportHeaderProvider(new ReportHeaderProvider() {
    
                @Override
                public Canvas getReportHeader() {
                    return ReportHeaderBuilder.build(SessionData.getInstance(), getPrintingTitle(), startDate, finalDate);
                }
            });
            grid.setCanPrint(true);
            grid.setCanExport(true);
    
            grid.setExportFilename(CONSTANTS.vehicleHistoryTitle());
            grid.setExportClientSide(false);
    
            grid.setAutoFitFieldWidths(true);
            grid.setAutoFitFieldsFillViewport(true);
            grid.setAutoFitWidthApproach(AutoFitWidthApproach.TITLE);
            grid.setAutoFetchData(false);
            grid.setFilterOnKeypress(true);
    
            setGridDataSource(grid);
            setGridActions(grid);
            setGridFields(grid);
            configureFilter(grid);
    
            return grid;
        }
    
        private void setGridDataSource(final BaseListGrid grid) {
            DataSource vehicleHistoryDS = PortalOrionDataSource.getDataSource(HistoryEntryFieldsConstants.DATASOURCE_ID);
    
            grid.setDataSource(vehicleHistoryDS);
            vehicleHistoryDS.addHandleErrorHandler(new HandleErrorHandler() {
                @Override
                public void onHandleError(ErrorEvent event) {
                    String error = event.getResponse().getAttribute("Error");
                    Message message = null;
                    switch (ErrorType.getByCode(error)) {
                    case INVALID_CLIENT_PERMISSION:
                        message = new Message(MessageType.WARNING, MESSAGES.warningLandmarkDiferentClient());
                        break;
                    default:
                        break;
                    }
    
                    if (message != null) {
                        CommonEventBus.getInstance().fireEvent(new MessageIssueEvent(message));
                    }
    
                    grid.discardAllEdits();
                    event.cancel();
                }
            });
        }
    
        @Override
        public void refreshFilter(Date startDate, Date finalDate, Long vehicleId, String vehicleName) {
    
            this.startDate = startDate;
            this.finalDate = finalDate;
            this.vehicleId = vehicleId;
    
            if (vehicleName != null && vehicleName.equals(CONSTANTS.select())) {
                this.vehicleName = CONSTANTS.allVehicles();
            } else {
                this.vehicleName = vehicleName;
            }
    
            criteria = createGridCriteria(vehicleId, startDate, finalDate);
    
            ShowVehicleHistoryTitleEvent event = new ShowVehicleHistoryTitleEvent(vehicleName, startDate, finalDate);
            CommonEventBus.getInstance().fireEvent(event);
    
            Portlet portletHistory = Dashboard.getInstance().getPortletByName(Dashboard.HISTORY_PORTLET_NAME);
            if (!portletHistory.isVisible()) {
                portletHistory.show();
            }
            portletHistory.bringToFront();
            refreshGrid();
        }
    
        @Override
        public void refreshGrid() {
            vehicleHistoryGrid.setCriteria(criteria);
            vehicleHistoryGrid.fetchData(criteria);
            vehicleHistoryGrid.invalidateCache();
        }
    
        private AdvancedCriteria createGridCriteria(Long vehicleId, Date start, Date end) {
    
            Criterion clientCriteria = new Criterion(HistoryEntryFieldsConstants.FIELD_PK_OWNER_ID, OperatorId.EQUALS,
                    session.getClient().getId());
    
            Criterion vehicleCriteria = new Criterion(HistoryEntryFieldsConstants.FIELD_VEHICLE_ID, OperatorId.EQUALS,
                    vehicleId);
    
            Criterion permissionCriteria = new Criterion(HistoryEntryFieldsConstants.FIELD_PERMISSION_CODE,
                    OperatorId.IN_SET, session.getPermissions());
    
            Criterion persistedDateCriteria = new Criterion(HistoryEntryFieldsConstants.FIELD_PERSISTED_DATE,
                    OperatorId.BETWEEN_INCLUSIVE, start, end);
    
            // Com ou sem filtro de veículo
            AdvancedCriteria advancedCriteria;
    
            if (vehicleId != null) {
                advancedCriteria = new AdvancedCriteria(OperatorId.AND, new Criterion[] { clientCriteria, vehicleCriteria,
                        permissionCriteria, persistedDateCriteria });
            } else {
                // se o usuário é gestor, pesquisa pelo cliente apenas
                if (session.isMasterContext()) {
    
                    advancedCriteria = new AdvancedCriteria(OperatorId.AND, new Criterion[] { clientCriteria,
                            permissionCriteria, persistedDateCriteria });
    
                } else {
                    // se o usuário é comum, é necessário passar a lista de veículo associados a ele
                    List<VehicleDTO> userVehicles = session.getUser().getVehicleDTOs();
                    List<String> userVehicleIdList = new ArrayList<String>();
    
                    for (VehicleDTO vehicleDTO : userVehicles) {
                        userVehicleIdList.add(vehicleDTO.getId().toString());
                    }
    
                    String[] arrayUserVehicleId = (String[]) userVehicleIdList.toArray();
    
                    Criterion userVehicleCriteria = new Criterion(HistoryEntryFieldsConstants.FIELD_VEHICLE_ID,
                            OperatorId.IN_SET, arrayUserVehicleId);
    
                    advancedCriteria = new AdvancedCriteria(OperatorId.AND, new Criterion[] { clientCriteria,
                            userVehicleCriteria, permissionCriteria, persistedDateCriteria });
                }
            }
    
            return advancedCriteria;
        }
    
        private void configureFilter(BaseListGrid grid) {
            grid.addFilterEditorSubmitHandler(new FilterEditorSubmitHandler() {
                @Override
                public void onFilterEditorSubmit(FilterEditorSubmitEvent event) {
                    if (criteria == null) {
                        // evita que seja feito o fecth sem criteria
                        event.cancel();
                        return;
                    }
                }
            });
        }
    http://www.4shared.com/file/UtKfO6Z9...storyView.html

    Grid Presenter
    Code:
            public void bind() {
        
                CommonEventBus.getInstance().addHandler(ClientChangedInContextEvent.TYPE,
                        new ClientChangedInContextEventHandler() {
                            @Override
                            public void onClientChangedInContext(ClientChangedInContextEvent event) {
                                if (Dashboard.getInstance().isVisible()) {
                                    view.clientChanged();
                                    bindGridActions();
                                    bindPdfButton();
                                    CommonEventBus.getInstance().fireEvent(new ResetVehicleHistoryTitleEvent());
                                }
                            }
                        });
        
                bindGridActions();
                bindPdfButton();
        
                // Handler para tratamento do retorno de pontos do grupo de histórico
                CommonEventBus.getInstance().addHandler(ResponsePointsByGroupMapEvent.TYPE,
                        new ResponsePointsByGroupMapEventHandler() {
                            @Override
                            public void onResponse(ResponsePointsByGroupMapEvent event) {
                                validateGridAndMapPoints(event.getResult(), event.getToken());
                            }
                        });
        
                // Handler para filtrar por veículo quando for solicitado pelo grid Situação Atual
                CommonEventBus.getInstance().addHandler(ShowVehicleHistoryEvent.TYPE, new ShowVehicleHistoryEventHandler() {
                    @Override
                    public void onShowVehicleHistory(ShowVehicleHistoryEvent event) {
                        VehicleDTO vehicle = event.getVehicle();
                        Date finalDate = event.getFinalDate();
                        Date startDate = event.getFinalDate();
                        refreshGrid(startDate, finalDate, vehicle.getId(), vehicle.getVehicleNamePlate());
                    }
                });
        
                CommonEventBus.getInstance().addHandler(VehicleHistoryFilterEvent.TYPE, new VehicleHistoryFilterEventHandler() {
                    @Override
                    public void onNewFilter(Date startDate, Date finalDate, Long vehicleId, String vehicleName) {
                        refreshGrid(startDate, finalDate, vehicleId, vehicleName);
                    }
                });
        
                CommonEventBus.getInstance().addHandler(ShowVehicleHistoryTitleEvent.TYPE,
                        new ShowVehicleHistoryTitleEventHandler() {
                            @Override
                            public void onShowVehicleTitleHistory(ShowVehicleHistoryTitleEvent event) {
                                Canvas reportHeader = ReportHeaderBuilder.build(SessionData.getInstance(),
                                        uiConstants.vehicleHistoryTitle(), event.getStartDate(), event.getEndDate());
                                view.resetPrintHeader(reportHeader);
                            }
                        });
        
                CommonEventBus.getInstance().addHandler(ResetVehicleHistoryTitleEvent.TYPE,
                        new ResetVehicleHistoryTitleEventHandler() {
        
                            @Override
                            public void onResetVehicleTitleHistory(ResetVehicleHistoryTitleEvent event) {
                                Canvas reportHeader = ReportHeaderBuilder.build(SessionData.getInstance(),
                                        uiConstants.vehicleHistoryTitle());
                                view.resetPrintHeader(reportHeader);
                            }
                        });
                
            }
    
            private void refreshGrid(Date startDate, Date finalDate, Long vehicleId, String vehicleName) {
                if (finalDate == null) {
                    finalDate = new Date();
                }
                finalDate = getEndOfDay(finalDate);
        
                if (startDate == null) {
                    startDate = getStartDate(finalDate);
                }
                startDate = getBeginOfDay(startDate);
        
                view.refreshFilter(startDate, finalDate, vehicleId, vehicleName);
                
                lastStartPeriodDate = startDate;
                lastEndPeriodDate = finalDate;
                lastSelectedVehicle = vehicleId;        
        
                // Envia Hit de pageview ao Google Analytics
                GoogleAnalytics.sendPageViewHit("VehicleHistory", "Histórico de eventos");
            }
    http://www.4shared.com/file/ooeTLYn9...Presenter.html

    Implementation of ListGrid
    Code:
    public class BaseListGrid extends ListGrid {
    
        // Definição das seções da barra de ferramentas do grid
    
        // Seção de ações básicas (Ex.: Adicionar)
        public static final int BASIC_ACTIONS = 0;
        // Seção de ações customizadas (Ex.: Botão ajuda)
        public static final int CUSTOM_ACTIONS = 1;
        // Seção de ações extras (Ex.: Exportar)
        public static final int EXTRA_ACTIONS = 2;
    
        // Interface para os métodos de criação da barra de ferramentas
        private interface ToolbarBuilder {
            void create();
        };
    
        // Construtor da seção de ações básicas
        public class CreateBasicActions implements ToolbarBuilder {
            @Override
            public void create() {
                createBasicActions();
            }
        }
    
        // Construtor da seção de ações customizadas
        public class CreateCustomActions implements ToolbarBuilder {
            @Override
            public void create() {
                createCustomActions();
            }
        }
    
        // Construtor da seção de ações extras
        public class CreateExtraActions implements ToolbarBuilder {
            @Override
            public void create() {
                createExtraActions();
            }
        }
    
        private static final UserInterfaceConstants CONSTANTS = GWT.create(UserInterfaceConstants.class);
        private static final UserInterfaceMessages MESSAGES = GWT.create(UserInterfaceMessages.class);
    
        private static final String HAS_DETAIL_ATTRIBUTE = "BaseListGrid.hasDetail";
        private static final String CAN_SELECT_ATTRIBUTE = "BaseListGrid.canSelect";
        private static final String CAN_PRINT_ATTRIBUTE = "BaseListGrid.canPrint";
        private static final String CAN_EXPORT_ATTRIBUTE = "BaseListGrid.canExport";
        private static final String CAN_ADD_ATTRIBUTE = "BaseListGrid.canAdd";
        private static final String CAN_UPDATE_ATTRIBUTE = "BaseListGrid.canUpdate";
        private static final String CAN_UPDATE_CELL_ATTRIBUTE = "BaseListGrid.canUpdateCell";
        private static final String CAN_REMOVE_ATTRIBUTE = "BaseListGrid.canRemove";
        private static final String CAN_MOVE_ATTRIBUTE = "BaseListGrid.canMove";
        private static final Logger logger = Logger.getLogger(BaseListGrid.class.getName());
    
        private static final String PRINT_HEADER_ATTRIBUTE = "BaseListGrid.printHeader";
        private static final String EXPORT_FILENAME_ATTRIBUTE = "BaseListGrid.exportFilename";
        private static final String EXPORT_CLIENT_SIDE_ATTRIBUTE = "BaseListGrid.exportClientSide";
    
        public static final String ACTIONS_FIELD = "BaseListGrid_actionsField";
    
        private ToolStrip tools;
        private List<Canvas> customToolbarMembers = null;
    
        private ToolbarBuilder createFirstGroupActions = null;
        private ToolbarBuilder createSecondGroupActions = null;
        private ToolbarBuilder createThirdGroupActions = null;
    
        private Layout rollOver = null;
    
        private int countActions = 0;
        private int actionsColumnPosition = -1;
        private boolean editConfigDone = false;
    
        private CanDoActionRecordRuler hasDetailRecordRuler = null;
        private CanDoActionRecordRuler canUpdateRecordRuler = null;
        private CanDoActionRecordRuler canRemoveRecordRuler = null;
    
        private ConfirmActionHandler confirmDetailHandler = null;
        private ConfirmActionHandler confirmAddHandler = null;
        private ConfirmActionHandler confirmUpdateHandler = null;
        private ConfirmActionHandler confirmRemoveHandler = null;
    
        private RecordValidator recordAddValidator = null;
        private RecordValidator recordUpdateValidator = null;
    
        private Collection<ActionDoneHandler> recordAddedHandlers = new LinkedList<ActionDoneHandler>();
        private Collection<ActionDoneHandler> recordUpdatedHandlers = new LinkedList<ActionDoneHandler>();
        private Collection<ActionDoneHandler> recordRemovedHandlers = new LinkedList<ActionDoneHandler>();
    
        private CustomListGridRecordAction detailAction = null;
        private CustomListGridRecordAction updateAction = null;
        private CustomListGridRecordAction removeAction = null;
        private CustomListGridRecordAction upAction = null;
        private CustomListGridRecordAction downAction = null;
        private List<CustomListGridRecordAction> customActions = null;
    
        private Map<Integer, CustomListGridRecordAction> updateActionMap = new HashMap<Integer, CustomListGridRecordAction>();
    
        private DetailLayoutProvider detailLayoutProvider = null;
    
        private HoverCustomizer hoverCustomizer = null;
    
        private Map<String, ComponentListGridField> componentFields = new HashMap<String, ComponentListGridField>();
        private boolean showToolBar;
        private HandlerRegistration dataArrivedRegistration;
        
        private Canvas printHeader;
        private ReportHeaderProvider reportHeaderProvider;
    
        private ImgButton excelTool;
        private ImgButton csvTool;
        private ImgButton pdfTool;
        private ImgButton printTool;
    
         
        private boolean useDefaultPdfTool = true;
    
         
        private List<String> fieldsToShow = new ArrayList<String>();
    
        // TODO [helenov] avaliar tratamento de inserção de novo registro
        // private ListGridRecord addedRecord;
    
         
        public static BaseListGrid getOrCreateRef(JavaScriptObject jsObj) {
            if (jsObj == null)
                return null;
            BaseWidget obj = BaseWidget.getRef(jsObj);
            if (obj != null) {
                return (BaseListGrid) obj;
            } else {
                return new BaseListGrid(jsObj);
            }
        }
    
         
        public BaseListGrid(JavaScriptObject jsObj) {
            super(jsObj);
        }
    
         
        public BaseListGrid(int firstGroupType, int secondGroupType, int thirdGroupType) {
            this.useDefaultPdfTool = false;
    
            createFirstGroupActions = makeToolbarBuilder(firstGroupType);
            createSecondGroupActions = makeToolbarBuilder(secondGroupType);
            createThirdGroupActions = makeToolbarBuilder(thirdGroupType);
    
            initBaseListGrid();
        }
    
        private ToolbarBuilder makeToolbarBuilder(int groupType) {
            ToolbarBuilder toolbarBuilder = null;
    
            if (groupType == BASIC_ACTIONS) {
                toolbarBuilder = new CreateBasicActions();
            } else if (groupType == CUSTOM_ACTIONS) {
                toolbarBuilder = new CreateCustomActions();
            } else if (groupType == EXTRA_ACTIONS) {
                toolbarBuilder = new CreateExtraActions();
            }
            return toolbarBuilder;
        }
    
         
        public BaseListGrid() {
            this(true);
        }
    
         
        public BaseListGrid(boolean useDefaultPdfTool) {
            this.useDefaultPdfTool = useDefaultPdfTool;
    
            // Define a ordem padrão de criação das seções da barra de ferramentas.
            this.createFirstGroupActions = new CreateBasicActions();
            this.createSecondGroupActions = new CreateCustomActions();
            this.createThirdGroupActions = new CreateExtraActions();
    
            initBaseListGrid();
        }
    
         
        public BaseListGrid(boolean useDefaultPdfTool, int actionsColumnPos) {
            this.useDefaultPdfTool = useDefaultPdfTool;
    
            // Define a ordem padrão de criação das seções da barra de ferramentas.
            this.createFirstGroupActions = new CreateBasicActions();
            this.createSecondGroupActions = new CreateCustomActions();
            this.createThirdGroupActions = new CreateExtraActions();
    
            actionsColumnPosition = actionsColumnPos;
    
            initBaseListGrid();
        }
    
        private void initBaseListGrid() {
            // Evita que após a edição de uma linha do grid, a mesma seja eliminada do cache.
            ResultSet resultSetProperties = new ResultSet();
            resultSetProperties.setNeverDropUpdatedRows(true);
            setDataProperties(resultSetProperties);
            
            // configuração padrão de ações
            this.setCanSelect(false);
            this.setCanAdd(false);
            this.setCanUpdate(false);
            this.setCanRemove(false);
            this.setWarnOnRemoval(true);
            this.setWarnOnRemovalMessage(MESSAGES.confirmRemove());
    
            // configuração geral
            this.setBooleanTrueImage(DesignConstants.CHECKED_ICON);
            this.setShowRecordComponents(true);
            this.setShowRecordComponentsByCell(true);
            this.setWrapCells(true);
            this.setShowAlternate(true, 1);
            this.setExportAll(false);
    
            // configuração de scroll
            this.setLeaveScrollbarGap(true);
            this.setBodyOverflow(Overflow.AUTO);
            this.setFixedRecordHeights(false);
            this.setVirtualScrolling(true);
    
            // configuração do rollover
            this.setShowRollOver(true);
    
            // configuração da consulta
            this.setAutoFetchData(true);
            this.setDataFetchMode(FetchMode.PAGED);
            // [TODO] Parametrizar tamanho das páginas
            this.setDataPageSize(30);
            this.setFetchDelay(500);
            this.setLoadingMessage(CONSTANTS.loading());
            this.setDrawAheadRatio(4.0f);
    
            // configuração do cabeçalho
            this.setShowHeader(true);
    
            // configuração do filtro
            this.setShowFilter(true);
    
            // configuração dos componentes
            this.setGridComponents(new Object[] { createToolbar(), ListGridComponent.HEADER,
                    ListGridComponent.FILTER_EDITOR, ListGridComponent.BODY });
    
             
            this.addFilterEditorSubmitHandler(new FilterEditorSubmitHandler() {
    
                @Override
                public void onFilterEditorSubmit(FilterEditorSubmitEvent event) {
                    invalidateCache();
    
                }
            });
    
            this.addDrawHandler(new DrawHandler() {
                @Override
                public void onDraw(DrawEvent event) {
                    if (showToolBar) {
                        tools.show();
                    } else {
                        tools.hide();
                    }
                }
            });
    
            addFetchDataHandler(new FetchDataHandler() {
                public void onFilterData(FetchDataEvent event) {
                    putTimeZoneParameter(event.getRequestProperties());
                }
            });
        }
    
         
        public void setShowAlternate(boolean showAlternate) {
            this.setShowAlternate(showAlternate, 1);
        }
    
         
        public void enableEditUnsavedRecord() {
            if (getCanAdd()) {
                this.addCellClickHandler(new CellClickHandler() {
                    @Override
                    public void onCellClick(CellClickEvent event) {
                        ListGridRecord record = event.getRecord();
                        if (record == null) {
                            setEditEvent(ListGridEditEvent.CLICK);
                        } else {
                            setEditEvent(ListGridEditEvent.NONE);
                        }
                    }
                });
            }
        }
    
         
        public void setShowAlternate(boolean showAlternate, int frequency) {
            this.setAlternateRecordStyles(showAlternate);
            this.setAlternateRecordFrequency(frequency);
        }
    
         
        public void setShowHeader(Boolean showHeader) {
            super.setShowHeader(showHeader);
    
            this.setShowHeaderContextMenu(false);
            this.setShowHeaderMenuButton(false);
            this.setCanAddSummaryFields(false);
        }
    
         
        public void setShowFilter(Boolean showFilter) {
            this.setShowFilterEditor(showFilter);
            this.setFilterButtonPrompt(CONSTANTS.filter());
            this.setFilterOnKeypress(true);
        }
    
         
        public void setFields(List<ListGridField> fields) {
            this.setFields(fields.toArray(new ListGridField[fields.size()]));
        }
    
         
        @Override
        public void setFields(ListGridField... fields) {
            super.setFields(getFieldsWithActions(fields));
            this.setExportFields(getExportableFields(fields)); // define fields que poderão ser exportados
        }
    
         
        private ListGridField[] getFieldsWithActions(ListGridField... fields) {
            countActions = countActions();
            if (countActions > 0) {
                // copia fields originais
                ArrayList<ListGridField> fieldsList = new ArrayList<ListGridField>(fields.length + countActions);
                for (ListGridField field : fields) {
                    fieldsList.add(field);
    
                    if (hoverCustomizer != null && field.getShowHover() != null && !field.getShowHover()) {
                        field.setShowHover(true);
                        field.setHoverCustomizer(hoverCustomizer);
                    }
                }
                // acrescenta coluna de ações
                if (actionsColumnPosition == -1) {
                    fieldsList.add(createActionsField(countActions));
                } else {
                    fieldsList.add(actionsColumnPosition, createActionsField(countActions));
                }
    
                // reconverte lista em array
                fields = fieldsList.toArray(fields);
            }
    
            // faz configurações de campos customizados
            for (ListGridField field : fields) {
                if (field instanceof CustomListGridField) {
                    CustomListGridField customField = (CustomListGridField) field;
                    configCustomField(customField);
                }
                if (field instanceof ComponentListGridField) {
                    ComponentListGridField compField = (ComponentListGridField) field;
                    configComponentField(compField);
                }
            }
            return fields;
        }
    
         
        @Override
        public void setDataSource(DataSource ds, ListGridField... fields) {
            if (!isCreated()) {
                super.setDataSource(ds, fields);
            } else {
                super.setDataSource(ds, getFieldsWithActions(fields));
            }
        }
    
         
        private void configCustomField(CustomListGridField field) {
            // configura refresh automático de detalhes
            if (field.getRefreshDetailOnChanged()) {
                field.addChangedHandler(new ChangedHandler() {
                    @Override
                    public void onChanged(ChangedEvent event) {
                        int rowNum = event.getRowNum();
                        ListGridRecord record = (ListGridRecord) getEditedRecord(rowNum);
                        if (isDetailExpanded(record)) {
                            DynamicForm form = getDetailForm(record);
                            form.markForRedraw(); // força reavaliar showIfConditions
                        }
                    }
                });
            }
    
            // configura refresh automático de campos do registro
            final String[] refreshFields = field.getRefreshFieldOnChanged();
            if (refreshFields != null) {
                field.addChangedHandler(new ChangedHandler() {
                    @Override
                    public void onChanged(ChangedEvent event) {
                        int rowNum = event.getRowNum();
                        refreshCells(rowNum, refreshFields);
                    }
                });
            }
        }
    
         
        private void configComponentField(final ComponentListGridField compField) {
            componentFields.put(compField.getName(), compField);
    
            this.addRecordRemovedHandler(new ActionDoneHandler() {
                @Override
                public void onActionDone(ListGridRecord record) {
                    compField.removeComponent(record);
                }
            });
    
            if (compField instanceof AssociationListGridField) {
                final AssociationListGridField assocField = (AssociationListGridField) compField;
                assocField.addAssociationRefreshHandler(new AssociationRefreshHandler() {
                    @Override
                    public void onAssociationRefresh(String id, boolean associated) {
                        // atualiza valor do field de associação
                        String fieldId = assocField.getIdField();
                        Record record = getRecordList().find(fieldId, id);
                        record.setAttribute(assocField.getName(), associated);
    
                        // atualiza células dependes
                        final String[] refreshFields = assocField.getRefreshFieldOnChanged();
                        if (refreshFields != null) {
                            int rowNum = getRecordIndex(record);
                            refreshCells(rowNum, refreshFields);
                        }
                    }
                });
            }
        }
    
         
        public void refreshCells(int rowNum, String[] fields) {
            for (String fieldName : fields) {
                int colNum = getFieldNum(fieldName);
                refreshCell(rowNum, colNum);
            }
        }
    
         
        @Override
        public void refreshCell(int rowNum, int colNum) {
            super.refreshCell(rowNum, colNum);
            this.refreshRecordComponent(rowNum, colNum);
        }
    
         
        private int countActions() {
            int actions = 0;
            if (this.getHasDetail()) {
                actions += 1;
            }
            if (this.getCanUpdate()) {
                actions += 1;
            }
            if (customActions != null) {
                actions += customActions.size();
            }
            if (this.getCanRemove()) {
                actions += 1;
            }
            if (this.getCanMove()) {
                actions += 2;
            }
            return actions;
        }
    
         
        private ListGridField createActionsField(int actions) {
            ListGridField actionsField = new ListGridField(ACTIONS_FIELD, CONSTANTS.actions());
            actionsField.setCanFilter(false);
            actionsField.setCanEdit(false);
            actionsField.setCanSort(false);
            actionsField.setShouldPrint(false);
            actionsField.setCanExport(false);
            actionsField.setAlign(Alignment.CENTER);
    
            int width = (DesignConstants.ACTION_ICON_SIZE + 3) * actions;
            actionsField.setWidth(width);
            if (actions <= 1) {
                actionsField.setTitle(" ");
            }
            return actionsField;
        }
    
         
        @Override
        protected Canvas createRecordComponent(ListGridRecord record, Integer colNum) {
            HStack panel = null;
            String field = this.getFieldName(colNum);
            // TODO [helenov] fazer do action field um component field
            if (field.equals(ACTIONS_FIELD)) {
                // FIXME: [ERROR] [Main] - TMR8:WARN:Log:Specified ID: isc_Canvas_15 collides with the ID for
                // an existing SmartGWT component or object. The existing object will be destroyed and the ID bound to the
                // new object.
                panel = new HStack();
                panel.setHeight(DesignConstants.ACTION_ICON_SIZE);
                panel.setMembersMargin(3);
    
                this.addDetailAction(record, panel);
                this.addUpdateAction(record, panel);
                this.addCustomActions(record, panel);
                this.addRemoveAction(record, panel);
                this.addUpAction(record, panel);
                this.addDownAction(record, panel);
            }
            if (componentFields.containsKey(field)) {
                ComponentListGridField compField = componentFields.get(field);
                int rowNum = getRecordIndex(record);
                return compField.createComponent(record, rowNum);
            }
            return panel;
        }
    
         
        @Deprecated
        public void setCustomActions(CustomListGridRecordAction... actions) {
            setCustomAction(Arrays.asList(actions));
        }
    
         
        public void setCustomAction(List<CustomListGridRecordAction> actions) {
            customActions = actions;
        }
    
         
        public void setCustomToolbarMembers(Canvas... customToolbarMembers) {
            setCustomToolbarMembers(Arrays.asList(customToolbarMembers));
        }
    
         
        public void setCustomToolbarMembers(List<Canvas> customToolbarMembers) {
            this.customToolbarMembers = customToolbarMembers;
            this.resetToolbar();
        }
    
         
        private ToolStrip createToolbar() {
            tools = new ToolStrip();
            tools.setHeight(DesignConstants.ACTION_ICON_SIZE + 4);
            tools.setMembersMargin(3);
            this.resetToolbar();
            return tools;
        }
    
         
        private void resetToolbar() {
            if (tools != null) {
                tools.removeMembers(tools.getMembers());
    
                showToolBar = false;
    
                createFirstGroupActions.create();
                createSecondGroupActions.create();
                createThirdGroupActions.create();
            }
        }
    
        private void createBasicActions() {
            if (this.addAddAction()) {
                showToolBar = true;
            }
        }
    
        private void createCustomActions() {
            // ações customizadas
            if (customToolbarMembers != null) {
                showToolBar = true;
                for (Canvas action : customToolbarMembers) {
                    if (action instanceof ToolStripButton) {
                        tools.addButton((ToolStripButton) action);
                    } else {
                        tools.addMember(action);
                    }
                }
            }
        }
    
        private void createExtraActions() {
            // ações build-in auxiliares
            boolean haveExport = this.addExportAction();
            boolean havePrint = this.addPrintAction();
            if (haveExport || havePrint) {
                showToolBar = true;
            }
        }
    
         
        private ImgButton createGridAction(String icon, String prompt) {
            ImgButton action = new ImgButton();
            action.setSrc(icon);
            action.setShowDown(false);
            action.setSize(DesignConstants.ACTION_ICON_SIZE);
            action.setPrompt(prompt);
            return action;
        }
    
        // Suporte a seleção de registros do grid.
        // /////////////////////////////////////////////////////////////////////////////
    
         
        public Boolean getCanSelect() {
            Boolean canSelect = getAttributeAsBoolean(CAN_SELECT_ATTRIBUTE);
            return canSelect != null ? canSelect : false;
        }
    
         
        public void setCanSelect(Boolean canSelect) {
            this.setAttribute(CAN_SELECT_ATTRIBUTE, canSelect, true);
            if (canSelect) {
                this.setSelectionType(SelectionStyle.SIMPLE);
                this.setSelectionAppearance(SelectionAppearance.CHECKBOX);
                this.setCanSelectAll(true);
    
                this.setCheckboxFieldTrueImage(DesignConstants.CHECKBOX_CHECKED);
                this.setCheckboxFieldFalseImage(DesignConstants.CHECKBOX_UNCHECKED);
    
                this.addRecordClickHandler(new RecordClickHandler() {
                    @Override
                    public void onRecordClick(RecordClickEvent event) {
                        if (!event.getField().getName().equals("_checkboxField")) { // Ignora o click no checkbox para não
                                                                                    // fazer 2x
                            ListGridRecord record = getRecord(event.getRecordNum());
                            boolean newState = !isSelected(record);
                            selectRecord(record, newState);
                        }
                    }
                });
            } else {
                this.setSelectionType(SelectionStyle.NONE);
            }
        }
    
        // [helenov] TODO verificar pq não funcionou
        // private ListGridField getSelectionField() {
        // return ListGridField.getOrCreateRef(getAttributeAsJavaScriptObject("checkboxField"));
        // }
    
        // Suporte a exibição de detalhes dos registros no grid.
        // /////////////////////////////////////////////////////////////////////////////
    
         
        public Boolean getHasDetail() {
            Boolean hasDetail = getAttributeAsBoolean(HAS_DETAIL_ATTRIBUTE);
            return hasDetail != null ? hasDetail : false;
        }
    
         
        private boolean getHasDetail(ListGridRecord record) {
            boolean hasDetail = false;
            if (getHasDetail()) {
                hasDetail = getDetailAction().getCanDoAction(record);
            }
            return hasDetail;
        }
    
         
        public void setHasDetail(Boolean hasDetail) {
            this.setAttribute(HAS_DETAIL_ATTRIBUTE, hasDetail, true);
            if (hasDetail) {
                this.setExpansionMode(ExpansionMode.EDITOR);
            }
        }
    
         
        public CanDoActionRecordRuler getHasDetailRecordRuler() {
            return hasDetailRecordRuler;
        }
    
         
        public void setHasDetailRecordRuler(CanDoActionRecordRuler ruler) {
            hasDetailRecordRuler = ruler;
            if (detailAction != null) {
                detailAction.setCanDoActionRecordRuler(ruler);
            }
        }
    
         
        public ConfirmActionHandler getConfirmDetailHandler() {
            return confirmDetailHandler;
        }
    
         
        public void setConfirmDetailHandler(ConfirmActionHandler handler) {
            confirmDetailHandler = handler;
            if (detailAction != null) {
                detailAction.setConfirmActionHandler(handler);
            }
        }
    
         
        public DetailLayoutProvider getDetailLayoutProvider() {
            return detailLayoutProvider;
        }
    
         
        public void setDetailLayoutProvider(DetailLayoutProvider provider) {
            this.detailLayoutProvider = provider;
        }
    
         
        @Override
        public void setHoverCustomizer(HoverCustomizer hoverCustomizer) {
            this.hoverCustomizer = hoverCustomizer;
        }
    
         
        private void addDetailAction(ListGridRecord record, Layout panel) {
            if (getHasDetail()) {
                CustomListGridRecordAction action = getDetailAction();
                panel.addMember(action.getActionIcon(record));
            }
        }
    
         
        private CustomListGridRecordAction getDetailAction() {
            if (detailAction == null) {
                detailAction = createDetailAction();
            }
            return detailAction;
        }
    
         
        private CustomListGridRecordAction createDetailAction() {
            CustomListGridRecordAction action = new CustomListGridRecordAction(DesignConstants.VIEW_RECORD_IMAGE,
                    CONSTANTS.view());
    
            action.setCanDoActionRecordRuler(hasDetailRecordRuler);
            action.setConfirmActionHandler(confirmDetailHandler);
            action.setExecuteActionHandler(new ExecuteActionHandler() {
                @Override
                public void execute(ListGridRecord record) {
                    // se está editando já está aberto e não deve fechar
                    if (!isEditing(record)) {
                        toggleDetail(record);
                    }
                }
            });
            return action;
        }
    
         
        private void toggleDetail(ListGridRecord record) {
            if (getHasDetail(record)) {
                if (!isDetailExpanded(record)) {
                    this.expandRecord(record);
                } else {
                    this.collapseRecord(record);
                }
            }
        }
    
         
        public void expandRecord(ListGridRecord record) {
            this.collapseRecord(record);
            super.expandRecord(record);
        }
    
         
        @Override
        protected Canvas getExpansionComponent(ListGridRecord record) {
            Canvas canvas;
            if (detailLayoutProvider != null) {
                boolean canEdit = isEditing(record);
                canvas = this.getDetailLayout(record, canEdit);
            } else {
                canvas = super.getExpansionComponent(record);
            }
            return canvas;
        }
    
         
        private Layout getDetailLayout(final ListGridRecord record, boolean canEdit) {
            final DynamicForm form = detailLayoutProvider.getDetailLayout(record, canEdit);
            form.setWidth100();
            form.setHeight100();
            form.setCanEdit(canEdit);
            form.setDataSource(this.getDataSource());
            form.addDrawHandler(new DrawHandler() {
                public void onDraw(DrawEvent event) {
                    form.editRecord(record);
                }
            });
            form.setCanSubmit(false);
            if (canEdit) {
                form.setSaveOnEnter(true);
                form.addSubmitValuesHandler(new SubmitValuesHandler() {
                    @Override
                    public void onSubmitValues(SubmitValuesEvent event) {
                        endEditing();
                    }
                });
            }
    
            Layout layout = new VLayout();
            layout.setWidth100();
            layout.setHeight100();
            layout.addMember(form);
            return layout;
        }
    
         
        @SuppressWarnings({ "rawtypes", "unchecked" })
        private ListGridRecord completeRecord(int rowNum, ListGridRecord record) {
    
            // valores do registro
            Map values = this.getEditValues(record);
    
            // acrescenta valores do form de detalhes
            DynamicForm form = getDetailForm(record);
            FormItem[] itens = form.getFields();
            for (FormItem item : itens) {
                String itemName = item.getName();
                Object itemValue = form.getValue(itemName);
                values.put(itemName, itemValue);
            }
            this.setEditValues(rowNum, values);
            return getEditedRecord(record);
        }
    
         
        public boolean isDetailExpanded(ListGridRecord record) {
            Canvas expansion = this.getCurrentExpansionComponent(record);
            return expansion != null;
        }
    
         
        public DynamicForm getDetailForm(ListGridRecord record) {
            Layout expansion = (Layout) this.getCurrentExpansionComponent(record);
            return (DynamicForm) expansion.getMember(0);
        }
    
        // Suporte a impressão da grid.
        // /////////////////////////////////////////////////////////////////////////////
    
         
        public Boolean getCanPrint() {
            Boolean canPrint = getAttributeAsBoolean(CAN_PRINT_ATTRIBUTE);
            return canPrint != null ? canPrint : false;
        }
    
         
        public void setCanPrint(Boolean canPrint) {
            this.setAttribute(CAN_PRINT_ATTRIBUTE, canPrint, true);
            this.resetToolbar();
        }
        
         
        public void setReportHeaderProvider(ReportHeaderProvider reportHeaderProvider) {
            this.reportHeaderProvider = reportHeaderProvider;
        }
    
         
        public Canvas getPrintHeader() {
            return printHeader;
        }
        
         
        public void setPrintHeader(Canvas printHeader) {
            this.printHeader = printHeader;
        }
        
         
        private boolean addPrintAction() {
            boolean show = false;
            if (this.getCanPrint()) {
                show = true;
                printTool = createGridAction(DesignConstants.PRINT_IMAGE, CONSTANTS.print());
                printTool.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {
                        disableButtons();
                        endEditing();
                        startPrinting();
                    }
                });
                tools.addMember(printTool);
            }
            return show;
        }
    
        private void setResultSetFetchModePostCreate(FetchMode fetchMode) {
            getOriginalResultSet().setAttribute("fetchMode", fetchMode.getValue(), true);
        }
    
        private static native void downloadAsPDF(String html, DSRequest requestProperties)  ;
    
        private Canvas[] getPrintView() {
            if (reportHeaderProvider != null) {
                Canvas printHeader = reportHeaderProvider.getReportHeader();
                return new Canvas[] { printHeader, this };
            } else {
                return new Canvas[] { this };
            }
        }
    
        private String generateReportFileName() {
            String title = getExportFilename();
            if (title == null) {
                title = "Relatório";
            }
            DateTimeFormat dateTimeFormatter = DateTimeFormat.getFormat(CONSTANTS.patternDateTimeSeconds());
            String timestamp = dateTimeFormatter.format(new Date());
            String fileName = title + " " + timestamp;
            return fileName.replaceAll("[/: ]", "_");
        }
    
        protected void startExportingPdf() {
            CommonEventBus.getInstance().fireEvent(
                    new MessageIssueEvent(new Message(MessageType.INFO, MESSAGES.infoExportWaiting())));
    
            expandGroups();
            
            runAfterFullFetch(new Runnable() {
                @Override
                public void run() {
                    Canvas.getPrintHTML(getPrintView(), new PrintProperties(), new PrintHTMLCallback() {
                        @Override
                        public void setHTML(final String html) {
                            logger.info("callback getPrintHTML");
                            DSRequest requestProperties = new DSRequest();
                            requestProperties.setAttribute("skinName", "Linker");
                            requestProperties.setAttribute("pdfName", generateReportFileName());
                            requestProperties.setExportDisplay(ExportDisplay.DOWNLOAD);
                            downloadAsPDF(html, requestProperties);
                            logger.info("after exportContent");
                            enableButtons(); // Reabilita os botões
                            enablePrintFetch();
                        }
                    });
                }
            });
        }
    
         
        protected void startPrinting() {
            expandGroups();
            
            runAfterFullFetch(new Runnable() {
                @Override
                public void run() {
                    Canvas.showPrintPreview(getPrintView(), new PrintProperties(), null, new PrintPreviewCallback() {
                        @Override
                        public void execute(PrintCanvas printCanvas, PrintWindow printWindow) {
                            logger.info("callback showPrintPreview");
                            enableButtons();
                            enablePrintFetch();
                        }
                    });
                }
            });
        }
    
         
        private void expandGroups() {
            Tree groupTree = getGroupTree();
            
            if (groupTree != null) {
                groupTree.openAll();
            }
        }
    
        private boolean fetchDisabledByPrint = false;
        private boolean fetchDisabledByEdition = false;
        private boolean delayFetch = false;
    
        private void runAfterFullFetch(final Runnable runnable) {
            if (getOriginalResultSet() == null) {
                logger.info("resultSet is null!");
                runnable.run();
                return;
            }
            dataArrivedRegistration = addDataArrivedHandler(new DataArrivedHandler() {
                @Override
                public void onDataArrived(DataArrivedEvent event) {
                    logger.info("data arrived!");
                    removeDataArrivedRegistration();
                    fetchDisabledByPrint = true;
                    runnable.run();
                }
            });
    
            // Configura o grid para buscar todos os registros
            setResultSetFetchModePostCreate(FetchMode.BASIC);
            // Força refetch
            invalidateCache();
        }
    
        private void enablePrintFetch() {
            fetchDisabledByPrint = false;
            // logger.info("Retorna grid para modo PAGED");
            setResultSetFetchModePostCreate(FetchMode.PAGED);
            // Força refetch
            invalidateCache();
            // logger.info("done");
        }
    
        @Override
        public void invalidateCache() {
            logger.info("invalidateCache called");
            if (fetchDisabledByPrint) {
                logger.info("invalidateCache skiped!");
                return;
            }
            super.invalidateCache();
        }
    
        private void removeDataArrivedRegistration() {
            if (dataArrivedRegistration != null) {
                dataArrivedRegistration.removeHandler();
            }
            dataArrivedRegistration = null;
        }
    
        // Suporte a exportação da grid.
        // /////////////////////////////////////////////////////////////////////////////
    
         
        public Boolean getCanExport() {
            Boolean canExport = getAttributeAsBoolean(CAN_EXPORT_ATTRIBUTE);
            return canExport != null ? canExport : false;
        }
    
         
        public void setCanExport(Boolean canExport) {
            this.setAttribute(CAN_EXPORT_ATTRIBUTE, canExport, true);
            this.resetToolbar();
        }
    
         
        public Boolean getExportClientSide() {
            Boolean exportClient = getAttributeAsBoolean(EXPORT_CLIENT_SIDE_ATTRIBUTE);
            if (exportClient == null) {
                exportClient = true;
            }
            return exportClient;
        }
    
         
        public void setExportClientSide(Boolean exportClient) {
            this.setAttribute(EXPORT_CLIENT_SIDE_ATTRIBUTE, exportClient, true);
        }
    
         
        public String getExportFilename() {
            return getAttribute(EXPORT_FILENAME_ATTRIBUTE);
        }
    
         
        public void setExportFilename(String filename) {
            filename = StringUtilsClient.filterHtmlEntities(filename);
            this.setAttribute(EXPORT_FILENAME_ATTRIBUTE, filename, true);
        }
    
        public void addFieldToExport(String field) {
            fieldsToShow.add(field);
        }
    
        private void export(ExportFormat format) {
            disableButtons();
            endEditing();
            for (String field : fieldsToShow) {
                showField(field);
            }
            startExporting(format);
            for (String field : fieldsToShow) {
                hideField(field);
            }
        }
    
         
        private boolean addExportAction() {
            boolean show = false;
            if (this.getCanExport()) {
                show = true;
                excelTool = createGridAction(DesignConstants.EXPORT_EXCEL_IMAGE, CONSTANTS.exportExcel());
                excelTool.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {
                        export(ExportFormat.XLS);
                    }
                });
                tools.addMember(excelTool);
    
                csvTool = createGridAction(DesignConstants.EXPORT_CSV_IMAGE, CONSTANTS.exportCsv());
                csvTool.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {
                        export(ExportFormat.CSV);
                    }
                });
                tools.addMember(csvTool);
    
                pdfTool = createGridAction(DesignConstants.EXPORT_PDF_IMAGE, CONSTANTS.exportPdf());
                if (useDefaultPdfTool) {
                    pdfTool.addClickHandler(new ClickHandler() {
                        public void onClick(ClickEvent event) {
                            disableButtons();
                            endEditing();
                            startExportingPdf();
                        }
                    });
                }
                tools.addMember(pdfTool);
            }
            return show;
        }
    
         
        public ImgButton getPdfTool() {
            return pdfTool;
        }
    
        private void disableButtons() {
            excelTool.disable();
            csvTool.disable();
            pdfTool.disable();
            if (printTool != null) {
                printTool.disable();
            }
        }
    
        private void enableButtons() {
            excelTool.enable();
            csvTool.enable();
            pdfTool.enable();
            if (printTool != null) {
                printTool.enable();
            }
        }
    
         
        private void startExporting(ExportFormat format) {
            if (!this.getDataAsRecordList().isEmpty()) {
                DSRequest dsRequestProps = new DSRequest();
                dsRequestProps.setExportAs(format);
                dsRequestProps.setExportDisplay(ExportDisplay.DOWNLOAD);
                dsRequestProps.setExportDelimiter(";");
    
                // coloca o TimeZone
                putTimeZoneParameter(dsRequestProps);
    
                dsRequestProps.setExportFilename(generateReportFileName());
    
                if (!this.getExportClientSide()) {
                    prepareDataSourceTitles();
                    this.exportData(dsRequestProps);
                } else {
                    this.exportClientData(dsRequestProps);
                }
            } else {
                CommonEventBus.getInstance().fireEvent(
                        new MessageIssueEvent(new Message(MessageType.INFO, MESSAGES.infoNoRecordToExport())));
            }
    
            // Reabilita os botões de exportação
            enableButtons();
        }
    
         
        private void putTimeZoneParameter(DSRequest dsRequestProps) {
            // pega o TimeZone do client
            Date today = new Date();
            String timeZone = DateTimeFormat.getFormat("v").format(today);
    
            // coloca o parametro TimeZone no DSrequest
            Map<String, String> param = new HashMap<String, String>();
            param.put("timeZone", timeZone);
            dsRequestProps.setParams(param);
        }
    
         
        private void prepareDataSourceTitles() {
    
            Date date = new Date();
    
            DataSource ds = this.getDataSource();
            ListGridField[] fields = this.getAllFields();
            for (ListGridField field : fields) {
                String title = null;
                if (fieldIsExportable(field)) {
                    title = StringUtilsClient.filterHtmlEntities(field.getTitle());
                    if (ListGridFieldType.DATETIME.equals(field.getType())) {
                        title = title + " (" + DateTimeFormat.getFormat("ZZZZ").format(date) + ")";
                    }
                }
                DataSourceField dsField = ds.getField(field.getName());
                if (dsField != null && title != null) {
                    dsField.setTitle(title);
                }
            }
        }
    
         
        protected String[] getExportableFields(ListGridField... fields) {
            List<String> exportFields = new ArrayList<String>(fields.length);
            for (ListGridField field : fields) {
                if (fieldIsExportable(field)) {
                    exportFields.add(field.getName());
                }
            }
            return exportFields.toArray(new String[exportFields.size()]);
        }
    
        private boolean fieldIsVisible(ListGridField field) {
            String showIf = field.getAttribute("showIf");
            return showIf == null || "true".equals(showIf);
        }
    
         
        protected boolean fieldIsExportable(ListGridField field) {
            Object canExportString = field.getAttributeAsObject("canExport");
            if (canExportString == null) {
                return fieldIsVisible(field);
            } else {
                return (Boolean) canExportString;
            }
        }
    
        // Suporte a inclusão de registros no grid.
        // /////////////////////////////////////////////////////////////////////////////
    
         
        public Boolean getCanAdd() {
            Boolean canAdd = getAttributeAsBoolean(CAN_ADD_ATTRIBUTE);
            return canAdd != null ? canAdd : false;
        }
    
         
        public void setCanAdd(Boolean canAdd) {
            this.setAttribute(CAN_ADD_ATTRIBUTE, canAdd, true);
            this.resetToolbar();
            this.setCanEdit();
        }
    
         
        public ConfirmActionHandler getConfirmAddHandler() {
            return confirmAddHandler;
        }
    
         
        public void setConfirmAddHandler(ConfirmActionHandler handler) {
            confirmAddHandler = handler;
        }
    
         
        public RecordValidator getRecordAddValidator() {
            return recordAddValidator;
        }
    
         
        public void setRecordAddValidator(RecordValidator validator) {
            recordAddValidator = validator;
        }
    
         
        public synchronized void addRecordAddedHandler(ActionDoneHandler handler) {
            recordAddedHandlers.add(handler);
        }
    
         
        private boolean addAddAction() {
            boolean show = false;
            if (this.getCanAdd()) {
                show = true;
                ImgButton addTool = createGridAction(DesignConstants.ADD_LINE_IMAGE, CONSTANTS.add());
                addTool.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {
                        boolean confirm = confirmAdding();
                        if (confirm) {
                            startAdding();
                        }
                    }
                });
                tools.addMember(addTool);
            }
            return show;
        }
    
         
        private boolean confirmAdding() {
            boolean confirm = true;
            if (confirmAddHandler != null) {
                confirm = confirmAddHandler.confirm(null, new BooleanCallback() {
                    @Override
                    public void execute(Boolean confirm) {
                        if (confirm) {
                            startAdding();
                        }
                    }
                });
            }
            return confirm;
        }
    
         
        private void startAdding() {
            this.startEditingNew();
        }
    
         
        private boolean validateAdd(ListGridRecord record) {
            boolean valid = true;
            if (recordAddValidator != null) {
                valid = recordAddValidator.validate(record);
            }
            return valid;
        }
    
         
        private synchronized void notifyRecordAdded(ListGridRecord record) {
            for (ActionDoneHandler handler : recordAddedHandlers) {
                handler.onActionDone(record);
            }
        }
    
        // Suporte a edição de registros no grid.
        // /////////////////////////////////////////////////////////////////////////////
    
         
        public Boolean getCanUpdate() {
            Boolean canUpdate = getAttributeAsBoolean(CAN_UPDATE_ATTRIBUTE);
            return canUpdate != null ? canUpdate : false;
        }
    
         
        public void setCanUpdate(Boolean canUpdate) {
            this.setAttribute(CAN_UPDATE_ATTRIBUTE, canUpdate, true);
            this.setCanEdit();
        }
    
         
        public CanDoActionRecordRuler getCanUpdateRecordRuler() {
            return canUpdateRecordRuler;
        }
    
         
        public void setCanUpdateRecordRuler(CanDoActionRecordRuler ruler) {
            canUpdateRecordRuler = ruler;
            if (updateAction != null) {
                updateAction.setCanDoActionRecordRuler(ruler);
            }
            if (!updateActionMap.isEmpty()) {
                for (CustomListGridRecordAction action : updateActionMap.values()) {
                    action.setCanDoActionRecordRuler(ruler);
                }
            }
        }
    
         
        public ConfirmActionHandler getConfirmUpdateHandler() {
            return confirmUpdateHandler;
        }
    
         
        public void setConfirmUpdateHandler(ConfirmActionHandler handler) {
            confirmUpdateHandler = handler;
            if (updateAction != null) {
                updateAction.setConfirmActionHandler(handler);
            }
            if (!updateActionMap.isEmpty()) {
                for (CustomListGridRecordAction action : updateActionMap.values()) {
                    action.setConfirmActionHandler(handler);
                }
            }
        }
    
         
        public RecordValidator getRecordUpdateValidator() {
            return recordUpdateValidator;
        }
    
         
        public void setRecordUpdateValidator(RecordValidator validator) {
            recordUpdateValidator = validator;
        }
    
         
        public synchronized void addRecordUpdatedHandler(ActionDoneHandler handler) {
            recordUpdatedHandlers.add(handler);
        }
    
        private void addUpdateAction(ListGridRecord record, Layout panel) {
            if (getCanUpdate()) {
                CustomListGridRecordAction action = getUpdateAction();
                panel.addMember(action.getActionIcon(record));
                if (!action.getCanDoAction(record)) {
                    record.setAttribute(getRecordEditProperty(), false);
                }
            }
        }
    
         
        private CustomListGridRecordAction getUpdateAction() {
            if (updateAction == null) {
                updateAction = createUpdateAction();
            }
            return updateAction;
        }
    
        private CustomListGridRecordAction createUpdateAction() {
            CustomListGridRecordAction action = new CustomListGridRecordAction(DesignConstants.CHANGE_RECORD_IMAGE,
                    CONSTANTS.edit());
    
            action.setCanDoActionRecordRuler(canUpdateRecordRuler);
            action.setConfirmActionHandler(confirmUpdateHandler);
            action.setExecuteActionHandler(new ExecuteActionHandler() {
                @Override
                public void execute(ListGridRecord record) {
                    startUpdating(record, null);
                    CommonEventBus.getInstance().fireEvent(new MessageClearEvent());
                }
            });
            return action;
        }
    
        private void startUpdating(ListGridRecord record, Integer colNum) {
            // se já está editando, já está aberto e não deve mudar
            if (!isEditing(record)) {
                int rowNum = this.getRecordIndex(record);
                if (colNum == null) {
                    colNum = this.getFirstEditableColumn(rowNum);
                }
                if (startEditing(rowNum, colNum, false)) {
                     if (getHasDetail(record)) {
                        expandRecord(record);
                    }
                }
            }
        }
    
        private boolean validateUpdate(ListGridRecord record) {
            boolean valid = true;
            if (recordUpdateValidator != null) {
                valid = recordUpdateValidator.validate(record);
            }
            return valid;
        }
    
         
        private synchronized void notifyRecordUpdated(ListGridRecord record) {
            for (ActionDoneHandler handler : recordUpdatedHandlers) {
                handler.onActionDone(record);
            }
        }
    
        public Boolean getCanUpdateCell() {
            Boolean canUpdate = getAttributeAsBoolean(CAN_UPDATE_CELL_ATTRIBUTE);
            return canUpdate != null ? canUpdate : false;
        }
    
        public void setCanUpdateCell(Boolean canUpdate) {
            this.setAttribute(CAN_UPDATE_CELL_ATTRIBUTE, canUpdate, true);
            this.setCanEdit();
    
            this.setEditByCell(canUpdate);
            this.setShowRollOverCanvas(canUpdate);
            this.setUseCellRollOvers(canUpdate);
        }
    
    
        @Override
        protected Canvas getRollOverCanvas(Integer rowNum, Integer colNum) {
            if (isEditing()) {
                return null;
            }
            Layout layout = null;
            if (CustomListGridField.getCanUpdateCell(getField(colNum))) {
                CustomListGridRecordAction action = getUpdateCellAction(colNum);
                ListGridRecord record = (ListGridRecord) this.getEditedRecord(rowNum);
                if (action.getCanDoAction(record)) {
                        layout = createRollOverCanvas(record, colNum);
                    layout.addMember(action.getActionIcon(record));
                }
            }
            return layout;
        }
    
        private Layout createRollOverCanvas(ListGridRecord record, Integer colNum) {
    
            if (rollOver == null) {
                rollOver = new HLayout(2);
                rollOver.setSnapTo("TR");
                rollOver.setWidth(22);
                rollOver.setHeight(22);
            } else {
                rollOver.removeMembers(rollOver.getMembers());
            }
            return rollOver;
        }
    
        private CustomListGridRecordAction getUpdateCellAction(int colNum) {
            CustomListGridRecordAction action = updateActionMap.get(colNum);
            if (action == null) {
                action = createUpdateAction(colNum);
            }
            return action;
        }
    
         
        private CustomListGridRecordAction createUpdateAction(final int colNum) {
            CustomListGridRecordAction action = new CustomListGridRecordAction(DesignConstants.CHANGE_RECORD_IMAGE,
                    CONSTANTS.edit());
    
            action.setCanDoActionRecordRuler(canUpdateRecordRuler);
            action.setConfirmActionHandler(confirmUpdateHandler);
            action.setExecuteActionHandler(new ExecuteActionHandler() {
                @Override
                public void execute(ListGridRecord record) {
                    startUpdating(record, colNum);
                    CommonEventBus.getInstance().fireEvent(new MessageClearEvent());
                }
            });
            return action;
        }
    
        public Boolean getCanRemove() {
            Boolean canRemove = getAttributeAsBoolean(CAN_REMOVE_ATTRIBUTE);
            return canRemove != null ? canRemove : false;
        }
    
        public void setCanRemove(Boolean canRemove) {
            this.setAttribute(CAN_REMOVE_ATTRIBUTE, canRemove, true);
        }
    
        public CanDoActionRecordRuler getCanRemoveRecordRuler() {
            return canRemoveRecordRuler;
        }
    
         
        public void setCanRemoveRecordRuler(CanDoActionRecordRuler ruler) {
            canRemoveRecordRuler = ruler;
            if (removeAction != null) {
                removeAction.setCanDoActionRecordRuler(ruler);
            }
        }
    
        public ConfirmActionHandler getConfirmRemoveHandler() {
            return confirmRemoveHandler;
        }
    
        public void setConfirmRemoveHandler(ConfirmActionHandler handler) {
            confirmRemoveHandler = handler;
            if (removeAction != null) {
                removeAction.setConfirmActionHandler(handler);
            }
        }
    
        public synchronized void addRecordRemovedHandler(ActionDoneHandler removeRecordListener) {
            recordRemovedHandlers.add(removeRecordListener);
        }
    
        private void addRemoveAction(ListGridRecord record, Layout panel) {
            if (getCanRemove()) {
                CustomListGridRecordAction action = getRemoveAction();
                panel.addMember(action.getActionIcon(record));
            }
        }
    
        private CustomListGridRecordAction getRemoveAction() {
            if (removeAction == null) {
                removeAction = createRemoveAction();
            }
            return removeAction;
        }
    
        private CustomListGridRecordAction createRemoveAction() {
            CustomListGridRecordAction action = new CustomListGridRecordAction(DesignConstants.DELETE_RECORD_IMAGE,
                    CONSTANTS.delete());
    
            action.setCanDoActionRecordRuler(canRemoveRecordRuler);
            action.setConfirmActionHandler(confirmRemoveHandler);
            action.setExecuteActionHandler(new ExecuteActionHandler() {
                @Override
                public void execute(ListGridRecord record) {
                    startRemoving(record);
                }
            });
            return action;
        }
    
        private void startRemoving(final ListGridRecord record) {
            if (this.getWarnOnRemoval()) {
                this.warnRemove(record);
            } else {
                this.doRemove(record);
            }
        }
    
         
        private void warnRemove(final ListGridRecord record) {
            Dialog dialog = new Dialog();
            dialog.setBodyColor("#EDEDED");
            SC.ask(CONSTANTS.warning(), this.getWarnOnRemovalMessage(), new BooleanCallback() {
                @Override
                public void execute(Boolean ok) {
                    if (ok) {
                        doRemove(record);
                    }
                }
            }, dialog);
        }
    
        private void doRemove(final ListGridRecord record) {
            removeData(record, new DSCallback() {
                @Override
                public void execute(DSResponse response, Object rawData, DSRequest request) {
                    if (response.getStatus() == DSResponse.STATUS_SUCCESS) {
                        notifyRecordRemoved(record);
                    }
                }
            });
        }
    
        private synchronized void notifyRecordRemoved(ListGridRecord record) {
            for (ActionDoneHandler handler : recordRemovedHandlers) {
                handler.onActionDone(record);
            }
        }
    
        private void addUpAction(ListGridRecord record, Layout panel) {
            if (getCanMove()) {
                CustomListGridRecordAction action = getUpAction();
                panel.addMember(action.getActionIcon(record));
            }
        }
    
        private void addDownAction(ListGridRecord record, Layout panel) {
            if (getCanMove()) {
                CustomListGridRecordAction action = getDownAction();
                panel.addMember(action.getActionIcon(record));
            }
        }
    
        private CustomListGridRecordAction getUpAction() {
            if (upAction == null) {
                upAction = createUpAction();
            }
            return upAction;
        }
    
        private CustomListGridRecordAction getDownAction() {
            if (downAction == null) {
                downAction = createDownAction();
            }
            return downAction;
        }
    
         
        private CustomListGridRecordAction createUpAction() {
            CustomListGridRecordAction upAction = new CustomListGridRecordAction(DesignConstants.MOVE_UP_RECORD_IMAGE,
                    CONSTANTS.moveUp());
    
            upAction.setExecuteActionHandler(new ExecuteActionHandler() {
                @Override
                public void execute(ListGridRecord record) {
                    RecordList rs = getRecordList();
                    int index = getRecordIndex(record);
    
                    if (index > 0) {
                        rs.removeAt(index);
                        rs.addAt(record, index - 1);
                    }
                }
            });
            return upAction;
        }
    private CustomListGridRecordAction createDownAction() {
            CustomListGridRecordAction downAction = new CustomListGridRecordAction(DesignConstants.MOVE_DOWN_RECORD_IMAGE,
                    CONSTANTS.moveDown());
    
            downAction.setExecuteActionHandler(new ExecuteActionHandler() {
                @Override
                public void execute(ListGridRecord record) {
                    RecordList rs = getRecordList();
                    int index = getRecordIndex(record);
                    int numRecords = rs.getLength();
    
                    if (index < numRecords - 1) {
                        rs.removeAt(index);
                        rs.addAt(record, index + 1);
                    }
                }
            });
            return downAction;
        }
    
        public Boolean getCanMove() {
            Boolean canMove = getAttributeAsBoolean(CAN_MOVE_ATTRIBUTE);
            return canMove != null ? canMove : false;
        }
    
        public void setCanMove(Boolean canMove) {
            this.setAttribute(CAN_MOVE_ATTRIBUTE, canMove, true);
        }
    
        private void addCustomActions(ListGridRecord record, Layout panel) {
            if (customActions != null) {
                for (CustomListGridRecordAction action : customActions) {
                    panel.addMember(action.getActionIcon(record));
                }
            }
        }
    
        private void setCanEdit() {
            boolean canEdit = this.getCanAdd() || this.getCanUpdate() || this.getCanUpdateCell();
            setCanEdit(canEdit);
        }
    
        public void setCanEdit(Boolean canEdit) {
            super.setCanEdit(canEdit);
            configEdit();
        }
    
        private void configEdit() {
            if (getCanEdit() && !editConfigDone) {
                editConfigDone = true;
    
                this.setEditEvent(ListGridEditEvent.NONE);
                this.setAutoSaveEdits(true);
    
                this.setSelectOnEdit(false);
                this.setModalEditing(false);
    
                this.setConfirmCancelEditing(false);
                this.setConfirmDiscardEdits(false);
    
                bindEditHandlers();
            }
        }
    
        private void bindEditHandlers() {
            this.addRecordClickHandler(new RecordClickHandler() {
                @Override
                public void onRecordClick(RecordClickEvent event) {
                    int editingRow = getEditRow();
                    int clickedRow = event.getRecordNum();
                    if (editingRow >= 0 && editingRow != clickedRow) {
                        endEditing();
                    }
                }
            });
    
            // salva registro quando usuario clica em coluna não editável do mesmo registro
            this.addCellClickHandler(new CellClickHandler() {
                @Override
                public void onCellClick(CellClickEvent event) {
                    if (getCanUpdateCell()) {
                        int editingRow = getEditRow();
                        int clickedRow = event.getRowNum();
                        if (editingRow >= 0 && editingRow == clickedRow) {
                            int editingCol = getEditCol();
                            int clickedCol = event.getColNum();
                            if (editingCol >= 0 && editingCol != clickedCol) {
                                endEditing();
                            }
                        }
                    }
                }
            });
    
            // inclui detalhes, se houver, nos dados a serem salvos
            this.addRowEditorExitHandler(new RowEditorExitHandler() {
                @Override
                public void onRowEditorExit(RowEditorExitEvent event) {
                    int editingRow = getEditRow();
                    ListGridRecord record = (ListGridRecord) getEditedRecord(editingRow);
                    if (event.getEditCompletionEvent() != EditCompletionEvent.ESCAPE_KEYPRESS) {
                        if (isEditing(record) && isDetailExpanded(record)) {
                            record = completeRecord(editingRow, record);
                        }
                        if (!validateEdit(record)) {
                            event.cancel();
                        }
                    } else {
                        // fecha os detalhes
                        collapseRecord(record);
                    }
                }
            });
    
            this.addEditCompleteHandler(new EditCompleteHandler() {
                @Override
                public void onEditComplete(EditCompleteEvent event) {
                    final ListGridRecord record = getEditedRecord(event);
                    if (record != null) {
                        collapseRecord(record);
                        notifyRecordEdited(event, record);
                    }
                }
            });
        }
    
        private void notifyRecordEdited(EditCompleteEvent event, final ListGridRecord record) {
            if (event.getOldValues() == null) {
                // na inserção, se tem detalhes, emenda uma edição
                if (getHasDetail(record)) {
                    startUpdating(record, null);
                }
                notifyRecordAdded(record);
            } else {
                notifyRecordUpdated(record);
            }
        }
    
        // TODO [helenov] avaliar tratamento de inserção de novo registro
        // private void bindChangedHandler() {
        // ResultSet rs = this.getResultSet();
        // rs.addDataChangedHandler( new DataChangedHandler() {
        // @Override
        // public void onDataChanged(DataChangedEvent event) {
        // // TODO implementar destaque do registro editado
        // if ( addedRecord != null ) {
        // addedRecord = null;
        // redraw();
        // scrollToRow(getRecordIndex(addedRecord));
        // // selectRecord(record);
        // }
        // }
        // });
        // }
    
         
        private boolean validateEdit(ListGridRecord record) {
            if (record.getAttribute("id") == null) {
                return validateAdd(record);
            } else {
                return validateUpdate(record);
            }
        }
    
         
        @Override
        public boolean canEditCell(int rowNum, int colNum) {
            CustomListGridField customField = new CustomListGridField(this.getField(colNum));
            CanDoActionRecordRuler ruler = customField.getCanEditCellRuler();
            if (ruler != null) {
                ListGridRecord record = (ListGridRecord) this.getEditedRecord(rowNum);
                return ruler.getCanDoAction(record);
            }
            return super.canEditCell(rowNum, colNum);
        }
    
         
        public boolean isEditing() {
            return this.getEditRow() != -1;
        }
    
         
        public boolean isEditing(ListGridRecord record) {
            int editRow = this.getEditRow();
            int recordRow = this.getRecordIndex(record);
            boolean canEdit = false;
            // registro está sendo editado
            if (editRow != -1 && editRow == recordRow) {
                canEdit = true;
            }
            return canEdit;
        }
    
         
        public Record getEditedRecord(int rowNum) {
            return ListGridRecord.getOrCreateRef(super.getEditedRecord(rowNum).getJsObj());
        }
    
         
        public ListGridRecord getEditedRecord(Record record) {
            int rowNum = getRecordIndex(record);
            return (ListGridRecord) getEditedRecord(rowNum);
        }
    
         
        private ListGridRecord getEditedRecord(EditCompleteEvent event) {
            ListGridRecord edited = null;
            String pkField = getDataSource().getPrimaryKeyFieldName();
            Record[] response = event.getDsResponse().getData();
            // TODO [helenov] verificar porque às vezes response vem vazio.
            if (response.length > 0) {
                String pkValue = response[0].getAttribute(pkField);
                Record record = getRecordList().find(pkField, pkValue);
                edited = ListGridRecord.getOrCreateRef(record.getJsObj());
            }
            return edited;
        }
         
        private int getFirstEditableColumn(int rowNum) {
            ListGridField[] fields = this.getFields();
            for (int i = 0; i < fields.length; i++) {
                if (canEditCell(rowNum, i)) {
                    return i;
                }
            }
            return 0;
        }
    
         
        public String getFilterState() {
            JSONEncoder encoder = new JSONEncoder();
            return encoder.encode(this.getFilterEditorCriteria().getJsObj());
        }
    
         
        public void setFilterState(String state) {
            AdvancedCriteria criteria = new AdvancedCriteria(JSONEncoder.decode(state));
            this.setCriteria(criteria);
        }
    
        public void setActionsColumnPosition(int actionsColumnPosition) {
            this.actionsColumnPosition = actionsColumnPosition;
        }
    
        public void setCustomAction(Canvas customAction, int position) {
            tools.addMember(customAction, position);
        }
    http://www.4shared.com/file/vcMkdlLe...eListGrid.html




    Best regards
    Last edited by zatix; 30 Aug 2016, 11:53.

    #2
    Hi zatix,

    can you please post the code here in code-tags? Downloading files from a shared hoster is really not necessary in this case.
    Without seeing the actual code - do you perhaps have autoFetchData activated and are doing a fetch yourself as well?

    Best regards
    Blama

    Comment


      #3
      Originally posted by Blama View Post
      Hi zatix,

      can you please post the code here in code-tags? Downloading files from a shared hoster is really not necessary in this case.
      Without seeing the actual code - do you perhaps have autoFetchData activated and are doing a fetch yourself as well?

      Best regards
      Blama
      Hey, Thanks for your response!

      I put the code in code tags.

      Best regards
      Zatix

      Comment


        #4
        Hi zatix,

        that is much code. I spotted these potential causes, but you'll have to check them for correctness yourself:
        • vehicleHistoryGrid.fetchData(criteria)
        • // configuração da consulta
          this.setAutoFetchData(true);
        • @Override
          public void refreshGrid() {
          vehicleHistoryGrid.setCriteria(criteria);
          vehicleHistoryGrid.fetchData(criteria);
          vehicleHistoryGrid.invalidateCache(); //DEFINITELY WRONG
          }
        • @Override
          public Boolean willFetchData(Criteria newCriteria) {
          return true;
          }
        All these points might be related to your issue. From my gut feeling you are using invalidateCache() way too much in your code.

        Best regards
        Blama

        Comment


          #5
          We haven't actually run the code, but from a quick scan, Blama's assessment looks to be correct.
          The invalidateCache method tells a listgrid that its current data set is stale, and forces a new fetch to occur. Changing a grids criteria will cause a fetch to occur (if necessary), so invalidateCache() is not required, and could lead to double-fetching.
          The override to willFetchData is confusing - not sure what you're trying to achieve but this could quite plausibly cause additional fetches as the grid would assume that it didn't have a cache (or active fetch in progress) for criteria when it already does.
          Also 'autoFetchData' will cause a fetch to occur automatically when the grid is drawn. Having an explicit call to fetchData in addition to this could easily lead to extra fetches.

          If you want to see where fetches come from, in the developer console, you can enable "track rpc's" on the RPC tab, and view each request. By selecting a request, you can see details of the fetch, as well as a stack trace which will indicate the (javascript) stack that led to the fetch being issued. This can help identify the cause of unexpected fetches.

          And lastly - if you think you're seeing a framework problem or you simply can't make sense of a behavior, we're happy to take a look at a test case - but we'd typically recommend you post a much smaller snippet of code. The best approach is to build a small (self contained and runnable without any supporting classes) EntryPoint consisting of just enough UI elements to demonstrate the problem, and show us that code along with your dataSource definition, and a description of the steps to execute to see the problem in action.

          Thanks and Regards
          Isomorphic Software

          Comment

          Working...
          X