Author: norman
Date: Fri Aug 14 06:06:04 2009
New Revision: 804086

URL: http://svn.apache.org/viewvc?rev=804086&view=rev
Log:
Better handle refetching of rows (bulk refetch)
add some javadocs

Modified:
    
labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
    labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
    
labs/hupa/src/main/java/org/apache/hupa/client/widgets/RefetchPagingScrollTable.java

Modified: 
labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
URL: 
http://svn.apache.org/viewvc/labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java?rev=804086&r1=804085&r2=804086&view=diff
==============================================================================
--- 
labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
 (original)
+++ 
labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
 Fri Aug 14 06:06:04 2009
@@ -20,7 +20,6 @@
 package org.apache.hupa.client.mvp;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 
 import net.customware.gwt.dispatch.client.DispatchAsync;
 import net.customware.gwt.presenter.client.EventBus;
@@ -56,9 +55,6 @@
 import com.google.gwt.event.dom.client.HasClickHandlers;
 import com.google.gwt.gen2.table.event.client.HasPageLoadHandlers;
 import com.google.gwt.gen2.table.event.client.HasRowSelectionHandlers;
-import com.google.gwt.gen2.table.event.client.RowSelectionEvent;
-import com.google.gwt.gen2.table.event.client.RowSelectionHandler;
-import com.google.gwt.gen2.table.event.client.TableEvent.Row;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.SourcesTableEvents;
 import com.google.gwt.user.client.ui.TableListener;
@@ -75,7 +71,8 @@
                public IMAPMessage getData(int rowIndex);
                public HasClickHandlers getDeleteClick();
                public void reloadData(User user, IMAPFolder folder,String 
searchValue);
-               public void removeMessages(ArrayList<Long> uids);
+               public void removeMessages(ArrayList<IMAPMessage> messages);
+               public ArrayList<IMAPMessage> getSelectedMessages();
                public void reset();
                public HasDialog getConfirmDialog();
                public HasClickHandlers getConfirmDialogClick();
@@ -90,7 +87,6 @@
        private String searchValue;
        private DispatchAsync dispatcher;
        public final static Place PLACE = new Place("IMAPMessageList");
-       private ArrayList<IMAPMessage> selectedMessages = new 
ArrayList<IMAPMessage>();
        
        @Inject
        public IMAPMessageListPresenter(IMAPMessageListPresenter.Display 
display,EventBus bus,DispatchAsync dispatcher) {
@@ -113,7 +109,7 @@
                                folder = loadMessagesEvent.getFolder();
                                searchValue = 
loadMessagesEvent.getSearchValue();
                                display.reloadData(user, folder, searchValue);
-                               selectedMessages.clear();
+                               display.deselectAllMessages();
                        }
                        
                });
@@ -123,7 +119,7 @@
                                user = event.getUser();
                                folder = new 
IMAPFolder(IMAPFolder.DEFAULT_INBOX);
                                display.reloadData(user, folder, null);
-                               selectedMessages.clear();
+                               display.deselectAllMessages();
 
                        }
 
@@ -133,7 +129,7 @@
 
                        public void onLogout(LogoutEvent event) {
                                display.reset();
-                               selectedMessages.clear();
+                               display.deselectAllMessages();
                        }
 
                        
