前进、目标  

 report bcalvc_dnd_01 message-id tree_control_msg.


  class lcl_application definition deferred.
  class cl_gui_cfw definition load.

  types: node_table_type like standard table of mtreesnode
           with default key.
* CAUTION: MTREESNODE is the name of the node structure which must
* be defined by the programmer. DO NOT USE MTREESNODE!

  data: g_application type ref to lcl_application,
        g_docking_container_1 type ref to cl_gui_docking_container,
        g_docking_container_2 type ref to cl_gui_docking_container,
        g_tree type ref to cl_gui_simple_tree,
        g_alv type ref to cl_gui_alv_grid,
        g_node_table type node_table_type,

* §1. Define reference variables to CL_DRAGDROP:
*     One for your drag source and one for your drop target.
        g_behaviour_tree type ref to cl_dragdrop,
        g_behaviour_alv type ref to cl_dragdrop,
*
        g_repid like sy-repid,
        g_ok_code type sy-ucomm,
        gt_outtab type table of sbook,
        g_max type value 50.
* You need the layout structure of alv to transfer the handle
* of your defined behaviour (see step 2).
data:   gs_layout type lvc_s_layo.


* §4. Define a class for a data object to exchange data
*      between two controls using the drag and drop operation.
class lcl_dragdropobj definition.
  public section.
    data: ls_sbook type sbook,
          index type i.
endclass.

*---------------------------------------------------------------------*
*       CLASS LCL_APPLICATION DEFINITION
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
* §5. Define methods for three events raised by the drag and drop
*      control. (Note that the names for these events depend on
*      the classes for which the behaviour was defined!).
class lcl_application definition.

  public section.
    data: next_node_key type i.

    methods:
      handle_alv_drag
        for event ondrag
        of cl_gui_alv_grid
        importing e_row e_column e_dragdropobj,
      handle_tree_drop
        for event on_drop
        of cl_gui_simple_tree
        importing node_key drag_drop_object,
      handle_alv_drop_complete
        for event ondropcomplete
        of cl_gui_alv_grid
        importing e_row e_column e_dragdropobj.
endclass.

*---------------------------------------------------------------------*
*       CLASS LCL_APPLICATION IMPLEMENTATION
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
class lcl_application implementation.
*-------------------------------------------------------------------
* §6.In the 'onDrag' event handler create a data object and fill it with
*    appropriate data for your intended operation. This event is used
*    to 'fetch' information from the drag source.
  method handle_alv_drag.
    data: dataobj type ref to lcl_dragdropobj,
          line type sbook.

* Read dragged row
    read table gt_outtab index e_row-index into line.

* create and fill dataobject for events ONDROP and ONDROPCOMPLETE
    create object dataobj.
    move line to dataobj->ls_sbook.

* remember also the row index in case of effect 'move'
    move e_row-index to dataobj->index.

* §7. Assign your data object to the refering event parameter.
*     This parameter ensures that your data object can be referenced
*     in each of the following events.
    e_dragdropobj->object = dataobj.
  endmethod.
*--------------------------------------------------------------------
* §8.Implement the event handler for event 'OnDrop'. This event is used
*    to use your dragged information in combination with your drop
*    source. What is more, you should make all checks
*    if the operation is successful _at this point_.
  method handle_tree_drop.
    data: local_node_table type node_table_type,
          new_node type mtreesnode,
          dataobj type ref to lcl_dragdropobj,
          l_keytxt(30) type c.

*!!!
* Very importent: 'e_dragDropObj->object' can have any instance type
* The needed cast type may lead to a system-exception if the
* cast can not be performed.
* For this reason: use ALWAYS the Catch-Statement to make sure
* that the drag&drop-Operation is aborted properly.
*!!!
    catch system-exceptions move_cast_error = 1.

      dataobj ?= drag_drop_object->object.

      new_node-node_key = next_node_key.
      add to next_node_key.
      new_node-relatkey = node_key.
      new_node-relatship = cl_gui_simple_tree=>relat_last_child.
      perform set_keytxt using dataobj->ls_sbook
                         changing l_keytxt.

      new_node-text = l_keytxt.

      append new_node to local_node_table.
      append new_node to g_node_table.
      call method g_tree->add_nodes
        exporting
          table_structure_name = 'MTREESNODE'
          node_table           = local_node_table
        exceptions
          failed                         = 1
          error_in_node_table            = 2
          dp_error                       = 3
          table_structure_name_not_found = 4
          others                         5.
      if sy-subrc <> 0.
        message a000.
      endif.
