все что связано с моей работой
Главная » Програмирование » Программа “Заметки”. ТЗ, база, форма ввода.

Программа “Заметки”. ТЗ, база, форма ввода.

Прочитав несколько книг и прослушав пару аудиокурсов по Тайм менеджменту понимаешь что самое главное в этом деле вести что-то типа дневника, куда надо постоянно записывать , что делаешь, сколько времени тратишь на это и т.д., а потом анализируешь как прошел день, неделя и т.п. Так родилась идея написать программку “Заметки”.

Естественно, прежде чем изобретать велосипед, я поискал его вокруг. Из того что видел, знал не нашлось ничего что мне бы подошло. Практически все выглядит примерно как Tomboy, этакие “липкие” бумажки на экране. Но у меня зачастую запущено 6-7 приложений которыми я пользуюсь и эти бумажечки как и сам рабочий стол просто закрыт таким количеством окон …

Тех. задание

Ввиду всего сказанного попробуем сформировать ТЗ:

  1. Кросс-платформеность.
  2. Портабельность, т.к. приходится иногда работать на разных компьютерах, хочется чтоб программа работала с флешки.
  3. Чтоб программа висела в трее
  4. Щелчок по значку открывал окно ввода заметки
  5. Имелась возможность просмотра заметок за любой день
  6. Естественно возможность исправить заметку, хотя вопрос спорный, мат и ошибки могут рассказать об пережитых эмоциях :)

Наверно пока все, а то что ж потом добавлять :). Разберем по-подробнее и немного по-проектируем.

Проектирование.

С первым пунктом все понятно, в основном пишу я на Lazarus-е, который и обеспечит кросс-платформенность. С портабельностью тоже никаких сложностей – надо следить чтоб не было привязок к конкретным директориям, ни какого реестра, исполняемый файл, базу и все библиотеки в одной папке. Если в качестве базы использовать свой формат (плоские файлы), если брать нормальный SQL сервер – то тот, который умеет быть встраиваемым. С готовым сервером работать проще, чем писать библиотеку работы с базой на файлах. Из SQLite и Firebird, я выбрал второе – как-то роднее и знакомее, других embendded я на вскидку я не вспомнил.

Четвертый пункт – это чисто реализация, сказать тут нечего.

Из пунктов 3,5,6 следует что будет пять форм:

  1. Форма ввода заметки
  2. Форма редактирования
  3. Вывод всех записей за день
  4. Главная форма – маленькая, пустая, на которой только меню для трея
  5. Настройки программы, пока что у нас нечего настраивать, но … аппетит приходит во время еды

База данных. Тут все предельно просто: дата и текст заметки. И еще одну табличку для настроек.

Реализация

База

SET SQL DIALECT 3;
SET NAMES UTF8;

CREATE TABLE NOTES (
    ID    INTEGER NOT NULL,
    DATA  TIMESTAMP DEFAULT 'NOW' NOT NULL,
    NOTE  VARCHAR(3000) CHARACTER SET UTF8 NOT NULL
);

CREATE TABLE SETTINGS (
    ID       INTEGER NOT NULL,
    NAME     VARCHAR(20) CHARACTER SET UTF8 NOT NULL,
    "VALUE"  VARCHAR(30) CHARACTER SET UTF8 DEFAULT ''
);

ALTER TABLE SETTINGS ADD CONSTRAINT UNQ1_SETTINGS UNIQUE (NAME);
ALTER TABLE NOTES ADD CONSTRAINT PK_NOTES PRIMARY KEY (ID);
ALTER TABLE SETTINGS ADD CONSTRAINT PK_SETTINGS PRIMARY KEY (ID);

CREATE INDEX NOTES_DATA ON NOTES COMPUTED BY (cast(data as date));
CREATE DESCENDING INDEX NOTES_DATA_DESC ON NOTES COMPUTED BY (cast(data as date));

Генераторы описывать не буду они стандартные. По умолчанию дата заполнится текущим временем, текст заметки хранится в varchar, с blob-ами какие-то трудности были, программка написана 3 месяца назад, все руки не доходили до описания. Так же надо сказать что изначально рассматривался вариант с MSSQL, но лазарь криво работает с UTF8 для него – еще одна причина почему выбор пал на феникса.

