Page 4 of 5

Re: Felices reyes!

PostPosted: Sat Feb 18, 2017 1:48 pm
by Carlos Mora
mastintin wrote:
Sin problemas. Una idea que se me ocurre para no romper compatibilidad con lo que tengas hecho y crearla con printer seria hacer algo así :
Añadir un metodo ... ( ojo que no se si estan bien los parametros que pongo pues va de memoria )

METHOD Box( nRow, nCol, nBottom, nRight, oPen ) INLINE ;
::Rect( nRow, nCol, nBottom, nRight, oPen )

METHOD RoundBox( nRow, nCol, nBottom, nRight, nWidth, nHeight, oPen, nBGColor ) INLINE ;
::Rect( nRow, nCol, nBottom, nRight, oPen,, Min( nWidth, nHeight ) , nBGColor )

METHOD CmBox( nRow, nCol, nBottom, nRight, oPen ) INLINE ;
::CmRect( nRow, nCol, nBottom, nRight, oPen )


Quedando la opción de usar box() o rect () indistintamente ...




Perfecto!
Hay una forma un poco más sencilla si lo unico que difiere es el nombre:

MESSAGE Box METHOD Rect
MESSAGE CmBox METHOD CmRect

Y te ahorras la llamada en la pila y el stackeado de los parametros.

mastintin wrote:Tengo otra pequeña corrección en el metodo say :

Code: Select all  Expand view


   ::CheckPage()
   HPDF_Page_BeginText( ::hPage )

   //-------------- nuevo sino se pasaba fuente daba error ahora coge la que esta activa  //
   If Empty( oFont )
      oFont := { HPDF_Page_GetCurrentFont( ::hPage ), HPDF_Page_GetCurrentFontSize(  ::hPage ) }
   EndIf
  //---------------------------------

   HPDF_Page_SetFontAndSize( ::hPage, oFont[1], oFont[2] )

 


Vale, aunque más corto sería
Code: Select all  Expand view

   If !Empty( oFont )
       HPDF_Page_SetFontAndSize( ::hPage, oFont[1], oFont[2] )
   EndIf
 


Ya que ya está seteado oFont.

Seguimos....

Re: Felices reyes!

PostPosted: Tue Feb 21, 2017 3:55 pm
by mastintin
Carlos Mora.
Otro pequeño bug en ::say() si se centra el say ( nPad := 2 ) daba error fues falta el valor de nWidth .
Code: Select all  Expand view


METHOD Say(
  ..........................
   OTHER
      nWidth := HPDF_Page_TextWidth( ::hPage, cText )   // nuevo
      HPDF_Page_TextOut( ::hPage, nCol-nWidth/2, ::nHeight - nRow - oFont[2], cText )
   ENDCASE
.........................
 

Re: Felices reyes!

PostPosted: Tue Feb 21, 2017 5:50 pm
by Carlos Mora
Gracias! Se ve que le estas dando cera!

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 1:04 am
by ruben Dario
Saludos.

Podrian Publicar la clase completo con todos los cambios.

Una Pregunta con lo que indicas con el commando PRINT
Se usaria asi. (Practicamente igual como se usa el command tradicional)

Code: Select all  Expand view

  PRINT  oPrn TO HARU  PREVIEW
        PAGE HARU
        .........
        ENDPAGE  HARU
   ENDPRINT
 

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 7:45 am
by mastintin
ruben Dario wrote:Saludos.

Podrian Publicar la clase completo con todos los cambios.

Una Pregunta con lo que indicas con el commando PRINT
Se usaria asi. (Practicamente igual como se usa el command tradicional)

Code: Select all  Expand view

  PRINT  oPrn TO HARU  PREVIEW
        PAGE HARU
        .........
        ENDPAGE  HARU
   ENDPRINT
 


ENDPRINT HARU :D

Si se usaria como indicas . Se podría hacer sin ningun cambio ( no tocando casi ni una linea de código ) pero no podrían convivir en el mismo prg las clases "print" y "PrintHaru" . La idea es que de esta forma con poner unos "if else endif " la misma funcion realiza un listado con salida a impresora o pdf .

Rubén . Estos no son cambios realizados en la librería. Son solo "apuntes" que yo he hecho, como posibles cambios a realizar en ella por Carlos Mora que es el propietario de esa librería . Los he probado y funcionan correctamente pero de eso a añadirlos ....
El decide que se añade y que no se añade y eso previo análisis de pros y contras de los cambios. Demos le un poco de tiempo para que lo mire y decida.
Otra cosa distinta son los pequeños bugs , que son correcciones rápidas de cosas evidentes. :D
Un saludo a todos.

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 9:01 am
by mastintin
Carlos Mora .
Uno de los fix de bug que propones en el say no es valido ...
Vale, aunque más corto sería

If !Empty( oFont )
HPDF_Page_SetFontAndSize( ::hPage, oFont[1], oFont[2] )
EndIf

Ya que ya está seteado oFont.


Ya que si no pasas font el codigo de mas abajo donde se hace referencia a ofont[2] rompe al no existir ofont .

Code: Select all  Expand view


   If Empty( oFont )
      oFont := { HPDF_Page_GetCurrentFont( ::hPage ), HPDF_Page_GetCurrentFontSize(  ::hPage ) }
   else
       HPDF_Page_SetFontAndSize( ::hPage, oFont[1], oFont[2] )
   EndIf

 


y aún mejor sería :


Code: Select all  Expand view


   METHOD GetFont() INLINE { HPDF_Page_GetCurrentFont( ::hPage ), HPDF_Page_GetCurrentFontSize(  ::hPage ) }

METHOD SetFont( oFont )
   If Empty( oFont )
      oFont := ::GetFont()
   else
      HPDF_Page_SetFontAndSize( ::hPage, oFont[1], oFont[2] )
   endif
Return oFont


//------------------------------------------------------------------------------
METHOD Say( nRow, nCol, cText, oFont, nWidth, nClrText, nBkMode, nPad )
//------------------------------------------------------------------------------

   LOCAL c
   ::CheckPage()
   HPDF_Page_BeginText( ::hPage )

   oFont := ::SetFont( oFont )

   ...........................

 

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 9:24 am
by Carlos Mora
Buenos días gente,

@Ruben: dame unos días, te prometo que lo vas a tener. Las ideas y los aportes de Mastintín son excelentes, y los vamos a incorporar. as mí me lleva más tiempo porque no estoy todo el tiempo con Harbour, estoy con otros proyectos.
Ten en cuenta que para ponerlo en una librería que sea genérica y GUI agnóstica hay que tener algunas premisas. Te doy un ejemplo: la idea de la preview es sencilla, muy simple, son dos líneas... siempre y cuando estés dentro de FW. Yo uso la librería en unos programas de consola, donde (por ejemplo) no existe la funcion ShellExecute (o al menos no sé como reemplazarla de forma equivalente con Harbour nativo) Entonces ya el cambio se transforma en más lineas de código y en buscar como hacer un ShellExecute desde fuera de FiveWin.
Nota: Por cierto, si alguien tiene una idea de como hacer un ShellExecute directamente desde Harbour sin FW, agradecido. Hasta ahora la solución es escribir una llamada en C al ShellExecute original

De todas maneras, si quieres ir incorporando los cambios, tienes la clase THaruPdf vacía, que esta justa y precisamente para eso: es el lugar donde el usuario de la librería puede poner su propio código, o adaptaciones a sus necesidades, hasta que la funconalidad esté prevista en la librería. Está explicado en la documentación, es una técnica que da buenos resultados y por eso la incluí. Puedes sentirte tentado a hacerlo en la THaruBase, pero despues te va a costar incorporar las actualizaciones que vengan a posterior.
Como la librería es un trabajo de colaboración donde todos podemos aportar, es de esperar que sufra algunos cambios, y más en épocas tan cercanas al lanzamiento como ahora. Con suerte será código vivo, y trataré de mantenerlo.

@Mastintín: La idea de los comandos esta muy bien, vamos a ver de implementarla de forma modular. Lo de incluir la static 'dentro' de la clase es algo que trataría de evitar. Justamente no se pueden redefinir los comandos porque la clase TPrinter tiene la STATIC y las funciones dentro de la clase, con lo que no puedes tener TPrinter sin tener que usar esos comandos si o si, sin posibilidad de redefinirlos. La idea pasaría por un prg separado, que puede manejar cualquiera de las dos impresoras, ya sea TPrint o THaru. Salvo la definición, el resto es exactamente igual,es parte de las premisas, asi es que nos vamos a ahorrar código si lo ponemos por separado. Y además, si no lo usas, no se enlaza, menos código sin usar en el exe.

Hasta ahora, las diferencias entre TPrinter y THaru están dadas en la definición y las fuentes, con lo que podemos poner el código diferente al principio y reutilizar el resto sin tener que duplicar el código.

Un saludo y gracias.

A ver si me pongo y lo sacamos de una vez.

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 10:37 am
by hmpaquito
como hacer un ShellExecute desde fuera de FiveWin



Code: Select all  Expand view


FUNCTION OpenPdf( cPdf )

Local lOk:= .t.
Local oShell


TRY

   #IFDEF __XHARBOUR__

       oShell := CreateObject( "WScript.Shell" )

   #ELSE

       oShell := Win_OleCreateObject( "WScript.Shell" )

   #ENDIF

CATCH

      lOk:=.F.

END

IF lOk

   TRY

       oShell:Run( "%ComSpec% /C " + cPdf, 0, .T. )

   CATCH

       lOk:=.f.

   END

ENDIF

RETURN lOk

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 10:43 am
by Carlos Mora
Paquito,
vi tu respuesta despues de haber subido el commit.
Sin dudas la tuya es la mejor solución, escribí algo en 'C' pero me quedo con la tuya, que está en Harbour.

Muchas gracias!

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 11:29 am
by hmpaquito
No hombre, gracias a ti.

Déjalo para la siguiente edición. :)