* expand node
      call method g_tree->expand_node
          exporting node_key = node_key.

    endcatch.
    if sy-subrc <> 0.
* If anything went wrong this is the clean way of aborting the
* drag and drop operation:
      call method drag_drop_object->abort.
    endif.
  endmethod.
*-------------------------------------------------------------------
* §9.Implement the event handler for event 'OnDropComplete'. This event
*    is used to change the state after a successful drag and drop
*    operation, e.g., update your internal table if a row has been
*    moved.
  method handle_alv_drop_complete.
    data: dataobj type ref to lcl_dragdropobj.

* Again: do not forget to catch this system exception!
    catch system-exceptions move_cast_error = 1.

      dataobj ?= e_dragdropobj->object.
      if e_dragdropobj->effect = cl_dragdrop=>move.
* delete one line from internal table and refresh display
        delete gt_outtab index dataobj->index.
        if sy-subrc eq 0.
* refresh alv control
          call method g_alv->refresh_table_display.
        endif.
      endif.
      endcatch.
      if sy-subrc <> 0.
* If anything went wrong this is the clean way of aborting the
* drag and drop operation:
        call method e_dragdropobj->abort.
      endif.
    endmethod.

  endclass.
*&---------------------------------------------------------------------*
*&      Module  PBO_0400  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
module pbo_100 output.

  set pf-status 'MAIN'.
  set titlebar 'MAIN'.
  if g_tree is initial.
    perform create_and_init_controls.
  endif.

endmodule.                 " PBO_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  PAI_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
module pai_100 input.

  case g_ok_code.
    when 'BACK'" Finish program
      if not g_docking_container_1 is initial.
        " destroy tree containers (detroys contained tree control, too)
        call method g_docking_container_1->free
          exceptions
            cntl_system_error = 1
            cntl_error        = 2.
        if sy-subrc <> 0.
          message a000.
        endif.
        call method g_docking_container_2->free
          exceptions
            cntl_system_error = 1
            cntl_error        = 2.
        if sy-subrc <> 0.
          message a000.
        endif.
        call method cl_gui_cfw=>flush
          exceptions
            cntl_system_error = 1
            cntl_error        = 2.
        if sy-subrc <> 0.
          message a000.
        endif.
        clear g_docking_container_1.
        clear g_tree.
        clear g_docking_container_2.
        clear g_alv.
      endif.
      leave program.
  endcase.

* CAUTION: clear ok code!
  clear g_ok_code.
endmodule.                 " PAI_0100  INPUT
*&---------------------------------------------------------------------*
*&      Form  CREATE_AND_INIT_CONTROLS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form create_and_init_controls.
  g_repid = sy-repid.

* create docking container for tree control
  create object g_docking_container_1
    exporting
      repid = g_repid
      dynnr = '100'
      extension = 205
      side  = cl_gui_docking_container=>dock_at_left.
  if sy-subrc <> 0.
    message a000.
  endif.

* create docking container for alv control
  create object g_docking_container_2
    exporting
      repid = g_repid
      dynnr = '100'
      extension = 160
      side  = cl_gui_docking_container=>dock_at_top.
  if sy-subrc <> 0.
    message a000.
  endif.

* create left tree control
  create object g_tree
    exporting
      parent              = g_docking_container_1
      node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single
    exceptions
      lifetime_error              = 1
      cntl_system_error           = 2
      create_error                = 3
      failed                      = 4
      illegal_node_selection_mode = 5.
  if sy-subrc <> 0.
    message a000.
  endif.

* create alv control
  create object g_alv
     exporting i_parent = g_docking_container_2.

* create the application object
* this object is needed to handle the ABAP Objects Events of
* Controls
  create object g_application.

* Events alv control
  set handler g_application->handle_alv_drag for g_alv.
  set handler g_application->handle_alv_drop_complete for g_alv.


* Events tree control
  set handler g_application->handle_tree_drop for g_tree.

* build tree nodes and describe behaviour of drag&drop
  perform build_nodes_and_handles.

  call method g_tree->add_nodes
    exporting
      table_structure_name = 'MTREESNODE'
      node_table           = g_node_table
    exceptions
      failed                         = 1
      error_in_node_table            = 2
      dp_error                       = 3
      table_structure_name_not_found = 4
      others                         5.
  if sy-subrc <> 0.
    message a000.
  endif.

  call method g_tree->expand_node
    exporting node_key = 'SBOOK'.

