Subversion Repository Public Repository

litesoft

Diff Revisions 949 vs 950 for /trunk/Java/DATT/src/org/litesoft/datt/client/ui/views/stories/AbstractPrioritizeScreenView.java

Diff revisions: vs.
  @@ -1,369 +1,369 @@
1 - package org.litesoft.datt.client.ui.views.stories;
2 -
3 - import org.litesoft.GWT.client.*;
4 - import org.litesoft.GWT.client.view.*;
5 - import org.litesoft.GWT.client.widgets.Button;
6 - import org.litesoft.GWT.client.widgets.*;
7 - import org.litesoft.GWT.client.widgets.datatables.*;
8 - import org.litesoft.GWT.forms.client.*;
9 - import org.litesoft.bo.views.*;
10 - import org.litesoft.commonfoundation.typeutils.*;
11 - import org.litesoft.core.util.*;
12 - import org.litesoft.datt.client.boviews.*;
13 - import org.litesoft.datt.client.support.*;
14 - import org.litesoft.uispecification.*;
15 -
16 - import com.google.gwt.core.client.*;
17 - import com.google.gwt.event.dom.client.*;
18 - import com.google.gwt.event.logical.shared.*;
19 - import com.google.gwt.user.client.*;
20 - import com.google.gwt.user.client.ui.*;
21 -
22 - import java.util.*;
23 -
24 - public abstract class AbstractPrioritizeScreenView extends ScreenView implements StoryViewNames,
25 - SimpleDataProviderCallBack,
26 - DataAvailableCallBack<StoryView> {
27 - protected final String mWhat;
28 - protected final StoryViewDataProvider mDP = StoryViewDataProvider.getInstance();
29 - protected final ListTableModel<StoryView> mTableModel = new ListTableModel<StoryView>();
30 - protected final CheckBoxSelectRegularTable<StoryView> mTable;
31 - protected final MoveControlPanel mMoveControlPanel;
32 - private Set<StoryView> mSavedSelectedValues = null;
33 -
34 - private Integer mTopRowOffset = null;
35 -
36 - @Override
37 - protected UriFragmentIdParams createRefreshParams() {
38 - return ReprioritizeFactory.encodeParams( mTopRowOffset );
39 - }
40 -
41 - public AbstractPrioritizeScreenView( String pSection, ViewDef pViewDef, String pWhat, boolean pAddUpDown, BoTableDefinition<StoryView> pTableDef,
42 - Integer pTopRowOffset ) {
43 - super( title( pSection, pViewDef ) );
44 -
45 - mTopRowOffset = pTopRowOffset;
46 -
47 - mWhat = pWhat;
48 -
49 - addRight( Button.named( "Refresh" ).blue().text().add( new ClickHandler() {
50 - @Override
51 - public void onClick( ClickEvent event ) {
52 - fetchRows();
53 - }
54 - } ).create() );
55 - addStandardTitleBar();
56 -
57 - addSectionTitle( mWhat );
58 -
59 - mMoveControlPanel = new MoveControlPanel( pAddUpDown );
60 - mTable = new CheckBoxSelectRegularTable<StoryView>( mTableModel, pTableDef, mMoveControlPanel );
61 -
62 - SizeableHorizontalPanel zPanel = new SizeableHorizontalPanel().stretchable();
63 - zPanel.add( mTable );
64 - zPanel.add( mMoveControlPanel );
65 - add( zPanel );
66 - }
67 -
68 - @Override
69 - protected void justLoaded() {
70 - super.justLoaded();
71 - fetchRows();
72 - }
73 -
74 - abstract protected void fetchRows();
75 -
76 - protected FetchRowsDataProviderCallBack<StoryView> createFetchRowsCallBack() {
77 - return new FetchRowsDataProviderCallBack<StoryView>() {
78 - @Override
79 - public void tooMany( long pCount ) {
80 - systemError( "System Error: Should not happen", //
81 - "Found " + pCount + " " + mWhat + ".", //
82 - "This is more than the application is willing to display." );
83 - }
84 -
85 - @Override
86 - public void error( String pError ) {
87 - systemError( "Requesting " + mWhat + " - Errored", //
88 - "", //
89 - "Error: " + pError );
90 - }
91 -
92 - @Override
93 - public void success( ImmutableArrayList<StoryView> pRows ) {
94 - if ( pRows.isEmpty() ) {
95 - backToHome( "Nothing to " + mWhat );
96 - return;
97 - }
98 - mTableModel.clear();
99 - mTableModel.addAll( pRows );
100 - Collections.sort( mTableModel );
101 - mTable.loadData();
102 - mTable.deselectAll();
103 - mMoveControlPanel.handleButtons( reselectAll() );
104 - }
105 -
106 - private Set<StoryView> reselectAll() {
107 - boolean zFound = false;
108 - if ( mSavedSelectedValues != null ) {
109 - for ( StoryView zValue : mSavedSelectedValues ) {
110 - if ( mTable.selectRow( zValue ) ) {
111 - zFound = true;
112 - }
113 - }
114 - mSavedSelectedValues = null;
115 - }
116 - return zFound ? mTable.getSelectedValues() : null;
117 - }
118 - };
119 - }
120 -
121 - @Override
122 - public void error( String pError ) {
123 - if ( Strings.isNotNullOrEmpty( pError ) ) {
124 - systemError( "Requested Prioritizing - Errored", //
125 - "", //
126 - "Error: " + pError );
127 - } else {
128 - fetchRows();
129 - }
130 - }
131 -
132 - @Override
133 - public Widget getBottomBar() {
134 - return null;
135 - }
136 -
137 - protected static class TableDef extends BoTableDefinition<StoryView> implements StoryViewNames,
138 - DataTableStyle {
139 - public TableDef() {
140 - StoryViewMetaData zMD = StoryViewMetaData.getInstance();
141 -
142 - addColumn( zMD.getBoAttribute( aName ) ); // .initialWidth( FontSizer.get( TABLE_TEXT ).EMsPlus( 20, CELL_PADDING ) );
143 - addColumn( zMD.getBoAttribute( aDescriptionThreeLines ),
144 - "Description" ); // .initialWidth( FontSizer.get( TABLE_TEXT ).EMsPlus( 40, CELL_PADDING ) );
145 - }
146 - }
147 -
148 - private class MoveControlPanel extends VerticalPanel implements SelectionHandler<StoryView> {
149 - private final Button mBetweenButton, mUpButton, mDownButton;
150 - private final List<GroupMover> mGroupMovers = new ArrayList<GroupMover>();
151 -
152 - private MoveControlPanel( boolean pAddUpDown ) {
153 - mBetweenButton = Button.named( "Between" ).blue().text( "To There" ).add( new ClickHandler() {
154 - @Override
155 - public void onClick( ClickEvent event ) {
156 - reprioritizeBetween();
157 - }
158 - } ).create().disable();
159 - mUpButton = Button.named( "Up" ).blue().text().add( new ClickHandler() {
160 - @Override
161 - public void onClick( ClickEvent event ) {
162 - reprioritizeUp();
163 - }
164 - } ).create().disable();
165 - mDownButton = Button.named( "Down" ).blue().text().add( new ClickHandler() {
166 - @Override
167 - public void onClick( ClickEvent event ) {
168 - reprioritizeDown();
169 - }
170 - } ).create().disable();
171 -
172 - setHorizontalAlignment( VerticalPanel.ALIGN_CENTER );
173 - add( new Label( "Move..." ) );
174 - add( new Spacer( 20 ) );
175 - add( mBetweenButton );
176 - add( new Spacer( 20 ) );
177 - PriorityGroup[] zGroups = PriorityGroup.values();
178 - for ( int i = zGroups.length; --i >= 0; ) {
179 - PriorityGroup zGroup = zGroups[i];
180 - if ( PriorityGroup.Initial != zGroup ) {
181 - GroupMover zMover = new GroupMover( zGroup );
182 - mGroupMovers.add( zMover );
183 - add( zMover.getButton() );
184 - }
185 - }
186 - add( new Spacer( 20 ) );
187 - if ( pAddUpDown ) {
188 - add( mUpButton );
189 - add( mDownButton );
190 - }
191 - }
192 -
193 - @Override
194 - protected void onAttach() {
195 - super.onAttach();
196 - sameSizeButtons();
197 - }
198 -
199 - private void sameSizeButtons() {
200 - if ( isAttached() ) {
201 - Integer zMaxWidth = getMaxControlButtonWidth();
202 - if ( zMaxWidth != null ) {
203 - setControlButtonSameWidth( zMaxWidth );
204 - return;
205 - }
206 - }
207 - Scheduler.get().scheduleDeferred( new Command() {
208 - @Override
209 - public void execute() {
210 - sameSizeButtons();
211 - }
212 - } );
213 - }
214 -
215 - private Integer getMaxControlButtonWidth() {
216 - int zMaxWidth = mBetweenButton.getOffsetWidth();
217 - for ( Widget zWidget : getChildren() ) {
218 - if ( zWidget instanceof Button ) {
219 - zMaxWidth = Math.max( zMaxWidth, zWidget.getOffsetWidth() );
220 - }
221 - }
222 - return (zMaxWidth > 30) ? zMaxWidth : null;
223 - }
224 -
225 - private void setControlButtonSameWidth( int pWidth ) {
226 - String zWidth = "" + pWidth;
227 - for ( Widget zWidget : getChildren() ) {
228 - if ( zWidget instanceof Button ) {
229 - zWidget.setWidth( zWidth );
230 - }
231 - }
232 - }
233 -
234 - @Override
235 - public void onSelection( SelectionEvent<StoryView> event ) {
236 - handleButtons( mTable.getSelectedValues() );
237 - }
238 -
239 - private void handleButtons( Set<StoryView> pSelectedValues ) {
240 - boolean zAnySelected = (pSelectedValues != null) && !pSelectedValues.isEmpty();
241 - mBetweenButton.setEnabled( zAnySelected && betweenable( pSelectedValues ) );
242 - mUpButton.setEnabled( zAnySelected && upable( pSelectedValues ) );
243 - mDownButton.setEnabled( zAnySelected && downable( pSelectedValues ) );
244 - for ( GroupMover zMover : mGroupMovers ) {
245 - zMover.setEnable( zAnySelected, pSelectedValues );
246 - }
247 - }
248 - }
249 -
250 - private class GroupMover implements ClickHandler {
251 - private PriorityGroup mGroup;
252 - private Button mButton;
253 -
254 - private GroupMover( PriorityGroup pGroup ) {
255 - mGroup = pGroup;
256 - mButton = Button.named( mGroup.name() ).blue().text().add( this ).create().disable();
257 - }
258 -
259 - public Button getButton() {
260 - return mButton;
261 - }
262 -
263 - @Override
264 - public void onClick( ClickEvent event ) {
265 - reprioritizeToGroup( mGroup );
266 - }
267 -
268 - public void setEnable( boolean pAnySelected, Set<StoryView> pSelectedValues ) {
269 - mButton.setEnabled( pAnySelected && applicable( pSelectedValues ) );
270 - }
271 -
272 - private boolean applicable( Set<StoryView> pSelectedValues ) {
273 - for ( StoryView zStoryView : pSelectedValues ) {
274 - if ( mGroup != PriorityGroup.from( zStoryView.getPriority() ) ) {
275 - return true;
276 - }
277 - }
278 - return false;
279 - }
280 - }
281 -
282 - abstract protected boolean betweenable( Set<StoryView> pSelectedValues );
283 -
284 - protected boolean upable( Set<StoryView> pSelectedValues ) {
285 - return !isAtEdge( pSelectedValues, 0 );
286 - }
287 -
288 - protected boolean downable( Set<StoryView> pSelectedValues ) {
289 - return !isAtEdge( pSelectedValues, mTableModel.size() - 1 );
290 - }
291 -
292 - protected boolean isAtEdge( Set<StoryView> pSelectedValues, int pEdge ) {
293 - for ( StoryView zStoryView : pSelectedValues ) {
294 - if ( mTableModel.indexOf( zStoryView ) == pEdge ) {
295 - return true;
296 - }
297 - }
298 - return false;
299 - }
300 -
301 - private void reprioritizeUp() {
302 - int zMin = mTableModel.size();
303 - for ( StoryView zStoryView : mTable.getSelectedValues() ) {
304 - zMin = Math.min( zMin, mTableModel.indexOf( zStoryView ) );
305 - }
306 - if ( zMin != mTableModel.size() ) {
307 - reprioritizeBetween( mSavedSelectedValues = mTable.getSelectedValues(), getStoryView( zMin - 1 ), getStoryView( zMin - 2 ) );
308 - }
309 - }
310 -
311 - private void reprioritizeDown() {
312 - int zMax = -1;
313 - for ( StoryView zStoryView : mTable.getSelectedValues() ) {
314 - zMax = Math.max( zMax, mTableModel.indexOf( zStoryView ) );
315 - }
316 - if ( zMax != -1 ) {
317 - reprioritizeBetween( mSavedSelectedValues = mTable.getSelectedValues(), getStoryView( zMax + 2 ), getStoryView( zMax + 1 ) );
318 - }
319 - }
320 -
321 - private void reprioritizeBetween( StoryView pLowerBound, StoryView pUpperBound ) {
322 - reprioritizeBetween( mTable.getSelectedValues(), pLowerBound, pUpperBound );
323 - }
324 -
325 - private void reprioritizeBetween( Set<StoryView> pSelectedValues, StoryView pLowerBound, StoryView pUpperBound ) {
326 - mDP.reprioritizeBetween( pLowerBound, pUpperBound, pSelectedValues, this );
327 - }
328 -
329 - private void reprioritizeToGroup( PriorityGroup pGroup ) {
330 - mDP.reprioritizeToGroup( pGroup, mTable.getSelectedValues(), this );
331 - }
332 -
333 - private StoryView getStoryView( int pIndex ) {
334 - return ((0 <= pIndex) && (pIndex < mTableModel.size())) ? mTableModel.get( pIndex ) : null;
335 - }
336 -
337 - abstract protected void fetchTargetBetweenRows( final DataAvailableCallBack<StoryView> pCallBack );
338 -
339 - private void reprioritizeBetween() {
340 - fetchTargetBetweenRows( this );
341 - }
342 -
343 - @Override
344 - public void dataAvailable( List<StoryView> pData ) // called when we can proceed with the InjectionPointSelector
345 - {
346 - if ( pData.isEmpty() ) {
347 - error( "There are Nothing but " + PriorityGroup.Initial + " priority Stories" );
348 - return;
349 - }
350 - Set<StoryView> zSelectedRows = mTable.getSelectedValues();
351 - List<StoryView> zNonSelectedRows = new ArrayList<StoryView>( pData.size() );
352 - for ( StoryView zStoryView : pData ) {
353 - if ( !zSelectedRows.contains( zStoryView ) ) {
354 - zNonSelectedRows.add( zStoryView );
355 - }
356 - }
357 - if ( zNonSelectedRows.isEmpty() ) {
358 - error( "At least one Story must not be selected" );
359 - return;
360 - }
361 - new InjectionPointSelectionDialog<StoryView>( "Select 'There' to Move Selected Rows", 4, zNonSelectedRows,
362 - new InjectionPointSelector.Callback<StoryView>() {
363 - @Override
364 - public void injectBetween( StoryView pLowerBound, StoryView pUpperBound ) {
365 - reprioritizeBetween( pLowerBound, pUpperBound );
366 - }
367 - } ).show();
368 - }
369 - }
1 + package org.litesoft.datt.client.ui.views.stories;
2 +
3 + import org.litesoft.GWT.client.*;
4 + import org.litesoft.GWT.client.view.*;
5 + import org.litesoft.GWT.client.widgets.Button;
6 + import org.litesoft.GWT.client.widgets.*;
7 + import org.litesoft.GWT.client.widgets.datatables.*;
8 + import org.litesoft.GWT.forms.client.*;
9 + import org.litesoft.bo.views.*;
10 + import org.litesoft.commonfoundation.base.*;
11 + import org.litesoft.core.util.*;
12 + import org.litesoft.datt.client.boviews.*;
13 + import org.litesoft.datt.client.support.*;
14 + import org.litesoft.uispecification.*;
15 +
16 + import com.google.gwt.core.client.*;
17 + import com.google.gwt.event.dom.client.*;
18 + import com.google.gwt.event.logical.shared.*;
19 + import com.google.gwt.user.client.*;
20 + import com.google.gwt.user.client.ui.*;
21 +
22 + import java.util.*;
23 +
24 + public abstract class AbstractPrioritizeScreenView extends ScreenView implements StoryViewNames,
25 + SimpleDataProviderCallBack,
26 + DataAvailableCallBack<StoryView> {
27 + protected final String mWhat;
28 + protected final StoryViewDataProvider mDP = StoryViewDataProvider.getInstance();
29 + protected final ListTableModel<StoryView> mTableModel = new ListTableModel<StoryView>();
30 + protected final CheckBoxSelectRegularTable<StoryView> mTable;
31 + protected final MoveControlPanel mMoveControlPanel;
32 + private Set<StoryView> mSavedSelectedValues = null;
33 +
34 + private Integer mTopRowOffset = null;
35 +
36 + @Override
37 + protected UriFragmentIdParams createRefreshParams() {
38 + return ReprioritizeFactory.encodeParams( mTopRowOffset );
39 + }
40 +
41 + public AbstractPrioritizeScreenView( String pSection, ViewDef pViewDef, String pWhat, boolean pAddUpDown, BoTableDefinition<StoryView> pTableDef,
42 + Integer pTopRowOffset ) {
43 + super( title( pSection, pViewDef ) );
44 +
45 + mTopRowOffset = pTopRowOffset;
46 +
47 + mWhat = pWhat;
48 +
49 + addRight( Button.named( "Refresh" ).blue().text().add( new ClickHandler() {
50 + @Override
51 + public void onClick( ClickEvent event ) {
52 + fetchRows();
53 + }
54 + } ).create() );
55 + addStandardTitleBar();
56 +
57 + addSectionTitle( mWhat );
58 +
59 + mMoveControlPanel = new MoveControlPanel( pAddUpDown );
60 + mTable = new CheckBoxSelectRegularTable<StoryView>( mTableModel, pTableDef, mMoveControlPanel );
61 +
62 + SizeableHorizontalPanel zPanel = new SizeableHorizontalPanel().stretchable();
63 + zPanel.add( mTable );
64 + zPanel.add( mMoveControlPanel );
65 + add( zPanel );
66 + }
67 +
68 + @Override
69 + protected void justLoaded() {
70 + super.justLoaded();
71 + fetchRows();
72 + }
73 +
74 + abstract protected void fetchRows();
75 +
76 + protected FetchRowsDataProviderCallBack<StoryView> createFetchRowsCallBack() {
77 + return new FetchRowsDataProviderCallBack<StoryView>() {
78 + @Override
79 + public void tooMany( long pCount ) {
80 + systemError( "System Error: Should not happen", //
81 + "Found " + pCount + " " + mWhat + ".", //
82 + "This is more than the application is willing to display." );
83 + }
84 +
85 + @Override
86 + public void error( String pError ) {
87 + systemError( "Requesting " + mWhat + " - Errored", //
88 + "", //
89 + "Error: " + pError );
90 + }
91 +
92 + @Override
93 + public void success( ImmutableArrayList<StoryView> pRows ) {
94 + if ( pRows.isEmpty() ) {
95 + backToHome( "Nothing to " + mWhat );
96 + return;
97 + }
98 + mTableModel.clear();
99 + mTableModel.addAll( pRows );
100 + Collections.sort( mTableModel );
101 + mTable.loadData();
102 + mTable.deselectAll();
103 + mMoveControlPanel.handleButtons( reselectAll() );
104 + }
105 +
106 + private Set<StoryView> reselectAll() {
107 + boolean zFound = false;
108 + if ( mSavedSelectedValues != null ) {
109 + for ( StoryView zValue : mSavedSelectedValues ) {
110 + if ( mTable.selectRow( zValue ) ) {
111 + zFound = true;
112 + }
113 + }
114 + mSavedSelectedValues = null;
115 + }
116 + return zFound ? mTable.getSelectedValues() : null;
117 + }
118 + };
119 + }
120 +
121 + @Override
122 + public void error( String pError ) {
123 + if ( Currently.isNotNullOrEmpty( pError ) ) {
124 + systemError( "Requested Prioritizing - Errored", //
125 + "", //
126 + "Error: " + pError );
127 + } else {
128 + fetchRows();
129 + }
130 + }
131 +
132 + @Override
133 + public Widget getBottomBar() {
134 + return null;
135 + }
136 +
137 + protected static class TableDef extends BoTableDefinition<StoryView> implements StoryViewNames,
138 + DataTableStyle {
139 + public TableDef() {
140 + StoryViewMetaData zMD = StoryViewMetaData.getInstance();
141 +
142 + addColumn( zMD.getBoAttribute( aName ) ); // .initialWidth( FontSizer.get( TABLE_TEXT ).EMsPlus( 20, CELL_PADDING ) );
143 + addColumn( zMD.getBoAttribute( aDescriptionThreeLines ),
144 + "Description" ); // .initialWidth( FontSizer.get( TABLE_TEXT ).EMsPlus( 40, CELL_PADDING ) );
145 + }
146 + }
147 +
148 + private class MoveControlPanel extends VerticalPanel implements SelectionHandler<StoryView> {
149 + private final Button mBetweenButton, mUpButton, mDownButton;
150 + private final List<GroupMover> mGroupMovers = new ArrayList<GroupMover>();
151 +
152 + private MoveControlPanel( boolean pAddUpDown ) {
153 + mBetweenButton = Button.named( "Between" ).blue().text( "To There" ).add( new ClickHandler() {
154 + @Override
155 + public void onClick( ClickEvent event ) {
156 + reprioritizeBetween();
157 + }
158 + } ).create().disable();
159 + mUpButton = Button.named( "Up" ).blue().text().add( new ClickHandler() {
160 + @Override
161 + public void onClick( ClickEvent event ) {
162 + reprioritizeUp();
163 + }
164 + } ).create().disable();
165 + mDownButton = Button.named( "Down" ).blue().text().add( new ClickHandler() {
166 + @Override
167 + public void onClick( ClickEvent event ) {
168 + reprioritizeDown();
169 + }
170 + } ).create().disable();
171 +
172 + setHorizontalAlignment( VerticalPanel.ALIGN_CENTER );
173 + add( new Label( "Move..." ) );
174 + add( new Spacer( 20 ) );
175 + add( mBetweenButton );
176 + add( new Spacer( 20 ) );
177 + PriorityGroup[] zGroups = PriorityGroup.values();
178 + for ( int i = zGroups.length; --i >= 0; ) {
179 + PriorityGroup zGroup = zGroups[i];
180 + if ( PriorityGroup.Initial != zGroup ) {
181 + GroupMover zMover = new GroupMover( zGroup );
182 + mGroupMovers.add( zMover );
183 + add( zMover.getButton() );
184 + }
185 + }
186 + add( new Spacer( 20 ) );
187 + if ( pAddUpDown ) {
188 + add( mUpButton );
189 + add( mDownButton );
190 + }
191 + }
192 +
193 + @Override
194 + protected void onAttach() {
195 + super.onAttach();
196 + sameSizeButtons();
197 + }
198 +
199 + private void sameSizeButtons() {
200 + if ( isAttached() ) {
201 + Integer zMaxWidth = getMaxControlButtonWidth();
202 + if ( zMaxWidth != null ) {
203 + setControlButtonSameWidth( zMaxWidth );
204 + return;
205 + }
206 + }
207 + Scheduler.get().scheduleDeferred( new Command() {
208 + @Override
209 + public void execute() {
210 + sameSizeButtons();
211 + }
212 + } );
213 + }
214 +
215 + private Integer getMaxControlButtonWidth() {
216 + int zMaxWidth = mBetweenButton.getOffsetWidth();
217 + for ( Widget zWidget : getChildren() ) {
218 + if ( zWidget instanceof Button ) {
219 + zMaxWidth = Math.max( zMaxWidth, zWidget.getOffsetWidth() );
220 + }
221 + }
222 + return (zMaxWidth > 30) ? zMaxWidth : null;
223 + }
224 +
225 + private void setControlButtonSameWidth( int pWidth ) {
226 + String zWidth = "" + pWidth;
227 + for ( Widget zWidget : getChildren() ) {
228 + if ( zWidget instanceof Button ) {
229 + zWidget.setWidth( zWidth );
230 + }
231 + }
232 + }
233 +
234 + @Override
235 + public void onSelection( SelectionEvent<StoryView> event ) {
236 + handleButtons( mTable.getSelectedValues() );
237 + }
238 +
239 + private void handleButtons( Set<StoryView> pSelectedValues ) {
240 + boolean zAnySelected = (pSelectedValues != null) && !pSelectedValues.isEmpty();
241 + mBetweenButton.setEnabled( zAnySelected && betweenable( pSelectedValues ) );
242 + mUpButton.setEnabled( zAnySelected && upable( pSelectedValues ) );
243 + mDownButton.setEnabled( zAnySelected && downable( pSelectedValues ) );
244 + for ( GroupMover zMover : mGroupMovers ) {
245 + zMover.setEnable( zAnySelected, pSelectedValues );
246 + }
247 + }
248 + }
249 +
250 + private class GroupMover implements ClickHandler {
251 + private PriorityGroup mGroup;
252 + private Button mButton;
253 +
254 + private GroupMover( PriorityGroup pGroup ) {
255 + mGroup = pGroup;
256 + mButton = Button.named( mGroup.name() ).blue().text().add( this ).create().disable();
257 + }
258 +
259 + public Button getButton() {
260 + return mButton;
261 + }
262 +
263 + @Override
264 + public void onClick( ClickEvent event ) {
265 + reprioritizeToGroup( mGroup );
266 + }
267 +
268 + public void setEnable( boolean pAnySelected, Set<StoryView> pSelectedValues ) {
269 + mButton.setEnabled( pAnySelected && applicable( pSelectedValues ) );
270 + }
271 +
272 + private boolean applicable( Set<StoryView> pSelectedValues ) {
273 + for ( StoryView zStoryView : pSelectedValues ) {
274 + if ( mGroup != PriorityGroup.from( zStoryView.getPriority() ) ) {
275 + return true;
276 + }
277 + }
278 + return false;
279 + }
280 + }
281 +
282 + abstract protected boolean betweenable( Set<StoryView> pSelectedValues );
283 +
284 + protected boolean upable( Set<StoryView> pSelectedValues ) {
285 + return !isAtEdge( pSelectedValues, 0 );
286 + }
287 +
288 + protected boolean downable( Set<StoryView> pSelectedValues ) {
289 + return !isAtEdge( pSelectedValues, mTableModel.size() - 1 );
290 + }
291 +
292 + protected boolean isAtEdge( Set<StoryView> pSelectedValues, int pEdge ) {
293 + for ( StoryView zStoryView : pSelectedValues ) {
294 + if ( mTableModel.indexOf( zStoryView ) == pEdge ) {
295 + return true;
296 + }
297 + }
298 + return false;
299 + }
300 +
301 + private void reprioritizeUp() {
302 + int zMin = mTableModel.size();
303 + for ( StoryView zStoryView : mTable.getSelectedValues() ) {
304 + zMin = Math.min( zMin, mTableModel.indexOf( zStoryView ) );
305 + }
306 + if ( zMin != mTableModel.size() ) {
307 + reprioritizeBetween( mSavedSelectedValues = mTable.getSelectedValues(), getStoryView( zMin - 1 ), getStoryView( zMin - 2 ) );
308 + }
309 + }
310 +
311 + private void reprioritizeDown() {
312 + int zMax = -1;
313 + for ( StoryView zStoryView : mTable.getSelectedValues() ) {
314 + zMax = Math.max( zMax, mTableModel.indexOf( zStoryView ) );
315 + }
316 + if ( zMax != -1 ) {
317 + reprioritizeBetween( mSavedSelectedValues = mTable.getSelectedValues(), getStoryView( zMax + 2 ), getStoryView( zMax + 1 ) );
318 + }
319 + }
320 +
321 + private void reprioritizeBetween( StoryView pLowerBound, StoryView pUpperBound ) {
322 + reprioritizeBetween( mTable.getSelectedValues(), pLowerBound, pUpperBound );
323 + }
324 +
325 + private void reprioritizeBetween( Set<StoryView> pSelectedValues, StoryView pLowerBound, StoryView pUpperBound ) {
326 + mDP.reprioritizeBetween( pLowerBound, pUpperBound, pSelectedValues, this );
327 + }
328 +
329 + private void reprioritizeToGroup( PriorityGroup pGroup ) {
330 + mDP.reprioritizeToGroup( pGroup, mTable.getSelectedValues(), this );
331 + }
332 +
333 + private StoryView getStoryView( int pIndex ) {
334 + return ((0 <= pIndex) && (pIndex < mTableModel.size())) ? mTableModel.get( pIndex ) : null;
335 + }
336 +
337 + abstract protected void fetchTargetBetweenRows( final DataAvailableCallBack<StoryView> pCallBack );
338 +
339 + private void reprioritizeBetween() {
340 + fetchTargetBetweenRows( this );
341 + }
342 +
343 + @Override
344 + public void dataAvailable( List<StoryView> pData ) // called when we can proceed with the InjectionPointSelector
345 + {
346 + if ( pData.isEmpty() ) {
347 + error( "There are Nothing but " + PriorityGroup.Initial + " priority Stories" );
348 + return;
349 + }
350 + Set<StoryView> zSelectedRows = mTable.getSelectedValues();
351 + List<StoryView> zNonSelectedRows = new ArrayList<StoryView>( pData.size() );
352 + for ( StoryView zStoryView : pData ) {
353 + if ( !zSelectedRows.contains( zStoryView ) ) {
354 + zNonSelectedRows.add( zStoryView );
355 + }
356 + }
357 + if ( zNonSelectedRows.isEmpty() ) {
358 + error( "At least one Story must not be selected" );
359 + return;
360 + }
361 + new InjectionPointSelectionDialog<StoryView>( "Select 'There' to Move Selected Rows", 4, zNonSelectedRows,
362 + new InjectionPointSelector.Callback<StoryView>() {
363 + @Override
364 + public void injectBetween( StoryView pLowerBound, StoryView pUpperBound ) {
365 + reprioritizeBetween( pLowerBound, pUpperBound );
366 + }
367 + } ).show();
368 + }
369 + }