Programas actualizados

El mes pasado subí actualizaciones de todos mis programas a la zona de descargas. Estas actualizaciones consisten en la eliminación de todos los errores reportados hasta la fecha y la compilación con la versión más actualizada que tengo de FWH. Todas las versiones de los programas han sido numeradas como 24.04 y a partir de ahora las versiones seguirán esta nomenclatura del año y mes en que se han actualizado.

cuaderno de bitácora 8.61, con formulario exprés de documentos

Está disponible para descargar la versión 8.61 de Cuaderno de Bitácora,  mi organizador de libros, discos, videos, direcciones de internet y documentos. La novedad de esta versión es la incorporación de un nuevo formulario exprés de edición de documentos. Este nuevo formulario es similar al introducido en la versión 8.60 para la edición de referencias de fotografía, pero que ahora también se puede editar para editar los documentos. Una vez dentro del documento se puede alternar entre el formulario completo y el exprés a través de un botón dentro del propio formulario.

Con esta modificación ahora es bastante más sencillo registrar los documentos.

mejora en la fuente de mis programas

Un tema que para mi ha sido un dolor de cabeza continuo es el tema de la fuente que utilizo en mis programas. El problema lo llevaba arrastrando muchos años y es el siguiente: en Windows los programas de 32bits se ven borrosos al utilizar fuentes grandes o un escalado del tamaño de fuentes en la pantalla. En mi caso utilizo escalado de fuentes tanto en un monitor de 24″ y en un portátil que utilizo habitualmente. Hasta hora en mis programas utilizaba la fuente del sistema tal como expliqué en una entrada anterior.

El caso es que hace poco estuve revisando la carpeta samples de FWH y algunos de sus programas, como FiveDBU, se veían tremendamente bien, sin fuentes borrosas. La manera de definir la fuente era algo tan sencillo como esto:

  DEFINE FONT ::oFont  NAME "Calibri" SIZE 0, -14 

y como decía un conocido programador ¡listo el pollo!. Increíble. Con la de vueltas que le he dado yo a este tema y la solución era la más sencilla posible. Esta solución tenía un pero, y es que tuve que adaptar algunos controles para que la letra elegida se mostrase correctamente. Como los formularios que utilizo en mis programas los genero desde recursos también tuve que adaptar todos los formularios a la nueva letra. Los formularios son ahora un poco más grandes que antes pero el trabajo ha merecido la pena.

En la siguiente imagen muestro mi Cuaderno de Bitácora, a la izquierda con el nuevo tipo de letra y a la derecha con el antiguo. La claridad y legibilidad del programa ha mejorado bastante.

A la izquierda el nuevo tipo de letra y a la derecha el antiguo.

generación de pdf de listados

Hace poco he descubierto una cosa bastante curiosa sobre la generación de PDF de los listados de mis programas y que es aplicable a todos ellos. Cuando se genera un listado en cualquiera de mis programas aparece la siguiente ventana de previsualización y lo que aparece en la parte derecha es una imagen con la previsualización del listado.

Para generar un PDF con el listado normalmente pulsaba en el botón de Acrobat marcado con (2) en la imagen superior, pero se me ocurrió hacerlo seleccionando la impresora ‘Microsoft print to PDF’ que aparece en el menú desplegable bajo el icono de la impresora (1). El caso es que el resultado parece similar pero es totalmente distinto.

A la izquierda está el PDF generado con ‘Microsoft print to PDF’ y a la derecha el generado con la opción de PDF de FWH. El PDF de la izquierda es texto, se puede seleccionar, copiar texto, etc., mientras que el de la derecha es una imagen y no se puede hacer nada con el texto, simplemente porque no hay texto, hay una imagen con el texto.

En resumen, si tienes que generar un PDF a partir de uno de mis programas mira a ver si tienes disponible la impresora ‘Microsoft print to PDF’ y genera el PDF a través de ella.

organizando referencias de fotografía

En los talleres de fotografía a los que asisto a menudo se hace referencia a trabajos de fotográfos que, por un motivo u otro, el ponente introduce cuando habla de un tema concreto. Suelo anotar estas referencias a autores y trabajos en la libreta que utilizo para estos talleres y hace pocos días me planteé la manera de organizar todas estas referencias.

La primera idea fue utilizar Notion, que es una aplicación que utilizo de vez en cuando pero a la que no consigo extraer su supuesto potencial. Así que me creé una base de datos de autores y otra de trabajos, tal como lo siguiente:

Tabla de fotógrafos en Notion
Tabla de trabajos de fotógrafos en Notion

El caso es que no me acababa de gustar cómo quedaba y estuve dándole vueltas a la manera de mejorarlo. Hasta que caí que tenía algo así hecho en Cuaderno de Bitácora, en el apartado de gestión de documentos. Llevaba mucho tiempo sin utilizar esta parte del programa, que es la integración de Azeta, y que es donde tengo guardados los artículos que utilizaba en mis tiempos de profesor asociado de la Universidad de Alicante y también de temas relacionados con programación. Así que me puse a ver si la gestión de documentos me permite almacenar las referencias de fotografía y creo que sí.

La manera de hacerlo consiste en guardar los fotógrafos como autores de documentos y los sitios web donde estan los artículos o los canales de YT con los videos como publicaciones. Cierto es que tengo que darle una pensada y simplificar un tanto la gestión de documentos y de publicaciones, quizás con versiones exprés de los formularios de mantenimiento tanto de documentos como de publicaciones, pero de tal manera que no pierda la información que te ahora mismo tengo metida en el programa. Pero creo que sí me va a servir.

Ejemplo de referencia de fotografía almacenada en Cuaderno de Bitácora

Así que voy a comenzar una actualización del programa, llevando cuidado de mantener la compatibilidad con versiones anteriores del programa, pero modificándolo para su nueva funcionalidad.

cómo hacer una galería de imágenes con FWH

Esta entrada se publicó originalmente en Harbour Magazine, mi publicación sobre el lenguaje de programación Harbour.

Desde hace mucho tiempo he querido incorporar una galería de imágenes a algunos de mis programas. Esto data de mis tiempos de fanboy de Apple, cuando quedé prendado de un programa llamado Delicious Library al que me referí en esta entrada.

El caso es que hace poco estaba dándole vueltas a la cabeza en la manera de hacerlo y pregunté en el foro de FWH. La primera intención fue crear una clase a medida dentro de una ventana, pero esa solución no me valía porqué el flujo del programa es muy complicado de controlar pues las ventanas quedan independientes. Hubo otra propuesta de clase basada en diálogo utilizando la clase TPanel de FWH, y buscando ejemplos de esta clase me topé con la clase TScrollPanel que no conocía y de la que apenas hay documentación. Utilizando esta clase y el código que Mr. Rao había realizado para la clase TAlbum fue muy sencillo implementar la galería de imágenes.

Esta galería de imágenes la puedo utilizar, por ejemplo, para crear una galería de portadas de libros.

Ejemplo de galería de portadas de libros

Lo bueno de esta galería es que muestra las portadas en el orden de la rejilla de libros y si hay algún filtro activo la galería muestra unicamente los libros que aparecen en el filtro.

El código que he utilizado para crear la galería es el siguiente:

Function LiGaleria()
   LOCAL cAlias  := "LI"
   LOCAL nRecno  := ( cAlias )->( RecNo() )
   LOCAL nOrder  := ( cAlias )->( ordNumber() )
   local aImages := {}
   local aLabels := {}
   local aRecno  := {}
   local oDlgAlbum, oAlbum

   LI->(DbGoTop())
   WHILE ! LI->(EOF())
      IF ! Empty(Rtrim(LI->LiImagen))
         AAdd(aImages, Rtrim(LI->LiImagen))
         AAdd(aLabels, Rtrim(LI->LiTitulo))
         AAdd(aRecno, LI->(Recno()))
      ENDIF
      LI->(DbSkip())
   ENDDO
   LI->(DbGoTo(nRecno))

   DEFINE DIALOG oDlgAlbum SIZE oApp():oGrid:nWidth, oApp():oGrid:nHeight PIXEL TRUEPIXEL ;
      TITLE "Galería de portadas de libros - dobleclik para editar un libro"
   oDlgAlbum:SetFont(oApp():oFont)
   //
   oAlbum := TScrollPanel():New( 20, 20, oApp():oGrid:nHeight-50, oApp():oGrid:nWidth-20, oDlgAlbum, .f. )
   oAlbum:SetColor(CLR_WHITE, CLR_WHITE)
   oAlbum:SetFont( oDlgAlbum:oFont )

   @ oApp():oGrid:nHeight-40, oApp():oGrid:nWidth-96 BUTTON "Aceptar" ;
      SIZE 76, 24 PIXEL OF oDlgAlbum ACTION oDlgAlbum:End()

   ACTIVATE DIALOG oDlgAlbum ;
      ON INIT ( LiAlbum( oAlbum, aImages, aRecno, oDlgAlbum ), oDlgAlbum:Center( oApp():oWndMain ) )

   RETURN NIL  