* select and display data from SBOOK
  select from sbook into table gt_outtab up to g_max rows.  "#EC CI_NOWHERE

  gs_layout-grid_title = text-101.

  call method g_alv->set_table_for_first_display
          exporting i_structure_name = 'SBOOK'
                    is_layout        = gs_layout
          changing  it_outtab        = gt_outtab.

endform.                               " CREATE_AND_INIT_CONTROLS
*&---------------------------------------------------------------------*
*&      Form  build_nodes_and_handles
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*

form build_nodes_and_handles.

  data: node like mtreesnode,
        effect type i,
        handle_tree type i,
        handle_alv type i.

* § 2.Define a behaviour for drag and drop on alv objects
*     and tree nodes. Get a handle for each defined behaviour.
*     define a drag & Drop behaviour for the two leaves in the left tree

  create object g_behaviour_tree.
  effect = cl_dragdrop=>move + cl_dragdrop=>copy.
  call method g_behaviour_tree->add
    exporting
      flavor = 'Line'     "#EC NOTEXT
      dragsrc = ' '
      droptarget = 'X'
      effect = effect.
  call method g_behaviour_tree->get_handle
                importing handle = handle_tree.


* define a drag & Drop behaviour for the whole grid
  create object g_behaviour_alv.
  effect = cl_dragdrop=>move + cl_dragdrop=>copy.
  call method g_behaviour_alv->add
    exporting
      flavor = 'Line'   "#EC NOTEXT
      dragsrc = 'X'
      droptarget = ' '
      effect = effect.
  call method g_behaviour_alv->get_handle
    importing handle = handle_alv.

*..........
* § 3. Transfer behaviour handles to each involved object of
*      the drag and drop operation.
*
* Remark: The place at which you transfer your handle is control
*         dependend!

* node table of the tree
* Only the three subfolders shall provide a drag and drop behaviour,
* so the first one does not get a handle.
  clear node.
  node-node_key = 'SBOOK'.
  node-isfolder = 'X'.
  node-text = 'Bookings'(140).
  append node to g_node_table.

  clear node.
  node-node_key = 'PAYED'.
  node-isfolder = 'X'.
  node-relatkey = 'SBOOK'.
  node-relatship = cl_gui_simple_tree=>relat_last_child.
  node-text = 'Bill payed'(130).
* In case of trees you transfer a handle by using field 'dragdropid':
  node-dragdropid = handle_tree.
  append node to g_node_table.

  clear node.
  node-node_key = 'REMINDED'.
  node-isfolder = 'X'.
  node-relatkey = 'SBOOK'.
  node-relatship = cl_gui_simple_tree=>relat_last_child.
  node-text = 'Client reminded'(120).
  node-dragdropid = handle_tree.
  append node to g_node_table.

  clear node.
  node-node_key = 'CANCELED'.
  node-isfolder = 'X'.
  node-relatkey = 'SBOOK'.
  node-relatship = cl_gui_simple_tree=>relat_last_child.
  node-text = 'Canceled'(110).
  node-dragdropid = handle_tree.
  append node to g_node_table.

* provide handle to alv control using the layout-structure
* In this example all rows obtain the same drag and drop behaviour:
  gs_layout-s_dragdrop-row_ddid = handle_alv.

endform.                               " build_nodes_and_handles

*&---------------------------------------------------------------------*
*&      Form  SET_KEYTXT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_L_KEYTXT  text
*      -->P_DATAOBJ_>LS_SBOOK  text
*----------------------------------------------------------------------*
form set_keytxt using    ls_sbook type sbook
                changing keytxt type c.
  data: s1(4) value 'B:',
        s2(2),
        s3(4) value ' C:',
        s4(2),
        s5(4) value ' D:',
        custid(20),
        bookid(20),
        date(8),
        len type i,
        offset type i.
* SBOOK-CUSTID and SBOOK-BOOKID are always <100, so two characters
* are sufficient.
  move ls_sbook-bookid to bookid.
  compute len = strlen( bookid ).
  offset = len - 2.
  s2 = bookid+offset(2).

  move ls_sbook-customid to custid.
  compute len = strlen( custid ).
  offset = len - 2.
  s4 = custid+offset(2).

  date = ls_sbook-fldate.
  concatenate s1 s2 s3 s4 s5 date into keytxt.

endform.                               " SET_KEYTXT

start-of-selection.
  set screen 100.

posted on 2011-11-25 17:30  前进、目标  阅读(3109)  评论(0)    收藏  举报