Page 1 of 2

Dos preguntas de xbrowse

PostPosted: Wed Aug 06, 2008 4:53 pm
by quique
¿como puedo mostrar una línea en todo el registro del browse como la de twbrowse?

¿como puedo manejar la edición de las celdas de forma parecida a la de twbrowse? lo que pasa es que cada registro tiene una manera de editar difrente, algunos son cadenas de caracteres (dependiendo el registro manejo dos tipos difrentes de edición), otros son númericos, algunos en vez de editar sobre la celda se despliega un diálogo. No depende del campo, sino del registro, porque manejo 2 columnas, una con la descripción y otra con el valor del campo. Esto es muy fácil de controlar con wbrowse, pero no encontré como hacerlo con xbrowse.

PostPosted: Wed Aug 06, 2008 5:32 pm
by Antonio Linares
Quique,

A la primera pregunta:
oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW

A la segunda:
Dices que tienes dos columnas solamente. Que tipo de edición quieres para cada una de ellas ? (un inspector de objetos?)

PostPosted: Wed Aug 06, 2008 5:49 pm
by quique
Gracias antonio.

Sip, básicamente es un editor de objetos ¿has visto el editor que estoy haciendo? (de hecho alguna vez lo viste que hasta me reportaste una ventana de error ;) ) el diálogo que permite modificar las propiedades de los objetos (realmente no son propiedades de los objetos, sino los parámetros recibidos por el constructor) es lo que quiero modificar, algunos parámetros son simples strings, como por ejemplo ccaption, otras como ntop y nleft son númericos (aunque tengo pendiente modificar esa parte, porque podría manejarse con variables en vez de coordenada explicita), y por ejemplo, los campos de un browse o los items de un combo son matrices, en estos caso abro un diálogo.

PostPosted: Wed Aug 06, 2008 6:46 pm
by Antonio Linares
Quique,

Seguro que te va a gustar :-)

Code: Select all  Expand view
// An object inspector using XBrowse
// (c) FiveTech Software 2008

#include "FiveWin.ch"
#include "XBrowse.ch"

function Main()

   local oWnd, oBrw
   local aData := { { "A edit", "text",     EDIT_GET },;
                    { "A combobox", "test", EDIT_LISTBOX, { "One", "Two", "Three" } },;
                    { "A dialog", "result", EDIT_BUTTON,  { || MsgYesNo( "Select a value" ) } } }
   
   DEFINE WINDOW oWnd TITLE "Object inspector" FROM 10, 10 TO 40, 48
   
   oWnd:ToolWindow()

   @ 0, 0 XBROWSE oBrw ARRAY aData COLUMNS 1, 2 COLSIZES 100, 140 ;
      ON CHANGE SetEditType( oBrw, aData )
   
   oBrw:nMarqueeStyle = MARQSTYLE_HIGHLROW
   // oBrw:lFastEdit = .T. only compatible with MARQSTYLE_HIGHLCELL
   // oBrw:nStretchCol = 2 // crashes with EDIT_LISTBOX and EDIT_BUTTON for now
   oBrw:aCols[ 1 ]:cHeader = "Property"
   oBrw:aCols[ 2 ]:cHeader = "Value"
   // oBrw:lRecordSelector := .F.

   oWnd:oClient = oBrw

   ACTIVATE WINDOW oWnd ;
      ON RESIZE oBrw:aCols[ 2 ]:nWidth := oWnd:nWidth - oBrw:aCols[ 1 ]:nWidth - 63

return nil

function SetEditType( oBrw, aData )

   local nEditType := aData[ oBrw:nArrayAt ][ 3 ]
   local oCol := oBrw:aCols[ 2 ]
   
   oCol:nEditType := nEditType
   
   do case
      case nEditType == EDIT_LISTBOX
           oCol:aEditListTxt   = aData[ oBrw:nArrayAt ][ 4 ]
           oCol:aEditListBound = aData[ oBrw:nArrayAt ][ 4 ] // remove this if you want the index, not the string
           
      case nEditType == EDIT_BUTTON
           oCol:bEditBlock = aData[ oBrw:nArrayAt ][ 4 ] // whatever is returned by the codeblock, it will be asigned
   endcase
   
return nil           

PostPosted: Wed Aug 06, 2008 6:47 pm
by Antonio Linares
Image

PostPosted: Wed Aug 06, 2008 9:26 pm
by quique
Gracias Antonio, se ve muy bien y casi es lo que necesito, tengo que hacer unas pruebas reales para entenderle bien principalmente confirmar la parte del diálogo (el que manejas en el tercer ejemplo), pero te voy a reportar 3 bugs, dos de ellos se me hacen básicos porque pueden confundir al usuario (por lo menos me pasó a mi por el concepto de browse que pienso manejar, esto es que como se maneja solamente la edición del valor, no de la columna de la descripción, puedes editar el valor simplemente dando enter o dobleclick en el registro)

1. Al dar doble click en la columna de la izquierda no se modifica el valor

2. Al dar enter en la columna de la izquierda no se modifica el valor, esto se puede reproducir intentando mover el cursor a la derecha, luego a la izquierda y dar enter