function LiAlbum( oPanel, aPhotos, aRecno, oDlgAlbum )
   local nImgPerRow  := 8
   local nImgWidth   // := 180
   local nImgHeight  // := Int( nImgWidth * 4 / 3 )
   local nHGutter    := 10
   local nVGutter    := 20
   local nCols       := nImgPerRow 
   local nRows, nRow, nCol, x, y, nImage, xMax, nImages := Len( aPhotos )
   local oImage, oSay

   // el ancho del scrollbar es 16
   nImgWidth := INT((oPanel:nWidth-16-(nImgPerRow+1)*nHGutter)/nImgPerRow)
   nImgHeight:= Int( nImgWidth * 4 / 3 )
   nRows    := Ceiling( nImages / nCols )
   xMax     := nCols * ( nImgWidth * nHGutter )
   y        := nVGutter
   nImage   := 1
   do while nImage <= nImages
      x     := nHGutter
      nCol  := 1
      do while nCol <= nCols .and. nImage <= nImages
         // llamo a una funcion para conseguir detached locals
         LiAlbumImage(y, x, nImgWidth, nImgHeight, oPanel, aPhotos, aRecno, nImage, nVGutter, oDlgAlbum)
         nImage++
         nCol++
         x  += ( nImgWidth + nHGutter )
      enddo
      y  += ( nImgHeight + nVGutter )
   enddo
   //::nImgCols  := nCols
   // ::nHeight   := y
   oPanel:SetRange() // call this after defining all controls

return nil

Function LiAlbumImage(y, x, nImgWidth, nImgHeight, oPanel, aPhotos, aRecno, nImage, nVGutter, oDlgAlbum)
   local oImage, oSay, nLiRecno
   nLiRecno := aRecno[nImage]
   @ y, x XIMAGE oImage SIZE nImgWidth, nImgHeight OF oPanel NOBORDER
   oImage:SetSource( If( HB_ISARRAY( aPhotos[ nImage ] ), aPhotos[ nImage, 1 ], aPhotos[ nImage ] ) )
   oImage:nUserControl := 0
   oImage:lBmpTransparent := .f.
   oImage:bLDblClick := { || ( LiForm( oApp():oGrid, "edt", , nLiRecno, oDlgAlbum )) }

   //@ y+nImgHeight+(nVGutter/2), x SAY oSay PROMPT nLiRecno FONT oApp():oFont ;
   //   COLOR CLR_BLACK, CLR_WHITE ;
   //   SIZE nImgWidth, 2*nVGutter CENTER PIXEL OF oPanel
return NIL

En este código estoy utilizando tres funciones:

  • LaGaleria que recorre el fichero de libros para crear 3 arrays donde guardo las portadas, los títulos y los número de registro a que se refiere cada portada. Aquí creo el diálogo y el ScrollPanel.
  • LiAlbum donde recorro el array de imágenes para crear las imágenes dentro del ScrollPanel. Como luego quiero acceder a cada imagen para editar el libro haciendo doble click tengo que crear las imágenes en otra función utilizando la técnica de ‘detached locals’.
  • LiAlbumImage que es donde creo cada una de las imágenes, este código lo realizó Mr. Rao en el foro de FWH.

En una próxima actualización de Cuaderno de Bitácora incluiré galerías con las portadas de libros, discos y videos.

generando ficheros .rtf con harbour/fwh

Esta entrada se publicó originalmente en Harbour Magazine, mi publicación sobre el lenguaje de programación Harbour.

Una de las opciones que trae el Puchero es la posibilidad de generar un fichero .rtf con la información almacenada de una receta. Hasta ahora el fichero .rtf que se generaba era algo como lo siguiente:

Fichero .rtf a partir de una receta… hasta ahora 😉

