Project

General

Profile

6764.02.patch

Marian Edu, 09/29/2022 07:06 AM

Download (34.6 KB)

View differences:

new/src/com/goldencode/p2j/ui/EventDefinition.java 2022-09-28 10:39:06 +0000
63 63
**     CA  20210917          Javadoc fixes.
64 64
**     CA  20211005          Set the matchedWidgetId when lookup is performed.
65 65
**     SBI 20211024          Added containsWidget(int) method.
66
**     ME  20220928          Rewrite trigger lookup, move some of the logic in EventList.
66 67
**/
67 68

  
68 69
/*
......
855 856
    * Checks whether this event matches any event defined in this <code>EventDefinition</code>
856 857
    * instance.
857 858
    *
858
    * @param    frameId
859
    *           Frame ID, can be <code>-1</code>.
860 859
    * @param    widgetId
861 860
    *           Widget ID to check or -1 if this is a global anywhere event.
862 861
    * @param    event
......
866 865
    *           seach for an exit condition.
867 866
    * @param    specific
868 867
    *           <code>true</code> if an exact match is to be returned.
869
    * @param    universal
870
    *           <code>true</code> if the event is of the universal class.
871
    * @param    result
872
    *           On output both trigger ID and matched widget ID may be modified.  If no match
873
    *           was found, then the trigger ID will be set to -1.
868
    * @return   returns trigger ID or -1 if no match was found.
874 869
    */
875
   public void lookup(int     frameId,
876
                      int     widgetId,
870
   public int lookup(int     widgetId,
877 871
                      Integer event,
878 872
                      boolean isTrigger,
879
                      boolean specific,
880
                      boolean universal,
881
                      TriggerMatch result)
873
                      boolean specific)