Oye una cosa... que sé que dominas :) ... off-topic... estoy subiendo una base de datos a mysql de una webapp. El proceso se ha de hacer regularmente. Son como 400 Mb. lo que subo a base de UPDATE. El problema es que tarda una eternidad y lo siguiente :D

Buscando en Inet he visto que alguien lo hace a partir de CSV, así:
Code: Select all  Expand view

LOAD DATA LOCAL INFILE 'c:/importar.txt'
INTO TABLE importacion
FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '"'
LINES TERMINATED BY ' '


¿ Lo has tenido que hacer alguna vez tu ? Es decir, ¿ Como subirias un conjunto enorme de registros a UPDATEar a MySql ?

Te agradecería una respuesta. Saludos.

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 12:15 pm
by Carlos Mora
La mejor solución es si tienes acceso al servidor. Genera un fichero con todos los updates y actualizas desde la linea de comandos con

mysql -u <usuario> -p <pass> <basededatos> < fichero.txt

suele ser lo mas rápido. Y si puedes administrarlo, metes en el cron un script que chequee cada 15 minutos la existencia de un archivoen un lugar específico , y si lo encuentra que haga un 'mysql < fichero.txt' , y pasas el fichero con los updates del tirón. Vas a cargar el servidor? si, pero por solo unos segundos.

Si no hay acceso al servidor, genera una sola sentencia lo mas tocha posible y se la vas dando de a tragos largos :)
Por ejemplo, meter de a 200 registros por update o algo así. De todas maneras con 400 Mb ya tienes bastante con la transferencia si el servidor no es local, lo mejor sería la primera opción.

Tambien hay algo que suele ser significativo a la hora de ahorrar tiempo y ancho de banda, y es transferir solo los cambios, tal vez si vemos los detalles del problema se nos ocurra algo.

Cuanta conmigo para lo que te pueda ayudar. Un saludo.

Re: Felices reyes!

PostPosted: Wed Feb 22, 2017 12:41 pm
by hmpaquito
Muchas gracias Carlos,

Sí tengo acceso al servidor. La situación es:

He hecho una WebApp, no está aún en producción, para recogida de pedidos y tratamiento de informacion de clientes. Tengo que subirle los datos desde la aplicacion escritorio.
Subo varias tablas, articulos, clientes, etc.. y fotos y pdfs. Ahora mismo lo hago con UPDATE, uno por cada registro. Cada UPDATE lleva todos los campos del registro a grabar.

Creo que la primera de las soluciones que me has dado es la mejor, dado que tengo acceso al server.

Por cierto, como tengo que subir fotos y pdfs que estan en ficheros sueltos... ¿ aquí como actuar ?... los estaba subiendo con ftp...pero es muy lento.

Editado: ¿ Por qué el volcado de los UPDATEs hay que hacerlo por consola ? ¿ No es igual de efectivo si lo pego en un la ventana SQL de HeidiSql, pongamos por caso, y lo ejecuto ?


Muchas gracias de nuevo.


--


Reeditado 2

Me da vergüenza seguir con el off-topic on off-topic. Así que mis respuesta y las siguientes, si no te importa, las añadiré a este post.



Si le pasas todos los campos al update aumentas el ancho de banda, si de alguna manera puedes pasar solo los cambios vas a ganar en velocidad. Piensa que entre actualizaciones no es tanto lo que cambia, por lo que reducir por ahí te va a hacer ganar mucho en términos de velocidad.

Establecer control de modificación por cada campo sería lo indicado, entiendo, pero es una locura. Así que tengo que pasar el registro entero.



Es que tu problema es de ancho de banda. Y ftp no es particularmente rápido, aún en modo binario. El problema de velocidad, la mayoría de las veces, es un problema de percepción: Si el proceso es lento pero el usuario no se da cuenta, deja de ser tan relevante. En el caso de los archivos externos, yo plantearía la solucion de forma inversa: Publico un directorio local usando algun servicio, y en el servidor web pongo un cliente de sincronizacion. Por ejemplo, te paso una invitación de hubic que tiene clientes para muchas plataformas, y la sincronización es inteligente, mueve solo novedades. No sé que lógica usas para vincular las imágenes con los correspondientes registros, pero si tienes eso resuelto, es lo mejor que puedes hacer.

Me encantó el tema de de "es un problema de percepción": Ojos que no ven corazón que no siente...
Para el tema de la sincronizacion de archivos tengo echa una sincronización lopez perez: en una .dbf grabo la fecha/hora de subida del archivo y solo sube si cambia. Aun no la he probado, pero creo que funcionara. La primera vez tengo que subirlo todo a manubrio, claro está. :) Te pregunté por ella para saber cómo lo hacias tu.

Si quieres crea una cuenta en Hubic, usa el código ZZOSRX al darte de alta para que te dé 5Gb de espacio extra (se va a 30Gb), y haz alguna prueba. Creo que si logras hacer andar la sincronización con Hubic vas a resolver un problema importante, porque sería instantáneo y automágico, en cuanto se copia un fichero en la carpeta de las imágenes quedaría automáticamente publicada.

Te agradezco un montón la informacion. De momento seguiré con la sincronizacion lopez-perez, pero tengo en cuenta el hubic si necesito cambiar.


Pensaba en hacer procesos automáticos. Si lo quieres hacer con Heidi no le veo inconveninte, yo pensaba en algo desatendido. Si es por una única vez, esta bien, si es de forma permanente... es para pensárselo.

Sip. El proceso al final tendrá que ser desatendido. Mi comentario era por el tema de la velocidad. ¿ Qué es más rápido, miles de UPDATES con HeidiSql o con la consola Mysql, teniendo en cuenta que la bbdd se encuentra en el ordenador al que tengo acceso (server) ?

Nuevamente, muchas gracias :D

Re: Felices reyes!

PostPosted: Thu Feb 23, 2017 9:08 am
by Carlos Mora
hmpaquito wrote:He hecho una WebApp, no está aún en producción, para recogida de pedidos y tratamiento de informacion de clientes. Tengo que subirle los datos desde la aplicacion escritorio.
Subo varias tablas, articulos, clientes, etc.. y fotos y pdfs. Ahora mismo lo hago con UPDATE, uno por cada registro. Cada UPDATE lleva todos los campos del registro a grabar.

Si le pasas todos los campos al update aumentas el ancho de banda, si de alguna manera puedes pasar solo los cambios vas a ganar en velocidad. Piensa que entre actualizaciones no es tanto lo que cambia, por lo que reducir por ahí te va a hacer ganar mucho en términos de velocidad.

hmpaquito wrote:Creo que la primera de las soluciones que me has dado es la mejor, dado que tengo acceso al server.

Por cierto, como tengo que subir fotos y pdfs que estan en ficheros sueltos... ¿ aquí como actuar ?... los estaba subiendo con ftp...pero es muy lento.

Es que tu problema es de ancho de banda. Y ftp no es particularmente rápido, aún en modo binario. El problema de velocidad, la mayoría de las veces, es un problema de percepción: Si el proceso es lento pero el usuario no se da cuenta, deja de ser tan relevante. En el caso de los archivos externos, yo plantearía la solucion de forma inversa: Publico un directorio local usando algun servicio, y en el servidor web pongo un cliente de sincronizacion. Por ejemplo, te paso una invitación de hubic que tiene clientes para muchas plataformas, y la sincronización es inteligente, mueve solo novedades. No sé que lógica usas para vincular las imágenes con los correspondientes registros, pero si tienes eso resuelto, es lo mejor que puedes hacer.

Si quieres crea una cuenta en Hubic, usa el código ZZOSRX al darte de alta para que te dé 5Gb de espacio extra (se va a 30Gb), y haz alguna prueba. Creo que si logras hacer andar la sincronización con Hubic vas a resolver un problema importante, porque sería instantáneo y automágico, en cuanto se copia un fichero en la carpeta de las imágenes quedaría automáticamente publicada.

hmpaquito wrote:Editado: ¿ Por qué el volcado de los UPDATEs hay que hacerlo por consola ? ¿ No es igual de efectivo si lo pego en un la ventana SQL de HeidiSql, pongamos por caso, y lo ejecuto ?


Pensaba en hacer procesos automáticos. Si lo quieres hacer con Heidi no le veo inconveninte, yo pensaba en algo desatendido. Si es por una única vez, esta bien, si es de forma permanente... es para pensárselo.

Re: Felices reyes!

PostPosted: Mon May 22, 2017 3:25 pm
by horacio
Colegas, para saber el ancho y alto de una página en TPrint uso

Code: Select all  Expand view

oPrn : GetPhySize()
 


Cual es el equivalente en esta clase. Desde ya muchas gracias.

Saludos

Re: Felices reyes!

PostPosted: Mon May 22, 2017 4:39 pm
by Carlos Mora
Hola,

METHOD nVertSize()
METHOD nHorzSize()

Ambos te dan el tamaño en pixeles, por lo que si quieres las medidas en mm harias oPrn:nVertSize() * 25.4 / 72 , oPrn:nHorzSize() * 25.4 / 72