*---------------------------------------------------------------------*
*                 Z _ B J H _ C O N T R O L _ P I C                   *
*                                                                     *
*               Autor:  Bernd Haase (bjh@bmksound.de)                 *
*---------------------------------------------------------------------*
* SAP Programmierbeispiel. Programmierung eines Controles, welches    *
* Bild auf dem Bildschirm bringt. Das Bild kann entweder intern gela- *
* den werden, ein Bild, welches mit der SE78 bearbeitbar ist, oder    *
* extern als eine Grafikdatei von der Festplatte des Rechners         *
*---------------------------------------------------------------------*
* Hinweis: Das Bild ist in einem Splitting Container untergebracht,   *
* wenn Sie jedoch ein Bild in einem Dynpro direkt einbetten möchten,  *
* so schauen Sie bitte im Programm z_bjh_dynpro_tab_fix , wo diese    *
* Methodik beschrieben ist                                            *
*---------------------------------------------------------------------*
* Angelegt werden müssen nur ein leeres Dynpro 9000 sowie eine GUI    *
* Statuszeile mit den Funktionen BACK und ENDE                        *
*---------------------------------------------------------------------*
* (DM) Dynpro Splitting Container.                                    *
*---------------------------------------------------------------------*
* 19.03.2008 BHaa: Programm erstellt aus Quelle z_bjh_oo_tree         *
*---------------------------------------------------------------------*

SAP Programm Picture Control, Anzeige von Fotos und Bildern

REPORT z_bjh_control_pic.

TABLES:
* Datei, in welcher die Bilder der SE78 gespeichert sind
 stxbitmaps.

CONSTANTS:
 gc_container_dynpro LIKE sy-dynnr VALUE '9000',

 gc_tdid  LIKE stxbitmaps-tdid     VALUE 'BMAP',
 gc_btype LIKE stxbitmaps-tdbtype  VALUE 'BCOL'.

DATA:
 gv_okcode     LIKE sy-ucomm,
 gv_repid      LIKE sy-repid,
 gi_i          TYPE i,

* für die Grafiken vergibt SAP eine interne URL-Adresse.
 gv_sap_url(255) TYPE c,
 gv_subtype(3)   TYPE c,
* wenn die Daten von der stxbitmaps SE78 geladen werden, werden die
* Daten erstmal zusammengebaut. Dafür ist diese Variablen notwendig,
* die die Größe speichert
 gi_graphic_size TYPE i,
 gs_bitmaps      LIKE stxbitmaps,
* Struktur und Tabelle der Grafikdatei gelesen aus SAP. Wichtig ist,
* das die Variable als Hexadezimal deklariert ist. Sie kann auch als
* Struktur und Tabelle der einzulesenden Grafikdatei verwendet werden
 gs_jpg(255)     TYPE x,
 gt_jpg          LIKE STANDARD TABLE OF gs_jpg,

* Control für Images / Bilder, einmal Trägerdynpro und Bild selbst
 go_screen_pic   TYPE REF TO cl_gui_docking_container,
 go_pic          TYPE REF TO cl_gui_picture.

*---------------------------------------------------------------------*
*                                                                     *
*                 A u s w a h l b i l d s c h i r m                   *
*                                                                     *
*---------------------------------------------------------------------*
* Aktion, ob ein Bild von Datei laden oder das Bild anzeigen
SELECTION-SCREEN BEGIN OF BLOCK a1 WITH FRAME TITLE text-901.
PARAMETERS:
* Bild aus der SE78 einspielen
 px_se78  TYPE xfeld RADIOBUTTON GROUP grp1 DEFAULT 'X',
* Grafik oder Foto von der Festplatte laden
 px_datei TYPE xfeld RADIOBUTTON GROUP grp1,
* Foto von der Festplatte laden und ins SAP einspielen
 px_laden TYPE xfeld RADIOBUTTON GROUP grp1.
