Archivo para febrero, 2008

Actualización Leopard 10.5.2

Posted in Apple on febrero 17, 2008 by César Intriago

Ya está disponible la actualización de Leopard a la versión 10.5.2, la instalé ayer de forma automática:

Esta actualización incluye correcciones y algunas nuevas características como:

Stacks: Se agregó el modo de lista para ver el contenido:

También da la opción de ver el Stack como "pila" o como una "carpeta", esto se debe supongo a las quejas de que el modo "pila" muestra el última archivo creado o modificado, mientras que el modo "carpeta" permite fijar un ícono a nuestro gusto.

Otra cosa nueva fue la adición del ícono de TimeMachine en la barra superior de Leopard:

Que permite realizar una copia de seguridad en cualquier momento de forma mas rápida.

Estas son las mejores que he podido ver en este poco tiempo. En el siguiente link encontrarán la lista de completa de cambios y correcciones:

http://docs.info.apple.com/article.html?artnum=307109

Que incluye actualizaciones para :

  • Soporte mejorado para Active Directory
  • AirPort
  • Dashboard
  • Dock
  • Barra de menú transparnte
  • iCal
  • VistaPrevia
  • Safari
  • Sistema
  • Time Machine

Mas Música con Automator – Un Apple WOW

Posted in Apple, Tutorial on febrero 17, 2008 by César Intriago

Imaginen esto:

Estan en cualquier lugar de su oficina o casa, mandan la palabra "musica" por  mail desde un blackberry o lo que sea, y luego de un minuto empieza a sonar la música de la iMac en la casa.

Eso mismo fue lo que probé con una persona, le dije "manda un mail desde tu blackberry con el Asunto -musica-", luego de un minuto cuando se empezó a escuchar, se quedó lo que se puede decir "es loco", ¿puedo hacer eso con mi compu? preguntó (Laptop + Vista)… la respuesta no se, los entendidos en Vista sabrán decirlo, pero así se hace con leopard en menos de 5 minutos:

1. Con Automator creamos una actividad que reproduce música de iTunes de forma aleatoria, grabamos el flujo en una carpeta, por ejemplo "AutoMusica"

2. Con Apple Script  invocamos el flujo creado en el paso 1, por ejemplo si el flujo se llama MusicaDJ, el único código que se necesita es:

y lo guardamos en la misma carpeta "AutoMusica" con un nombre cualquiera, por ejemplo "ScriptMusica"

3. Entramos a Mail y configuramos una nueva regla en la que especificamos que al recibir un mensaje de un destinatario en particular, con el asunto "musica", ejecute el script del paso 2 y luego borre el mail (no tiene mucho sentido mantenerlo).

Eso es todo, ahora se manda el mail y ya, WOW… chis pun chis pun chis pun.

Esto lo encontré en Internet, donde se puede ver un video-ejemplo de algo casi igual:

http://murphymac.com/slib/sleep-your-mac-by-email.htm

::Fin::

A dormir iMac con Automator

Posted in Apple, Tutorial on febrero 16, 2008 by César Intriago

¿Cuántos de ustedes acostumbran a dormir con música?, algunas veces yo lo hago, y mejor aún si es de la música del iTunes de la Mac, pero resulta que mi iMac está en mi "mini-oficina" junto a mi cuarto y el home-theater en mi cuarto. Bueno, el poryecto casero era el siguiente:

1. Armar un cable de audio que pase de un cuarto al otro y vaya de la iMac al Home Theater.

2. Poner la música en el iTunes.

3. Poner Sleep  a la iMac.

Como nuevo usuario de Mac me preocupaba un poco la parte 3, pero resultó increiblemente sencillo, esto fue así:

1. "La Soldada", por menos de 5 dólares compré suficiente cable para audio y unos conectores RCA para armar el cable, cautín, cortadora y el cable estaba armado

Desde aquí:

Hasta aquí:

2. "Música Disyoquer", ya podía escuchar mis canciones desde la iMac en mi cuarto.

3. "Duuuuerrrrrmeeeee iMac". Configurar la iMac para que se apague de forma automática luego de un tiempo en partiular resula sencillo gracias a Automator.

Esto es lo que tenía que hacer: Pedir el tiempo (segundos) en el que se apagaría, esperar, ajustar el volumen a la mitad, cerrar las aplicaciones y apagar la computadora. Automator permite realizar flujos de actividades de forma rápida y sencilla, este el flujo que configuré para ese caso:

Lo guardé en mi carpeta de aplicaciones como "MacSleep" y eso fue todo.

Ahora puede poner música, abro el "MacSleep", ingreso el tiempo antes de que se apague la iMac y zzzzZZZZZzzzzz.

 

UPDATE (03-FEB-2009) Gracias David por el comentario, adjunto una captura de pantalla del código que te hace falta.

