El historial de deshacer

Implemnetar la capacidad de deshacer en una aplicación tampoco parece, en principio, demasiado complicado, si se tiene la aplicación diseñada a base de comandos como es el caso de konqueror. Simplemente se guardan los comandos en una pila y ya está. El problema viene cuando tan pronto como tocamos con la realidad.

Resulta que konqueror permite tener varias instancias de sí mismas en ejecución, pero comparten un historial de deshacer entre ellas. Por ejemplo, arrastramos de una ventana a otra un fichero. Desde ambas (y desde cualquier otra) es posible deshacer ésta acción. Esta característica es típica en los administradores de archivos. Pero resulta que las “pestañas cerradas recientemente” son propias de cada ventana. Además, dependiendo de la vista en que se esté, solo se podrán deshacer un tipo de comandos u otro. Es decir, en la vista de navegador web no puede deshacerse la creación de pestañas.

Toda ésta parafernalia viene como resultado de que konqueror sea una aplicación extremadamente versatil y sirva tanto para administrar ficheros como de navegador web. En KDE4 el administrador de ficheros por defecto será dolphin, pero Konqueror seguirá siendo tan flexible como ahora.

A éste cóctel, añadir que resulta que Qt ahora implementa unas serie de clases específicas para manejar la pila de deshacer, y que nos gustaría poder usar. Pero no permite acceder ni eliminar cualquier elemento de la pila, sólo el que está encima del todo. He mandado un reporte de error a la gente de Qt para que subsanen ese problemilla.

De todo esto y más cosas he estado charlando ésta tarde con David Faure por IRC hoy, uno de los principales desarrolladores de KDE. Debido a que no está nada claro el tema, aun no se ha incluído el parche que mandé a la lista de desarrollo 😉

Anuncios