SELECTION-SCREEN END OF BLOCK a1.

* Name des Bildes, wie es im SAP-System bekannt ist
SELECTION-SCREEN BEGIN OF BLOCK a2 WITH FRAME TITLE text-902.
PARAMETERS:
* Name, wie das Bild in der SE78 heißt
 pm_name LIKE stxbitmaps-tdname,
* Dateiname auf der Platte
 pm_in LIKE rlgrap-filename.
SELECTION-SCREEN END OF BLOCK a2.

INITIALIZATION.
* Control bereitstellen
 PERFORM dynpro_bild.

 PERFORM dynpro_control_ereignisse.

***********************************************************************
*                                                                     *
*                     P R O G R A M M S T A R T                       *
*                                                                     *
***********************************************************************
AT SELECTION-SCREEN ON VALUE-REQUEST FOR pm_in.

* Suchhilfe für den Dateiname
 CALL FUNCTION 'F4_FILENAME'
      EXPORTING
*           PROGRAM_NAME  = SYST-CPROG
*           DYNPRO_NUMBER = SYST-DYNNR
           field_name    = 'PM_IN'
      IMPORTING
           file_name     = pm_in.

AT SELECTION-SCREEN.

 IF px_laden = 'X'
* Bilddatei von der Platte laden, am Bildschirm anzeigen und danach als
* Image ins SAP überspielen, welches dieses in der SE78 anzeigt
 OR px_datei = 'X'.
* Fotodatei von der Festplatte laden
   PERFORM bild_laden_datei USING pm_in.

* Extension, Dateikennung für den Funktionsbaustein merken
   COMPUTE gi_i = STRLEN( pm_in ).
   SUBTRACT 3 FROM gi_i.
   MOVE pm_in+gi_i(3) TO gv_subtype.
   TRANSLATE gv_subtype TO UPPER CASE.

   IF px_laden = 'X'.
* Datei ins SAP importieren
     PERFORM bild_datei_in_se78 USING pm_in pm_name ''.
   ENDIF.
 ELSE.
* Bild so laden, wie SAP das in der SE78 auch macht
   PERFORM bild_laden_stx USING pm_name.
* Dateikennung ... unbekannt
   MOVE cndp_sap_tab_unknown TO gv_subtype.
 ENDIF.

* Bild im Control am Bildschirm einbetten und bereitstellen
 PERFORM bild_aufbau_anzeige USING gv_subtype.

* Sprung ins Dynpro und somit zur Anzeige
 LEAVE TO SCREEN gc_container_dynpro.

END-OF-SELECTION.
 EXIT.

*---------------------------------------------------------------------*
*                 B I L D _ A U F B A U _ A N Z E I G E               *
*---------------------------------------------------------------------*
* SAP speichert für Bilder eine interne URL-Adresse. Diese wird hier  *
* über den Funktionsbaustein bestimmt.                                *
*---------------------------------------------------------------------*
* =>] jv_subtype: Extension bei Datei, was für ein Bild es ist        *
* =>] gi_graphic_size: bei stxbitmaps, wie groß ist das Bild          *
* ]=> gv_sap_url: interne Referenzierung auf das Foto                 *
*---------------------------------------------------------------------*
FORM bild_aufbau_anzeige
    USING jv_subtype.

* die SAP interne Verknüpfung generieren
 CALL FUNCTION 'DP_CREATE_URL'
   EXPORTING
     type     = 'IMAGE'
     subtype  = jv_subtype
     size     = gi_graphic_size
     lifetime = cndp_lifetime_transaction  " 'T'
   TABLES
     data     = gt_jpg
   CHANGING
     url      = gv_sap_url.

* Bildchen bereitstellen
 CALL METHOD go_pic->load_picture_from_url
   EXPORTING
     url = gv_sap_url.