Para generar este fichero utilizo la clase TRtfFile de FWH que basicamente genera un fichero rtf a partir de una variable de tipo texto, pero sin permitir formateos ni muchas alegrías. Algo muy básico. La pregunta que te harás es ¿ por qué no generar un fichero docx directamente con la clase TWord o similar ? Pues porque la clase Tword para FWH requiere que el usuario tenga Word instalado, y eso es algo que evito a toda costa. La generación de ficheros XLS en mis programas la realizo utilizando la clase FileXls que Ramón Avendaño publicó en el foro de FWH hace muchos años, y que he subido a un repositorio de GitHub para evitar que desaparezca. Al generar el fichero desde cero, creando un fichero con el formato adecuado, se evita que el programa pierda funcionalidad si el usuario no tiene tal o cual programa instalado. En mi caso utilizo desde hace muchos años LibreOffice sin echar de menos ninguna funcionalidad del paquete Office de Microsoft, y los ficheros XLS los abro perfectamente con Calc.

Me puse a investigar sobre la generación de ficheros .rtf desde Harbour y FWH y encontré cosas interesantes hasta que llegué a un post en el grupo de Harbour Users en que había una clase para generar ficheros .rtf que me llamó la atención. Me puse a probarla y era lo que estaba buscando, la posibilidad de generar ficheros .rtf desde cero, creando el fichero con el formato adecuado. La clase está escrita por Thomas R. Marchione y la he publicado en Github sin tocar una coma. Espero que si el autor lee este post no haya ningún problema.

Utilizando esta clase, la exportación de receta a formato .rtf en el Puchero ahora mejora sustancialmente, puedo dar formato a los párrafos y crear tablas dentro del .rtf. Justo que lo quería.

A la hora de utilizar la clase con FWH hay que tener en cuenta lo siguiente:

  • En el fichero richtext.prg hay una instrucción #Command SET DEFAULT <x> TO <y> => <x> := IIF( HB_ISNIL( <x> ), <x> := <y>, <x> ) que genera un error debido a que FWH tiene una definición similar. Lo que he hecho ha sido cambiar esta instrucción por #Command SET RTFDEFAULT <x> TO <y> => <x> := IIF( HB_ISNIL( <x> ), <x> := <y>, <x> ) y modificar el fichero en consecuencia.
  • También hay una función FUNCTION cValToChar( xVal ) que hace reescribe otra de FWH y da problemas, en mi caso el los bitmaps de los browses aparecía NIL encima del bitmap en cuestión. En mi caso la comenté y listo.

A ver si alguien se anima a incluir posibilidad de añadir imágenes en el fichero .rtf

😉

visual studio code para harbour – II

Esta entrada se publicó originalmente en Harbour Magazine, mi publicación sobre el lenguaje de programación Harbour.

Hace algo más de un año escribí para Harbour Magazine la entrada Visual Studio Code para Harbour, donde explicaba la configuración de VSCode para Harbour. Sin embargo, por pereza o por comodidad, seguía utilizando Hippoedit como mi editor principal. Hace pocas semanas, cosas del aburrimiento por la confinamiento, decidí restaurar Windows 10 en mi PC y reinstalar programas por aquello del mantenimiento del sistema y quitar rastros del registro. Tras la reinstalación Hippoedit comenzó a dar unos problemas extraños con la codificación de los ficheros y decidí quedarme unicamente con Visual Studio Code como único editor. Tras varias semanas de uso puedo decir que ha sido una buena decisión. Creo que VSCode es uno de los mejores editores de código que hay actualmente, y aunque haya otros editores específicos para Harbour que lo superen en cuanto al uso con este lenguaje, utilizar un único editor para todos tus proyectos en diversos lenguajes es mejor que utilizar distintos editores.

En estas semanas de uso intensivo he mejorado la configuración de VSCode para Harbour. Basicamente utilizo los mismos plugins que expliqué en la entrada anterior, pero he mejorado la configuración de las tareas de compilación y ejecución de manera que puedo compilar y ejecutar mis aplicaciones de manera cómoda y sencilla. Lo que hago es tener en cada aplicación Harbour cuatro ficheros bat que hacen lo siguiente:

  • hbformat.bat – hace una llamada a hbformat para dar formato al fichero con el que estoy trabajando. Me gusta tener una uniformidad en mi código y la mejor manera de conseguirlo es usar hbformat. El fichero contiene lo siguiente:
C:\Fivetech\hb32_bcc7_1905\bin\hbformat.exe @C:\alanit\develop\hbformat.ini %1
  • rc32.bat – llama al compilador de recursos para generar el fichero .res a partir del .rc donde están todos los formularios y bitmaps del programa. Los recursos están en una carpeta llamada recursos dentro de la carpeta del proyecto. El fichero contiene lo siguiente:
cd recursos
c:\bcc\bcc7\bin\brc32 -ic:\bcc\bcc7\include;c:\bcc\bcc7\include\windows\sdk -r puchero.rc
copy puchero.res ..
  • bh.bat – es el build de la aplicación. Llama al makefile de BCC con el fichero .mak de la aplicación. Si quieres ver el contenido de los ficheros .mak de mis programas echa un vistazo a la entrada código de alanit en GitHub. El contenido del fichero – tachán, tachán 😉 – es el siguiente:
C:\BCC\BCC7\bin\make.exe -f makefile\pch1905.mak
  • go.bat – ejecuta la aplicación.
puchero.exe

Todos estos bats se llaman desde el fichero tasks.json del proyecto que contiene lo siguiente:

{
	// See https://go.microsoft.com/fwlink/?LinkId=733558
	// for the documentation about the tasks.json format

	"version": "2.0.0",
	"tasks": [
		{
			"label": "hbformat",
			"type": "shell",
			"command": ".\\hbformat.bat",
			"args": [
				"${file}"
			],
			"presentation": {
				"echo": true,
				"focus":true,
				"reveal": "always"
			},
			"problemMatcher": [
				"$harbour"
			]
		},
		{
			"label": "brc",
			"type": "shell",
			"group": "build",
			"command": ".\\rc32.bat",
			"presentation": {
				"echo": true,
				"focus":true,
				"reveal": "always"
			},
			"problemMatcher": [
				"$harbour"
			]
		},
		{
			"label": "build",
			"type": "shell",
			"group": "build",
			"command": ".\\bh.bat",
			"presentation": {
				"echo": true,
				"focus":true,
				"reveal": "always"
			},
			"problemMatcher": [
				"$harbour"
			]
		},
		{
			"label": "run",
			"type": "shell",
			"command": ".\\go.bat",
			"presentation": {
				"reveal": "never"
			},	
			"problemMatcher": [
				"$go"
			]
		}
	]
}

Además, usando el plugin Tasks-Here las tareas del proyecto me aparecen en la barra de estado (1) de manera que puedo lanzar las tareas haciendo click sobre ellas. A la derecha de las tareas aparecen el proyecto con el que estoy trabajando y puedo cambiar de proyecto desde ahí o desde la barra lateral.

Otro plugin que he comenzado a utilizar es Bookmarks que me permite añadir marcas a mi código para luego moverme por el código con facilidad. Mas marcas se muestran en la barra lateral agrupados por el fichero que las contiene y es muy fácil moverse entre ellas.

La elección de un editor de código es algo muy personal, cada programador tiene unos motivos u otros para realizar su elección. Yo actualmente estoy usando VSCode y me encuentro muy a gusto trabajando con él. No digo que sea mejor ni peor que otros editores, pero sí que se puede trabajar prefectamente con él utilizando Harbour.

código de alanit en GitHub

Esta entrada se publicó originalmente en Harbour Magazine, mi publicación sobre el lenguaje de programación Harbour.

He publicado en Github el codigo fuente de algunos de los programas disponibles en mi sitio web https://alanit.com. Estos programas están hechos con Harbour y FiveWinHarbour y creo que constituyen un buen punto de partida para cualquier programador que quiera iniciarse o profundizar en el conocimiento de estos lenguajes.

En el blog de mi web personal hay cientos de artículos sobre programación https://alanit.com/category/programacion y de aspectos relacionados con mis programas https://alanit.com/category/alanit/ que he ido publicando desde el año 2003.

Cuaderno de Bitácora

Imagen de Cuaderno de Bitácora

el Puchero

Findemes

Imagen de Findemes

El código fuente de Colossus, mi programa de gestión de contraseñas, también se encuentra publicado desde hace tiempo en https://github.com/JoseluisSanchez/colossus

Videos de la 2ª Conferencia de Harbour Magazine

Esta entrada se publicó originalmente en Harbour Magazine, mi publicación sobre el lenguaje de programación Harbour.

Publicamos los videos de las ponencias de la 2ª Conferencia de programadores de Harbour Magazine. Todos los videos están en español, pero algunas de las conferencias no pudieron grabarse por problemas técnicos.

Pruebas unitarias con Harbour por Manuel Calero Solís

TDolphin por Biel Maimó

Migración DBF — SQL por Bingen Ugaldebere

Harbour en Android por Antonio Linares