@@ -141,24 +137,24 @@
                eventBus.addHandler(LoadMessagesEvent.TYPE, new 
LoadMessagesEventHandler() {
 
                        public void onLoadMessagesEvent(LoadMessagesEvent 
loadMessagesEvent) {
-                               selectedMessages.clear();
+                               display.deselectAllMessages();
                        }
                        
                });
                eventBus.addHandler(MoveMessageEvent.TYPE, new 
MoveMessageEventHandler() {
 
                        public void onMoveMessageHandler(MoveMessageEvent 
event) {
-                               final long uid = event.getMessage().getUid();
-                               dispatcher.execute(new 
MoveMessage(event.getUser().getSessionId(),event.getOldFolder(),event.getNewFolder(),uid),
 new AsyncCallback<MoveMessageResult>() {
+                               final IMAPMessage message = event.getMessage();
+                               dispatcher.execute(new 
MoveMessage(event.getUser().getSessionId(),event.getOldFolder(),event.getNewFolder(),message.getUid()),
 new AsyncCallback<MoveMessageResult>() {
 
                                        public void onFailure(Throwable caught) 
{
                                                GWT.log("ERROR while 
moving",caught);
                                        }
 
                                        public void onSuccess(MoveMessageResult 
result) {
-                                               ArrayList<Long> uidArray = new 
ArrayList<Long>();
-                                               uidArray.add(uid);
-                                               
display.removeMessages(uidArray);
+                                               ArrayList<IMAPMessage> 
messageArray = new ArrayList<IMAPMessage>();
+                                               messageArray.add(message);
+                                               
display.removeMessages(messageArray);
                                        }
                                        
                                });
@@ -168,7 +164,7 @@
                display.getSelectAllClick().addClickHandler(new ClickHandler() {
 
                        public void onClick(ClickEvent event) {
-                               selectedMessages.clear();
+                               display.deselectAllMessages();
                                display.selectAllMessages();
                        }
                        
@@ -192,21 +188,7 @@
                        }
 
                });
-               display.getDataTableSelection().addRowSelectionHandler(new 
RowSelectionHandler() {
 
-                       public void onRowSelection(RowSelectionEvent event) {
-                               
-                               Iterator<Row> rowIt = 
event.getSelectedRows().iterator();
-                               while(rowIt.hasNext()) {
-                                       
selectedMessages.add(display.getData(rowIt.next().getRowIndex()));
-                               }
-                               Iterator<Row> deselectedRowIt = 
event.getDeselectedRows().iterator();
-                               while(deselectedRowIt.hasNext()) {
-                                       
selectedMessages.remove(display.getData(deselectedRowIt.next().getRowIndex()));
-                               }
-                       }
-                               
-                       });
                display.getDeleteClick().addClickHandler(new 
com.google.gwt.event.dom.client.ClickHandler() {
 
                        public void 
onClick(com.google.gwt.event.dom.client.ClickEvent event) {
@@ -238,10 +220,15 @@
        }
 
        private void deleteMessages() {
-               dispatcher.execute(new 
DeleteMessage(user.getSessionId(),folder,getSelectedMessageUids()), new 
MyAsyncCallback<DeleteMessageResult>(eventBus,user) {
+               final ArrayList<IMAPMessage> selectedMessages = new 
ArrayList<IMAPMessage>(display.getSelectedMessages());
+               ArrayList<Long> uids = new ArrayList<Long>();
+               for (int i = 0; i < selectedMessages.size(); i++) {
+                       uids.add(selectedMessages.get(i).getUid());
+               }
+               dispatcher.execute(new 
DeleteMessage(user.getSessionId(),folder,uids), new 
MyAsyncCallback<DeleteMessageResult>(eventBus,user) {
 
                        public void onSuccess(DeleteMessageResult result) {
-                               display.removeMessages(result.getMessageUids());
+                               display.removeMessages(selectedMessages);
                                eventBus.fireEvent(new 
DecreaseUnseenEvent(user,folder,result.getMessageUids().size()));
                        }
                        
@@ -267,14 +254,5 @@
                // TODO Auto-generated method stub
                
        }
-       
-       private ArrayList<Long> getSelectedMessageUids() {
-               ArrayList<Long> l = new ArrayList<Long>();
-               for (int i = 0; i < selectedMessages.size();i++) {
-                       l.add(selectedMessages.get(i).getUid());
-               }
-               return l;
-       }
-       
 
 }

Modified: 
labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
URL: 
http://svn.apache.org/viewvc/labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java?rev=804086&r1=804085&r2=804086&view=diff
==============================================================================
--- labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java 
(original)
+++ labs/hupa/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java 
Fri Aug 14 06:06:04 2009
@@ -127,8 +127,7 @@
                cTableModel.setPostCachedRowCount(50);
                cTableModel.setRowCount(MutableTableModel.UNKNOWN_ROW_COUNT);
                mailTable = new DragRefetchPagingScrollTable<IMAPMessage>(
-                               cTableModel, dataTable,
-                               createHeaderTable(),
+                               cTableModel, dataTable, new 
FixedWidthFlexTable(),
                                createTableDefinitation(),controller,1);
                mailTable.setPageSize(20);
                mailTable.setDragHandler(0,30, new DragHandlerFactory() {
@@ -245,11 +244,6 @@
                return def;
        }
 
-       private FixedWidthFlexTable createHeaderTable() {
-               FixedWidthFlexTable headerTable = new FixedWidthFlexTable();
-               return headerTable;
-               
-       }
        
        /**
           * @return the newly created data table.
@@ -260,6 +254,10 @@
            return dataTable;
          }
 
+       /**
+        * Create a new List which holds all needed ColumnDefinitions 
+        * 
+        */
        private List<ColumnDefinition<IMAPMessage, ?>> 
createColumnDefinitionList() {
                List<ColumnDefinition<IMAPMessage, ?>> cList = new 
ArrayList<ColumnDefinition<IMAPMessage, ?>>();
 
@@ -281,6 +279,7 @@
                
                AttachmentColumnDefination attachment = new 
AttachmentColumnDefination();
                attachment.setColumnTruncatable(false);
+               // display an image if the message contains an attachment
                attachment.setCellRenderer(new CellRenderer<IMAPMessage, 
Boolean>() {
 
                        public void renderRowValue(IMAPMessage rowValue,
@@ -303,6 +302,7 @@
                
                DateColumnDefination date = new DateColumnDefination();
                date.setColumnTruncatable(true);
+               // set a special renderer for the date
                date.setCellRenderer(new CellRenderer<IMAPMessage, Date>() {
 
                        public void renderRowValue(IMAPMessage rowValue,
@@ -344,14 +344,19 @@
                return cList;
        }
        
+       /**
+        * TableModel which retrieve the messages for the user
+        *
+        */
        private final class IMAPMessageTableModel extends 
MutableTableModel<IMAPMessage> {
 
                @Override
                public void requestRows(
                                final Request request,
                                final 
com.google.gwt.gen2.table.client.TableModel.Callback<IMAPMessage> callback) {
+                       
+                       // if the given user or folder is null, its safe to 
return an empty list
                        if (user == null || folder == null) {
-                               //setRowCount(UNKNOWN_ROW_COUNT);
                                callback.onRowsReady(request, new 
TableModelHelper.Response<IMAPMessage>() {
 
                                        @Override
@@ -365,8 +370,6 @@
                        dispatcher.execute(new 
FetchMessages(user.getSessionId(),folder,request.getStartRow(),request.getNumRows(),searchValue),
 new AsyncCallback<FetchMessagesResult>() {
 
                                public void onFailure(Throwable caught) {
-                                       GWT.log("E=", caught);
-                                       //setRowCount(UNKNOWN_ROW_COUNT);
                                        callback.onFailure(caught);
                                }
 
@@ -404,6 +407,12 @@
                
        }
 
+       
+       /**
+        * ColumnDefination which display if the message contains an attachment
+        * @author Norman
+        *
+        */
        private final class AttachmentColumnDefination extends 
AbstractColumnDefinition<IMAPMessage, Boolean> {
 
                @Override
@@ -416,7 +425,11 @@
                }
                
        }
-       
+
+       /**
+        * ColumnDefination which display the From 
+        *
+        */
        private final class FromColumnDefination extends 
AbstractColumnDefinition<IMAPMessage, String> {
 
                @Override
@@ -431,6 +444,10 @@
                
        }
        
+       /**
+        * ColumnDefination which display the Subject
+        *
+        */
        private final class SubjectColumnDefination extends 
AbstractColumnDefinition<IMAPMessage, String> {
 
                @Override
@@ -446,6 +463,10 @@
                
        }
        
+       /**
+        * ColumnDefination which display the Date
+        * 
+        */
        private final class DateColumnDefination extends 
AbstractColumnDefinition<IMAPMessage, Date> {
 
                @Override
@@ -460,10 +481,18 @@
                
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getDataTableSelection()
+        */
        public HasRowSelectionHandlers getDataTableSelection() {
                return mailTable.getDataTable();
        }
        
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#reloadData(org.apache.hupa.shared.data.User,
 org.apache.hupa.shared.data.IMAPFolder, java.lang.String)
+        */
        public void reloadData(User user, IMAPFolder folder,String searchValue) 
{
                this.user = user;
                this.folder = folder;
@@ -473,6 +502,10 @@
                mailTable.reloadPage();
        }
        
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#reset()
+        */
        public void reset() {
                this.user = null;
                this.folder = null;
@@ -482,54 +515,78 @@
                mailTable.reloadPage();
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getDataTableLoad()
+        */
        public HasPageLoadHandlers getDataTableLoad() {
                return mailTable;
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#addTableListner(com.google.gwt.user.client.ui.TableListener)
+        */
        @SuppressWarnings("deprecation")
        public void addTableListner(TableListener listener) {
                dataTable.addTableListener(listener);
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
net.customware.gwt.presenter.client.widget.WidgetDisplay#asWidget()
+        */
        public Widget asWidget() {
                return this;
        }
 
+       /*
+        * (non-Javadoc)
+        * @see net.customware.gwt.presenter.client.Display#startProcessing()
+        */
        public void startProcessing() {
                // TODO Auto-generated method stub
                
        }
 
+       /*
+        * (non-Javadoc)
+        * @see net.customware.gwt.presenter.client.Display#stopProcessing()
+        */
        public void stopProcessing() {
                // TODO Auto-generated method stub
                
        }
 
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getDeleteClick()
+        */
        public HasClickHandlers getDeleteClick() {
                return deleteMailButton;
        }
 
-       public void removeMessages(ArrayList<Long> uids) {
-               List<Integer> rows = new ArrayList<Integer>();
-               for (int a = 0; a < dataTable.getRowCount(); a++) {
-                       IMAPMessage msg = mailTable.getRowValue(a);
-                       if (uids.contains(msg.getUid())) {
-                               rows.add(a);
-                       }
-               }
-               // remove rows
-               for (int i = 0; i < rows.size(); i++) {
-                       cTableModel.removeRow(rows.get(i) -i);
-               }
-       }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getNewClick()
+        */
        public HasClickHandlers getNewClick() {
                return newMailButton;
        }
        
+       /**
+        * Renderer which fill empty rows with a whitespace 
+        *
+        * @param <E> RowType
+        */
        private final class WhiteSpaceCellRenderer<E> implements 
CellRenderer<E, String> {
 
+               /*
+                * (non-Javadoc)
+                * @see 
com.google.gwt.gen2.table.client.CellRenderer#renderRowValue(java.lang.Object, 
com.google.gwt.gen2.table.client.ColumnDefinition, 
com.google.gwt.gen2.table.client.TableDefinition.AbstractCellView)
+                */
                public void renderRowValue(E rowValue,
                                ColumnDefinition<E, String> columnDef, 
AbstractCellView<E> view) {
                        String cellValue = columnDef.getCellValue(rowValue);
@@ -543,31 +600,75 @@
                
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getData(int)
+        */
        public IMAPMessage getData(int rowIndex) {
                return mailTable.getRowValue(rowIndex);
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getConfirmDialog()
+        */
        public HasDialog getConfirmDialog() {
                return confirmBox;
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getConfirmDialogClick()
+        */
        public HasClickHandlers getConfirmDialogClick() {
                return confirmBox;
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#deselectAllMessages()
+        */
        public void deselectAllMessages() {
                mailTable.getDataTable().deselectAllRows();
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getSelectAllClick()
+        */
        public HasClickHandlers getSelectAllClick() {
                return allLink;
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getSelectNoneClick()
+        */
        public HasClickHandlers getSelectNoneClick() {
                return noneLink;
        }
 
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#selectAllMessages()
+        */
        public void selectAllMessages() {
                mailTable.getDataTable().selectAllRows();
        }
+
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#getSelectedMessages()
+        */
+       public ArrayList<IMAPMessage> getSelectedMessages() {
+               return mailTable.getSelectedRows();
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see 
org.apache.hupa.client.mvp.IMAPMessageListPresenter.Display#removeMessages(java.util.ArrayList)
+        */
+       public void removeMessages(ArrayList<IMAPMessage> messages) {
+               mailTable.removeRows(messages);
+       }
 }

Modified: 
labs/hupa/src/main/java/org/apache/hupa/client/widgets/RefetchPagingScrollTable.java
URL: 
http://svn.apache.org/viewvc/labs/hupa/src/main/java/org/apache/hupa/client/widgets/RefetchPagingScrollTable.java?rev=804086&r1=804085&r2=804086&view=diff
==============================================================================
--- 
labs/hupa/src/main/java/org/apache/hupa/client/widgets/RefetchPagingScrollTable.java
 (original)
+++ 
labs/hupa/src/main/java/org/apache/hupa/client/widgets/RefetchPagingScrollTable.java
 Fri Aug 14 06:06:04 2009
@@ -19,6 +19,7 @@
 
 package org.apache.hupa.client.widgets;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 
@@ -30,8 +31,9 @@
 import com.google.gwt.gen2.table.client.TableModel.Callback;
 import com.google.gwt.gen2.table.client.TableModelHelper.Request;
 import com.google.gwt.gen2.table.client.TableModelHelper.Response;
-import com.google.gwt.gen2.table.event.client.RowRemovalEvent;
-import com.google.gwt.gen2.table.event.client.RowRemovalHandler;
+import com.google.gwt.gen2.table.event.client.RowSelectionEvent;
+import com.google.gwt.gen2.table.event.client.RowSelectionHandler;
+import com.google.gwt.gen2.table.event.client.TableEvent.Row;
 
 /**
  * PagingScrollTable which refetch a row after one is deleted. This ensure 
that always the configured page
@@ -41,26 +43,74 @@
  * @param <RowType>
  */
 public class RefetchPagingScrollTable<RowType> extends 
PagingScrollTable<RowType>{
+       private ArrayList<RowType> selectedRows = new ArrayList<RowType>();
 
        public RefetchPagingScrollTable(MutableTableModel<RowType> tableModel,
                        FixedWidthGrid dataTable, FixedWidthFlexTable 
headerTable,
                        TableDefinition<RowType> tableDefinition) {
                super(tableModel, dataTable, headerTable, tableDefinition);
 
-               tableModel.addRowRemovalHandler(new RowRemovalHandler() {
+               getDataTable().addRowSelectionHandler(new RowSelectionHandler() 
{
 
-                       public void onRowRemoval(RowRemovalEvent event) {
-                               final int rowIndex = event.getRowIndex();
-                               
-                               // remove the row value on deletion
-                               getRowValues().remove(rowIndex);
-                               // request one row
-                               Request r = new 
Request(getAbsoluteLastRowIndex(),1);
+                       public void onRowSelection(RowSelectionEvent event) {
+                               Iterator<Row> rowIndexIt = 
event.getSelectedRows().iterator();
+                               while(rowIndexIt.hasNext()) {
+                                       RowType row = 
getRowValue(rowIndexIt.next().getRowIndex());
+                                       if (selectedRows.contains(row) == 
false) {
+                                               selectedRows.add(row);
+                                       }
+                               }
                                
+                               Iterator<Row> rowDeselectIndexIt = 
event.getDeselectedRows().iterator();
+                               while(rowDeselectIndexIt.hasNext()) {
+                                       RowType row = 
getRowValue(rowDeselectIndexIt.next().getRowIndex());
+                                       selectedRows.remove(row);
+                               }
+                       }
+                       
+               });
+       }
+       
+       /**
+        * Get selected rows
+        * 
+        * @return rows
+        */
+       public ArrayList<RowType> getSelectedRows() {
+               return selectedRows;
+       }
+
+       /**
+        * Remove the given rows from the underlying dataTable 
+        * 
+        * @param rows
+        */
+       @SuppressWarnings("unchecked")
+       public void removeRows(ArrayList<RowType> rows) {
+               ArrayList<Integer> rowsIndex = new ArrayList<Integer>();
+               for (int i = 0; i < rows.size(); i++) {
+                       int rowIndex = getRowValues().indexOf(rows.get(i));
+                       if (rowsIndex.contains(rowIndex) == false) {
+                               rowsIndex.add(rowIndex);
+                       }
+               }
+               // Check if we found any rows to remove
+               if (rowsIndex.isEmpty() == false) {
+                       // remove the row value on deletion
+                       getRowValues().removeAll(rows);
+                       selectedRows.removeAll(rows);
+                       for (int i = 0; i <rowsIndex.size();i++) {
+                               ((MutableTableModel) 
getTableModel()).removeRow(rowsIndex.get(i));
+                       }
+                       
+                       // Check if we need to refetch rows
+                       if (getTableModel().getRowCount() > (getPageCount() * 
getPageSize())) {
+                               // request new rows to fill the table again
+                               Request r = new 
Request(getAbsoluteLastRowIndex(),rowsIndex.size());
                                getTableModel().requestRows(r, new 
Callback<RowType>() {
 
                                        public void onFailure(Throwable caught) 
{
-                                               // Nothing todo
+                                       // Nothing todo
                                        }
 
                                        public void onRowsReady(Request request,
@@ -70,24 +120,23 @@
                                                while (it.hasNext()) {
                                                        
getRowValues().add(it.next());
                                                }
-                                               
                                                // copy the selected rows to 
reset it after reloading the data
                                                Iterator<Integer> selected = 
new HashSet<Integer>(getDataTable().getSelectedRows()).iterator();
-                                               
+                                       
                                                // set the data
                                                
setData(getAbsoluteFirstRowIndex(), getRowValues().iterator());
-                                               
+                                       
                                                // select the rows again
                                                while (selected.hasNext()) {
                                                        
getDataTable().selectRow(selected.next(), false);
-
                                                }
                                        }
-                                       
+                               
                                });
+                       } else {
+                               // redraw the table to eliminate empty rows
+                               redraw();
                        }
-                       
-               });
+               }
        }
-
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to