882 874
   {
883
      result.matchedWidgetId = -1;
884

  
885 875
      // check the search type
886 876
      if (isTrigger && triggerId == -1)
887 877
      {
888 878
         // no match; not a trigger
889
         result.triggerId = -1;
890
         return;
879
         return -1;
891 880
      }
892 881

  
893 882
      if (!isTrigger && triggerId != -1)
894 883
      {
895 884
         // no match; not an exit condition
896
         result.triggerId = -1;
897
         return;
885
         return -1;
898 886
      }
899 887

  
900 888
      // check if the event is listed
901 889
      if (!isEventMatch(event))
902 890
      {
903
         result.triggerId = -1;
904
         return;
891
         return -1;
905 892
      }
906 893

  
907 894
      // check global anywhere case
908
      if (globalAnywhere && widgetId == -1)
909
      {
910
         result.triggerId = isTrigger ? triggerId : 0;
911
         return;
912
      }
913

  
914
      if (!hasWidget() && widgetId != -1)
915
      {
916
         // no match; only global anywhere
917
         result.triggerId = -1;
918
         return;
919
      }
920

  
921
      if (widgetId == -1)
922
      {
923
         // no match; only specific widgets
924
         result.triggerId = -1;
925
         return;
895
      if (widgetId == -1 && globalAnywhere && !hasWidget())
896
      {
897
         return isTrigger ? triggerId : 0;
926 898
      }
927 899

  
928 900
      // check specific widget
929
      if (isWidgetMatch(widgetId))
930
      {
931
         result.triggerId = isTrigger ? triggerId : 0;
932
         result.matchedWidgetId = widgetId;
933
         return;
934
      }
935

  
936
      if (specific && !anywhere) // exact match but if not anywhere
937
      {
938
         result.triggerId = -1;
939
         return;
940
      }
941

  
942
      // check anywhere within the frame
943
      if (!anywhere && !universal)
944
      {
945
         result.triggerId = -1;
946
         return;
947
      }
948

  
949
      // WARNING: This code can currently only run on the client due to direct references to ThinClient,
950
      //          Browse, TitledWindow, Window and Widget.
951
      Widget<?> w = ThinClient.getInstance().registry().getComponent(widgetId);
952
      Browse<?> parentBrowse = w != null ? (Browse<?>) w.parent(Browse.class) : null;
953
      if (parentBrowse != null)
954
      {
955
         // If an event occurs for an in-browse editor, and there is a trigger for the browse column, it
956
         // should be fired. But if there is not column trigger and there is an OF BROWSE br ANYWHERE trigger,
957
         // it should be fired instead. This case is handled here.
958
         int browseId = parentBrowse.getId().asInt();
959
         if (isWidgetMatch(browseId))
960
         {
961
            result.triggerId = isTrigger ? triggerId : 0;
962
            result.matchedWidgetId = browseId;
963
            return;
964
         }
965
      }
966

  
967
      if (frameId != -1)
968
      {
969
         if (isWidgetMatch(frameId))
970
         {
971
            result.triggerId = isTrigger ? triggerId : 0;
972
            result.matchedWidgetId = frameId;
973
            return;
974
         }
975
      }
976
      else
977
      {
978
         TitledWindow<?> winInFocus = UiUtils.getCurrentFocusWindow();
979
         if (winInFocus instanceof Window && winInFocus.getId().asInt() == widgetId)
980
         {
981
            // added events propagation from window to its frames
982
            Widget<?>[] topComps = UiUtils.getTopLevelComponents((Window<?>) winInFocus);
983
            
984
            for (Widget<?> widget : topComps)
985
            {
986
               if (widget.getId() != null && isWidgetMatch(widget.getId().asInt()))
987
               {
988
                  result.triggerId = isTrigger ? triggerId : 0;
989
                  result.matchedWidgetId = widget.getId().asInt();
990
                  return;
991
               }
992
            }
993
         }
994
         else
995
         {
996
            // determine the frame ID based on given widget ID, consider parent frames as well
997
            for (Integer parentFrameId : UiUtils.getParentFrames(widgetId))
998
            {
999
               if (isWidgetMatch(parentFrameId))
1000
               {
1001
                  result.triggerId = isTrigger ? triggerId : 0;
1002
                  result.matchedWidgetId = parentFrameId;
1003
                  return;
1004
               }
1005
            }
1006
         }
1007
      }
1008

  
1009
      result.triggerId = -1;
901
      if (widgetId != -1 && isWidgetMatch(widgetId))
902
      {
903
         if (!specific || !anywhere) // exact match but if not anywhere
904
         {
905
            return isTrigger ? triggerId : 0;
906
         }
907
         
908
      }
909

  
910
      return -1;
1010 911
   }
1011 912

  
1012 913
   /**
new/src/com/goldencode/p2j/ui/EventList.java 2022-09-28 11:12:07 +0000
165 165
**     ME  20220907          Rework lookupEventHelper to consider function key, any-printable, any-key for key
166 166
**                           events (in that order), first for specific widget then anywhere and last the frame.
167 167
**     CA  20220907          Added isEventMatchForWidget.
168
**     ME  20220928          Clean-up lookupEventHandler, reduce recursive calls.
168 169
*/
169 170

  
170 171
/*
......
1859 1860
    * {@link #lookup(int, int, boolean, boolean, boolean, TriggerMatch)} with
1860 1861
    * <code>specificWidget</code> set to <code>false</code>.
1861 1862
    *
1862
    * @param    fid
1863
    *           Frame ID, can be <code>-1</code>
1863
    * @param    cid
1864
    *           Parent container ID, can be <code>-1</code>
1864 1865
    * @param    wid
1865 1866
    *           widget ID, can't be <code>-1</code>, but can be <code>SESSION_WINDOW_ID</code>.
1866 1867
    * @param    trigger
......
1874 1875
    *           For more information see
1875 1876
    *           {@link #lookup(int, int, boolean, boolean, boolean, TriggerMatch)}.
1876 1877
    */
1877
   public void lookup(int fid, int wid, boolean trigger, boolean isKey, TriggerMatch result)
1878
   public void lookup(int cid, int wid, boolean trigger, boolean isKey, TriggerMatch result)
1878 1879
   {
1879
      lookup(fid, wid, trigger, isKey, false, result);
1880
      lookup(cid, wid, trigger, isKey, false, result);
1880 1881
   }
1881 1882

  
1882 1883
   /**
......
1924 1925
    * <br>
1925 1926
    * If the widget is the session window, only the first step is taken.
1926 1927
    *
1927
    * @param    fid
1928
    *           Frame ID, can be <code>-1</code>
1928
    * @param    cid
1929
    *           Parent container ID, can be <code>-1</code>
1929 1930
    * @param    wid
1930 1931
    *           widget ID, can't be <code>-1</code>, but can be <code>SESSION_WINDOW_ID</code>.
1931 1932
    * @param    trigger
......
1934 1935
    * @param    isKey
1935 1936
    *           Marks real key pressed by user.
1936 1937
    * @param    specificWidget
1937
    *           When <code>true</code> only the specific widget events are lsearched, i.e.
1938
    *           When <code>true</code> only the specific widget events are searched, i.e.
1938 1939
    *           anywhere, session window, etc. are ignored.
1939 1940
    * @param    result
1940 1941
    *           On input this contains the numeric event code that is the subject of the search.
......
1944 1945
    *           given event code in the case of ANY-KEY or ANY-PRINTABLE).  For exit conditions,
1945 1946
    *           the trigger ID will be the found event index when it is found.
1946 1947
    */
1947
   public void lookup(int fid, int wid, boolean trigger, boolean isKey,
1948
   public void lookup(int cid, int wid, boolean trigger, boolean isKey,
1948 1949
                      boolean specificWidget, TriggerMatch result)
1949 1950
   {
1950
      lookupWorker(fid, wid, trigger, isKey, specificWidget, result);
1951
      lookupWorker(cid, wid, trigger, isKey, specificWidget, result);
1951 1952

  
1952 1953
      if (result.triggerId == -1 && chain != null)
1953 1954
      {
1954
         chain.lookup(fid, wid, trigger, isKey, result);
1955
         chain.lookup(cid, wid, trigger, isKey, result);
1955 1956
      }
1956 1957
   }
1957 1958

  
......
2576 2577
   /**
2577 2578
    * Worker routine for {@link #lookup(int, int, boolean, boolean, TriggerMatch)}.
2578 2579
    * 
2579
    * @param    fid
2580
    *           Frame ID, can be <code>-1</code>.
2580
    * @param    cid
2581
    *           Parent container ID, can be <code>-1</code>.
2581 2582
    * @param    wid
2582 2583
    *           Widget ID, can't be <code>-1</code>, but can be <code>SESSION_WINDOW_ID</code>.
2583 2584
    * @param    trig
......
2596 2597
    *           given event code in the case of ANY-KEY or ANY-PRINTABLE).  For exit conditions,
2597 2598
    *           the trigger ID will be the found event index when it is found.
2598 2599
    */
2599
   private void lookupWorker(int fid, int wid, boolean trig, boolean isKey,
2600
   private void lookupWorker(int cid, int wid, boolean trig, boolean isKey,
2600 2601
                             boolean specificWidget, TriggerMatch result)
2601 2602
   {
2602
      LookupWidgetKey key = new LookupWidgetKey(fid, wid, trig, isKey, specificWidget, result.eventId);
2603
      LookupWidgetKey key = new LookupWidgetKey(cid, wid, trig, isKey, specificWidget, result.eventId);
2603 2604
      if (lookupWidgets == null)
2604 2605
      {
2605 2606
         lookupWidgets = new HashMap<>();
......
2616 2617
      {
2617 2618
         // obtain the event name and class
2618 2619
         String event = Keyboard.eventName(result.eventId);
2619
         boolean universal = EventDefinition.isEventUniversal(result.eventId);
2620 2620
         
2621 2621
         // convert the event name to the proper case
2622 2622
         String ev = setCase(event);
......
2627 2627
         order = calculatesEventsPriority(events);
2628 2628
         
2629 2629
         // is this a valid label?
2630
         if (code != -1)
2630
         if (code != -1 && code != result.eventId)
2631 2631
         {
2632 2632
            // yes, it was a label so now convert the common code to the primary label name
2633 2633
            String primary = Keyboard.keyLabel(code); 
......
2641 2641
                                           " could not be resolved!");
2642 2642
         }
2643 2643
         
2644
         // lookup event for a specific widget and honor any-printable/any-key if needed
2645
         lookupEventHelper(-1, wid, evCode, trig, true, false, isKey, result);
2646
         
2647
         if (result.triggerId != -1)
2648
         {
2649
            return;
2650
         }
2651
   
2652
         if (specificWidget)
2653
         {
2654
            return;
2655
         }
2656
   
2657
         // lookup event for a anywhere in the frame and honor any-printable/any-key if needed
2658
         lookupEventHelper(fid, wid, evCode, trig, false, universal, isKey, result);
2659
         
2660
         if (result.triggerId != -1)
2644
         // lookup event for the widget and honor any-printable/any-key if needed (specific or anywhere)
2645
         if (lookupEventHelper(wid, evCode, trig, specificWidget, isKey, result) != -1 || specificWidget)
2646
         {
2647
            return;
2648
         }
2649
   
2650
         // lookup event for the parent container and honor any-printable/any-key if needed
2651
         if (cid != -1 && lookupEventHelper(cid, evCode, trig, false, isKey, result) != -1)
2661 2652
         {
2662 2653
            result.matchedWidgetId = wid;
2663 2654
            return;
2664 2655
         }
2665 2656
         
2666
         // look the list up for the specified event and the containing frame
2667
         if (!trig || universal)
2668
         {
2669
            for (EventDefinition ed : events)
2670
            {
2671
               ed.lookup(-1, fid, evCode, trig, true, false, result);
2672
               if (result.triggerId != -1)
2673
               {
2674
                  result.matchedWidgetId = fid;
2675
                  return;
2676
               }
2677
            }
2678
         }
2679

  
2680 2657
         ThinClient tc = ThinClient.getInstance();
2681 2658
         Widget<?> widget = tc.getWidget(wid);
2682 2659
         
......
2689 2666
            {
2690 2667
               int id = frame.getId().asInt();
2691 2668
               
2692
               if (id != wid && id != fid && frame.isVisible() && !frame.hidden())
2693
               {
2694
                  lookupEventHelper(id, wid, evCode, trig, true, false, isKey, result);
2695
               }
2696
               
2697
               if (result.triggerId != -1)
2669
               if (id != wid && id != cid && frame.isVisible() && !frame.hidden() &&  lookupEventHelper(id, evCode, trig, false, isKey, result) != -1)
2698 2670
               {
2699 2671
                  result.matchedWidgetId = wid;
2700 2672
                  return;
2701 2673
               }
2702 2674
            }
2703 2675
            
2704
            TopLevelWindow<?> win = null;
2705
            Frame<?> rootFrame =  UiUtils.locateRootFrame(widget);
2706
            if (rootFrame != null)
2707
            {
2708
               if (rootFrame.isDialog())
2709
               {
2710
                  // for dialog-box, consider parent windows only if its top-level window is not visible
2711
                  TopLevelWindow dlgWnd = rootFrame.topLevelWindow();
2712
                  if (dlgWnd == null || !dlgWnd.isVisible())
2713
                  {
2714
                     int parentId = rootFrame.config().parentId;
2715
                     if (WidgetId.INVALID_WIDGET_ID != parentId)
2716
                     {
2717
                        Widget parent = tc.getWidget(parentId);
2718
                        if (parent instanceof TopLevelWindow)
2719
                        {
2720
                           win = (TopLevelWindow<?>) parent;
2721
                        }
2722
                     }
2723
                  }
2724
               }
2725
               else
2726
               {
2727
                  win = rootFrame.topLevelWindow();
2728
               }
2729
            }
2730
            else if (widget instanceof TopLevelWindow)
2731
            {
2732
               win = (TopLevelWindow<?>) widget;
2733
            }
2734

  
2676
            TopLevelWindow<?> win = UiUtils.getTopLevelWindow(widget);
2735 2677
            // search the target trigger in the window parent hierarchy up recursively
2736 2678
            while (win != null && win.config() != null)
2737 2679
            {
2738 2680
               // note that the target window doesn't need to be visible (except dialog-box, but visible
2739 2681
               // dialog-box should not reach this code block)
2740
               int winid = win.getId().asInt();
2741
               // lookup event for a specific widget and honor any-printable/any-key if needed
2742
               lookupEventHelper(rootFrame == null ? -1 : rootFrame.getId().asInt(),
2743
                                 winid, evCode, trig, true, false, isKey, result);
2744

  
2745
               if (result.triggerId != -1)
2682
               int id = win.getId().asInt();
2683
               if (id != wid && id != cid && lookupEventHelper(win.getId().asInt(), evCode, trig, true, isKey, result) != -1)
2746 2684
               {
2747
                  result.matchedWidgetId = winid;
2748
                  break;
2685
                  return;
2749 2686
               }
2750 2687

  
2751 2688
               BaseConfig c = win.config();
2752 2689
               win = (TopLevelWindow<?>) tc.getWidget(c.parentId);
2753 2690
            }
2691
            
2754 2692
         }
2755
         
2756
         if (result.triggerId != -1)
2757
            return;
2758
         
2759 2693
         // lookup event for a anywhere globally and honor any-printable/any-key if needed
2760
         lookupEventHelper(-1, -1, evCode, trig, false, false, isKey, result);
2761
         
2762
         if (result.triggerId != -1)
2763
            return;
2694
         lookupEventHelper(-1, evCode, trig, false, isKey, result);
2764 2695
      }
2765 2696
      finally
2766 2697
      {
......
2862 2793
    * and then upon an ANY-PRINTABLE event and finally upon an ANY-KEY event. The first
2863 2794
    * match aborts further checking.
2864 2795
    *
2865
    * @param    fid
2866
    *           Frame ID, can be <code>-1</code>.
2867
    * @param    wid
2868
    *           Widget ID to check or -1 if this is a global anywhere event.
2869
    * @param    evCode
2870
    *           The event ID.
2871
    * @param    trigger  
2872
    *           <code>true</code> if the search is for a trigger or <code>false</code> to 
2873
    *           search for an exit condition.
2874
    * @param    specific
2875
    *           <code>true</code> if an exact match is to be returned.
2876
    * @param    universal
2877
    *           <code>true</code> if the event is of the universal class.
2878
    * @param    isKey
2879
    *           <code>true</code> if the event was generated from the keyboard, which will
2880
    *           cause the ANY-PRINTABLE/ANY-KEY events to be checked.
2881
    * @param    result
2882
    *           On input this contains the numeric event code that is the subject of the search.
2883
    *           On output both the event code and the trigger id may be modified.  If no match
2884
    *           was found, then the trigger ID will be set to -1.  For trigger searches, this is
2885
    *           the matching trigger ID and matched event code (which may be different from the
2886
    *           given event code in the case of ANY-KEY or ANY-PRINTABLE).  For exit conditions,
2887
    *           the trigger ID will be the found event index when it is found.
2888
    */
2889
   private void lookupEventHelper(int          fid,
2890
                                  int          wid,
2891
                                  Integer      evCode,
2892
                                  boolean      trigger,
2893
                                  boolean      specific,
2894
                                  boolean      universal,
2895
                                  boolean      isKey,
2896
                                  TriggerMatch result)
2897
   {
2898
      lookupEventHelper(fid, wid, evCode, trigger, specific, universal, isKey, false, result);
2899
   }
2900
   
2901
   /**
2902
    * Handles an event definition lookup for all known events and then it may also try the
2903
    * same lookup for ANY-PRINTABLE and ANY-KEY events, depending on the properties of the
2904
    * original event.  This will match first on a specific event match (e.g. the letter "A"
2905
    * and then upon an ANY-PRINTABLE event and finally upon an ANY-KEY event. The first
2906
    * match aborts further checking.
2907
    *
2908
    * @param    fid
2909
    *           Frame ID, can be <code>-1</code>.
2910
    * @param    wid
2911
    *           Widget ID to check or -1 if this is a global anywhere event.
2912
    * @param    evCode
2913
    *           The event ID.
2914
    * @param    trigger  
2915
    *           <code>true</code> if the search is for a trigger or <code>false</code> to 
2916
    *           search for an exit condition.
2917
    * @param    specific
2918
    *           <code>true</code> if an exact match is to be returned.
2919
    * @param    universal
2920
    *           <code>true</code> if the event is of the universal class.
2921
    * @param    isKey
2922
    *           <code>true</code> if the event was generated from the keyboard, which will
2923
    *           cause the ANY-PRINTABLE/ANY-KEY events to be checked.
2924
    * @param    isKeyFunction
2925
    *           <code>true</code> if the event is for a key function, as opposed to key label.
2926
    * @param    result
2927
    *           On input this contains the numeric event code that is the subject of the search.
2928
    *           On output both the event code and the trigger id may be modified.  If no match
2929
    *           was found, then the trigger ID will be set to -1.  For trigger searches, this is
2930
    *           the matching trigger ID and matched event code (which may be different from the
2931
    *           given event code in the case of ANY-KEY or ANY-PRINTABLE).  For exit conditions,
2932
    *           the trigger ID will be the found event index when it is found.
2933
    */
2934
   private void lookupEventHelper(int          fid,
2935
                                  int          wid,
2936
                                  Integer      evCode,
2937
                                  boolean      trigger,
2938
                                  boolean      specific,
2939
                                  boolean      universal,
2940
                                  boolean      isKey,
2941
                                  boolean      isKeyFunction,
2796
    * @param    wid
2797
    *           Widget ID to check or -1 if this is a global anywhere event.
2798
    * @param    evCode
2799
    *           The event ID.
2800
    * @param    trigger  
2801
    *           <code>true</code> if the search is for a trigger or <code>false</code> to 
2802
    *           search for an exit condition.
2803
    * @param    specific
2804
    *           <code>true</code> if an exact match is to be returned.
2805
    * @param    isKey
2806
    *           <code>true</code> if the event was generated from the keyboard, which will
2807
    *           cause the ANY-PRINTABLE/ANY-KEY events to be checked.
2808
    * @param    result
2809
    *           On input this contains the numeric event code that is the subject of the search.
2810
    *           On output both the event code and the trigger id may be modified.  If no match
2811
    *           was found, then the trigger ID will be set to -1.  For trigger searches, this is
2812
    *           the matching trigger ID and matched event code (which may be different from the
2813
    *           given event code in the case of ANY-KEY or ANY-PRINTABLE).  For exit conditions,
2814
    *           the trigger ID will be the found event index when it is found.
2815
    */
2816
   private int lookupEventHelper(int          wid,
2817
                                  Integer      evCode,
2818
                                  boolean      trigger,
2819
                                  boolean      specific,
2820
                                  boolean      isKey,
2942 2821
                                  TriggerMatch result)
2943 2822
   {
2944 2823
      if (eventCodes == null)
......
2947 2826
         events.forEach(evt -> evt.gatherEventCodes(eventCodes));
2948 2827
      }
2949 2828

  
2829
      int functionCode = isKey ? Keyboard.eventCode(Keyboard.keyFunction(evCode)) : -1;
2830
      
2950 2831
      if (!eventCodes.contains(evCode)
2951
               && (!isKey || (!eventCodes.contains(Keyboard.SE_ANY_PRINTABLE)
2832
               && (!isKey || (functionCode != -1 && !eventCodes.contains(functionCode) && 
2833
                        !eventCodes.contains(Keyboard.SE_ANY_PRINTABLE)
2952 2834
                        && !eventCodes.contains(Keyboard.SE_ANY_KEY))))
2953 2835
      {
2954
         return;
2836
         return -1;
2955 2837
      }
2956 2838

  
2839
      // array for trigger ids matching in order: 
2840
      // 0 - key function
2841
      // 1 - any-printable
2842
      // 2 - any-key
2843
      // 3 - key label anywhere
2844
      // 4 - key function anywhere
2845
      // 5 - any-printable anywhere
2846
      // 6 - any-key anywhere
2847
      int[] matches = new int[] { -1, -1, -1, -1, -1, -1, -1};
2848
      
2957 2849
      // look the list up for the specified event and widget 
2958 2850
      for (EventDefinition ed: events)
2959 2851
      {
2960
         // do not use parent frame here, instead use the same widget id
2961
         ed.lookup(wid, wid, evCode, trigger, specific, universal, result);
2962
         
2963
         // if found check for widget match or default trigger
2964
         if (result.triggerId != -1 && (!specific || !ed.isAnywhere())
2965
                  && (wid == -1 || ed.isWidgetMatch(wid)))
2966
         {
2967
            return;
2968
         }
2969
      }
2970
               
2971
      
2972
      // keyboard only, look for "function key" then "any printable" and "any key" as needed
2973
      if (isKey && evCode != Keyboard.SE_ANY_KEY) {
2974
         // honor "function key" event (must be before ANY-PRINTABLE)
2975
         if (!isKeyFunction && evCode != Keyboard.SE_ANY_PRINTABLE)
2976
         {
2977
            int functionCode = Keyboard.eventCode(Keyboard.keyFunction(evCode));
2978
            
2979
            if (functionCode != -1 && !evCode.equals(functionCode))
2980
            {
2981
               lookupEventHelper(fid, wid, functionCode, trigger, specific, universal, isKey, true, result);
2982
               
2983
               if (result.triggerId != -1)
2984
               {
2985
                  result.eventId = functionCode;
2986
                  
2987
                  return;
2988
               }
2989
            }
2990
         }
2991

  
2992
         // honor ANY-PRINTABLE event (must be before ANY-KEY)
2993
         if (evCode != Keyboard.SE_ANY_PRINTABLE)
2994
         {
2995
            if (Keyboard.isPrintable(Keyboard.eventName(evCode)))
2996
            {
2997
               lookupEventHelper(fid, wid, Keyboard.SE_ANY_PRINTABLE, trigger, specific, universal, isKey, true, result);
2998
               
2999
               if (result.triggerId != -1)
3000
               {
3001
                  result.eventId = Keyboard.SE_ANY_PRINTABLE;
3002
                  
3003
                  return;
3004
               }
3005
            }
3006
            
3007
            // look for ANY-KEY
3008
            if (result.eventId != Key.VK_ALT && result.eventId != Key.VK_CTRL
3009
                     && result.eventId != Key.VK_SHIFT)
3010
            {
3011
               
3012
               lookupEventHelper(fid, wid, Keyboard.SE_ANY_KEY, trigger, specific, universal, isKey, true, result);
3013
               
3014
               if (result.triggerId != -1)
3015
               {
3016
                  result.eventId = Keyboard.SE_ANY_KEY;
3017
                  
3018
                  return;
3019
               }
3020
            }
3021
         }
3022
      }
3023
      
3024
      // if specific trigger wasn't found fallback to anywhere for the widget
3025
      if (specific)
3026
      {
3027
         lookupEventHelper(fid, wid, evCode, trigger, false /* anywhere */, universal, isKey, isKeyFunction, result);
3028
      }
3029
      else
3030
      {
3031
         // lookup for parent frame triggers
3032
         if (fid != -1 && fid != wid)
3033
         {
3034
            lookupEventHelper(fid, fid, evCode, trigger, false /* anywhere */, universal, isKey, isKeyFunction, result);
3035
            
3036
            // reset back the widget id
3037
            if (result.triggerId != -1)
3038
            {
3039
               result.matchedWidgetId = wid;
3040
            }
3041
         }
3042
      }
3043
      
2852
         // for specific skip anywhere triggers
2853
         if (specific && ed.isAnywhere()) {
2854
            continue;
2855
         }
2856
         
2857
         int triggerId = ed.lookup(wid, evCode, trigger, specific);
2858
         
2859
         if (triggerId != -1) {
2860
            if (!ed.isAnywhere()) 
2861
            {
2862
               // exact match
2863
               result.triggerId = triggerId;
2864
               
2865
               return triggerId;
2866
            }
2867
            else 
2868
            {
2869
               matches[3] = triggerId; // key label anywhere
2870
            }
2871
         }
2872
         else if (isKey)
2873
         {
2874
            // key function: 0 - widget, 4 - anywhere
2875
            // if already have a match for widget no point on testing further
2876
            if (functionCode != -1 && functionCode != evCode && matches[0] == -1)
2877
            {
2878
               triggerId = ed.lookup(wid, functionCode, trigger, specific);
2879
               
2880
               if (triggerId != -1) {
2881
                  matches[ed.isAnywhere() ? 4 : 0] = triggerId;
2882
               }
2883
            }
2884

  
2885
            // any-printable: 1 - widget, 5 - anywhere
2886
            // if already have a match for widget no point on testing further
2887
            if (evCode != Keyboard.SE_ANY_PRINTABLE && matches[0] == -1 && matches[1] == -1
2888
                     && (matches[5] == -1 || !ed.isAnywhere())
2889
                     && Keyboard.isPrintable(Keyboard.eventName(evCode)))
2890
            {
2891
               triggerId = ed.lookup(wid, Keyboard.SE_ANY_PRINTABLE, trigger, specific);
2892

  
2893
               if (triggerId != -1)
2894
               {
2895
                  matches[ed.isAnywhere() ? 5 : 1] = triggerId;
2896
               }
2897
            }
2898

  
2899
            // any-key: 2 - widget, 6 - anywhere
2900
            // if already have a match for widget no point on testing further
2901
            if (evCode != Keyboard.SE_ANY_KEY && matches[0] == -1 && matches[1] == -1
2902
                     && matches[2] == -1 && (matches[6] == -1 || !ed.isAnywhere()))
2903
            {
2904
               triggerId = ed.lookup(wid, Keyboard.SE_ANY_KEY, trigger, specific);
2905

  
2906
               if (triggerId != -1)
2907
               {
2908
                  matches[ed.isAnywhere() ? 6 : 2] = triggerId;
2909
               }
2910
            }
2911
         }
2912
      }
2913
               
2914
      
2915
      // no exact match
2916
      for (int i = 0; i < (specific ? 3 : matches.length); i++)
2917
      {
2918
         if (matches[i] != -1) {
2919
            result.triggerId = matches[i];
2920
            return matches[i];
2921
         }
2922
      }
2923
      
2924
      return -1;
3044 2925
   }
3045 2926
   
3046 2927
   /**
new/src/com/goldencode/p2j/ui/chui/ThinClient.java 2022-09-28 11:10:39 +0000
2856 2856
**     EVL 20220913          Fix for regression in non date fill-ins with screen value getting.
2857 2857
**      HC 20220915          Performance: Eliminated integer auto-boxing when enqueuing widget attributes.
2858 2858
**      CA 20220918          Allow legacy client sockets to be ran on FWD server instead of FWD client.
2859
**      ME 20220920          Use widget parent 'container' when looking up triggers.
2859 2860
*/
2860 2861

  
2861 2862
/*
......
17253 17254
         // assume no trigger is found
17254 17255
         moreKeys = true;
17255 17256

  
17256
         Frame frame = UiUtils.locateFrame(focused);
17257
         Widget container = UiUtils.locateContainer(focused);
17257 17258
         int focusId = UiUtils.lookupWidgetIdAsInt(focused);
17258
         int frameId = UiUtils.lookupWidgetIdAsInt(frame);
17259
         int containerId = UiUtils.lookupWidgetIdAsInt(container);
17259 17260
         
17260 17261
         TriggerMatch result = new TriggerMatch(key.keyCode());
17261 17262

  
17262 17263
         // check if there is a trigger for this specific key
17263
         currentEventList.lookup(frameId, focusId, true, true, result);
17264
         currentEventList.lookup(containerId, focusId, true, true, result);
17264 17265
         
17265 17266
         if (result.triggerId == -1)
17266 17267
         {
......
17272 17273
               result = new TriggerMatch(defaultEvent);
17273 17274
               
17274 17275
               // check if there is a trigger for this default event
17275
               currentEventList.lookup(frameId, focusId, true, true, result);
17276
               currentEventList.lookup(containerId, focusId, true, true, result);
17276 17277
               
17277 17278
               // only if there is no other more specific match AND there is a match to 
17278 17279
               // a system event, do we call invoke
......
20606 20607
      // in the event list for an active user interface trigger
20607 20608
      if (key > 0 && key != KeyInput.CHAR_UNDEFINED && evt.id() != EventType.KEY_RELEASED)
20608 20609
      {
20609
         tr = invokeTriggers(src, key, false);
20610
         tr = invokeTriggers(src, key, evt.isRealKey());
20610 20611

  
20611 20612
         if (tr.executed)
20612 20613
         {
......
21626 21627
      }
21627 21628
      else if (!WidgetId.virtualWidget(widgetId))
21628 21629
      {
21629
         currentEventList.lookup(frameId, widgetId, true, isKey, result);
21630
         Widget container = UiUtils.locateContainer(widget);
21631
         
21632
         currentEventList.lookup(container != null && container != frame ? UiUtils.getWidgetIdAsInt(container) : frameId, widgetId, true, isKey, result);
21630 21633
      }
21631 21634

  
21632 21635
      // activate trigger
......
26153 26156
   /**
26154 26157
    * Applies widget attributes in the widget tree.
26155 26158
    *
26156
    * @param   widgetAttrs
26159
    * @param   widgetAttrsIds
26157 26160
    *          Flat array of widget attribute ids.
26158 26161
    * @param   widgetAttrValues
26159 26162
    *          Flat array of widget attribute values.
new/src/com/goldencode/p2j/ui/client/UiUtils.java 2022-09-29 11:03:14 +0000
110 110
**         20220527 Improved error logging.
111 111
**     IAS 20220803 Fixed loop condition in 'resolveLocalFileResource'.
112 112
**     EVL 20220809 Fixed issue with buildCanonicalUrl() on Windows server installation.
113
**     ME  20220928 Added two methods to get widget container and top level window.
113 114
*/
114 115

  
115 116
/*
......
807 808
   }
808 809

  
809 810
   /**
811
    * Return the widget which contains the specified widget. Most of the time this going to be the 
812
    * frame containing the widget except for the browse column where the container is the browse. 
813
    *
814
    * @param    widget
815
    *           Widget for which to find the container.
816
    *
817
    * @return   The container widget which contains specified widget, or <code>null</code>
818
    *           if <code>null</code> is passed as the parameter or the widget 
819
    *           is not placed in a container. 
820
    */
821
   public static Widget<?> locateContainer(Widget<?> widget)
822
   {
823
      if (widget == null)
824
      {
825
         return null;
826
      }
827

  
828
      if (!(widget instanceof Frame))
829
      {
830
         // check if parent is a browse (browse column)
831
         Browse<?> browse = widget.parent(Browse.class);
832
         
833
         if (browse != null)
834
         {
835
            return browse;
836
         }
837
      }
838
      
839
      return locateFrame(widget);
840
   }
841
   
842
   /**
810 843
    * Return the root frame which contains the specified widget. If the given 
811 844
    * widget is itself a root frame, then it will be returned.
812 845
    * 
......
1438 1471
   {
1439 1472
      return wnd.getContentPane().widgets();
1440 1473
   }
1474
   
1475
   
1476
   /**
1477
    * Convenience method to retrieve the top level window of a widget.
1478
    * 
1479
    * @param widget
1480
    *        the widget
1481
    * @return  The top level window of the widget.
1482
    */
1483
   public static TopLevelWindow<?> getTopLevelWindow(Widget<?> widget)
1484
   {
1485
      if (widget instanceof TopLevelWindow)
1486
      {
1487
         return (TopLevelWindow<?>) widget;
1488
      }
1489
      
1490
      Frame<?> rootFrame =  UiUtils.locateRootFrame(widget);
1491
      if (rootFrame != null)
1492
      {
1493
         if (rootFrame.isDialog())
1494
         {
1495
            // for dialog-box, consider parent windows only if its top-level window is not visible
1496
            TopLevelWindow dlgWnd = rootFrame.topLevelWindow();
1497
            if (dlgWnd == null || !dlgWnd.isVisible())
1498
            {
1499
               int parentId = rootFrame.config().parentId;
1500
               if (WidgetId.INVALID_WIDGET_ID != parentId)
1501
               {
1502
                  Widget parent = ThinClient.getInstance().getWidget(parentId);
1503
                  if (parent instanceof TopLevelWindow)
1504
                  {
1505
                     return (TopLevelWindow<?>) parent;
1506
                  }
1507
               }
1508
            }
1509
         }
1510
         else
1511
         {
1512
            return rootFrame.topLevelWindow();
1513
         }
1514
      }
1515
      
1516
      return null;
1517
   }
1441 1518

  
1442 1519
   /**
1443 1520
    * Get DCOLOR attribute for specified widget taking into account color