fix.diff
src/com/goldencode/p2j/ui/BaseEntity.java 2022-05-06 20:47:54 +0000 | ||
---|---|---|
1799 | 1803 |
* Value of the attribute. |
1800 | 1804 |
*/ |
1801 | 1805 |
@Override |
1802 |
public void setTabStop(boolean value) |
|
1806 |
public void setTabStop(final boolean value)
|
|
1803 | 1807 |
{ |
1804 | 1808 |
if (config.tabStop == value) |
1805 | 1809 |
{ |
1806 | 1810 |
return; |
1807 | 1811 |
} |
1808 | 1812 |
|
1809 |
boolean oldValue = config.tabStop; |
|
1810 |
|
|
1811 | 1813 |
config.tabStop = value; |
1812 | 1814 |
|
1813 |
if (this.group instanceof FieldGroup)
|
|
1815 |
if (group instanceof FieldGroup) |
|
1814 | 1816 |
{ |
1815 |
FieldGroup fg = (FieldGroup) this.group; |
|
1816 |
// add widget to the end of NEXT-TAB-ITEM list iff the widget is not in this list |
|
1817 |
if (value) |
|
1818 |
{ |
|
1819 |
fg.updateTabItemsOnTabStop(this, !oldValue); |
|
1820 |
} |
|
1821 |
|
|
1822 |
GenericFrame ownerFrame = fg.getFrame(); |
|
1823 |
|
|
1824 |
if (_isRealized() && ownerFrame != null && ownerFrame.getFrameWidget()._isRealized()) |
|
1825 |
{ |
|
1826 |
LogicalTerminal.updateTabItemList(fg); |
|
1827 |
} |
|
1817 |
((FieldGroup) this.group).updateTabStopForWidget(this, value); |
|
1828 | 1818 |
} |
1829 | 1819 | |
1830 | 1820 |
pushWidgetAttr("tabStop", config.tabStop); |
src/com/goldencode/p2j/ui/FieldGroup.java 2022-05-06 20:09:33 +0000 | ||
---|---|---|
158 | 158 |
*/ |
159 | 159 |
private Consumer<GenericWidget<?>> widgetAdder = null; |
160 | 160 |
|
161 |
/** The first tab item */ |
|
162 |
private GenericWidget<?> firstTabItem; |
|
163 |
|
|
164 |
/** The last tab item */ |
|
165 |
private GenericWidget<?> lastTabItem; |
|
166 |
|
|
167 |
/** Tab item list */ |
|
168 |
private List<GenericWidget<?>> tabItems; |
|
161 |
/** The list of widgets in this field group with the TAP-STOP attribute value set */ |
|
162 |
private final List<GenericWidget<?>> tabItems = new LinkedList<GenericWidget<?>>(); |
|
163 | ||
169 | 164 |
|
170 | 165 |
/** |
171 | 166 |
* Creates an instance to groups related widgets in a frame. |
... | ... | |
191 | 186 |
*/ |
192 | 187 |
public void setWidgets(List<GenericWidget<?>> widgets) |
193 | 188 |
{ |
194 |
this.widgets = widgets; |
|
195 |
this.tabItems = new LinkedList<GenericWidget<?>>(); |
|
196 |
if (widgets != null) |
|
189 |
this.widgets = widgets; |
|
190 | ||
191 |
resetTabItems(); |
|
192 | ||
193 |
for (GenericWidget<?> next : widgets) |
|
197 | 194 |
{ |
198 |
for (GenericWidget<?> next : widgets)
|
|
195 |
if (next instanceof BaseEntity)
|
|
199 | 196 |
{ |
200 |
this.tabItems.add(next); |
|
201 |
if (next instanceof BaseEntity) |
|
202 |
{ |
|
203 |
BaseEntity<?> be = (BaseEntity<?>) next; |
|
204 |
be.setGroup(this); |
|
205 |
} |
|
197 |
((BaseEntity<?>) next).setGroup(this); |
|
206 | 198 |
} |
207 | 199 |
} |
208 | 200 |
|
201 |
} |
|
202 | ||
203 |
/** |
|
204 |
* Re-calculate tab items from current widget list and widget TAB-STOP attribute value. |
|
205 |
* Reset previous changes made with TAB-INDEX setter if any. |
|
206 |
*/ |
|
207 |
final void resetTabItems() |
|
208 |
{ |
|
209 |
tabItems.clear(); |
|
210 |
for (GenericWidget<?> w : widgets) |
|
211 |
{ |
|
212 |
if (w.isTabStop().booleanValue()) |
|
213 |
{ |
|
214 |
assert !tabItems.contains(w); |
|
215 |
tabItems.add(w); |
|
216 |
} |
|
217 |
} |
|
209 | 218 |
} |
210 | 219 |
|
211 | 220 |
/** |
... | ... | |
318 | 330 |
BaseEntity<?> be = (BaseEntity<?>) widget; |
319 | 331 |
be.setGroup(null); |
320 | 332 |
} |
321 |
this.tabItems.remove(widget); |
|
322 |
this.firstTabItem = null; |
|
323 |
this.lastTabItem = null; |
|
333 |
tabItems.remove(widget); |
|
334 |
assert !tabItems.contains(widget); |
|
324 | 335 |
|
325 | 336 |
frame.removeWidget(widget); |
326 | 337 |
} |
... | ... | |
331 | 342 |
* @param widget |
332 | 343 |
* The widget to be added to this field group. |
333 | 344 |
*/ |
345 |
@Override |
|
334 | 346 |
public void addWidget(GenericWidget<?> widget) |
335 | 347 |
{ |
336 |
this.widgets.remove(widget);
|
|
337 |
this.widgets.add(widget);
|
|
348 |
widgets.remove(widget); |
|
349 |
widgets.add(widget); |
|
338 | 350 |
|
339 | 351 |
Utils.normalizeZOrder(widgets, w -> { return w.getZOrderClass(); }); |
340 | 352 |
|
... | ... | |
350 | 362 |
be.setGroup(this); |
351 | 363 |
} |
352 | 364 |
} |
353 |
|
|
365 |
|
|
354 | 366 |
/** |
355 |
* Adds a new tab item to the end of the tab item list if the target widget is not in this list
|
|
367 |
* Adds a new tab-stoppable widget to the end of the tab item list if the target widget is not in this list
|
|
356 | 368 |
* and notifies the client about the changes. The widget can be added during addWidget calls. |
357 | 369 |
* |
358 | 370 |
* @param widget |
359 |
* The widget to be added to the tab item list. |
|
371 |
* The widget to be added to the tab item list with the attribute TAB-STOP set. |
|
372 |
* It is assumed the widget was not in the list before this call. |
|
360 | 373 |
*/ |
361 |
public void addNewTabItem(GenericWidget<?> widget)
|
|
374 |
final void addNewTabItem(GenericWidget<?> widget)
|
|
362 | 375 |
{ |
363 |
if (!widget.isTabWidget()) |
|
364 |
{ |
|
365 |
return; |
|
366 |
} |
|
367 | ||
368 |
// add widget to the tab item list |
|
369 |
if (!this.tabItems.contains(widget)) |
|
370 |
{ |
|
371 |
this.tabItems.add(widget); |
|
372 |
} |
|
373 | ||
376 |
assert !tabItems.contains(widget); |
|
377 |
|
|
378 |
tabItems.add(widget); |
|
374 | 379 |
LogicalTerminal.updateTabItemList(this); |
375 | 380 |
} |
376 | 381 |
|
377 | 382 |
/** |
383 |
* Update tab stop list when the widget TAB-STOP attribute changes. |
|
384 |
* |
|
385 |
* @param widget |
|
386 |
* the widget whose TAB-STOP attribute might changed |
|
387 |
* @param isTabStop |
|
388 |
* the widget TAB-STOP value |
|
389 |
*/ |
|
390 |
final void updateTabStopForWidget(final GenericWidget<?> widget, boolean isTabStop) |
|
391 |
{ |
|
392 |
if (isTabStop) |
|
393 |
{ |
|
394 |
// assure the widget is in the list, if missing, |
|
395 |
// append to the end of the list |
|
396 |
if (tabItems.contains(widget)) |
|
397 |
{ |
|
398 |
return; |
|
399 |
} |
|
400 |
|
|
401 |
tabItems.add(widget); |
|
402 |
} |
|
403 |
else |
|
404 |
{ |
|
405 |
if (!tabItems.remove(widget)) |
|
406 |
{ |
|
407 |
return; |
|
408 |
} |
|
409 |
|
|
410 |
assert !tabItems.contains(widget); |
|
411 |
} |
|
412 | ||
413 |
final GenericFrame ownerFrame = getFrame(); |
|
414 |
if (_isRealized() && ownerFrame != null && ownerFrame.getFrameWidget()._isRealized()) |
|
415 |
{ |
|
416 |
LogicalTerminal.updateTabItemList(this); |
|
417 |
} |
|
418 |
} |
|
419 |
|
|
420 |
/** |
|
378 | 421 |
* Removes the target widget from the tab item list and add it to the end of the tab item list. |
379 | 422 |
* |
380 | 423 |
* @param widget |
... | ... | |
382 | 425 |
*/ |
383 | 426 |
private void moveTabItemToEnd(GenericWidget<?> widget) |
384 | 427 |
{ |
385 |
moveTabItem(widget, () -> -1);
|
|
428 |
moveTabItem(widget, tabItems.size() - 1);
|
|
386 | 429 |
} |
387 | 430 |
|
388 | 431 |
/** |
389 |
* Removes the target widget from the tab item list, add it at the top of the tab item |
|
390 |
* list at the given position and shifts the other tab items below this target widget. |
|
391 |
* |
|
392 |
* @param widget |
|
393 |
* The target widget |
|
394 |
* @param pos |
|
395 |
* The position to place new widget. |
|
396 |
*/ |
|
397 |
private void moveTabItemAtTop(GenericWidget<?> widget, int pos) |
|
398 |
{ |
|
399 |
moveTabItem(widget, () -> pos); |
|
400 |
} |
|
401 | ||
402 |
/** |
|
403 | 432 |
* Places the given widget in the current tab item list. |
404 | 433 |
* |
405 | 434 |
* @param widget |
... | ... | |
411 | 440 |
*/ |
412 | 441 |
private void placeWidgetInTabList(GenericWidget<?> widget, UpdatesOp op, int pos) |
413 | 442 |
{ |
414 |
if (widget != null) |
|
415 |
{ |
|
416 |
switch(op) |
|
417 |
{ |
|
418 |
case UPDATE: |
|
419 |
case PROMPT_FOR: |
|
420 |
case SET: |
|
421 |
moveTabItemAtTop(widget, pos); |
|
422 |
break; |
|
423 |
case ENABLE: |
|
424 |
default: |
|
425 |
moveTabItemToEnd(widget); |
|
426 |
} |
|
427 |
} |
|
428 |
} |
|
429 | ||
430 |
/** |
|
431 |
* Updates tab items on tab stop. |
|
432 |
* |
|
433 |
* @param widget |
|
434 |
* The given widget |
|
435 |
* @param addToEnd |
|
436 |
* The true value indicates that the given widget is placed at the end of the tab |
|
437 |
* item list, otherwise its tab position is not changed. |
|
438 |
*/ |
|
439 |
public void updateTabItemsOnTabStop(GenericWidget<?> widget, boolean addToEnd) |
|
440 |
{ |
|
441 |
if (addToEnd) |
|
442 |
{ |
|
443 |
moveTabItemToEnd(widget); |
|
444 |
} |
|
445 |
updateExtremeTabItems(); |
|
446 |
} |
|
447 | ||
448 |
/** |
|
449 |
* Move the target widget after the provided widget in this field-group. |
|
450 |
* |
|
451 |
* @param widget |
|
452 |
* The target widget to be moved. |
|
453 |
* @param after |
|
454 |
* The provided widget. |
|
455 |
*/ |
|
456 |
public void moveWidgetAfter(GenericWidget<?> widget, GenericWidget<?> after) |
|
457 |
{ |
|
458 |
if (!tabItems.contains(widget) || !tabItems.contains(after)) |
|
459 |
{ |
|
460 |
throw new RuntimeException("The widgets must be in specified field-group"); |
|
461 |
} |
|
462 |
|
|
463 |
setTabItemAfter(widget, after); |
|
464 |
} |
|
465 |
|
|
443 |
switch (op) |
|
444 |
{ |
|
445 |
case UPDATE: |
|
446 |
case PROMPT_FOR: |
|
447 |
case SET: |
|
448 |
moveTabItem(widget, pos); |
|
449 |
break; |
|
450 |
case ENABLE: |
|
451 |
moveTabItemToEnd(widget); |
|
452 |
} |
|
453 |
} |
|
454 | ||
466 | 455 |
/** |
467 | 456 |
* Move the target widget before the provided widget in this field-group. |
468 | 457 |
* |
469 | 458 |
* @param widget |
470 | 459 |
* The target widget to be moved. |
471 |
* @param before
|
|
460 |
* @param anchor
|
|
472 | 461 |
* The provided widget. |
473 | 462 |
*/ |
474 |
public void moveWidgetBefore(GenericWidget<?> widget, GenericWidget<?> before)
|
|
463 |
public void moveWidgetBefore(GenericWidget<?> widget, GenericWidget<?> anchor)
|
|
475 | 464 |
{ |
476 |
if (!tabItems.contains(widget) || !tabItems.contains(before))
|
|
465 |
if (!tabItems.contains(widget)) |
|
477 | 466 |
{ |
478 | 467 |
throw new RuntimeException("The widgets must be in specified field-group"); |
479 | 468 |
} |
480 | 469 |
|
481 |
setTabItemBefore(widget, before);
|
|
470 |
setTabItemRelative(widget, anchor, false);
|
|
482 | 471 |
} |
483 | 472 |
|
484 | 473 |
/** |
... | ... | |
504 | 493 |
* @param name |
505 | 494 |
* The handle type to be set. |
506 | 495 |
*/ |
496 |
@Override |
|
507 | 497 |
public void name(character name) |
508 | 498 |
{ |
509 | 499 |
if (name == null || name.isUnknown()) |
... | ... | |
525 | 515 |
* |
526 | 516 |
* @return the parent widget for this widget |
527 | 517 |
*/ |
518 |
@Override |
|
528 | 519 |
public CommonWidget getParent() |
529 | 520 |
{ |
530 | 521 |
// explicitly set field group |
... | ... | |
579 | 570 |
* |
580 | 571 |
* @return The next widget or a <code>null</code> if there is no subsequent widget. |
581 | 572 |
*/ |
573 |
@Override |
|
582 | 574 |
public GenericWidget<?> getNextChild(GenericWidget<?> child) |
583 | 575 |
{ |
584 | 576 |
if (widgets == null || child == null) |
... | ... | |
599 | 591 |
* |
600 | 592 |
* @return The previous widget or <code>null</code> if there is no preceding widget. |
601 | 593 |
*/ |
594 |
@Override |
|
602 | 595 |
public GenericWidget<?> getPrevChild(GenericWidget<?> child) |
603 | 596 |
{ |
604 | 597 |
if (widgets == null || child == null) |
... | ... | |
619 | 612 |
@Override |
620 | 613 |
public handle getFirstTabItem() |
621 | 614 |
{ |
622 |
if (firstTabItem == null) |
|
623 |
{ |
|
624 |
firstTabItem = getExtremeTabItem(true); |
|
625 |
} |
|
626 |
|
|
627 |
if (firstTabItem == null) |
|
628 |
{ |
|
629 |
// when no item is found, unknown handle must be returned |
|
630 |
return new handle(); |
|
631 |
} |
|
632 |
|
|
633 |
return firstTabItem.asWidgetHandle(); |
|
615 |
return getExtremeTabItem(true); |
|
634 | 616 |
} |
635 | 617 |
|
636 | 618 |
/** |
... | ... | |
641 | 623 |
@Override |
642 | 624 |
public handle getLastTabItem() |
643 | 625 |
{ |
644 |
if (lastTabItem == null) |
|
645 |
{ |
|
646 |
lastTabItem = getExtremeTabItem(false); |
|
647 |
} |
|
648 |
|
|
649 |
if (lastTabItem == null) |
|
650 |
{ |
|
651 |
// when no item is found, unknown handle must be returned |
|
652 |
return new handle(); |
|
653 |
} |
|
654 |
|
|
655 |
return lastTabItem.asWidgetHandle(); |
|
626 |
return getExtremeTabItem(false); |
|
656 | 627 |
} |
657 | 628 | |
658 | 629 |
/** |
... | ... | |
664 | 635 |
@Override |
665 | 636 |
public void setFirstTabItem(handle wHandle) |
666 | 637 |
{ |
667 |
if (wHandle == null || !wHandle._isValid() || wHandle.isUnknown()) |
|
668 |
{ |
|
669 |
String ms = |
|
670 |
"**Unable to assign UNKNOWN value to attribute FIRST-TAB-ITEM on FIELD-GROUP widget"; |
|
671 |
ErrorManager.recordOrThrowError(4083, ms, false); |
|
672 |
return; |
|
673 |
} |
|
674 |
|
|
675 |
CommonWidget widget = wHandle.unwrapWidget(); |
|
676 |
|
|
677 |
if (!tabItems.contains(widget)) |
|
678 |
{ |
|
679 |
String ms = "**Unable to set attribute FIRST-TAB-ITEM for FIELD-GROUP widget"; |
|
680 |
ErrorManager.recordOrThrowError(4078, ms, false); |
|
681 |
return; |
|
682 |
} |
|
683 |
GenericWidget<?> anchor; |
|
684 |
if (firstTabItem != null) |
|
685 |
{ |
|
686 |
anchor = firstTabItem; |
|
687 |
} |
|
688 |
else |
|
689 |
{ |
|
690 |
anchor = tabItems.get(0); |
|
691 |
} |
|
692 |
firstTabItem = (GenericWidget<?>) widget; |
|
693 |
|
|
694 |
setTabItemBefore((GenericWidget<?>) widget, anchor); |
|
695 |
|
|
696 |
LogicalTerminal.updateTabItemList(this); |
|
638 |
setFirstLastTabItem(wHandle, true); |
|
697 | 639 |
} |
698 | 640 |
|
699 | 641 |
/** |
... | ... | |
705 | 647 |
@Override |
706 | 648 |
public void setLastTabItem(handle wHandle) |
707 | 649 |
{ |
650 |
setFirstLastTabItem(wHandle, false); |
|
651 |
} |
|
652 |
|
|
653 |
/** |
|
654 |
* Setting the FIRST-TAB-ITEM or LAST-TAB-ITEM attribute. |
|
655 |
* |
|
656 |
* @param wHandle |
|
657 |
* The handle of widget in this field-group to assign as last in the tab order. |
|
658 |
*/ |
|
659 |
private final void setFirstLastTabItem(final handle wHandle, final boolean isFirst) |
|
660 |
{ |
|
661 |
final String attName = isFirst ? "FIRST-TAB-ITEM" : "LAST-TAB-ITEM"; |
|
708 | 662 |
if (wHandle == null || !wHandle._isValid() || wHandle.isUnknown()) |
709 | 663 |
{ |
710 |
String ms = |
|
711 |
"**Unable to assign UNKNOWN value to attribute LAST-TAB-ITEM on FIELD-GROUP widget"; |
|
712 |
ErrorManager.recordOrThrowError(4083, ms, false); |
|
664 |
ErrorManager.recordOrShowError(4083, "Unable to assign UNKNOWN value to attribute " |
|
665 |
+ attName + " on FIELD-GROUP widget", false); |
|
713 | 666 |
return; |
714 | 667 |
} |
715 | 668 |
|
716 |
CommonWidget widget = wHandle.unwrapWidget(); |
|
669 |
final CommonWidget widget = wHandle.unwrapWidget();
|
|
717 | 670 |
|
718 | 671 |
if (!tabItems.contains(widget)) |
719 | 672 |
{ |
720 |
String ms = "**Unable to set attribute LAST-TAB-ITEM for FIELD-GROUP widget";
|
|
721 |
ErrorManager.recordOrThrowError(4078, ms, false);
|
|
673 |
ErrorManager.recordOrShowError(4078,
|
|
674 |
"Unable to set attribute " + attName + " for FIELD-GROUP widget", false);
|
|
722 | 675 |
return; |
723 | 676 |
} |
724 |
GenericWidget<?> anchor; |
|
725 |
if (lastTabItem != null) |
|
726 |
{ |
|
727 |
anchor = lastTabItem; |
|
728 |
} |
|
729 |
else |
|
730 |
{ |
|
731 |
anchor = tabItems.get(tabItems.size() - 1); |
|
732 |
} |
|
733 |
|
|
734 |
lastTabItem = (GenericWidget<?>) widget; |
|
735 |
|
|
736 |
setTabItemAfter((GenericWidget<?>) widget, anchor); |
|
737 |
|
|
677 |
|
|
678 |
moveTabItem((GenericWidget<?>) widget, isFirst ? 0 : tabItems.size() - 1); |
|
738 | 679 |
LogicalTerminal.updateTabItemList(this); |
739 | 680 |
} |
740 | 681 |
|
... | ... | |
774 | 715 |
{ |
775 | 716 |
throw new UnsupportedOperationException("The FieldGroup is not expandable"); |
776 | 717 |
} |
777 |
else |
|
778 |
{ |
|
779 |
if (widgets.contains(dynWidget)) |
|
780 |
{ |
|
781 |
return; |
|
782 |
} |
|
783 |
|
|
784 |
addWidget(dynWidget); |
|
785 |
|
|
786 |
if (notifyOwnerFrame) |
|
787 |
{ |
|
788 |
widgetAdder.accept(dynWidget); |
|
789 |
} |
|
718 |
|
|
719 |
if (widgets.contains(dynWidget)) |
|
720 |
{ |
|
721 |
return; |
|
722 |
} |
|
723 |
|
|
724 |
addWidget(dynWidget); |
|
725 |
|
|
726 |
if (notifyOwnerFrame) |
|
727 |
{ |
|
728 |
widgetAdder.accept(dynWidget); |
|
790 | 729 |
} |
791 | 730 |
} |
792 | 731 |
|
... | ... | |
802 | 741 |
} |
803 | 742 |
|
804 | 743 |
/** |
805 |
* Return the current tab item list. |
|
744 |
* Return the current tab item list as an array of integers.
|
|
806 | 745 |
* |
807 | 746 |
* @return The tab item list |
808 | 747 |
*/ |
809 | 748 |
public int[] getTabItemList() |
810 | 749 |
{ |
811 |
if (tabItems != null && !tabItems.isEmpty()) |
|
812 |
{ |
|
813 |
return tabItems.stream().filter(x -> (x.isTabStop().booleanValue())) |
|
814 |
.mapToInt(x -> x.getId()).toArray(); |
|
815 |
} |
|
816 |
|
|
817 |
return new int[0]; |
|
750 |
return tabItems.stream().mapToInt(x -> x.getId()).toArray(); |
|
818 | 751 |
} |
819 | 752 |
|
820 | 753 |
/** |
... | ... | |
836 | 769 |
{ |
837 | 770 |
int id = widgetIds[i]; |
838 | 771 |
GenericWidget<?> widget = LogicalTerminal.getWidgetForId(id); |
839 |
placeWidgetInTabList(widget, op, i); |
|
772 |
if (widget != null) |
|
773 |
placeWidgetInTabList(widget, op, i); |
|
840 | 774 |
} |
841 | 775 |
} |
842 | 776 |
|
843 |
updateExtremeTabItems(); |
|
844 |
|
|
845 | 777 |
return getTabItemList(); |
846 | 778 |
} |
847 | 779 |
|
... | ... | |
867 | 799 |
} |
868 | 800 |
} |
869 | 801 |
|
870 |
updateExtremeTabItems(); |
|
871 |
|
|
872 | 802 |
return getTabItemList(); |
873 | 803 |
} |
874 | 804 |
|
... | ... | |
882 | 812 |
*/ |
883 | 813 |
public handle nextTabItem(GenericWidget<?> widget) |
884 | 814 |
{ |
885 |
return nextTabItem(widget, false); |
|
815 |
return nextOrPreviousTabItem(widget, false);
|
|
886 | 816 |
} |
887 | 817 |
|
888 | 818 |
/** |
... | ... | |
895 | 825 |
*/ |
896 | 826 |
public handle previousTabItem(GenericWidget<?> widget) |
897 | 827 |
{ |
898 |
return nextTabItem(widget, true); |
|
828 |
return nextOrPreviousTabItem(widget, true);
|
|
899 | 829 |
} |
900 | 830 |
|
901 | 831 |
/** |
... | ... | |
953 | 883 |
* |
954 | 884 |
* @return An instance of <code>GenericWidget</code> or <code>null</code>. |
955 | 885 |
*/ |
956 |
private handle nextTabItem(GenericWidget<?> widget, boolean reverse) |
|
886 |
private handle nextOrPreviousTabItem(GenericWidget<?> widget, boolean reverse)
|
|
957 | 887 |
{ |
958 |
Iterator<GenericWidget<?>> widgetsIter; |
|
959 |
|
|
960 |
if (reverse) |
|
961 |
{ |
|
962 |
widgetsIter = Iterables.reverse(tabItems).iterator(); |
|
888 |
final int anchorIndex = tabItems.indexOf(widget); |
|
889 |
final int index; |
|
890 |
if (anchorIndex < 0) |
|
891 |
{ |
|
892 |
// widget is no tab-stoppable |
|
893 |
index = -1; |
|
894 |
} |
|
895 |
else if (reverse) |
|
896 |
{ |
|
897 |
index = anchorIndex > 0 ? anchorIndex - 1 : -1; |
|
963 | 898 |
} |
964 | 899 |
else |
965 | 900 |
{ |
966 |
widgetsIter = tabItems.iterator(); |
|
967 |
} |
|
968 |
|
|
969 |
boolean notFound = true; |
|
970 |
while(notFound && widgetsIter.hasNext()) |
|
971 |
{ |
|
972 |
GenericWidget<?> testableWidget = widgetsIter.next(); |
|
973 |
if (widget.equals(testableWidget)) |
|
974 |
{ |
|
975 |
notFound = false; |
|
976 |
} |
|
977 |
} |
|
978 |
|
|
979 |
if (notFound || !widget.isTabStop().booleanValue()) |
|
980 |
{ |
|
981 |
return new handle(); |
|
982 |
} |
|
983 |
|
|
984 |
notFound = true; |
|
985 |
GenericWidget<?> nextWidget = null; |
|
986 |
while(notFound && widgetsIter.hasNext()) |
|
987 |
{ |
|
988 |
nextWidget = widgetsIter.next(); |
|
989 |
if (nextWidget._isRealized() && nextWidget.isTabStop().booleanValue()) |
|
990 |
{ |
|
991 |
notFound = false; |
|
992 |
} |
|
993 |
} |
|
994 |
|
|
995 |
if (notFound) |
|
996 |
{ |
|
997 |
return new handle(); |
|
998 |
} |
|
999 |
|
|
1000 |
return nextWidget.asWidgetHandle(); |
|
901 |
index = anchorIndex < tabItems.size() - 1 ? anchorIndex + 1 : -1; |
|
902 |
} |
|
903 |
|
|
904 |
return index == -1 ? new handle() : new handle(tabItems.get(index)); |
|
1001 | 905 |
} |
1002 | 906 |
|
1003 | 907 |
/** |
... | ... | |
1006 | 910 |
* @return TRUE - if the logic of parent class {@link HandleChain} is used, |
1007 | 911 |
* FALSE - if own siblings implementation logic is used. |
1008 | 912 |
*/ |
913 |
@Override |
|
1009 | 914 |
protected boolean useHandleChainSiblings() |
1010 | 915 |
{ |
1011 | 916 |
return true; |
... | ... | |
1046 | 951 |
} |
1047 | 952 |
|
1048 | 953 |
/** |
1049 |
* Accesses the the first and the last field-level widget in the given field group.
|
|
954 |
* Find the first or the last tab-stoppable widget in this field group.
|
|
1050 | 955 |
* |
1051 | 956 |
* @param first |
1052 | 957 |
* The true value indicates that the first will be accessed, otherwise |
1053 | 958 |
* the last widget. |
1054 | 959 |
* |
1055 |
* @return The extreme possible field-level widget in this group or |
|
1056 |
* <code>null</code> if there are no field level widgets. |
|
1057 |
*/ |
|
1058 |
private GenericWidget<?> getExtremeTabItem(boolean first) |
|
1059 |
{ |
|
1060 |
if (tabItems == null) |
|
1061 |
{ |
|
1062 |
return null; |
|
1063 |
} |
|
1064 |
|
|
1065 |
Iterator<GenericWidget<?>> iter; |
|
1066 |
|
|
1067 |
if (first) |
|
1068 |
{ |
|
1069 |
iter = tabItems.iterator(); |
|
1070 |
} |
|
1071 |
else |
|
1072 |
{ |
|
1073 |
iter = Iterables.reverse(tabItems).iterator(); |
|
1074 |
} |
|
1075 |
|
|
1076 |
// scan first available field-level widget |
|
1077 |
|
|
1078 |
while (iter.hasNext()) |
|
1079 |
{ |
|
1080 |
GenericWidget<?> widget = iter.next(); |
|
1081 |
if (widget._isRealized() && widget.isTabStop().booleanValue()) |
|
1082 |
{ |
|
1083 |
return widget; |
|
1084 |
} |
|
1085 |
} |
|
1086 |
|
|
1087 |
return null; |
|
1088 |
} |
|
1089 |
|
|
1090 |
/** |
|
1091 |
* Set the tab item after the provided widget in this field-group. |
|
1092 |
* |
|
1093 |
* @param widget |
|
1094 |
* The tab item. |
|
1095 |
* @param after |
|
1096 |
* The provided widget. |
|
1097 |
*/ |
|
1098 |
private void setTabItemAfter(GenericWidget<?> widget, GenericWidget<?> after) |
|
1099 |
{ |
|
1100 |
if (widget != after) |
|
1101 |
{ |
|
1102 |
moveTabItem(widget, () -> tabItems.indexOf(after) + 1); |
|
1103 |
} |
|
1104 |
|
|
1105 |
updateExtremeTabItems(); |
|
1106 |
} |
|
1107 |
|
|
1108 |
/** |
|
1109 |
* Set the tab item before the provided widget in this field-group. |
|
1110 |
* |
|
1111 |
* @param widget |
|
1112 |
* The tab item. |
|
1113 |
* @param before |
|
1114 |
* The provided widget. |
|
1115 |
*/ |
|
1116 |
private void setTabItemBefore(GenericWidget<?> widget, GenericWidget<?> before) |
|
1117 |
{ |
|
1118 |
if (widget != before) |
|
1119 |
{ |
|
1120 |
moveTabItem(widget, () -> tabItems.indexOf(before)); |
|
1121 |
} |
|
1122 |
|
|
1123 |
updateExtremeTabItems(); |
|
1124 |
} |
|
1125 |
|
|
1126 |
/** |
|
1127 |
* Updates the first and last tab items if there are initialized. |
|
1128 |
*/ |
|
1129 |
private void updateExtremeTabItems() |
|
1130 |
{ |
|
1131 |
if (firstTabItem != null) |
|
1132 |
{ |
|
1133 |
firstTabItem = getExtremeTabItem(true); |
|
1134 |
} |
|
1135 |
|
|
1136 |
if (lastTabItem != null) |
|
1137 |
{ |
|
1138 |
lastTabItem = getExtremeTabItem(false); |
|
1139 |
} |
|
1140 |
} |
|
960 |
* @return the handle of the widget found or unknown if there is no tab stoppable widgets |
|
961 |
* in this group |
|
962 |
*/ |
|
963 |
private final handle getExtremeTabItem(boolean first) |
|
964 |
{ |
|
965 |
final int size = tabItems.size(); |
|
966 |
return size == 0 ? new handle() : new handle(tabItems.get(first ? 0 : size - 1)); |
|
967 |
} |
|
968 |
|
|
969 |
/** |
|
970 |
* Set widget relative to the provided anchor widget in this field-group. |
|
971 |
* |
|
972 |
* @param widget |
|
973 |
* The tab item. |
|
974 |
* @param anchor |
|
975 |
* The provided widget. |
|
976 |
* @param isAfter |
|
977 |
* {@code true} if place the widget after the anchor widget, otherwise place widget before |
|
978 |
* the anchor widget. |
|
979 |
*/ |
|
980 |
final void setTabItemRelative(final GenericWidget<?> widget, GenericWidget<?> anchor, |
|
981 |
boolean isAfter) |
|
982 |
{ |
|
983 |
if (!tabItems.contains(anchor)) |
|
984 |
{ |
|
985 |
throw new RuntimeException( |
|
986 |
"The anchor widget must be in specified field-group and tab-stoppable"); |
|
987 |
} |
|
1141 | 988 | |
989 |
if (widget != anchor) |
|
990 |
{ |
|
991 |
assert tabItems.contains(widget); |
|
992 |
|
|
993 |
tabItems.remove(widget); |
|
994 |
|
|
995 |
assert !tabItems.contains(widget); |
|
996 |
|
|
997 |
final int anchorIndex = tabItems.indexOf(anchor); |
|
998 |
tabItems.add(isAfter ? anchorIndex + 1 : anchorIndex, widget); |
|
999 |
} |
|
1000 |
} |
|
1001 |
|
|
1142 | 1002 |
/** |
1143 | 1003 |
* Get the NUM-TABS attribute, which indicates the number of tab widgets inside this |
1144 | 1004 |
* field-group container. |
... | ... | |
1148 | 1008 |
@Override |
1149 | 1009 |
public integer getNumTabs() |
1150 | 1010 |
{ |
1151 |
Iterator<GenericWidget<?>> widgetsIter = tabItems.iterator(); |
|
1152 |
|
|
1153 |
int count = 0; |
|
1154 |
|
|
1155 |
while(widgetsIter.hasNext()) |
|
1156 |
{ |
|
1157 |
GenericWidget<?> nextWidget = widgetsIter.next(); |
|
1158 |
if (nextWidget._isRealized() && nextWidget.isTabStop().booleanValue()) |
|
1159 |
{ |
|
1160 |
count++; |
|
1161 |
} |
|
1162 |
} |
|
1163 |
|
|
1164 |
return new integer(count); |
|
1011 |
return new integer(tabItems.size()); |
|
1165 | 1012 |
} |
1166 | 1013 | |
1167 | 1014 |
/** |
... | ... | |
1189 | 1036 |
* @param tabPosition |
1190 | 1037 |
* The tab position |
1191 | 1038 |
* |
1192 |
* @return The handle of the tab item by the given tab position. |
|
1039 |
* @return The handle of the tab item by the given tab position or |
|
1040 |
* UNKNOWN if tap position is out of valid position range. |
|
1193 | 1041 |
*/ |
1194 | 1042 |
@Override |
1195 | 1043 |
public handle getTabItem(int tabPosition) |
1196 | 1044 |
{ |
1197 |
if (tabPosition <= 0) |
|
1198 |
{ |
|
1199 |
return new handle(); |
|
1200 |
} |
|
1201 |
|
|
1202 |
Iterator<GenericWidget<?>> widgetsIter = tabItems.iterator(); |
|
1203 |
|
|
1204 |
int count = 0; |
|
1205 |
|
|
1206 |
while(widgetsIter.hasNext()) |
|
1207 |
{ |
|
1208 |
GenericWidget<?> nextWidget = widgetsIter.next(); |
|
1209 |
if (nextWidget._isRealized() && nextWidget.isTabStop().booleanValue()) |
|
1210 |
{ |
|
1211 |
count++; |
|
1212 |
if (count == tabPosition) |
|
1213 |
{ |
|
1214 |
return nextWidget.asWidgetHandle(); |
|
1215 |
} |
|
1216 |
} |
|
1217 |
} |
|
1218 |
|
|
1219 |
return new handle(); |
|
1045 |
return tabPosition > 0 && tabPosition <= tabItems.size() |
|
1046 |
? new handle(tabItems.get(tabPosition - 1)) |
|
1047 |
: new handle(); |
|
1220 | 1048 |
} |
1221 | 1049 |
|
1222 | 1050 |
/** |
... | ... | |
1235 | 1063 |
return new integer(); |
1236 | 1064 |
} |
1237 | 1065 |
|
1238 |
Iterator<GenericWidget<?>> widgetsIter = tabItems.iterator(); |
|
1239 |
|
|
1240 |
int tabPosition = 0; |
|
1241 |
|
|
1242 |
while(widgetsIter.hasNext()) |
|
1243 |
{ |
|
1244 |
GenericWidget<?> nextWidget = widgetsIter.next(); |
|
1245 |
|
|
1246 |
if (nextWidget._isRealized() && nextWidget.isTabStop().booleanValue()) |
|
1247 |
{ |
|
1248 |
tabPosition++; |
|
1249 |
|
|
1250 |
if (widget.equals(nextWidget)) |
|
1251 |
{ |
|
1252 |
return new integer(tabPosition); |
|
1253 |
} |
|
1254 |
} |
|
1255 |
} |
|
1256 |
|
|
1257 |
return new integer(); |
|
1258 |
} |
|
1259 | ||
1260 |
/** |
|
1261 |
* Remove from the list of tab items the items that became non-tab items. |
|
1262 |
*/ |
|
1263 |
public void cleanNonTabItems() |
|
1264 |
{ |
|
1265 |
if (tabItems != null) |
|
1266 |
{ |
|
1267 |
boolean removed = false; |
|
1268 |
Iterator<GenericWidget<?>> iter = tabItems.iterator(); |
|
1269 |
while (iter.hasNext()) |
|
1270 |
{ |
|
1271 |
GenericWidget<?> widget = iter.next(); |
|
1272 |
if (!widget.isTabWidget()) |
|
1273 |
{ |
|
1274 |
iter.remove(); |
|
1275 |
removed = true; |
|
1276 |
} |
|
1277 |
} |
|
1278 | ||
1279 |
if (removed) |
|
1280 |
{ |
|
1281 |
firstTabItem = null; |
|
1282 |
lastTabItem = null; |
|
1283 |
} |
|
1284 |
} |
|
1066 |
final int index = tabItems.indexOf(widget); |
|
1067 |
return index >= 0 ? new integer(index + 1) : new integer(); |
|
1285 | 1068 |
} |
1286 | 1069 | |
1287 | 1070 |
/** |
... | ... | |
1314 | 1097 |
* it will call {@linkplain LogicalTerminal#updateTabItemList(FieldGroup)} to reflect the |
1315 | 1098 |
* addition. |
1316 | 1099 |
* @param index |
1317 |
* The index supplier of the new widget position in the tab item list. Provide -1 to move the
|
|
1100 |
* The index of the new widget position in the tab item list. Provide -1 to move the |
|
1318 | 1101 |
* widget at the end of the list. The index is fetched after the widget is removed from the list. |
1319 | 1102 |
*/ |
1320 |
private void moveTabItem(GenericWidget<?> widget, Supplier<Integer> index)
|
|
1103 |
private final void moveTabItem(GenericWidget<?> widget, final int index)
|
|
1321 | 1104 |
{ |
1322 |
boolean contained = tabItems.remove(widget); |
|
1105 |
// final boolean contained = |
|
1106 |
tabItems.remove(widget); |
|
1323 | 1107 | |
1324 |
int i = index.get(); |
|
1325 |
if (i == -1) |
|
1108 |
assert !tabItems.contains(widget); |
|
1109 |
|
|
1110 |
if (index == -1) |
|
1326 | 1111 |
{ |
1327 | 1112 |
tabItems.add(widget); |
1328 | 1113 |
} |
1329 | 1114 |
else |
1330 | 1115 |
{ |
1331 |
tabItems.add(i, widget); |
|
1116 |
tabItems.add(index, widget);
|
|
1332 | 1117 |
} |
1333 | 1118 | |
1334 |
if (!contained) |
|
1335 |
{ |
|
1336 |
LogicalTerminal.updateTabItemList(this); |
|
1337 |
} |
|
1119 |
// FIXME: do we need to call LogicalTerminal.updateTabItemList only |
|
1120 |
// when a new item was added? |
|
1121 |
// if (!contained) |
|
1122 |
// { |
|
1123 |
// LogicalTerminal.updateTabItemList(this); |
|
1124 |
// } |
|
1125 |
LogicalTerminal.updateTabItemList(this); |
|
1338 | 1126 |
} |
1339 | 1127 | |
1340 | 1128 |
/** |
src/com/goldencode/p2j/ui/GenericFrame.java 2022-05-06 22:46:18 +0000 | ||
---|---|---|
1589 | 1592 |
* @return <code>TRUE</code> - if handle is valid, |
1590 | 1593 |
* <code>FALSE</code> - otherwise |
1591 | 1594 |
*/ |
1592 |
private boolean isAbleToDisplayWindow(handle hWin) |
|
1595 |
private static boolean isAbleToDisplayWindow(handle hWin)
|
|
1593 | 1596 |
{ |
1594 | 1597 |
// current-window is used (not the frame's window) |
1595 | 1598 |
if (hWin == null || !hWin._isValid() || hWin.isUnknown()) |
... | ... | |
1661 | 1664 |
frame.setInsideSetup(true); |
1662 | 1665 |
((Settable) frame).setup(frame); |
1663 | 1666 |
frame.setInsideSetup(false); |
1664 |
frame.cleanNonTabItems(); |
|
1665 | 1667 |
frame.batch(false); |
1666 | 1668 |
} |
1667 | 1669 |
|
... | ... | |
3456 | 3458 |
|
3457 | 3459 |
// hmmm, at this point we should have had a valid widget that was initialized |
3458 | 3460 |
// so encountering null here is unexpected. See below how we deal with unknown value. |
3459 |
String wt = widget.getDataType().toStringMessage(); |
|
3460 | 3461 |
// return new character(wt.startsWith("date") ? "" : "?"); |
3461 | 3462 |
return new character(""); |
3462 | 3463 |
} |
... | ... | |
6645 | 6646 |
* |
6646 | 6647 |
* @see #checkFieldGroup(GenericWidget) for limitations. |
6647 | 6648 |
*/ |
6648 |
private void setFieldGroupWidgets(FieldGroup fg, GenericWidget<?>[] widgets) |
|
6649 |
private static void setFieldGroupWidgets(FieldGroup fg, GenericWidget<?>[] widgets)
|
|
6649 | 6650 |
{ |
6650 | 6651 |
LinkedList<GenericWidget<?>> list = new LinkedList<>(); |
6651 | 6652 |
|
... | ... | |
6673 | 6674 |
* @param widget |
6674 | 6675 |
* The widget to check. |
6675 | 6676 |
*/ |
6676 |
private void checkFieldGroup(GenericWidget<?> widget) |
|
6677 |
private static void checkFieldGroup(GenericWidget<?> widget)
|
|
6677 | 6678 |
{ |
6678 | 6679 |
GenericFrame frame = widget.getFrame(); |
6679 | 6680 |
if (!widget._dynamic() && frame.frame.config.labels && !frame.frame.config.sideLabels) |
... | ... | |
7955 | 7956 |
} |
7956 | 7957 | |
7957 | 7958 |
/** |
7958 |
* Remove from the list of tab items the items that became non-tab items. |
|
7959 |
*/ |
|
7960 |
@Override |
|
7961 |
public void cleanNonTabItems() |
|
7962 |
{ |
|
7963 |
getFieldGroup().cleanNonTabItems(); |
|
7964 |
} |
|
7965 | ||
7966 |
/** |
|
7967 | 7959 |
* Marks the end of the editing block when triggered by any abnormal exit |
7968 | 7960 |
* from the block on the server. This method does NOT need to be called |
7969 | 7961 |
* if the exit is naturally triggered via {@link #continueEditing}. This |
... | ... | |
8222 | 8214 |
* if specified widget does not exists or does not support such a |
8223 | 8215 |
* request. |
8224 | 8216 |
*/ |
8225 |
public int[] getSelection(GenericWidget<?> widget)
|
|
8217 |
final static int[] getSelection(GenericWidget<?> widget)
|
|
8226 | 8218 |
{ |
8227 | 8219 |
return LogicalTerminal.getSelection(widget.getId()); |
8228 | 8220 |
} |
... | ... | |
8365 | 8357 |
* |
8366 | 8358 |
* @return Converted value. |
8367 | 8359 |
*/ |
8368 |
public Object convertScreenValue(Class<?> dataType, Object value, String format)
|
|
8360 |
static Object convertScreenValue(Class<?> dataType, Object value, String format)
|
|
8369 | 8361 |
{ |
8370 | 8362 |
if (value != null) |
8371 | 8363 |
{ |
... | ... | |
8713 | 8705 |
* @return The numeric ID assigned to the widget or -1 if no such widget |
8714 | 8706 |
* exists. |
8715 | 8707 |
*/ |
8716 |
int getWidgetId(GenericWidget<?> widget) |
|
8708 |
private final static int getWidgetId(GenericWidget<?> widget)
|
|
8717 | 8709 |
{ |
8718 | 8710 |
if (widget != null) |
8719 | 8711 |
{ |
... | ... | |
8748 | 8740 |
* @return The associated widget instance or <code>null</code> if a |
8749 | 8741 |
* widget by that ID does not exist in this frame. |
8750 | 8742 |
*/ |
8751 |
GenericWidget<?> getWidgetForId(int id) |
|
8743 |
final static GenericWidget<?> getWidgetForId(int id)
|
|
8752 | 8744 |
{ |
8753 | 8745 |
return LogicalTerminal.getWidgetForId(id); |
8754 | 8746 |
} |
... | ... | |
9182 | 9174 |
* |
9183 | 9175 |
* @return The String for dynamic widget name in string form of "ID". |
9184 | 9176 |
*/ |
9185 |
private String getDynamicWidgetName(GenericWidget<?> dynWidget) |
|
9177 |
private static String getDynamicWidgetName(GenericWidget<?> dynWidget)
|
|
9186 | 9178 |
{ |
9187 | 9179 |
return Integer.toString(dynWidget.getId()); |
9188 | 9180 |
} |
... | ... | |
9871 | 9863 |
* |
9872 | 9864 |
* @return <code>true</code> if the unnamed stream is redirected |
9873 | 9865 |
*/ |
9874 |
boolean isRedirected() |
|
9866 |
static boolean isRedirected()
|
|
9875 | 9867 |
{ |
9876 | 9868 |
return UnnamedStreams.isOut(); |
9877 | 9869 |
} |
... | ... | |
10178 | 10170 |
{ |
10179 | 10171 |
LiteralWidget lit = new LiteralWidget() |
10180 | 10172 |
{ |
10173 |
@Override |
|
10181 | 10174 |
public character getScreenValue() |
10182 | 10175 |
{ |
10183 | 10176 |
return widget == null ? new character(txt) : new character(widget.getLabelStr()); |
... | ... | |
10468 | 10461 |
/** |
10469 | 10462 |
* Returns the current screen value of the specified widget. |
10470 | 10463 |
* |
10471 |
* @param widgetName |
|
10472 |
* The widget name. |
|
10473 |
* @param dataType |
|
10474 |
* The widget data type; a class representing one of the |
|
10475 |
* following widget data types: |
|
10476 |
* <ul> |
|
10477 |
* <li><code>character</code>; |
|
10478 |
* <li><code>integer</code>; |
|
10479 |
* <li><code>decimal</code>; |
|
10480 |
* <li><code>logical</code>; |
|
10481 |
* <li><code>date</code>. |
|
10482 |
* </ul> |
|
10483 |
* |
|
10484 |
* @return <code>Object</code> currently in the screen buffer as the |
|
10485 |
* value of the widget or one of these defaults, if no value |
|
10486 |
* has been set: |
|
10487 |
* <ul> |
|
10488 |
* <li><code>character</code> - ""; |
|
10489 |
* <li><code>integer</code> - 0; |
|
10490 |
* <li><code>decimal</code> - 0; |
|
10491 |
* <li><code>logical</code> - no (false); |
|
10492 |
* <li><code>date</code> - ? (unknown). |
|
10493 |
* </ul> |
|
10494 |
*/ |
|
10495 |
@SuppressWarnings("unused") |
|
10496 |
private Object getter(String widgetName, Class<?> dataType) |
|
10497 |
{ |
|
10498 |
int index = getWidgetId(widgetName); |
|
10499 |
|
|
10500 |
if (index < 0) |
|
10501 |
{ |
|
10502 |
throw new RuntimeException("Invalid widget name " + widgetName); |
|
10503 |
} |
|
10504 |
|
|
10505 |
return getter(index, dataType, true, false); |
|
10506 |
} |
|
10507 |
|
|
10508 |
/** |
|
10509 |
* Returns the current screen value of the specified widget. |
|
10510 |
* |
|
10511 | 10464 |
* @param widgetId |
10512 | 10465 |
* The widget ID. |
10513 | 10466 |
* @param dataType |
... | ... | |
10631 | 10584 |
/** |
10632 | 10585 |
* Sets a new value for the specified widget in the screen buffer. |
10633 | 10586 |
* |
10634 |
* @param widgetName |
|
10635 |
* widget name |
|
10636 |
* @param value |
|
10637 |
* An object representing the widget value. Since this code is |
|
10638 |
* called from the Java Reflection API, any time a primitive |
|
10639 |
* (e.g. <code>int</code>) is passed, Reflection automatically |
|
10640 |
* wraps it in an <code>Object</code> of the correct type (e.g. |
|
10641 |
* <code>Integer</code>). Thus it is safe to always expect the |
|
10642 |
* value to be an <code>Object</code>. |
|
10643 |
* @return <code>null</code> to comply with <code>void</code> |
|
10644 |
*/ |
|
10645 |
@SuppressWarnings("unused") |
|
10646 |
private Object setter(String widgetName, Object value) |
|
10647 |
{ |
|
10648 |
int index = getWidgetId(widgetName); |
|
10649 | ||
10650 |
if (index < 0) |
|
10651 |
{ |
|
10652 |
throw new RuntimeException("Invalid widget name " + widgetName); |
|
10653 |
} |
|
10654 |
|
|
10655 |
return setter(index, value); |
|
10656 |
} |
|
10657 |
|
|
10658 |
/** |
|
10659 |
* Sets a new value for the specified widget in the screen buffer. |
|
10660 |
* |
|
10661 | 10587 |
* @param index |
10662 | 10588 |
* The widget ID. |
10663 | 10589 |
* @param value |
... | ... | |
10748 | 10674 |
* @throws RuntimeException |
10749 | 10675 |
* If the index object is not a supported numeric object. |
10750 | 10676 |
*/ |
10751 |
private String generateWidgetName(String base, int op, Object index) |
|
10677 |
private static String generateWidgetName(String base, int op, Object index)
|
|
10752 | 10678 |
throws RuntimeException |
10753 | 10679 |
{ |
10754 | 10680 |
String result = indexAsString(index); |
... | ... | |
10783 | 10709 |
* @return The resulting string or <code>null</code> if the type is not |
10784 | 10710 |
* one of the supported numeric types. |
10785 | 10711 |
*/ |
10786 |
private String indexAsString(Object index) |
|
10712 |
private static String indexAsString(Object index)
|
|
10787 | 10713 |
{ |
10788 | 10714 |
String result = null; |
10789 | 10715 |
|
... | ... | |
10828 | 10754 |
* an instance of the proper type (set as |
10829 | 10755 |
* <code>unknown value</code>) otherwise. |
10830 | 10756 |
*/ |
10831 |
private BaseDataType translateUnknown(BaseDataType value, ControlEntity<?> widget) |
|
10757 |
private static BaseDataType translateUnknown(BaseDataType value, ControlEntity<?> widget)
|
|
10832 | 10758 |
{ |
10833 | 10759 |
if (value instanceof unknown) |
10834 | 10760 |
{ |
... | ... | |
11343 | 11269 |
* @return The list of remaining ids or <code>null</code> if no ids |
11344 | 11270 |
* were included. |
11345 | 11271 |
*/ |
11346 |
public int[] validIds(GenericWidget<?>[] list)
|
|
11272 |
private final static int[] validIds(GenericWidget<?>[] list)
|
|
11347 | 11273 |
{ |
11348 | 11274 |
if (list == null || list.length == 0) |
11349 | 11275 |
return null; |
... | ... | |
11638 | 11564 |
* @return The list of remaining ids or <code>null</code> if all ids |
11639 | 11565 |
* were excluded. |
11640 | 11566 |
*/ |
11641 |
private int[] remainingIds(GenericWidget<?>[] all, GenericWidget<?>[] xcpt) |
|
11567 |
private static int[] remainingIds(GenericWidget<?>[] all, GenericWidget<?>[] xcpt)
|
|
11642 | 11568 |
{ |
11643 | 11569 |
Map<Integer, GenericWidget<?>> widgetIds = new LinkedHashMap<>(); |
11644 | 11570 |
|
... | ... | |
11677 | 11603 |
* @return The <code>int[]</code> or <code>null</code> if there are no |
11678 | 11604 |
* ids in the set. |
11679 | 11605 |
*/ |
11680 |
private int[] idSetToArray(Set<Integer> widgetIds) |
|
11606 |
private static int[] idSetToArray(Set<Integer> widgetIds)
|
|
11681 | 11607 |
{ |
11682 | 11608 |
// calculate the widgets |
11683 | 11609 |
int size = widgetIds.size(); |
... | ... | |
11706 | 11632 |
* |
11707 | 11633 |
* @return The array of widget IDs. |
11708 | 11634 |
*/ |
11709 |
private int[] idsFromWidgets(GenericWidget<?>[] widgets) |
|
11635 |
private static int[] idsFromWidgets(GenericWidget<?>[] widgets)
|
|
11710 | 11636 |
{ |
11711 | 11637 |
if (widgets == null) |
11712 | 11638 |
return null; |
... | ... | |
11731 | 11657 |
* |
11732 | 11658 |
* @return The array of widgets. |
11733 | 11659 |
*/ |
11734 |
private GenericWidget<?>[] widgetListFromFrameElements(FrameElement[] widgets) |
|
11660 |
private static GenericWidget<?>[] widgetListFromFrameElements(FrameElement[] widgets)
|
|
11735 | 11661 |
{ |
11736 | 11662 |
GenericWidget<?> current = null; |
11737 | 11663 |
GenericWidget<?>[] wids = new GenericWidget[widgets.length]; |
... | ... | |
11771 | 11697 |
* If the unnamed input is redirected and silent error mode is |
11772 | 11698 |
* off. |
11773 | 11699 |
*/ |
11774 |
private boolean errorOnRedirectedInput(int num, String txt) |
|
11700 |
private static boolean errorOnRedirectedInput(int num, String txt)
|
|
11775 | 11701 |
{ |
11776 | 11702 |
if (UnnamedStreams.input() != null) |
11777 | 11703 |
{ |
... | ... | |
11802 | 11728 |
* If the unnamed input is redirected and silent error mode is |
11803 | 11729 |
* off. |
11804 | 11730 |
*/ |
11805 |
private boolean errorOnBatchModeEnable(int num, String txt) |
|
11731 |
private static boolean errorOnBatchModeEnable(int num, String txt)
|
|
11806 | 11732 |
{ |
11807 | 11733 |
// It depends on underlying OS and|or background mode. |
11808 | 11734 |
if (LogicalTerminal.isInBatchMode() && |
... | ... | |
11845 | 11771 |
* If the unnamed input is redirected and silent error mode is |
11846 | 11772 |
* off. |
11847 | 11773 |
*/ |
11848 |
private boolean errorOnBatchModeSetPrompt(int num, String txt) |
|
11774 |
private static boolean errorOnBatchModeSetPrompt(int num, String txt)
|
|
11849 | 11775 |
{ |
11850 | 11776 |
// It depends on internal I/O redirection. |
11851 | 11777 |
if (LogicalTerminal.isInBatchMode() && UnnamedStreams.input() == null) |
... | ... | |
12297 | 12223 |
* |
12298 | 12224 |
* @return The remote stream ID. |
12299 | 12225 |
*/ |
12300 |
int getRemoteStreamId(Stream out) |
|
12226 |
final static int getRemoteStreamId(Stream out)
|
|
12301 | 12227 |
{ |
12302 | 12228 |
RemoteStream rs = null; |
12303 | 12229 |
|
... | ... | |
12357 | 12283 |
for (int i = 0; i < widgets.length; i++) |
12358 | 12284 |
{ |
12359 | 12285 |
int wid = widgets[i].getId(); |
12360 |
GenericWidget<?> widget = this.getWidgetForId(wid);
|
|
12286 |
GenericWidget<?> widget = getWidgetForId(wid); |
|
12361 | 12287 |
|
12362 | 12288 |
if (widget instanceof ControlTextWidget) |
12363 | 12289 |
{ |
... | ... | |
12389 | 12315 |
* |
12390 | 12316 |
* @return The array of the GenericWidget<?> values with HIDDEN attrubute is FALSE. |
12391 | 12317 |
*/ |
12392 |
private GenericWidget<?>[] removeHiddenWidgets(GenericWidget<?>[] inputList) |
|
12318 |
private static GenericWidget<?>[] removeHiddenWidgets(GenericWidget<?>[] inputList)
|
|
12393 | 12319 |
{ |
12394 | 12320 |
List<GenericWidget<?>> tmpList = new ArrayList<>(); |
12395 | 12321 |
|
... | ... | |
12428 | 12354 |
} |
12429 | 12355 |
|
12430 | 12356 |
/** |
12431 |
* Restores the widget registry for static content of this frame based on header and |
|
12432 |
* non-header widget info. |
|
12433 |
*/ |
|
12434 |
private void restoreWidgetRegistry() |
|
12435 |
{ |
|
12436 |
// non-header widgets first |
|
12437 |
for (int i = 0; i < widgets.length; i++) |
|
12438 |
{ |
|
12439 |
if (!widgets[i]._dynamic()) |
|
12440 |
{ |
|
12441 |
LogicalTerminal.registerWidget(widgets[i], widgets[i].getId()); |
|
12442 |
} |
|
12443 |
} |
|
12444 |
|
|
12445 |
// enumerate all the header widgets in the order of their definition |
|
12446 |
Iterator<String> iter = n2h.keySet().iterator(); |
|
12447 | ||
12448 |
while (iter.hasNext()) |
|
12449 |
{ |
|
12450 |
// get the widget |
|
12451 |
GenericWidget<?> gw = n2h.get(iter.next()); |
|
12452 |
|
|
12453 |
if (!gw._dynamic()) |
|
12454 |
{ |
|
12455 |
LogicalTerminal.registerWidget(gw, gw.getId()); |
|
12456 |
} |
|
12457 |
} |
|
12458 |
} |
|
12459 |
|
|
12460 |
/** |
|
12461 | 12357 |
* Provides a cleanup mechanism for editing blocks that exits abnormally |
12462 | 12358 |
* (without a natural exit via {@link #continueEditing}). |
12463 | 12359 |
*/ |
... | ... | |
13359 | 13255 |
} |
13360 | 13256 |
|
13361 | 13257 |
/** |
13362 |
* This method prints field-groups of the frame and is needed only for debugging purposes. |
|
13363 |
* |
|
13364 |
* Here is a sample output (each triplet group is for a distinct call): |
|
13365 |
* <pre> |
|
13366 |
* 3 |
|
13367 |
* gr1 [null, gr2] gr2 [gr1, gr3] gr3 [gr2, gr4] gr4 [gr3, gr5] gr5 [gr4, UN] |
|
13368 |
* 1 -> gr5, |
|
13369 |
* |
|
13370 |
* 3 |
|
13371 |
* gr1 [null, gr2] gr2 [gr1, gr3] gr3 [gr2, gr4] gr4 [gr3, gr5] gr5 [gr4, UN] |
|
13372 |
* 1 -> gr5, 2 -> gr1, |
|
13373 |
* |
|
13374 |
* 3 |
|
13375 |
* gr1 [null, gr2] gr2 [gr1, gr3] gr3 [gr2, gr4] gr4 [gr3, gr5] gr5 [gr4, UN] |
|
13376 |
* 1 -> gr5, 2 -> gr1, 3 -> gr2, |
|
13377 |
* </pre> |
|
13378 |
* |
|
13379 |
* Here are groups of several triplets of strings. |
|
13380 |
* The first line in a triplet is a number of lines to step. Can be < 0. |
|
13381 |
* The second row displays field groups, each with its neighbors in square brackets: |
|
13382 |
* [left, right]. |
|
13383 |
* The third row is a mapping from the row number to field-group, only for rows with an |
|
13384 |
* associated field-group. |
|
13385 |
* |
|
13386 |
* @param lines |
|
13387 |
* Number of lines to step. Can be <0 (UP statement) or >0 (DOWN statement). |
|
13388 |
*/ |
|
13389 |
private void printFieldGroups(int lines) |
|
13390 |
{ |
|
13391 |
System.out.println(lines); |
|
13392 |
String result = ""; |
|
13393 |
for (FieldGroup fg = fieldGroup; |
|
13394 |
fg != null; |
|
13395 |
fg = (FieldGroup) fg.getNextSibling().getResource()) |
|
13396 |
{ |
|
13397 |
result += " " + (fg.name().getValue() == null ? "UN" : fg.name().getValue()) + " ["; |
|
13398 |
if(fg.getPrevSibling() == null || fg.getPrevSibling().isUnknown()) |
|
13399 |
result += null; |
|
13400 |
else |
|
13401 |
{ |
|
13402 |
String fgName = ((FieldGroup)fg.getPrevSibling().getResource()).name().getValue(); |
|
13403 |
result += fgName == null ? "UN" : fgName; |
|
13404 |
} |
|
13405 |
result += ", "; |
|
13406 |
if(fg.getNextSibling() == null || fg.getNextSibling().isUnknown()) |
|
13407 |
result += null; |
|
13408 |
else |
|
13409 |
{ |
|
13410 |
String fgName = ((FieldGroup)fg.getNextSibling().getResource()).name().getValue(); |
|
13411 |
result += fgName == null ? "UN" : fgName; |
|
13412 |
} |
|
13413 |
result += "] "; |
|
13414 |
if (fg.getNextSibling() == null || fg.getNextSibling().isUnknown()) |
|
13415 |
break; |
|
13416 |
} |
|
13417 |
System.out.println(result); |
|
13418 |
|
|
13419 |
result = ""; |
|
13420 |
for(Entry<Integer, FieldGroup> entry : rows2fg.entrySet()) |
|
13421 |
{ |
|
13422 |
result += entry.getKey() + " -> " + entry.getValue().name().getValue() + ", "; |
|
13423 |
} |
|
13424 |
System.out.println(result); |
|
13425 |
System.out.println(); |
|
13426 |
} |
|
13427 | ||
13428 |
/** |
|
13429 | 13258 |
* This method actualizes field-groups of this frame in correspondance with |
13430 | 13259 |
* the current iteration (DOWN/UP step). For the cases DOWN-SIZE != 1 this method will |
13431 | 13260 |
* iterate steps one by one as it would be several DOWN/UP 1 statements. |
... | ... | |
13498 | 13327 |
} |
13499 | 13328 | |
13500 | 13329 |
/** |
13501 |
* This method checks if the specified field-group is used for some row in this frame. |
|
13502 |
* |
|
13503 |
* @param groupHandle |
|
13504 |
* Handle of specified field-group. |
|
13505 |
* |
|
13506 |
* @return true - if field-group is associated with some row in this frame |
|
13507 |
* false - otherwise. |
|
13508 |
*/ |
|
13509 |
private boolean isFGAssigned(handle groupHandle) |
|
13510 |
{ |
|
13511 |
return getFGRow(groupHandle) != null; |
|
13512 |
} |
|
13513 |
|
|
13514 |
/** |
|
13515 | 13330 |
* This method searches the frame row for specified field-group. |
13516 | 13331 |
* TODO: use bidirectional map |
13517 | 13332 |
* |
src/com/goldencode/p2j/ui/GenericWidget.java 2022-05-16 21:47:21 +0000 | ||
---|---|---|
397 | 397 |
package com.goldencode.p2j.ui; |
398 | 398 | |
399 | 399 |
import com.goldencode.util.*; |
400 | ||
401 |
import net.sf.ehcache.constructs.nonstop.concurrency.*; |
|
402 | ||
400 | 403 |
import com.goldencode.p2j.persist.*; |
401 | 404 |
import com.goldencode.p2j.util.*; |
402 | 405 | |
... | ... | |
634 | 637 |
this.frame = frame; |
635 | 638 |
this.config.frameId = frame.getFrameId(); |
636 | 639 |
|
637 |
if (this instanceof BaseEntity && !(this instanceof FieldGroup)) |
|
640 |
final FieldGroup fg = frame.getFieldGroup(); |
|
641 |
if (!(this instanceof FieldGroup)) |
|
638 | 642 |
{ |
639 |
FieldGroup fg = frame.getFieldGroup(); |
|
640 | ||
641 |
// fg == null when this frame widget is being initialized, |
|
642 |
// during the initialization this method may be called to link |
|
643 |
// this widget with the corresponding GenericFrame part and we don't |
|
644 |
// want it to end up in the field group |
|
645 |
if (fg != null) |
|
643 |
if (this instanceof BaseEntity && fg != null) |
|
646 | 644 |
{ |
645 |
// fg == null when this frame widget is being initialized, |
|
646 |
// during the initialization this method may be called to link |
|
647 |
// this widget with the corresponding GenericFrame part and we don't |
|
648 |
// want it to end up in the field group |
|
647 | 649 |
((BaseEntity) this).group = fg; |
648 | 650 |
if (dynamic) |
649 | 651 |
{ |
650 | 652 |
fg.addWidget(this); |
651 | 653 |
} |
652 | 654 |
} |
653 |
} |
|
654 | 655 | |
655 |
// dor dynamic widgets this is the place where we need to initialize all frame internals |
|
656 |
// related to the widget integration into the frame functionality |
|
657 |
if (dynamic && !(this instanceof FieldGroup)) |
|
658 |
{ |
|
659 |
if (!(this instanceof FrameWidget)) |
|
656 |
// for dynamic widgets this is the place where we need to initialize all frame internals |
|
657 |
// related to the widget integration into the frame functionality |
|
658 |
if (dynamic) |
|
660 | 659 |
{ |
661 |
if (frameLock) |
|
662 |
{ |
|
663 |
// continue collecting changes if frame lock was set |
|
664 |
frame.batch(true); |
|
665 |
} |
|
666 |
|
|
667 |
frame.addDynamicWidget(this); |
|
668 |
|
|
669 |
// added this dynamic widget to its field group if it hasn't been included yet. |
|
670 |
FieldGroup fg = frame.getFieldGroup(); |
|
671 |
if (fg != null) |
|
672 |
{ |
|
673 |
fg.addDynamicWidget(this, false); |
|
674 |
fg.addNewTabItem(this); |
|
660 |
if (!(this instanceof FrameWidget)) |
|
661 |
{ |
|
662 |
if (frameLock) |
|
663 |
{ |