* Bild ausrichten, Bild so einlegen, daß es entweder an die horizontale
* oder an die vertikale Abgrenzung stößt
 CALL METHOD go_pic->set_display_mode
   EXPORTING
*     display_mode = go_pic->display_mode_stretch.
     display_mode = go_pic->display_mode_fit.

ENDFORM.                    "bild_aufbau_anzeige

*---------------------------------------------------------------------*
*                     B I L D _ L A D E N _ S T X                     *
*---------------------------------------------------------------------*
* Interne Datenversorgung. Entspricht SE78. Das Bild wird aus der     *
* Datenbank geladen und in die interne Grafiktabelle überspielt. Diese*
* Routine ist ein Extrakt aus dem Programm SAPMSSCH, Unterprogramm    *
* graphic_print_bds                                                   *
*---------------------------------------------------------------------*
* =>] jv_tdname: Bildname, wie es in der SE78 gespeichert ist         *
*---------------------------------------------------------------------*
FORM bild_laden_stx
    USING jv_tdname.

 DATA:
   lv_graphic_xstr TYPE xstring,
   li_graphic_conv TYPE i,
   li_graphic_offs TYPE i.

* interne Grafiktabelle. Initialisieren
 CLEAR:   gt_jpg, gi_graphic_size.
 REFRESH: gt_jpg.

* Vorlauf, falls geprüft werden soll, ob das Bild überhaupt gespeichert
* ist. Wenn nicht, Fehler und Abbruch
 SELECT SINGLE * FROM stxbitmaps
 INTO  gs_bitmaps
 WHERE tdname   = jv_tdname
 AND   tdobject = 'GRAPHICS'
 AND   tdid     = 'BMAP'
 AND   tdbtype  = 'BCOL'.          "Bild sollte farbig sein

 IF sy-subrc <> 0.
* Diese datei gibt es nicht in der Kombination
   MESSAGE e287(td) WITH jv_tdname.
 ELSE.
* Datenstring des Bildes laden
   CALL METHOD cl_ssf_xsf_utilities=>get_bds_graphic_as_bmp
     EXPORTING
       p_object  = 'GRAPHICS'
       p_name    = jv_tdname
       p_id      = 'BMAP'
       p_btype   = 'BCOL'
     RECEIVING
       p_bmp     = lv_graphic_xstr
     EXCEPTIONS
       not_found = 1
       OTHERS    = 2.

* wie groß ist das Bild, Volumen speichern, wird bei Anzeige benötigt
   gi_graphic_size = XSTRLEN( lv_graphic_xstr ).

   CHECK gi_graphic_size > 0.

   li_graphic_conv = gi_graphic_size.
   li_graphic_offs = 0.

* datenstring in interne Hexadezimaltabelle in 255 Byte-Blöcken
* überspielen
   WHILE li_graphic_conv > 255.
     gs_jpg = lv_graphic_xstr+li_graphic_offs(255).
     APPEND gs_jpg TO gt_jpg.
     li_graphic_offs = li_graphic_offs + 255.
     li_graphic_conv = li_graphic_conv - 255.
   ENDWHILE.

   gs_jpg = lv_graphic_xstr+li_graphic_offs(li_graphic_conv).
   APPEND gs_jpg TO gt_jpg.
 ENDIF.

ENDFORM.                    "bild_laden_stx

*---------------------------------------------------------------------*
*                   B I L D _ L A D E N _ D A T E I                   *
*---------------------------------------------------------------------*
* Externe Datenversorgung. Ein Bild wird von der Platte geladen und in*
* der internen Grafiktabelle gespeichert.                             *
*---------------------------------------------------------------------*
* =>] jv_dateiname: Dateiname auf Platte, wo das Foto gespeichert ist *
*---------------------------------------------------------------------*
FORM bild_laden_datei
    USING jv_dateiname.

 DATA:
   li_subrc(2) TYPE n,
   lv_filename TYPE string.

 CLEAR gi_graphic_size.

 MOVE jv_dateiname TO lv_filename.

 CALL FUNCTION 'GUI_UPLOAD'
      EXPORTING
           filename                = lv_filename
           filetype                = 'BIN'