Imagen 1

Básicamente en la primera acción solicito el tiempo en segundos en el que se desea apagar la Mac, ese valor corresponde al parámetro INPUT de la siguiente acción, el script lo que hace es una pausa por los segundos especificados, luego sigue y al final ejecuta el script para apagar (el cual se ve en la captura de pantalla anterior).

Rotar, mover y escalar libremente controles de usuario

Posted in Aplicaciones, Blend, Tutorial, WPF on febrero 9, 2008 by César Intriago

En esta aplicación de ejemplo se mostrará una forma en la que se pueden crear controles de usuario con propiedades de ser movidos libremente, redimensionados y girados. Este es un ejemplo de lo que se obtendrá al final:

imagedesk_ejemplo01.png

Como se ve en el gráfico, se trata de un control funcionalmente “simple”: lo que se escriba en el textBox aparecerá en el TextBlock del control. Si se fijan podrán ver dos rectángulos Verdes, el de la esquina superior-izquierda representa el botón cerrar y el otro es para redimensionar el control. El rectángulo rojo que está detrás permite girar el control. Estos objetos son rectángulos ya que se les puede aplicar cualquier Brush (pincel), ya sea color sólido, gradiente o una imagen.

El otro punto importante que verán en la aplicación es que existe una clase llamada AdministradorSuperficie que permite acceder desde la ventana a las instancias de cada control y viceversa. Resulta bastante interesante este ejemplo, a partir de esto se pueden crear cosas mas interesantes, estoy trabajando en un visor de imágenes que espero pronto compartirlo.

Prototipo ImageDesk con Código Fuente

ACTUALZACIONES 26-Agosto-2008:

  • El vínculo para descargar la aplicación fue actualizado para usar mi SkyDrive ya que el anterior no estaba funcionando.
  • Sobre el ejemplo que me piden de poner navegación para una texto (adelante y atrás), no estoy seguro si este ejemplo es el que te puede servir: BlackoutNews. Dime si es lo que estabas buscando, debo tener el código fuente en algún lado, lo encuentro y lo publico.

 

:: Fin ::

Keynote

Posted in Apple, Opinion on febrero 5, 2008 by César Intriago

Keynote es la aplicación de Apple cuyo equivalente en el mundo Windows es PowerPoint, Keynote es parte del conjunto de aplicaciones de Apple llamado iWork.

He estado trabajando con Keynote, haciendo unas presentaciones de prueba y la verdad que de entrada es impresionante la calidad de herramientas gráficas, plantillas, animaciones y efectos que nos ofrece, un nivel superior al de PowerPoint por ejemplo. Keynote incluye:

  • Mover, escalar, difuminar texto.

  • Transiciones entre diapositivas 3D y 2D.

  • Efectos avanzados de entrada y salida a cada elemento.

  • Acceso a galería multimedia: video, mp3, fotos.

Que también las tienen otros, la diferencia está en la variedad y calidad, eso complementado con una facilidad de hacer las cosas características de Apple, además Keynote abre archivos de PowerPoint 2007, y puede exportar a formatos QuickTime, PowerPoint, PDF, HTML y Flash principalmente. Estando acostumbrado a usar PowerPoint, el cambio a Keynote ha sido sin problemas y muy favorable.

Como Keynote usa XML como su formato de archivos, algún momento podría aparecer una visor de Keynote para PC.

Opinión Final:

Keynote y PowerPoint básicamente hacen lo mismo, pero si quieres realizar de forma rápida y sencilla  una presentación que llame la atención, que tenga aspecto profesional (y si tienes una Mac), Keynote es el ganador.

ObjectDataProvider – Parte I

Posted in Blend, Tutorial, WPF on febrero 5, 2008 by César Intriago

Esta es la primera de dos partes de este tutorial, al final del mismo encontrán en enlace a la segunda parte.

Los definicón rápida "del libro" de ObjectDataProvider es que encapsula y expone un objeto para que pueda ser usado como una fuente de datos. En la práctica sigfnifica que pueden crear una clase, incluso usando constructores con parámetros, esa clase puede tener un miembro que devuelva un objeto List<>, y los datos de esa lista serán desplegados en cualquier control que soporte DataBinding con ObjectDataProvider. Realmente es muy útil y simplifica la reutilización de fuentes de datos, algo adicional es que tampién permite que los datos se mantengan sincronizados.

En el siguiente tutorial vamos a ver cómo enlazar datos entre una base de datos y un control Windows usando ObjectDataProviders y objetos del CLR.

Antes que nada, aclaro que para leer este tutorial deben tener conocimientos báscios de SqlConnection, referenciar proyectos, y conocer de forma general cómo se organizan los proyectos en Visual Studio y Blend.

Parte I: La Fuente de Datos.

Usaremos SQL Server para crear una tabla Personas con algunos campos como: Id, Nombre, Apellido.

