Tuesday, May 29, 2007

.Net biblioteka video montavimui

Neseniai programming@konferecijos.lt mailing liste kažkas prašė bibliotekos garso kodavimui.

Šiandien užtikau Auckland'o blog'e Splicer įrankį.


Ką gi jis gali daryti:
* Encode video or audio suitable for use on a website.
* Create slideshows from images, videos and audio.
* Apply effects and transitions to audio and video.
* Grab System.Drawing.Image clips from a video at certain times.
* Add new soundtracks to existing video clips.
* Watermark videos.
* Build a video editing suite, if you were so inclined.


Splicer galite rasti čia : http://www.codeplex.com/Wiki/View.aspx?ProjectName=splicer

Monday, May 28, 2007

Dokumentų spausdinimas

Vienas klausimas yra kokį būda naudoti ataskaitoms generuoti, o visai kitas, kaip į dokumentą duomenis sudėti.

Pirmasis variantas (kurį prieš pusę metų dariau) buvo paprastas switch / replace sakinių rašymas.

Rezultas - dėl kiekvieno menkniekio reikia programuoti. Tikrai nepavydinėtina.

Ką gi, naudojame kitą būdą, juk vis dėlto, gyvename .Net aplinkoje, ir skirtingai nei java yra daug ir įvairių kalbų. Tuo ir pasinaudokime.

Galbūt dar mažai kam žinoma, bet greitai auganti kalba Boo :)