6 Responses to El historial de deshacer

  1. danielnakata dice:

    Hola

    mi nombre es daniel y estoy en la licenciatura de informatica en Mexico, actualmente trabajo en mi tesís en compañia de mi novia y nuestro objetivo es desarrollar un navegador web que soporte WML, este navegador es para PC (ya sea linux, windows o OSX), lo estamos diseñando en Java.

    Aparte que interprete de manera correcta el WML, queremos que soporte HTML, CSS Java Script, y de ser posible PHP, ASP y AJAX. Pero la verdad es que tenemos muy pocas ideas de como realizar el interprete de HTML, es mas ni si quiera tengo una idea de como funciona dicho interprete.

    “Googleando” me encontre con tu pagina, y veo que hablas de Konqueror (navegador que he estado investigando junto con K-meleon, IE, FireFox, Camino, Safari, Opera y Mosaic) y mencionas sobre su codigo fuente. Mi pregunta es: existe algun link en le que pueda encontrar, no todo, sino alguna parte del código fuente para estudiarlo y saber como funciona?, En dado caso que no pueda adquirir dicho codigo, sabes de personas o si tu mismo me puedes explicar como funciona dicho interprete para poder hacer el mio en Java?

    El navegador que voy a realizar es Software Libre y quiero continuar desarrollandolo a futuro para que sea un producto de calidad

    Mi correo es danielnakata@hotmail.com para cualquier informacion.

    Te agradezco tu tiempo
    atte Víctor Daniel Ortega Cruz
    desde Teziutlan Puebla México

  2. santiagojbt dice:

    Cito textualmente:

    “A éste cóctel, añadir que resulta que Qt ahora implementa unas serie de clases específicas para manejar la pila de deshacer, y que nos gustaría poder usar. Pero no permite acceder ni eliminar cualquier elemento de la pila, sólo el que está encima del todo. He mandado un reporte de error a la gente de Qt para que subsanen ese problemilla.”

    Hombre, si es una pila, claro que no te va a dejar eliminar cualquier elemento. ¡Sólo el que está en la cima, por definición! Las únicas operaciones permitidas son apilar y desapilar.

    Al chico del anterior comentario: ¿Quieres desarrollar un navegador web con soporte WML para PC? Hombre, puede ser una buena idea. Pero ten en cuenta que el WML es una versión reducida del HTML para dispositivos de pequeño tamaño (teléfonos móviles, PDA’s). ¿Crees que podría ser útil (pregunto, no afirmo)? Porque claro, yo la utilidad que le veo es para depurar páginas que posteriormente se visualizarán en móviles o en PDA’s. Pero si tienes un PC con un navegador web, siempre preferirás ver la versión HTML de la página.

    Además, veo un segundo problema. Me suena de haber estudiado que la pila que utiliza WML por debajo no es TCP/IP, sino otra distinta. Hasta el nodo servidor web para móviles la pila podría ser TCP/IP, perfectamente. Pero luego la comunicación entre el servidor web y el dispositivo móvil no se basa en TCP/IP, puesto que, nuevamente, TCP/IP es un protocolo demasiado complejo para ésta aplicación. Se utiliza otro distinto. Por lo que si quieres visualizar WML en un PC, de alguna forma tendrás que simular esa pila. Vamos, es lo que intentaría hacer yo.

    Respecto al intérprete de HTML: Buf, ¡no sabes dónde te metes! Jejejeje. No digo que no puedas implementar correctamente un intérprete HTML, se puede hacer. El problema es que es complicado interpretar bien todo el HTML que hay en Internet, puesto que HTML no es un lenguaje “estricto”: Por ejemplo, puede haber etiquetas sin cerrar. De hecho, ya sabrás que si haces cosas raras en HTML, normalmente el navegador suele tragar con todo.

    Yo ahí no me metería ni loco. Además que hacer un navegador desde cero que soporte HTML, CSS, JavaScript… Buf, eso sería una condena. Por cierto, por lo que tengo entendido, AJAX no es un lenguaje. AJAX tampoco es una tecnología, es un paradigma de creación de servicios web que utiliza JavaScript y XML (las siglas vendrían de JavaScript y XML asíncrono, en inglés). Por lo que si implementáseis correctamente JavaScript y el soporte XML, ya estaría.

    Pero me reitero: Yo no me metería ni loco. El tema de los intérpretes HTML siempre fue un quebradero de cabeza. Respecto a WML, la cosa cambia, pues al estar basado en XML es un lenguaje mucho más estricto, y al ser más estricto es mucho más fácil de interpretar. De hecho, esa era la filosofía de XML, que luego se vio que valía para más cosas (para el intercambio de información entre dos aplicaciones heterogéneas), pero en principio creo que uno de sus objetivos principales fue el de ser fácilmente interpretable. De hecho, cualquier lenguaje de programación mínimamente moderno ofrece un API para interpretar XML de forma muy sencilla. Java sin dudarlo, ya que tiene una presencia importantísima en Internet.

    Respecto a WML, mirando en la wikipedia: http://es.wikipedia.org/wiki/WAP se puede leer lo siguiente:

    La incompatibilidad de la pila de protocolos WAP 1 con la de Internet exige la presencia de un nodo pasarela para hacer de intermediario en la comunicación entre un terminal WAP y un servidor de contenidos WAP residente en Internet.

    Sin embargo, dicho problema se subsana en WAP 2.0:

    La nueva versión de WAP, WAP 2.0, está presente en los teléfonos móviles de nueva generación (a partir de 2004). Esta versión es una reingeniería de WAP que utiliza XHTML-MP (Mobile Profile) como lenguaje de presentación de contenidos, y mejora el soporte de los gráficos (incluye color). En cuanto a los protocolos usados, en la capa de transporte se usa TCP y en la de aplicación, HTTP. Así pues, WAP 2.0 ha adoptado los protocolos de Internet.

    Bueno, espero que haya sido de utilidad mi comentario!

    Un saludo y suerte a todo el mundo!

    Santi

  3. edulix dice:

    Hombre, si es una pila, claro que no te va a dejar eliminar cualquier elemento. ¡Sólo el que está en la cima, por definición! Las únicas operaciones permitidas son apilar y desapilar.

    Si fuese una pila pura vale, pero es que las mismas pilas propias de Qt (QStack) no lo son y permiten acceder a elementos concretos. Yo lo único que les pido es que la pila que se use es la que ellos mismos ofrecen y además lo pido no por capricho sino por necesidad.

  4. santiagojbt dice:

    Pues tienes razón. En Java la clase Stack desciende de la clase Vector, por lo que puedes utilizar cualquier método del Vector sobre el Stack. En un principio pensé que no era posible, puesto que por definición si permites cualquier tipo de operación en una pila, la pila ya no es pila. No se trata de una estructura LIFO.

    De todas formas, sigo pensando que tiene que haber alguna razón por la que no se permite modificar un elemento de la pila. Bueno, se me ocurre otra posibilidad. Te la comento y me dices qué te parece. Si puede o no puede ser.

    Vamos a suponer, por simplicidad, un editor de documentos cualquiera (en tu caso las acciones son distintas, pero la idea básica es la misma). Como queremos hacer una buena aplicación, deseamos que nuestro editor de texto “pueda volver al pasado” o “volver al futuro”, en el sentido que podamos deshacer y rehacer lo que hicimos en un determinado instante de tiempo (obviamente sólo se puede rehacer después de deshacer :p).

    En otras palabras, queremos almacenar todos los estados intermedios por los que pasa el documento. Si hacemos dos veces clic en el botón deshacer, volvemos a un estado previo en el que se han “deshecho” las dos últimas acciones que hemos realizado.

    Como es muy costoso y muy ineficiente almacenar todos los documentos que se producen cuando ejecutamos una acción, se utiliza un enfoque alternativo. Podemos conceptualizar la acción en un objeto (según el patrón de diseño “Comando”), de tal forma que podamos almacenar acciones para aplicar en cualquier instante de tiempo. Por ejemplo, en una pila.

    Con ese enfoque, lo único que necesitamos es conocer la acción “contraria” a todos los comandos: Por ejemplo, la acción contraria de escribir “Pepito” es borrar la palabra “Pepito” (aunque a lo mejor las acciones son otras, las que aquí comento son simplemente con intención de dar una idea). La acción contraria de cambiar todas las letras “o” por letras “a”, es cambiar todas las letras “a” por letras “o”.

    Aunque ahora estemos hablando a nivel de “acciones”, de comandos, el comportamiento deseado es volver a un estado anterior en el que haya estado un documento durante su edición.

    QUndoStack is a list of QUndoCommand objects. It contains all the commands executed on the document and can roll the document’s state backwards or forwards by undoing or redoing them.

    Entonces para deshacer y rehacer sólo tenemos que movernos por la pila “and can roll the document’s state backwards or forwards” (nótese que aquí también habla de estado del documento).

    Ahora bien, ¿qué sucedería si se permitiese añadir o eliminar elementos en cualquier posición? Pues que estaríamos permitiendo que se añadiesen acciones que no se han producido, o que se eliminasen acciones que sí se han producido. En consecuencia, cuando recorriésemos la pila para deshacer / rehacer comandos, o bien nos aparecerían estados nuevos en el documento (en el sentido de que no es un estado por el que haya pasado el documento durante su edición), o bien nos saltaríamos estados por los que ha pasado el documento.

    En ambos casos, es una incoherencia, puesto que el objetivo era obtener todos los estados anteriores por los que ha pasado el documento. Ni uno más, ni uno menos.

    Es una idea. ¿Tú qué opinas?

    Un saludo,

    Santi

  5. Yo lo que utilizo, en vez de una pila es un Heap, un montón, en el que se puede asignar una prioridad de extracción.

  6. This quote sounds exactly like he’s describing Christof’s drinking habits…..”His manifold and miscellaneous blunders are expunged from memory, attribu Click http://tu2s.in/pookme100830

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: