Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Pages: 1
Supposons qu'on veuille construire dynamiquement un menu, par exemple pour afficher ou non des items selon les privilèges de l'utilisateur connecté.
Dans les newgroups Sybase, on suggère de créer tous les items manuellement (painter) et d'ajuster leur visibilité par script.
Cette solution n'est pas toujours satisfaisante, notamment quand le nombre d'items est élevé ou varie dans le temps (on n'a pas forcément envie de maintenir le menu "à la main").
L'objet PB système Menu possède la propriété Item[] qui est un tableau de menus, cf doc :
Menu property Datatype Description
Item[ ] Menu Specifies the Menu objects under a Menu object.
Item[ ] property for PowerScript controls
Applies to ListView, ListBox, PictureListBox, DropDownListBox, DropDownPictureListBox, and Toolbar controls
Usage In scripts
The Item[] property is an array of strings, but it is not updated after initialization. Use the AddItem or appropriate InsertItem function instead.
La doc précise donc que le tableau Item[] n'est plus remis à jour après initialisation et suggère d'utiliser les méthodes AddItem ou InsertItem. Ces méthodes existent pour les objets ListView, ListBox, PictureListBox, DropDownListBox, DropDownPictureListBox mais pas pour l'objet Menu... oups
L'astuce consiste à cacher le menu (Hide), le modifier (Item[i]), puis l'afficher (Show) pour forcer son rafraîchissement.
Exemple simple (sans utilisation de NVO ou de structure)
Données :
* fenêtre MDI : w_frame
* fenêtres filles : w_client, w_fournisseur, w_facture
* menu MDI : m_frame ayant un menu principal m_items vide qui sera construit dynamiquement
* item de menu : m_item
// ouverture de la fenêtre définie par le tag Window lw_child OpenSheet( lw_child, This.Tag, w_frame )
* données sur les items à afficher :
- tableau des libellés des items : ls_tab_items[]
- tableau des fenêtres associées aux items : ls_tab_windows[]
Code de construction du menu
A placer par exemple dans l'événement open de la fenêtre w_frame.
Integer li_cpt_item, li_count_item String ls_tab_items[], ls_tab_windows[] m_frame lm_frame Menu lm_items m_item lm_item // initialisation du tableau exemple ls_tab_items = { 'Clients', 'Fournisseurs', 'Factures' } ls_tab_windows = { 'w_client', 'w_fournisseur', 'w_facture' } // récupération d'une référence au menu 'Items' lm_frame = This.MenuId lm_items = lm_frame.m_items // cache le menu lm_items.Hide( ) // boucle sur les éléments du tableau li_count_item = UpperBound( ls_tab_items ) For li_cpt_item = 1 To li_count_item // création d'une nouvelle instance d'item lm_item = Create m_item // affectation des propriétés lm_item.Text = ls_tab_items [ li_cpt_item ] lm_item.Tag = ls_tab_windows[ li_cpt_item ] // ajout de l'item au menu lm_items.Item[ li_cpt_item ] = lm_item Next // affiche le menu (force refresh) lm_items.Show( )
Résultat
Extensions
* utiliser des NVOs pour les items de menu
* enrichir les items (MenuImage, MicroHelp, ...)
* faire plusieurs niveaux de menus imbriqués
* faire passer des paramètres (OpenSheetWithParm)
* ...
A vos claviers...
Hors ligne
Source compatible à 100% avec Webform
Hors ligne
Testé et approuvé par notre bug eradicator junior
00 pépites
Hors ligne
Nous utilisons le tag de chaque item du menu pour le rendre visible
Voici du code
u_nv_security
forward global type u_nv_security from nonvisualobject end type end forward global type u_nv_security from nonvisualobject end type global u_nv_security u_nv_security type variables PROTECTED: string isz_resources u_nv_string inv_string end variables forward prototypes public subroutine uf_security (menu arg_menu) public subroutine uf_security (commandbutton arg_object) public subroutine uf_security (checkbox arg_object) public subroutine uf_security (dropdownlistbox arg_object) public subroutine uf_security (graph arg_object) public subroutine uf_security (groupbox arg_object) public subroutine uf_security (listbox arg_object) public subroutine uf_security (multilineedit arg_object) public subroutine uf_security (picture arg_object) public subroutine uf_security (radiobutton arg_object) public subroutine uf_security (singlelineedit arg_object) public subroutine uf_security (statictext arg_object) public subroutine uf_security (datawindow arg_dw) public subroutine uf_initialize (string arg_user, string arg_appli) end prototypes public subroutine uf_security (menu arg_menu); long i int nitems string sz_security string sz_resource string sz_resource_modify string szSecurity,szpriveleges String ls_visible = "false" Integer li_memopossep = 0 // NB: Gestion particulière des séparateurs de menu car l'accès à la propriété Tag //de ces items particulier retourne une chaine vide systématiquement. nitems = UpperBound (arg_menu.item) FOR i = 1 TO nitems //Teste la propriété visible de l'item de menu réglée à la conception afin de déterminer //si les droits s'appliquent, et ce pour respecter le rendu visuel. if arg_menu.item[i].visible and arg_menu.item[i].Text <> "-" then //see if the object has any security szpriveleges = inv_string.uf_GetParm (arg_menu.item [i].Tag, "security=", "False", False ) IF szpriveleges <> "False" THEN //see if the user needs a resource to have the object enabled sz_resource = inv_string.uf_GetParm( szpriveleges, "access=","False", False ) sz_resource_modify = inv_string.uf_GetParm( szpriveleges, "modify=","False", False ) IF arg_menu.item[i].enabled And ( sz_resource <> "False" OR sz_resource_modify <> "False" ) THEN IF lower (inv_string.uf_getparm (isz_resources, sz_resource + "=", "False", False) ) = "true" or & lower (inv_string.uf_getparm (isz_resources, sz_resource_modify + "=", "False", False) ) = "true" & THEN arg_menu.item[i].enabled = true arg_menu.item[i].visible = true IF arg_menu.item [i].ToolBarItemVisible THEN arg_menu.item [i].ToolBarItemVisible = true END IF ELSE arg_menu.item[i].enabled = false arg_menu.item[i].visible = false arg_menu.item [i].ToolBarItemVisible = false END IF END IF END IF //Gère l'affichage des séparateurs de menu. if arg_menu.item[i].visible and ls_visible = "false" then //Cas élt avant séparateur ls_visible = "true" elseif arg_menu.item [i].visible and li_MemoPosSep > 0 and ls_visible = "true" then //Cas élt après => affichage séparateur arg_menu.item [li_MemoPosSep].visible = True ls_visible = "false" li_MemoPosSep = 0 end if //Le code ci-dessous traite un sous-menu dans tous les cas //pour gestion des icônes de menu If UpperBound( arg_menu.item[i].item ) > 0 Then uf_security( arg_menu.item[i] ) End If elseif arg_menu.item[i].visible and arg_menu.item[i].Text = "-" then //Gère l'affichage des séparateurs de menu. arg_menu.item[i].visible = False if li_MemoPosSep = 0 then li_MemoPosSep = i elseif not arg_menu.item[i].visible then arg_menu.item[i].ToolBarItemVisible = False //--- Fin SL end if NEXT end subroutine public subroutine uf_security (commandbutton arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security = lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False ) ) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (checkbox arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security = lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False ) ) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (dropdownlistbox arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (graph arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (groupbox arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (listbox arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (multilineedit arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (picture arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (radiobutton arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (singlelineedit arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (statictext arg_object); string sz_security string sz_resource //Check tag value for security= attribute sz_security =lower( inv_string.uf_GetParm( arg_object.tag, "security=",'?', False )) IF sz_security <> '?' THEN //Check sz_security value for access= attribute sz_resource = inv_string.uf_GetParm( sz_security, "access=",'?', False ) IF sz_resource <> '?' THEN arg_object.enabled = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF //Check sz_security value for modify= attribute sz_resource = inv_string.uf_GetParm( sz_security, "modify=",'?', False ) IF sz_resource <> '?' THEN arg_object.visible = "true" = lower( inv_string.uf_getparm( isz_resources, sz_resource+"=",'?',False)) END IF END IF end subroutine public subroutine uf_security (datawindow arg_dw); string sz_security string sz_resource string sz_tag string sz_ModString string sz_style int i,n boolean b_enable u_nv_column nv_column //See if the dw control is secured sz_security = lower( inv_string.uf_GetParm( arg_dw.tag, "security=",'?', False ) ) If lower( sz_security) = "none" Then Return End If IF sz_security <> "?" THEN nv_column.uf_Register( arg_dw ) //see if the user needs a resource to make the dw visible sz_resource = inv_string.uf_GetParm( sz_security,"modify=", "?", False ) IF sz_resource <> "?" THEN //make the dw control visible/invisible depending on the //user's resources arg_dw.visible = "true" = lower( inv_string.uf_GetParm( isz_resources, sz_resource+"=","false",False) ) END IF //if the entire dw control is invisible,no point in continuing... IF arg_dw.visible = False THEN Return END IF //Resource to make the DW control enabled sz_resource = inv_string.uf_GetParm( sz_security,"access=","?", False ) IF sz_resource <> "?" THEN //Make the DW control enabled/disabled depending on the //user's resources...note if DW control is disabled //we must disable all columns on the DW object arg_dw.enabled = "true" = lower( inv_string.uf_GetParm( isz_resources, sz_resource+"=","FALSE",False) ) If arg_dw.enabled = false Then //Disable all columns and return n = Integer( arg_dw.Object.DataWindow.Column.Count ) FOR i = 1 TO n //Get column tag sz_tag = arg_dw.Describe( "#" + String(i) + ".Tag" ) //Get security sz_security = inv_string.uf_GetParm( sz_tag, "security=", "?", False ) //Check visible sz_resource = inv_string.uf_GetParm( sz_security,"modify=","?", False ) IF sz_resource <> "?" THEN //Make visible if user has the resource IF "true" = lower( inv_string.uf_GetParm( isz_resources, sz_resource+"=","False",False) ) THEN sz_ModString += "#"+String(i)+".visible=1 " ELSE sz_ModString += "#"+String(i)+".visible=0 " //Column is not visible do not set its other attributes //continue with next column CONTINUE END IF END IF //Disable Column nv_column.uf_Column( i, false ) NEXT //Apply all security to the DataWindow object arg_dw.Modify( sz_ModString ) Return End If END IF END IF //DW control is enabled //Get the number of columns in the DW object and apply security //to every column n = Integer( arg_dw.Object.DataWindow.Column.Count ) FOR i = 1 TO n //Get column tag sz_tag = arg_dw.Describe( "#" + String(i) + ".Tag" ) //Get security sz_security = inv_string.uf_GetParm( sz_tag, "security=", "?", False ) IF sz_security = "?" THEN CONTINUE End IF //Check visible sz_resource = inv_string.uf_GetParm( sz_security,"modify=","?", False ) IF sz_resource <> "?" THEN //Make visible if user has the resource IF "true" = lower( inv_string.uf_GetParm( isz_resources, sz_resource+"=","False",False) ) THEN sz_ModString += "#"+String(i)+".visible=1 " ELSE sz_ModString += "#"+String(i)+".visible=0 " //Column is not visible do not set its other attributes //continue with next column CONTINUE END IF END IF //Check Enabled sz_resource = inv_string.uf_GetParm( sz_security,"access=","?", False ) If sz_resource <> '?' Then b_enable = "true" = lower( inv_string.uf_GetParm( isz_resources, sz_resource+"=",'?',False) ) nv_Column.uf_Column( i, b_enable ) End If NEXT //Apply all security to the DataWindow object arg_dw.Modify( sz_ModString ) end subroutine public subroutine uf_initialize (string arg_user, string arg_appli);Long ll_i Long ll_nbrow datastore ds_resource //Retrieve Resources for given application/user ds_resource = Create datastore ds_resource.dataobject = "d_user_resources" ll_i = ds_resource.SetTransObject (SQLCA) ll_nbrow = ds_resource.Retrieve (gi_userid, upper (arg_appli)) For ll_i = 1 to ll_nbrow isz_resources += " " + Lower (String (ds_resource.object.resource [ll_i])) + "=true " Next Destroy ds_resource end subroutine on u_nv_security.create call super::create TriggerEvent( this, "constructor" ) end on on u_nv_security.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
u_nv_string
forward global type u_nv_string from nonvisualobject end type end forward global type u_nv_string from nonvisualobject autoinstantiate end type forward prototypes public function string uf_getparm (ref string arg_szstring, string arg_szitem, string arg_szdefault, boolean arg_bremove) public function string uf_gettoken (ref string arg_parm, string arg_token) public function string uf_replaceall (string arg_parm, string arg_olditem, string arg_newitem) end prototypes public function string uf_getparm (ref string arg_szstring, string arg_szitem, string arg_szdefault, boolean arg_bremove); long l_BegPos,l_BegPosData,l_EndPos string sz_FirstByte,sz_LastByte,sz_Return,sz_Byte int n_ParenCount = 1 l_BegPos = PosA (arg_szString, arg_szItem) If l_BegPos = 0 Then Return arg_szDefault End If l_BegPosData = l_BegPos + LenA(arg_szItem) sz_FirstByte = MidA(arg_szString,l_BegPosData,1) CHOOSE CASE sz_FirstByte CASE "'" //Single Quote l_BegPosData++ sz_LastByte = "'" l_EndPos = PosA(arg_szString,sz_LastByte,l_BegPosData) CASE "~"" //Double Quote l_BegPosData++ sz_LastByte = "~"" l_EndPos = PosA(arg_szString,sz_LastByte,l_BegPosData) CASE "{" //Brace l_BegPosData++ sz_LastByte = "}" l_EndPos = PosA(arg_szString,sz_LastByte,l_BegPosData) CASE "[" //Bracket l_BegPosData++ sz_LastByte = "]" l_EndPos = PosA(arg_szString,sz_LastByte,l_BegPosData) CASE "|" //Pipe l_BegPosData++ sz_LastByte = "|" l_EndPos = PosA(arg_szString,sz_LastByte,l_BegPosData) CASE "(" //Open Paren l_BegPosData++ l_EndPos = l_BegPosData DO //Process one byte at a time till matching paren l_EndPos++ sz_Byte = MidA(arg_szString,l_EndPos,1) If sz_Byte = "(" Then n_ParenCount ++ ElseIf sz_Byte = ")" Then n_ParenCount -- End If LOOP UNTIL n_ParenCount = 0 CASE " " //Space l_BegPosData++ sz_LastByte = " " l_EndPos = PosA(arg_szString,sz_LastByte,l_BegPosData) CASE ELSE //No Space sz_LastByte = " " l_EndPos = PosA(arg_szString,sz_LastByte,l_BegPosData) END CHOOSE If l_EndPos = 0 Then l_EndPos = 9999999 End If sz_Return = MidA(arg_szString,l_BegPosData, l_EndPos - l_BegPosData) If arg_bRemove Then arg_szString = ReplaceA(arg_szString,l_BegPos, l_EndPos - l_BegPos + 1,"") End If Return sz_Return end function public function string uf_gettoken (ref string arg_parm, string arg_token);//Local Variables long l_Pos string sz_token string sz_null //End Variables //Dean Jones - PowerTeam, Inc. If IsNull( arg_parm ) OR IsNull( arg_token ) Then SetNull( sz_Null ) Return sz_Null End If l_Pos = PosA(arg_parm, arg_token) IF l_Pos = 0 THEN sz_token = arg_parm arg_parm = "" ELSE sz_token = MidA( arg_parm, 1, l_Pos - 1 ) arg_parm = RightA( arg_parm, LenA(arg_parm) - l_Pos ) END IF Return sz_token end function public function string uf_replaceall (string arg_parm, string arg_olditem, string arg_newitem);long l_Pos l_Pos = PosA( arg_parm, arg_olditem, 1 ) DO WHILE l_Pos > 0 arg_parm = ReplaceA ( arg_parm, l_pos, LenA( arg_olditem ), arg_newitem ) l_Pos = PosA( arg_parm, arg_olditem, l_pos + LenA( arg_newitem ) ) LOOP Return arg_parm end function on u_nv_string.create TriggerEvent( this, "constructor" ) end on on u_nv_string.destroy TriggerEvent( this, "destructor" ) end on
d_user_resources contient les ressources du user
exemple de tag d'un item du menu :
security="access=catabmodif modify=cmtabmodif"
Exemple d'appel :
u_nv_security gnv_security if IsValid( gnv_security ) Then Destroy gnv_security End if gnv_security = Create u_nv_security gnv_security.uf_Initialize (gs_user, gs_appli) if IsValid (This.MenuId) then gnv_security.uf_Security (This.MenuId) end if
Hors ligne
Pages: 1