Skip to content

Commit

Permalink
Minor speedups during saving, update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
davidbannon committed Dec 30, 2018
1 parent bede6a6 commit 97aa717
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 77 deletions.
25 changes: 9 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
### tomboy-ng

Copyright (C) 2017 David Bannon <dbannon@internode.on.net>
tomboy-ng is a note taking app that works and syncronises between Linux, Windows and MacOS. It will also Sync to Tomdroid on Android. It features a rich text markup, printing, spell check, backup and snapshot capability. Import and export (plain text, RFT, MarkDown). It has Tomboy's automatic linking between notes, searching abilities, NoteBooks and a similar interface.

The tomboy-ng homepage is part of the Tomboy homepage [here](https://wiki.gnome.org/Apps/Tomboy).
Importantly, tomboy-ng has little or in most cases no dependancies and so is an easy and lightweight install. Most people use the binary install kits but you are welcome to build from source.

[Screen_1](https://github.com/tomboy-notes/tomboy-ng/blob/master/doc/gallery/Screen_1.png)

Please see the [Wiki](https://github.com/tomboy-notes/tomboy-ng/wiki) for further information.

We use GitHub to store sources and track bugs, see [Tomboy](https://github.com/tomboy-notes/tomboy-ng).

The tomboy-ng homepage also is part of the Tomboy homepage [here](https://wiki.gnome.org/Apps/Tomboy).

If you're interested in discussing tomboy-ng, please consider our mailing list.
To subscribe, visit [here](http://lists.beatniksoftware.com/listinfo.cgi/tomboy-list-beatniksoftware.com)
or just send your questions and suggestions to <tomboy-list@beatniksoftware.com>.

Copyright (C) 2018 David Bannon <dbannon@internode.on.net>
---

Tomboy is a desktop note-taking application for Linux, Unix and Windows.
Simple and easy to use, but with potential to help you organize the ideas
and information you deal with every day (a direct quote from Tomboy's Readme).

tomboy-ng is a shameless copy of the origional Tomboy but rewritten in Free Pascal
and Lazarus in an effort to deliver the usefullness of Tomboy but in a simpler
to install and easier to maintain package.

So far it supports much the same editing and formatting capabilities as Tomboy.
It works seemlessly with Tomboy's file sync and supports the same Notebook
model (and slightly extends it).

And it works, out of the box, no extra libraries needed, on Linux (GTK), Windows
and Mac. In most cases, all you really need is the 3Mbyte to 4Mbyte binary.

61 changes: 37 additions & 24 deletions tomboy-ng/editbox.pas
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
2018/12/06 Drop all Ctrl Char on floor for the Mac. See if we are missing anything ?
2018/12/06 Added Ctrl 1, 2, 3, 4 as small, normal, large and huge fnt.
---- This is not put on menus or doced anywhere, an experiment ------
2018/12/29 Small improvements in time to save a file.
}

Expand Down Expand Up @@ -354,6 +355,7 @@ TEditBoxForm = class(TForm)
NoteFileName, NoteTitle : string;
Dirty : boolean;
Verbose : boolean;
// If a new note is a member of Notebook, this holds notebook name until first save.
TemplateIs : AnsiString;
{ Will mark this note as ReadOnly and not to be saved because the Sync Process
has either replaced or deleted this note OR we are using it as an internal viewer.
Expand Down Expand Up @@ -1657,7 +1659,6 @@ procedure TEditBoxForm.KMemo1KeyDown(Sender: TObject; var Key: Word; Shift: TShi
NoBulletPara : boolean = false;
begin
if not Ready then exit(); // should we drop key on floor ????

// don't let any ctrl char get through the kmemo on mac
{$ifdef DARWIN}
if [ssCtrl] = Shift then begin
Expand Down Expand Up @@ -1864,8 +1865,11 @@ procedure TEditBoxForm.SaveTheNote();
Saver : TBSaveNote;
SL : TStringList;
OldFileName : string ='';
// T1, T2, T3, T4, T5, T6, T7 : dword;
// TestI : integer;
begin
// T1 := gettickcount64();
Saver := Nil;
if KMemo1.ReadOnly then exit();
if length(NoteFileName) = 0 then
NoteFileName := Sett.NoteDirectory + GetAFilename();
Expand All @@ -1878,37 +1882,44 @@ procedure TEditBoxForm.SaveTheNote();
end;
end; //else debugln('NOT Working in Notes dir ' + Sett.NoteDirectory + ' <> ' + CleanAndExpandDirectory(extractFilePath(NoteFileName)));
// We do not enforce the valid GUID file name rule if note is not in official Notes Dir
if TemplateIs <> '' then begin
SL := TStringList.Create();
SL.Add(TemplateIs);
SearchForm.NoteLister.SetNotebookMembership(ExtractFileNameOnly(NoteFileName) + '.note', SL);
SL.Free;
TemplateIs := '';
end;
Saver := TBSaveNote.Create();
KMemo1.Blocks.LockUpdate;
try
if not GetTitle(Saver.Title) then exit();
{debugln('Saving Note, length of title =' + inttostr(length(Caption)) + ' No blocks =' + inttostr(KMemo1.Blocks.Count));
for TestI := 0 to KMemo1.Blocks.Count -1 do begin
debugln('Block=' + inttostr(TestI) + ' Type=' + KMemo1.Blocks[TestI].ClassName);
end; }

Caption := Saver.Title;
Saver.CreateDate := CreateDate;
if TemplateIs <> '' then begin
SL := TStringList.Create();
SL.Add(TemplateIs);
SearchForm.NoteLister.SetNotebookMembership(ExtractFileNameOnly(NoteFileName) + '.note', SL);
SL.Free;
TemplateIs := '';
end;
// debugln('about to save');
Saver.Save(NoteFileName, KMemo1);
SearchForm.UpdateList(CleanCaption(), Saver.TimeStamp, NoteFileName, self);
// if we have rewrtten GUID, that will create new entry for it.
Saver.CreateDate := CreateDate;
if not GetTitle(Saver.Title) then exit();
Caption := Saver.Title;
// T2 := GetTickCount64(); // 0mS
KMemo1.Blocks.LockUpdate; // to prevent changes during read of kmemo
try
// debugln('about to save');
Saver.ReadKMemo(NoteFileName, KMemo1);
// T3 := GetTickCount64(); // 6mS
finally
KMemo1.Blocks.UnLockUpdate;
end;
// T4 := GetTickCount64(); // 0mS
Saver.WriteToDisk(NoteFileName);
// T5 := GetTickCount64(); // 1mS
// Note that updatelist() can be quite slow, its because it calls UseList() and has to load and sort stringGrid
SearchForm.UpdateList(CleanCaption(), Saver.TimeStamp, NoteFileName, self);
// if we have rewritten GUID, that will create new entry for it.
// T6 := GetTickCount64(); // 14mS
if OldFileName <> '' then
SearchForm.DeleteNote(OldFileName);

finally
Saver.Destroy;
if Saver <> Nil then Saver.Destroy;
Dirty := false;
Caption := CleanCaption();
KMemo1.Blocks.UnLockUpdate;
end;
{T7 := GetTickCount64(); // 0mS
debugln('EditBox.SaveTheNote Timing ' + inttostr(T2 - T1) + ' ' + inttostr(T3 - T2) + ' ' + inttostr(T4 - T3) + ' ' +
inttostr(T5 - T4) + ' ' + inttostr(T6 - T5) + ' ' + inttostr(T7 - T6)); }
end;

function TEditBoxForm.NewNoteTitle(): ANSIString;
Expand All @@ -1924,4 +1935,6 @@ function TEditBoxForm.GetAFilename() : ANSIString;
Result := copy(GUIDToString(GUID), 2, 36) + '.note';
end;



end.
2 changes: 1 addition & 1 deletion tomboy-ng/mainunit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ procedure TMainForm.FormShow(Sender: TObject);
else LabelError.Caption := '';
if not AllowDismiss then begin
Label7.Caption := 'Sadly, on this OS or because of a Bad Note,';
Label8.Caption := 'I cannon let you dismiss this window';
Label8.Caption := 'I cannot let you dismiss this window';
Label7.Hint:='Are you trying to shut me down ? Dave ?';
Label8.Hint := Label7.Hint;
end;
Expand Down
10 changes: 9 additions & 1 deletion tomboy-ng/note_lister.pas
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
2018/07/04 Added a flag, XMLError, set if we found a note unable to index. Why ?
2018/08/24 Debugmode now set by calling process.
2018/11/04 Added support for updating NoteList after a sync.
2018/12/29 Small improvements in time to save a file.
}

{$mode objfpc}
Expand Down Expand Up @@ -685,17 +687,23 @@ function TNoteLister.GetNotes(const Term: ANSIstring): longint;
procedure TNoteLister.LoadStGrid(const Grid : TStringGrid);
var
Index : integer;
// T1, T2, T3, T4 : dword;
begin
// T1 := gettickcount64();
Grid.Clear; { TODO : we call these three lines from three different places ! }
Grid.FixedRows := 0;
Grid.InsertRowWithValues(0, ['Title', 'Last Change', 'Create Date', 'File Name']);
Grid.FixedRows := 1;
// T2 := gettickcount64(); // 2mS
for Index := 0 to NoteList.Count -1 do begin
Grid.InsertRowWithValues(Index+1, [NoteList.Items[Index]^.Title,
NoteList.Items[Index]^.LastChange, NoteList.Items[Index]^.CreateDate,
NoteList.Items[Index]^.ID]);
end;
Grid.AutoSizeColumns;
// T3 := gettickcount64(); // 3mS
// Grid.AutoSizeColumns; // Slow, so, instead, we call it on the SearchUnit.FormActivate()
//T4 := gettickcount64(); // 0mS
//debugln('NoteLister - LoadStGrid ' + inttostr(T2 - T1) + ' ' + inttostr(T3 - T2) + ' ' + inttostr(T4 - T3));
end;

procedure TNoteLister.LoadSearchGrid(const Grid: TStringGrid);
Expand Down
89 changes: 64 additions & 25 deletions tomboy-ng/savenote.pas
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
size and the CreatDate if any. If the supplied CreatDate is '', it will
stamp it Now().
All the work is done in the Save(..) function, it needs to be passed
the name of a file (that may or may not exist) and the RichMemo its
the name of a file (that may or may not exist) and the KMemo its
getting its content from.
}

Expand Down Expand Up @@ -58,6 +58,7 @@
2018/08/02 Fix to fixed width, better brackets and a 'not' where needed.
2018/08/15 ReplaceAngles() works with bytes, not char, so don't use UTF8Copy and UTF8Length ....
2018/12/04 Don't save hyperlinks's underline, its not real !
2018/12/29 Small improvements in time to save a file.
}

{$mode objfpc}{$H+}
Expand All @@ -74,6 +75,7 @@ interface
TBSaveNote = class

private
OutStream:TMemoryStream;
ID : ANSIString;
FSize : integer;
Bold : boolean;
Expand Down Expand Up @@ -101,14 +103,20 @@ TBSaveNote = class
function Header() : ANSIstring;
Function Footer() : ANSIstring;
//function GetLocalTime():ANSIstring;

// Assembles a list of tags this note is a member of, list is
// used in all note's footer - needs ID to have been set
function NoteBookTags() : ANSIString;
public
TimeStamp : string;
Title : ANSIString;
// FontNormal : integer; // Needs to be set after class created (could get from settings??)
// set to orig createdate if available, if blank, we'll use now()
CreateDate : ANSIString;
procedure SaveNewTemplate(NotebookName: ANSIString);
procedure Save(FileName : ANSIString; KM1 : TKMemo);
procedure ReadKMemo(FileName : ANSIString; KM1 : TKMemo);
procedure WriteToDisk(FileName : ANSIString);
constructor Create;
destructor Destroy; override;
end;


Expand All @@ -133,6 +141,20 @@ implementation
MonospaceFont = 'Lucida Console';
{$ifend}

constructor TBSaveNote.Create;
begin
OutStream := Nil;
end;

destructor TBSaveNote.Destroy;
begin
if OutStream <> Nil then begin
debugln('ERROR - ID=' + ID + ' outstream was not routinly freed .....');
OutStream.Free;
OutStream := Nil;
end;
end;

function TBSaveNote.SetFontXML(Size : integer; TurnOn : boolean) : string;
begin
Result := '';
Expand Down Expand Up @@ -491,23 +513,23 @@ function TBSaveNote.FontAttributes(const Ft : TFont; Ts : TKMemoTextStyle) : ANS
procedure TBSaveNote.SaveNewTemplate(NotebookName : ANSIString);
var
GUID : TGUID;
OutStream:TFilestream;
OStream:TFilestream;
Buff { TemplateID }: ANSIString;
begin
CreateGUID(GUID);
Title := NotebookName + ' Template';
ID := copy(GUIDToString(GUID), 2, 36) + '.note';
SearchForm.NoteLister.AddNoteBook(ID, NotebookName, True);
Outstream :=TFilestream.Create(Sett.NoteDirectory + ID, fmCreate);
Ostream :=TFilestream.Create(Sett.NoteDirectory + ID, fmCreate);
try
Buff := Header();
OutStream.Write(Buff[1], length(Buff));
OStream.Write(Buff[1], length(Buff));
Buff := Title + #10#10#10;
OutStream.Write(Buff[1], length(Buff));
OStream.Write(Buff[1], length(Buff));
Buff := Footer();
OutStream.Write(Buff[1], length(Buff));
OStream.Write(Buff[1], length(Buff));
finally
OutStream.Free;
OStream.Free;
end;
end;
procedure TBSaveNote.CopyLastFontAttr();
Expand All @@ -522,10 +544,10 @@ procedure TBSaveNote.CopyLastFontAttr();
PrevFSize := FSize;
end;

procedure TBSaveNote.Save(FileName : ANSIString; KM1 : TKMemo);
procedure TBSaveNote.ReadKMemo(FileName : ANSIString; KM1 : TKMemo);
var
Buff : ANSIstring = '';
OutStream:TFilestream;
// OutStream:TFilestream;
BlockNo : integer = 0;
Block : TKMemoBlock;
NextBlock : integer;
Expand All @@ -539,11 +561,11 @@ procedure TBSaveNote.Save(FileName : ANSIString; KM1 : TKMemo);
Underline := False;
InList := false;
FixedWidth := False;

ID := ExtractFileNameOnly(FileName) + '.note';
// Must deal with an empty list !
try
outstream :=TFilestream.Create(FileName, fmCreate);
// ID needs to be set so we can get list of notebooks for the footer.
// Must deal with an empty list !
// try
outstream :=TMemoryStream.Create({FileName, fmCreate});
// Write and WriteBuffer accept a buffer, not a string ! Need to start at pos 1
// when sending string or ANSIstring otherwise it uses first byte which makes it look like a binary file.
// http://free-pascal-general.1045716.n5.nabble.com/Creating-text-files-with-TFileStream-td2824859.html
Expand Down Expand Up @@ -610,26 +632,43 @@ procedure TBSaveNote.Save(FileName : ANSIString; KM1 : TKMemo);
Buff := Buff + SetFontXML(FSize, False);
if length(Buff) > 0 then
OutStream.Write(Buff[1], length(Buff));
Buff := Footer();
OutStream.Write(Buff[1], length(Buff));
//Buff := Footer();
//OutStream.Write(Buff[1], length(Buff));

Except { TODO 1 : Must test this to see what happens with an empty
list of blocks. Probably makes sense to not save anything
that does not have at least one TKMemotextBlock }
on EListError do begin
debugln('ERROR - EListError while writing note to stream.');
{ we now do footer in the WriteToDisk()
Buff := Footer();
OutStream.Write(Buff[1], length(Buff));
OutStream.Write(Buff[1], length(Buff)); }
end;
end;
finally
{ finally
OutStream.Free;
end;
end; }
end;

function TBSaveNote.NoteBookTags: ANSIString;
procedure TBSaveNote.WriteToDisk(FileName: ANSIString);
var
Buff : string = '';
begin
// we write out the footer here so we can do the searching to notebook stuff
// after we have released to lock on KMemo.
Buff := Footer();
OutStream.Write(Buff[1], length(Buff));

OutStream.SaveToFile(FileName);
OutStream.Free;
OutStream := nil;
end;


function TBSaveNote.NoteBookTags(): ANSIString;
var
SL : TStringList;
Index : Integer;
SL : TStringList;
Index : Integer;
begin
Result := '';
if SearchForm.NoteLister = nil then exit;
Expand All @@ -648,7 +687,7 @@ function TBSaveNote.NoteBookTags: ANSIString;
SL.Free;
end;

function TBSaveNote.Header: ANSIstring;
function TBSaveNote.Header(): ANSIstring;
var
S1, S2, S3, S4 : ANSIString;
begin
Expand All @@ -660,7 +699,7 @@ function TBSaveNote.Header: ANSIstring;
end;


function TBSaveNote.Footer: ANSIstring;
function TBSaveNote.Footer(): ANSIstring;
var
S1, S2, S3, S4, S5, S6 : string;

Expand Down
Loading

0 comments on commit 97aa717

Please sign in to comment.