Изначально база была на нормальном сервере, когда программка была готова и отлажена, перевел на embendded – делал все по инструкции docreadme.embended заработало, как говорится “из коробки”, причем с пол-пинка(!) очень понравилось решение. На будущее надо посмотреть что такое SQLite, может тоже нормальный функционал…

Форма ввода заметки

На форму кладем TMemo и выставляем Align=alClient, для красоты можно Color установить в желтый. У формы BorderStyle установим в bsSizeToolWin, чтоб нельзя было развернуть окно.

Добавим свойство property Database:TSQLConnection; и поле FSave:boolean. Код сохранения заметки повесим на OnCloseQuery, а FSave будем использовать как признак сохраняем заметку или нет код OnKeyUp:

  if (Key=VK_RETURN) and (Shift=[ssCtrl]) and Settings.SaveOnCtrlEnter then begin
    Key:=0;
    FSave:=true;
    Close;
  end;
  if Key=VK_ESCAPE then begin
    FSave:=not Settings.SaveOnCtrlEnter;
    Close;
  end;

Settings – класс который хранит настройки программы, он будет чуть позже. Пока в нем только один параметр – сохранять всегда по Esc или только при Ctrl+Enter.

Код сохранения заметки при закрытии:

procedure TfrmNewNote.FormCloseQuery(Sender: TObject; var CanClose: boolean);
var Q:TSQLQuery;
    T:TSQLTransaction;
begin
  if not FSave then exit;
  CanClose:=true;
  if Length(Trim(Memo1.Lines.Text))=0 then exit;
  try
    FDatabase.Connected:=true;
    T:=TSQLTransaction.Create(nil);
    T.DataBase:=FDatabase;
    Q:=TSQLQuery.Create(nil);
    Q.DataBase:=FDatabase;
    Q.Transaction:=T;
//    S:=Format('insert into notes (note) values ('#39'%s'#39')',[Memo1.Text]);
//    Q.SQL.Text:=S;
    Q.SQL.Text:='insert into notes (note) values (:note)';
    Q.Params.ParamByName('note').AsString:=Memo1.Text;
    try
      T.StartTransaction;
      Q.ExecSQL;
      T.Commit;
    except
      on E:Exception do begin
        ShowMessage(E.Message);
        CanClose:=false;
      end;
    end;
  finally
    FreeAndNil(Q);
    FreeAndNil(T);
  end;
end;

Не люблю пользоваться DBAware компонентами, потому что на открытие таблицы выполняется несколько запросов, еще таким способом легче контролировать — что сохраняется (вернее каким запросом). А еще самое главное это то – что, время жизни изменяющей/добавляющей транзакции сведено к минимуму. Конечно для просмотра данных без них не обойтись, но одиночные запросы заполнение checkbox-ов и другие простые запросы лучше делать таким способом. Вот для этого нам и нужно свойство Database. Комментарий специально не стал убирать, по нему необходимо пояснить. Всегда раньше, и в Delphi и в Lazarus-е, использовал конструкции как в комментарии, но лазарь почему-то упорно вставлял вместо #39 двойную кавычку, это раз. А второй плюс использование параметрических запросов, это то что такой подход делает сериализацию, будет очень неприятно если в Memo1.Text ввести что-то типа такого “бла-бла-бла’; select …”.

Ну вот с формой ввода пожалуй можно и закончить. Есть еще одна маленькая плюшка в событие OnFormShow напишем такой код:

procedure TfrmNewNote.FormShow(Sender: TObject);
{$IFDEF WIN32}
var RUS: HKL;
{$ENDIF}
begin
  if Settings.SaveOnCtrlEnter then
    Caption:='Esc-exit, Ctrl+Enter-save'
  else
    Caption:='Esc-save&exit';
  FSave:=false;
  Memo1.Lines.Clear;
{$IFDEF WIN32}
  rus:=LoadKeyboardLayout('00000419', 0);
  ActivateKeyboardLayout(rus,1); // устанавливаем русский язык
{$ENDIF}
end;

Правда этот будет работать только в Windows, но все равно приятно, что при открытии формы всегда будет русский.

Для первой части наверно хватит, все что было интересного в других формах будет чуть позже.

Комментариев нет

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.