3. (Solo es estético) Al subir al primer registro con el teclado pinta un cuadro a la derecha en la columna de la derecha

PostPosted: Thu Aug 07, 2008 12:55 am
by Antonio Linares
Quique,

>
1. Al dar doble click en la columna de la izquierda no se modifica el valor

2. Al dar enter en la columna de la izquierda no se modifica el valor, esto se puede reproducir intentando mover el cursor a la derecha, luego a la izquierda y dar enter
>

Piensa que estamos usando un browse genérico, no un inspector de objetos específico, por lo que hay que programar aquellos comportamientos que deseemos y que no sean propios de un browse genérico.

Por ejemplo, un doble click en una columna, intenta editar esa columna y si no tiene estilo editable, pues el browse no la edita. Esto hay que programarlo para que proporcione esos comportamientos.

>
3. (Solo es estético) Al subir al primer registro con el teclado pinta un cuadro a la derecha en la columna de la derecha
>

Visto, gracias. Hay que arreglarlo.

PostPosted: Thu Aug 07, 2008 7:55 am
by Antonio Linares
Quique,

Esta línea hace que un doble click en la primera columna, haga que la segunda columna entre en modo edición:

oBrw:aCols[ 1 ]:bLDClickData = { || oBrw:aCols[ 2 ]:Edit() }

PostPosted: Thu Aug 07, 2008 8:40 am
by Antonio Linares
Quique,

Esta línea hace que pulsando enter se entre en modo edición:

oBrw:bKeyChar = { | nKey | If( nKey == VK_RETURN .and. ! oBrw:lEditMode, oBrw:aCols[ 2 ]:Edit(), ) }

pero requiere estos dos cambios en la Clase TXBrowse:
Code: Select all  Expand view
METHOD KeyChar( nKey, nFlags ) CLASS TXBrowse
   ...
   if ::bKeyChar != nil
      Eval( ::bKeyChar, nKey, nFlags )
      if ::lEditMode  // nuevo
         return nil     // nuevo
      endif              // nuevo
   endif
   ...

Code: Select all  Expand view
METHOD RunBtnAction() CLASS TXBrwColumn
   ...

   ::oBrw:lEditMode := .T. // nuevo!
   ::PostEdit( Eval( ::bEditBlock, nRow, nCol, Self ), .t. )

return .T.

PostPosted: Thu Aug 07, 2008 9:42 am
by Antonio Linares
Aqui está el PRG final y el EXE para quienes deseen probarlo:
http://rapidshare.com/files/135497646/inspect.zip.html

PostPosted: Thu Aug 07, 2008 3:41 pm
by quique
Excelente antonio, muchas gracias, ya con eso cambio el wbrowse por xbrowse, lo último que hubiera intentado es modificar la clase porque luego trae complicaciones cuando se actualiza, pero quedo muy bien, solo hay un detalle, en el exe que mandas funciona correctamente, pero cuando lo compilo el listbox no permite salir con ESC, tengo la versión 8.07 ¿es problema de la versión o algo estoy haciendo mal?

PostPosted: Thu Aug 07, 2008 10:00 pm
by quique
Me respondo, con el beta de 8.08 funciona correctamente, el problema es la versión

PostPosted: Fri Aug 08, 2008 6:47 am
by quique
Si, ya se, otra vez yo, pero todo iba bien, iba a cambiar el wbrowse que tengo en el programa por xbrowse, pero hay un problema, lo que muestro en el browse es un hash, tengo una clase heredada del twbrowse a la cual le mando oBrw:setArray( hash ), el primer paso no tuve problemas, muestra el hash, pero al hash no le puedo agregar los elementos extra que tiene el array para indicar el modo de edición :(

PostPosted: Fri Aug 08, 2008 7:15 am
by quique
Una sugerencia que se me ocurre, y creo que sería algo sano porque no tienes que indicar en cada registro de que se trata, sería dar la posibilidad de dar un codeblock para poder seleccionar el tipo de edición, que es lo que permite hacer twbrowse, por ejemplo, se me ocurre algo así:

Code: Select all  Expand view
oBrw:bEditType := { || selecValor( oBrw, @xOpcion ) }

function selecValor( oBrw, xOpcion )
   local nEdit := EDIT_GET
   DO CASE
      CASE oBrw:aRow[ 1 ] in { "REG4", "REG9", "REG11" }
         nEdit   := EDIT_LISTBOX
         xOpcion := { "Uno", "Dos", "Tres" }
      CASE oBrw:aRow[ 1 ] == "REG8"
         nEdit   := EDIT_LISTBOX
         xOpcion := { "aaa", "bbb", "ccc" }
      CASE oBrw:aRow[ 1 ] == "REG15"
         nEdit   := EDIT_BUTTON
         xOpcion := { || MsgYesNo( "Select a value" ) }
   ENDCASE
return nEdit

PostPosted: Fri Aug 08, 2008 7:38 am
by Antonio Linares
Quique,

Es una muy buena idea. El problema es que no tenemos bEditType de momento...

Y además supondría una evaluación más de un codeblock en el xbrowse, con lo que se enlentecería

Habría que probarlo