My Shiny Weblog!

programming, photography and lifestyle

Финансов контрольор 1.0

Тези дни имах да върша една работа, която отлагам от доста време. Идеята беше да се напише една програма, на пръв поглед проста, която да съхранява голям брой еднотипни документи от два вида. Потребителят трябва да може да въвежда нови документи и от двата вида, да може да ги печати и да търси стари такива, по номер или дата. Документите съдържат отговори на някакви въпроси и текст. Оказа се, че тази задача хич не е толкова проста, колкото изглежда на пръв поглед. Тъй като въпросната програма има само един потребител, няма проблеми от типа на контрол на достъпа и автентикация. Тъй като не ми се занимаваше с огранизиране на работа с файлове, или още по-маллко XML документи, реших да използвам SQL таблици. По една за съхранение на документите от двата вида. Имах нужда от най-леката и проста реализация на SQL, веднага се сетих за SQLite. Спомних си, че в Qt има вградена поддръжка за SQLite, която е включена по подразбиране, още при компилация на системата (като самият SQLite е включен в Qt дистрибуцията). До тук добре, имам база данни и среда за разработка. Започнах да пиша, направих си базата данни. За текстовите полета в базата данни използвах тип “text”, а за въпросите “boolean”. Двете таблици имаха по един идентификатор, поле за дата на въвеждане и още няколко дребни нещица. Имаше и таблица за връзка между двете таблици. Целта е няколко документа от втори вид да могат да се връзват към един от първи и обратното (изискване на клиента). Изкефих се от резултата, тази проста базичка позволява съхранението на стотици хиляди такива документи, без почти никакви усилия. Не че ще се пазят толкова много в нея, но все пак беше доста елегантно решение. Написах си на C++ няколко функции за писане и четене на документи и започнах да мисля какво още ми трябва. Нещото, което ме притесняваше от самото начало беше принтирането. Не бях работил с принтер в Qt. След кратко четене и опитване се оказа, се работи доста лесно с QPrinter и QPrintDialog. След като видях, че няма да имам проблем с тях започнах да пиша интерфейса за въвеждане на документите. Това бяха два най-обикновени класа, който използваха QDialog. Не беше проблем да се нарисуват в Qt Designer. Тъй като не ми се занимаваше да правя отделен .h и .cpp файл за всеки диалог, реших да блъскам всичко в main.cpp (включително и дефиницията на базата данни, която се инициализира автоматично при нужда). Това в последствие се оказа голяма грешка, докара ми повече проблеми отколкото решения. Трябваше да се оправям ръчно с MOC и UIC, защото qmake очевидно не зацепи какво точно се опитвам да правя. Както и да е, оправих се с много псуване с тези проблеми. Въведох в базата данни няколко документа и видях, че въвеждането работи. За да мога да отпечатя на принтера каквото и да било, имах нужда от някакъв template. Идеята беше в този template да зареждам съдържането на един ред от съотетната SQL таблица, за въответния вид документ. Разрових по-сериозно какво предлага Qt по въпроса, и намерих нещо познато, което съм ползвал и преди – QTextDocument. Там може да се въвежда т.нар. Rich text и в последствие да се печати. Този Rich text всъшност представлява някакво подмножество на HTML и CSS за форматиране. Хич не ми се занимаваше с тези неща, защото са невероятно досадни, но в случая нямах избор. Написах някакви грозни templates и ги набутах в една SQL таблица. На местата, където трябваше да попълвам сложих някакви placeholders. По-късно при натискане на бутона “Принтиране” от главния прозорец, тези templates се пълнеха със съдържание от базата данни и се изпращаха на принтера, през QTextDocument. От тук нататък започнаха проблемите с принтера и принтирането. Изхабих доста време и нерви да наглася шрифтовете. Каквото и да сложех за шрифт в CSS по някакви причини не се появяваше в PS файла. После чак ми стана ясно, че всъшност “feature” на Post Script е да замества шрифтовете с други, по някакви неясни за мен правила. Това го преборих с много ровене из настройките на KDE/Windows. В последствие обаче се оказа, че има неприатен проблем с лигатурите на кирилицата. По някакви причини се използват лигатури за латинската азбука. Този проблем така и неможах да го реша, може би трябва да питам Trolltech. Накрая на цялата одисея компилирах всично на една Windows машина и използвах NSIS за да произведа едно голямо .exe (около 10 Mb, заедно с Qt библиотеките).

От цялата тази работа много ме хвана яд на няколко неща. Най-напред за това, че при решаването на една толкова проста административна задача, беше необходимо да използвам толкова различни и сложни технологии. Може би в случая нещо, като ORM в Qt щеше да ми е доста полезно. Мислех си за техния MVC framework, но до колкото аз имам опит с него, той е ориентиран към малко по-други проблеми. Другото неприятно нещо беше използването на HTML и CSS при положение, че цялото нещо няма нищо общо с Web. Генерирането на Post Script от тези неща също не ми се струва добра идея. Всъшност, май е необходимо (от много години насам) някакъв прост и printer-friendlly формат за форматиране на текст. Но такъв за съжаление няма…

Все пак съм доволен от цялата работа, програмата работи много добре и не използва много памет. Разбира се, неможе да се сравнява с някой native Win32 приложения, но все пак при писането и използвах само Open Source средства. Хубавото в подхода, който избрах е, че базата данни може да побере много документи и HTML templates могат да се променят лесно. Не на последно място имам и доволен потребител – една жена, на предпенсионна възраст, която от съвсем скоро работи с компютър, на длъжността “Финансов контрольор”. Големият плюс за нея е, че вече няма да се разхожда из сградата с две дебели, оръфани тетрадки. Дали ще има версия 2.0 на “Финансов контрольор” зависи главно от нея.