*           HAS_FIELD_SEPARATOR     = ' '
*           HEADER_LENGTH           = 0
*           READ_BY_LINE            = 'X'
*           DAT_MODE                = ' '
*           CODEPAGE                = ' '
*           IGNORE_CERR             = ABAP_TRUE
*           REPLACEMENT             = '#'
*           CHECK_BOM               = ' '
*           VIRUS_SCAN_PROFILE      =
*           NO_AUTH_CHECK           = ' '
*      IMPORTING
*           FILELENGTH              =
*           HEADER                  =
      TABLES
           data_tab                = gt_jpg
      EXCEPTIONS
           file_open_error         = 1
           file_read_error         = 2
           no_batch                = 3
           gui_refuse_filetransfer = 4
           invalid_type            = 5
           no_authority            = 6
           unknown_error           = 7
           bad_data_format         = 8
           header_not_allowed      = 9
           separator_not_allowed   = 10
           header_too_long         = 11
           unknown_dp_error        = 12
           access_denied           = 13
           dp_out_of_memory        = 14
           disk_full               = 15
           dp_timeout              = 16
           OTHERS                  = 17.

 IF sy-subrc <> 0.
   MOVE sy-subrc TO li_subrc.

   MESSAGE e000(vz) WITH li_subrc.
 ENDIF.


ENDFORM.                    "bild_laden_datei

*---------------------------------------------------------------------*
*                B I L D _ D A T E I _ I N _ S E 7 8                  *
*---------------------------------------------------------------------*
* Grafik in SAP-System transportieren. Die zu importierende Datei wird*
* direkt über eine SAP Routine eingefügt, die Daten werden hier in    *
* diesem Unterprogramm nicht zwischengelagert                         *
*---------------------------------------------------------------------*
* =>] jv_dateiname: Dateiname auf Platte, wo das Foto gespeichert ist *
* =>] jv_tdname: Bildname, wie es in der SE78 gespeichert werden soll *
* =>] jx_ersetz: Falls Bild schon vorhanden, ='' Fehler, =X ersetzen  *
*---------------------------------------------------------------------*
FORM bild_datei_in_se78
    USING jv_dateiname
          jv_tdname
          jx_ersetz.

 DATA:
   lv_filename TYPE localfile,

   BEGIN OF ls_image,
     title       TYPE bds_propva,
     resident    TYPE stxbitmaps-resident,
     autoheight  TYPE stxbitmaps-autoheight,
     bmcomp      TYPE stxbitmaps-bmcomp,
     resolution  TYPE stxbitmaps-resolution,
   END OF ls_image.

 SELECT SINGLE * FROM stxbitmaps
 INTO  gs_bitmaps
 WHERE tdname   = jv_tdname
 AND   tdobject = 'GRAPHICS'
 AND   tdid     = gc_tdid
 AND   tdbtype  = gc_btype.

 IF sy-subrc = 0.
   IF jx_ersetz = 'X'.
* wenn Grafik ersetzt werden soll, diese zuvor löschen
     DELETE FROM stxbitmaps
     WHERE tdobject = 'GRAPHICS'
     AND   tdname   = jv_tdname
     AND   tdid     = gc_tdid
     AND   tdbtype  = gc_btype.
   ELSE.
     MESSAGE e548(td) WITH jv_tdname.
   ENDIF.
 ENDIF.

 MOVE jv_dateiname TO lv_filename.

 CLEAR ls_image.

* das neue Bild einfügen oder überschreiben des alten Bildes (wobei
* dieses zuvor gelöscht wurde). Bitte nicht den SAP Funktionsbaustein
* benutzen, da dieser ein Pop-Up aufblendet, in dem der Dateiname einge-
* geben werden soll, was jedoch bereits in der Auswahl geschehen ist
 PERFORM graphic_import_bds(saplstxbitmaps)
         USING    lv_filename
                  jv_tdname
                  'GRAPHICS'
                  gc_tdid
                  gc_btype
                  ls_image-title
                  ls_image-resident
                  ls_image-autoheight
                  ls_image-bmcomp
         CHANGING ls_image-resolution.

 IF sy-subrc <> 0.
   MESSAGE i285(td) WITH jv_tdname 'IMPORT'.
 ELSE.
   MESSAGE i288(td) WITH jv_tdname.
 ENDIF.

ENDFORM.                    "bild_datei_in_se78

*---------------------------------------------------------------------*
*                         D Y N P R O _ B I L D                       *
*---------------------------------------------------------------------*
* Control Routinen für den Bildschirmaufbau durchlaufen. Methodik ist *
* ein Splitting Container, welcher das Basisdynpro 9000 ein wenig     *
* unterteilt.                                                         *
*---------------------------------------------------------------------*
FORM dynpro_bild.

 MOVE sy-repid TO gv_repid.

 CREATE OBJECT go_screen_pic
    EXPORTING
      repid     = gv_repid
      dynnr     = gc_container_dynpro
*      side      = cl_gui_docking_container=>dock_at_top
      side      = cl_gui_docking_container=>dock_at_left
      extension = 300
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      lifetime_dynpro_dynpro_link = 5
      OTHERS                      = 6.

 IF sy-subrc <> 0.
*   MESSAGE a110 WITH text-005.
 ELSE.
   CREATE OBJECT go_pic
     EXPORTING
       parent            = go_screen_pic
     EXCEPTIONS
       error             = 1
       OTHERS            = 5.

   IF sy-subrc <> 0.
*     MESSAGE a110 WITH text-006.
   ENDIF.
 ENDIF.

ENDFORM.                    "dynpro_bild

*---------------------------------------------------------------------*
*           D Y N P R O _ C O N T R O L _ E R E I G N I S S E         *
*---------------------------------------------------------------------*
* Ereignisse definieren, die die Controls hergeben und benötigt werden*
*---------------------------------------------------------------------*
FORM dynpro_control_ereignisse.

* im Moment sind keine Ereignisse in diesem Beispielprogramm vorgesehen

ENDFORM.                    "dynpro_control_ereignisse

*---------------------------------------------------------------------*
* MODULE                S T A T U S _ 9 0 0 0                  OUTPUT *
*---------------------------------------------------------------------*
* PBO bevor das Dynpro prozessiert wird. Das in diesem Programm nur   *
* das Bild angezeigt werden soll, brauchen keine großartigen Aktionen *
* in diesem Bereich programmiert werden                               *
*---------------------------------------------------------------------*
MODULE status_9000 OUTPUT.

 CLEAR gv_okcode.

 SET PF-STATUS '9000'.
* SET TITLEBAR 'xxx'.

ENDMODULE.                 " status_9000  OUTPUT

*---------------------------------------------------------------------*
* MODULE            U S E R _ C O M M A N D _ 9 0 0 0           INPUT *
*---------------------------------------------------------------------*
* PAI Reaktionen auf gedrückte Tasten oder Aktionen                   *
*---------------------------------------------------------------------*
MODULE user_command_9000 INPUT.

 CASE gv_okcode.
   WHEN 'BACK'.
* zurück zum Auswahlbildschirm
     CALL SCREEN '1000'.

   WHEN 'ENDE'.
* Programm verlassen
     CALL METHOD go_pic->free.

     CALL METHOD go_screen_pic->free.

     FREE: go_pic, go_screen_pic.

     LEAVE PROGRAM.

 ENDCASE.

ENDMODULE.                    "user_command_9000 INPUT

***** Ende *****
* Copyright BJH Software, Datei überarbeitet am: 21.3.2008