Luego nos creamos un procedimiento almacenado llamado por ejemplo ObtenerPersonas que contendrá la sentencia SELECT Id, Nombre, Apellido FROM Personas.

Llenamos algunos datos de prueba y tenemos lista esta primera parte.

Parte II: La arquitectura de la aplicación.

  • Para este ejemplo organizaremos el código en los siguientes proyectos:
  • Para acceso datos (DAL – Biblioteca de clases)
  • Para transferencia de objectos (DTO – Biblioteca de clases)
  • Para la lógica del negocio (BLL – Biblioteca de clases)
  • Para la presentación (Interfaz de Usuario – Cliente Windows tipo WPF)

Algo bastante típico y común: En el proyecto para el DTO crearemos una clase llamada PersonaDto (usando el método clásico para las propiedades):

public class PersonaDto
{
 private int id;
 private string nombre;
 private string apellido;


 // Creamos de forma explícita un constructor predeterminado
 public PersonaDto()
 {
 }


 // Propiedades públicas para acceder a los campos
 public int Id 
 { 
    get { return id; }
    set { id = value; }
 }

 public string Nombre 
 { 
    get { return nombre; }
    set { nombre = value; }
 }
 
 public string Apellido 
 { 
    get { return apellido; }
    set { apellido = value; }
 }
}

Este será el objeto que pasaremos entre las capas y será una lista de esos objetos los que el ObjectDataProvider encapsulará.

Ahora tenemos que escribir el código para la Dal (PersonaDal) y Bll (PersonaBll) , para este tutorial no se mostrará el código ya que no es de gran importancia, además no tiene nada en especial, en la DAL nos conectamos a SQL Server y cagamos un DataSet o DataTable. En la BLL cramos un método para transformar el DataSet de la DAL a un objeto List<PersonaDto> y ya.

Antes de continuar, primero vamos a agregar algo adicional a nuestro proyecto Windows (PersonaWpf). En lugar de conectar un control Windows (por ejemplo un ListView) directamente con la clase PersonaPwf, vamos a crear un objeto intermedio que se encargará de gestionar algunos servicios para la interfaz del usuario:

  • Notificación de cambios en la fuente de datos.
  • Búsquedas de datos.

A esta clase intermedia la llamaremos PersonaBinding, y el código es el siguiente:

public class PersonaBinding : INotifyPropertyChanged
{
 List<PersonaDto> listaCompleta = new List<PersonaDto>();
 List<PersonaDto> vista = new List<PersonaDto>();
 string patronBusqueda;
 public PersonaBinding()
 {
   patronBusqueda = "";
 
   if (!DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
   {
     Refrescar();
   }
   else
   {
    // Crear item de prueba
    PersonaDto dummy = new PersonaDto();
    dummy.Id = 1;
    dummy.Nombre = "Juan";
    dummy.Codigo = "Perez";
    listaCompleta.Add(dummy);
   }
   Items = listaCompleta;
 }
 public List<PersonaDto> Items
   {
   get { return vista; }
   set { vista = value; OnPropertyChanged("Items"); }
   }
 public void Refrescar()
 {
  if (!DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
   listaCompleta = PersonaBll.ConsultarTodos();
 }
 public void Filtrar(string patron)
 {
  patronBusqueda = patron.ToLower();
  if (String.IsNullOrEmpty(patron))
   Items = listaCompleta;
  else
   Items = listaCompleta.FindAll(ContienePatron);
 }
 public bool ContienePatron(PersonaDto persona)
 {
  return (persona.Nombre.ToLower().Contains(patronBusqueda) || persona.Codigo.ToLower().Contains(patronBusqueda));
 }
 #region Miembros de INotifyPropertyChanged
 public event PropertyChangedEventHandler PropertyChanged;
 private void OnPropertyChanged(string propertyName)
 {
  if (this.PropertyChanged != null)
  {
   this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  }
 }
 #endregion
}

El código anterior hace algunas cosas interesantes:

  • Primero implementa la interfaz INotifyPropertyChanged que nos permite activar la notificación a los consumidore de datos (ej: ListView) de que se ha modificado la colección y reflejen los nuevos datos. Es importante ver que en el atributo Set de la propiedad Items, invoco al método OnPropertyChange que dispara el evento que notifica a los consumidores de datos.
  • Segundo, notamos que la clase mantiene dos Listas de datos, la una siempre contiene la colección completa y se usa internamente, la segunad (llamada vista) es la que le pasamos a los controles, y puede ser la lista completa de datos o los que cumplan con el método-predicado ContienePatron.
  • Tercero, antes de invocar al método de la Bll que consulta los datos, primero verificamos si la ventana está abierta en el diseñador, si está en el diseñador NO nos conectamos a la base y llenamos la lista con datos de ejemplo, caso contrario (cuando el programa está en ejecución) se conecta a la base. Esto es porque en tiempo de diseño Blend intenta compilar y ejeuctar este código y produciría un error al momento de tratar de  conectar con la base. En este artículo se explica el por qué de este error.

Compilamos nuestro proyecto para ver que todo esté bien y continuamos a la Parte II.

ObjectDataProvider – Parte II (final)

Posted in Blend, Tutorial, WPF on febrero 5, 2008 by César Intriago

Esta es la segunda de dos partes de este tutorial, Este es el enlace a la primera parte.

En esta parte del tutorial, usaremos Blend para arrastrar un ListView y, crearemos el ObjectDataProvider que encapsulará la clase PersonaBinding.

Parte I: Consumir los datos

  1. Abrimos nuestra solución en Blend, y nos vamos a la ventana principal del proyecto WPF (referencia: Window1.xaml).
  2. Arrastramos un ListBox sobre nuestra ventana y lo llamaremos lsbPersonas, en las propiedades del ListBox buscamos ItemSource y seleccionamos DataBinding
  3. Ahora, Blend nos muestra una ventana de donde podemos escoger la fuente de datos para nuestro control, puede ser XML o CLR, en este caso seleccionamos CLR.
  4. La siguiente ventana muestra una lista de todos los objetos que se encuentran en los ensamblados referenciados por el proyecto WPF, buscamos y seleccionamos la clase PersonaBinding y la nombramos PersonasDS, luego presionamos OK.
  5. Regresamos a la ventana anterior, en el panel derecho debemos seleccionar el miembro de donde se leerán los datos, para este ejemplo seleccionamos la propiedad Items, luego presionamos OK.

Lo que acabamos de hacer es decirle a Blend que existe un ObjectDataProvider llamada PersonasDS que expone la clase PersonasBinding y, que nuestro ListView leerá los datos de la propiedad Items

Pueden ver el XAML de su ventana y encontrarán algo como:

 <Window.Resources>
 <ObjectDataProvider x:Key="PersonasDS" d:IsDataSource="True" ObjectType="{x:Type PersonasWpf:PersonasBinding}"/>
 </Window.Resources>
...
<ListBox Visibility="Visible" x:Name="lsbPersonas" Width="Auto"ItemsSource="{Binding Path=Items, Mode=Default, Source={StaticResource PersonasDS}}" IsSynchronizedWithCurrentItem="True"/>

Una vez creado el PersonasDS, lo podemos reutilizar en mas controles de la misma ventana, por ejemplo un combo.

Si se dan cuenta, en el diseñador, el ListBox se llena con los datos de ejemplo, y cuando la ejecutan se cargan los datos de la base de datos.

Parte II: Buscar datos.

La última parte de este tutorial consiste en implementar un buscador sencillo, estilo Spotlight o DesktopSearch, lo que vamos a hacer es agregar una caja de texto a nuestra ventana, y filtraremos los datos del ListBox según el contenido del TextBox:

Agregamos un TextBox a la ventana, lo llamaremos txtBuscar.

Creamos un manejador para el evento TextChanged y vamos a Visual Studio para escribir el código necesario. De forma general, esto es lo que tenemos en el XAML: Un ListBox que está enlazado a la propiedad Items de un ObjectDataProvider llamado PersonasDS que es de tipo ClienteBinding. Por el lado del CLR no tenemos ningún objeto hasta ahora, y lo que necesitamos hacer es filtrar esa lista de Items, para eso tenemos que referenciar al objeto PersonasDS que creamos en el XAML.

Debemos crear una variable de instancia de tipo PersonasDataBinding donde guardaremos la referencia a PersonasDS:

PersonasBinding listaClientes;

Luego, en el constructor buscamos el recurso llamado PersonasDS y lo convertimos al tipo PersonasBinding:

ObjectDataProvider odp = this.Resources["PersonasDS"] as ObjectDataProvider;
 listaClientes = odp.Data as PersonasBinding;

Ahora ya tenemos un objeto llamado listaClientes que representa los datos que están enlazados al ListBox, el paso final es ir al manejador del evento TextChanged del TextBox y escribir:

private void txtBuscar_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
 {
 listaClientes.Filtrar(txtBuscar.Text);
 }

Gracias al milagro del paso de datos por referencia y al ObjectDataProvider, enlazamos un control ListBox a una clase del CLR e implementamos de una forma sencilla un buscador.

Notas finales:

Como les había mencionado en un principio, este tutorial se enfoca en partes específicas y se salta algunas cosas de la implementación que no apoyan tanto a la idea principal, pero al final de cuentas se obtiene algo funcional y útil que demuestra como aprovechar esta tecnología.

Con gusto responderé inquietudes sobre este tema (comentarios).

:: Fin de la Transmisión ::