Boo yra dinaminė kalba, pagrįstas pytono sintakse. Ką gi mums duoda Boo.
Ogi du dalykus:
  • Boo turi interpretatorių
  • - kurį galime įtraukti į programą
  • Įdomiau gyventi



  • Taigi, dabar vietoje skurdžių sakinių

    ...
    if (m_node.InnerText = "Studento vardas">)
    m_node.Text = student.Name + student.Surname
    ...



    galime rašyti taip:
    kode:


    Interpretator m_interpetator = new Interpretator()
    m_interpratator.setValue ("RootEntity", student);

    ...
    m_interpretator.Eval(node.InnerText);
    m_node.Text = m_interpretator.LastValue
    ..




    dokumento šablone tuomet galima rašyti ką tik norime.
    Pavyzdžiui, dokumento pradžioje galime įdėti paslėptą tag'ą (jei konkrečiau - tai input field'ą) su tokiu kodu "Mokinys = RootEntity".

    tuomet tose vietose, kur turi atsidurti tekstas įdedame tokius paslėptus tag'us:

    vardas = Mokinys.Name + Mokinys.Surname; vardas.ToUpper();


    Šiais dviem sakiniais sujungėm mokinio vardą ir pavardė ir padarėm juos upper string'ais. Kadangi tai yra .Net aplinka, tai praktiškai galima naudotis absoliučiai visomis funkcijomis, kurias duoda .Net


    Daugiau jokių switch replace! :)

    Ataskaitų generavimas

    Yra užduotis : programa turi spausdinti įvairius dokumentus - sutartis, objektų sąrašus ir pan.

    Yra keli atsakymo variantai:
  • HTML templeitai
  • - net nepradėsiu kalbėti apie tai. Visi žinome kaip daryti replace'us.

  • CrystalReports
  • - teko naudoti porą kartų. Geri, greitai veikia. Bet širdies nedžiugina. Traukti ir kišti duomenis per datasetus nėra labai jau gudrus dalykas.
    Be to, už visą tą darbą gauni tik paprastą neredaguojamą dokumentą.

  • SharpReports
  • - tas pats kas crystal reports, tik laisvas produktas. Laisvė yra gerai, bet reportai ir afrikoj reportai. Ne.

  • Automatizuoti wordą
  • - mintis visai nebloga. Turint omeny, kad gauname begalę formatų, galimybę redaguoti duomenis po atspausdinimo. Tik nežinia kaip tuo wordu programuoti. Turbūt kažkokiu bibliotekų reikia. Be to, kažkas sakė, kad stabdo.

    Bet gal melavo

  • Automatizuoti OpenOffice
  • - kodėl gi ne? Formatas aiškus, visiems prieinamas. Bibliotekų yra
    OpenOffice į programą įdėti galima.

    Undo / Redo galimybės programoje (2 dalis)

    Ankščiau rašiau apie tai, kad mūsų kuriamoje desktop programoje reikia galimybės atšaukti naudotojo padarytus veiksmus.

    Nors API undo atžvilgiu dar nėra iki galo nusistovėjusi (tiesą sakant, undo mechanizmas šiek tiek *nervina*, nes jam *palaikyti* reikia tam tikrų pastangų), sprendimas yra.

    Sprendimas veikia, ir štai kaip jis maždaug atrodo.

    Undo mechanizmui užtenka turėti sąrašą objektų, kurie gali atstatyti naują būseną į seną būseną. Tarkime, IMemento:


    ///
    /// An interface for all undo / redo actions
    ///

    public interface IMemento
    {
    ///
    /// Restores the state of the object.
    ///

    /// A new memento, which performs the Redo action
    IMemento Restore();
    }


    Kiekvienas IMememtno Restore() metode atstato kokią nors informaciją į prieš tai buvusį būvį.

    Man kol kas prireikė dviejų memento tipų:
    PropertyMenento - atstato bet kurio properčio reikšmę į prieš tai buvusį
    DelegateMemento - lengvai kustomizuojamas memento per delegatus

    Saturday, April 21, 2007

    hammet apie Domain Driven Design Castle

    Užvakar hammet rašė įdomų straipsnį apie Domain Driven Design ir Castle.

    Rekomenduoju paskaityti.
    hammet ir Domain Driven Design

    Wednesday, April 4, 2007

    Kolekcijos su event'ais

    Bandau implementuoti UndoHistoryRepository ir susidūriau su tokia problema, kad UndoHistoryRepository turi žinoti, kada nauji objektai yra sukuriami, ir kada pašalinami.

    Microsofto System.Collections namespace'e jokių kolekcijų su eventais neradau, tad leidausi į kelionę ieškoti. Rezultatai tokie:

    * PowerCollections - Wintellect kompanijos(?) gaminama biblioteka. Kiek tikrinau, visos nuorodos į biblioteką yra mirusios. Be to, biblioteka neduoda reikiamo dalyko.

    * IESI.Collections - JasonSmith'o kolekcija. IESI pagrindins tikslas yra ISet (aibės) kolekcijos realizavimas. Vėlgi, eventai nerealizuoti, tačiau IESI.collections yra gana žinomas dalykas, paplitęs per NHibernate projektą


    * OpenDocument4All - Lars Behrmann'o parašyta OpenDocument generavimo biblioteka. Nors tai nėra kolekcijų biblioteka, bet jos viduje yra naudojamos kolekcijos su event'ais. Kodas nėra gražus, standartizuotas, ir tuo labiau tinkamas naudoti kituose projektuose.

    * C5 biblioteka - Niels Kokholm ir Peter Sestoft parašyta biblioteka, Kopenhagos universitetas. C5 is a library of generic collection classes for C# and other CLI languages and works with Microsoft .Net version 2.0 and Mono version 1.1.16 and later.

    Taip pat ši biblioteka turi neblogą (258 puslapių) manual'ą, kurio 8.8 skyryje parašyta : "Events: observing changes to a collection".

    Būtent to mums ir reikia.

    Monday, April 2, 2007

    Undo / Redo galimybės programoje

    Šiuo metu kuriame paprastą biuro programą.

    Reikia sukurti tokius langus: mokymo dalyko langą, ir mokymo pamokų langą.
    Be visų duomenų įvedimo laukų, langas turi turėti mygtukus išsaugoti ir uždaryti. Jei paspaudžiamas mygtukas išsaugoti, tai visi esami pakeitimai išsaugomi. Jei paspaudžiamas uždaryti, tai neišsaugoti pakeitimai turi būti atmesti ir langas uždarytas. Išsaugoti pakeitimai turi likti nepakitę.

    Registruojant arba redaguojant mokymo pamokas, visi pakeitimai paspaudus mygtuką "išsaugoti" turi būti išsaugoti tik atmintyje. Į duomenų bazę pakeitimai siunčiami tuomet, kai saugomas pats dalykas.


    Taigi, klausimas (labai jau daug išsiplėčiau apie probleminę sritį):
    Kaip galima kokybiškai realizuoti Undo mechanizmą?


    Ieškojau porą dienų sprendimo. Kol kas atsakymas matau yra toks: Memento design pattern'as.

    Gerą pavyzdį radau čia:
    Generic undo redo

    Autorius siūlo tokį sprendimį: "an object that is capable of restoring a target object to one of its previous states".

    Pavyzdys su c# būtų toks:

    interface IMemento
    {
    ///
    /// Restores target to the state memorized by this memento.
    ///

    ///
    /// A memento of the state before restoring
    ///

    IMemento Restore(T target);
    }



    Sprendimas su Memento būtų turėti kiekvienam veiksmui atstatymo veiksmą. Atstatymo sprendimai gali būti dviejų rūšių -
    1 - Atsatyti objektą darant jo deep-copy, ir vėliau originalą pakeičiant kopija
    2 - Kiekvienam objekto keitimo veiksmui generuoti anti-veiksmą, t.y. veiksmą, atsatantį objektą į buvusią būseną. Tokių veiksmų būtų dvi rūšys - properčių atstatymas, ir ryšių atstatymas (objekto kūrimo ir šalinimo atveju).

    Aš labiau linkstu prie antrojo varianto. Daryti objekto deep-copy gali sukelti daug problemų dėl ryšių. Atsatant objektus naudojant anti-veiksmus, viskas vyktų atvirkštine tvarka, negu tuomet, kai objektas buvo keičiamas.

    Šiandieną bandysim implementuoti tokį sprendimą, žiūrėsim, kas gausis