├── .gitignore
├── LICENSE
├── README.md
├── bin
└── todo.txt
├── common
├── customdrawn_ovonote.pas
├── todo_parser.pas
└── todotxtsyn_highlighter.pas
├── fovonote.lfm
├── fovonote.lrj
├── fovonote.lrt
├── fovonote.pas
├── images
├── archive_d.png
├── checked_d.png
├── delete_d.png
├── document.png
├── document_d.png
├── find.png
├── ovonote.ico
├── ovonote.xcf
├── plus.png
├── plus_d.png
├── reload_d.png
├── remove.png
├── remove_d.png
├── safe.png
├── safe_d.png
├── save_d.png
├── settings.png
├── settings_d.png
├── unchecked_d.png
├── web.png
└── web_d.png
├── language
├── ovonote.it.po
├── ovonote.po
└── ovonote.pot
├── ovonote.ico
├── ovonote.lpi
├── ovonote.lpr
├── ovonote.res
├── udatamodule.lfm
├── udatamodule.lrt
├── udatamodule.pas
├── uniqueinstance
├── registeruniqueinstance.pas
├── testcomponent
│ ├── fmain.lfm
│ ├── fmain.pas
│ ├── testinstance.lpi
│ └── testinstance.lpr
├── testraw
│ ├── project1.lpi
│ ├── project1.lpr
│ ├── unit1.lfm
│ └── unit1.pas
├── tuniqueinstance.png
├── uniqueicon.lrs
├── uniqueinstance.pas
├── uniqueinstance_package.lpk
├── uniqueinstance_package.pas
├── uniqueinstancebase.pas
└── uniqueinstanceraw.pas
├── urawedit.lfm
├── urawedit.lrt
├── urawedit.pas
├── usettings.lfm
├── usettings.lrt
└── usettings.pas
/.gitignore:
--------------------------------------------------------------------------------
1 | *.exe
2 | *.dll
3 | *.so
4 | *.map
5 | *.lib
6 | *.lps
7 | *.a
8 | *.o
9 | *.ppu
10 | *.compiled
11 |
12 | backup/
13 | lib/
14 | bin/
15 |
16 |
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## ovonote
2 | **Current state: RC**
3 |
4 | OvoNote is my personal implementation of todo.txt concept from Gina Trapani.
5 | Todo.txt is a simple and brilliant way to keep your todo items organized.
6 |
7 | All data are saved in a text file, based on a simple clear set of rules.
8 |
9 | ### ScreenShot
10 | Manage todo items with cool GUI
11 |
12 | 
13 |
14 | or with integrated text editor, with syntax highlighting!
15 | 
16 |
17 | ### Development
18 | This application is built using Lazarus (version 1.5) and FreePascal compiler (version 3.1.1).
19 |
20 | ### References
21 |
22 | * [Explanation of todo.txt](http://todotxt.com/)
23 | * [Reference command-line implementation on Github](https://github.com/ginatrapani/todo.txt-cli)
24 | * [File format documentation](https://github.com/ginatrapani/todo.txt-cli/wiki/The-Todo.txt-Format)
25 |
26 | ###License: GPLV2
27 |
28 | >Copyright (C) 2015 Marco Caselli
29 |
30 | >OvoPlayer is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
31 |
32 | >This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
33 |
34 | >You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
--------------------------------------------------------------------------------
/bin/todo.txt:
--------------------------------------------------------------------------------
1 | (A) Thank Mom for the meatballs @phone due:2015-04-21
2 | (B) Schedule Goodwill pickup +GarageSale @phone
3 | Post signs around the neighborhood +GarageSale
4 | @GroceryStore Eskimo pies
5 |
--------------------------------------------------------------------------------
/common/customdrawn_ovonote.pas:
--------------------------------------------------------------------------------
1 | unit customdrawn_ovonote;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | interface
6 |
7 | uses
8 | // RTL / FCL
9 | Classes, SysUtils, Types, Math, fpcanvas,
10 | // LazUtils
11 | lazutf8,
12 | // LCL -> Use only TForm, TWinControl, TCanvas and TLazIntfImage
13 | Graphics, Controls, LCLType,
14 | // Others only for types
15 | StdCtrls, ComCtrls, Forms, ExtCtrls,
16 | //
17 | customdrawndrawers, customdrawn_common;
18 |
19 | type
20 | { TCDDrawerOvoNote }
21 |
22 | TCDDrawerOvoNote = class(TCDDrawerCommon)
23 | private
24 | public
25 | function GetMeasures(AMeasureID: Integer): Integer; override;
26 | procedure CalculatePreferredSize(ADest: TCanvas; AControlId: TCDControlID;
27 | AState: TCDControlState; AStateEx: TCDControlStateEx;
28 | var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override;
29 |
30 | // General drawing routines
31 | // TCDRadioButton
32 | procedure DrawTickmark(ADest: TCanvas; ADestPos: TPoint;
33 | AState: TCDControlState); reintroduce;
34 | procedure DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
35 | AState: TCDControlState; AStateEx: TCDControlStateEx); override;
36 | procedure DrawCheckBox(ADest: TCanvas; ASize: TSize;
37 | AState: TCDControlState; AStateEx: TCDControlStateEx); override;
38 |
39 | end;
40 |
41 | implementation
42 |
43 | function TCDDrawerOvoNote.GetMeasures(AMeasureID: Integer): Integer;
44 | begin
45 | case AMeasureID of
46 | //
47 | TCDCHECKBOX_SQUARE_HALF_HEIGHT: Result := Floor(GetMeasures(TCDCHECKBOX_SQUARE_HEIGHT)/2);
48 | TCDCHECKBOX_SQUARE_HEIGHT: Result := DPIAdjustment(55);
49 | else
50 | result := Inherited GetMeasures(AMeasureID);
51 | end;
52 | end;
53 |
54 | procedure TCDDrawerOvoNote.CalculatePreferredSize(ADest: TCanvas;
55 | AControlId: TCDControlID; AState: TCDControlState;
56 | AStateEx: TCDControlStateEx; var PreferredWidth, PreferredHeight: integer;
57 | WithThemeSpace: Boolean);
58 | begin
59 | PreferredWidth := 0;
60 | PreferredHeight := 0;
61 |
62 | case AControlId of
63 | // In the LCL TEdit AutoSizes only its Height, so follow this here
64 | cidEdit: PreferredHeight := GetMeasuresEx(ADest, TCDCONTROL_CAPTION_HEIGHT, AState, AStateEx)+8;
65 | end;
66 | end;
67 |
68 | procedure TCDDrawerOvoNote.DrawTickmark(ADest: TCanvas; ADestPos: TPoint; AState: TCDControlState);
69 | begin
70 | ADest.Pen.Style := psSolid;
71 | ADest.Pen.Color := Palette.BtnShadow;
72 | ADest.Pen.Width:= DPIAdjustment(2);
73 | ADest.Line(0, 0, ADestPos.X, ADestPos.Y);
74 | ADest.Line(0, ADestPos.Y, ADestPos.X, 0);
75 | end;
76 |
77 |
78 | procedure TCDDrawerOvoNote.DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint;
79 | ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
80 | var
81 | lSquareHeight: Integer;
82 | begin
83 | lSquareHeight := GetMeasures(TCDCHECKBOX_SQUARE_HEIGHT);
84 |
85 | // the square background
86 | ADest.Pen.Style := psSolid;
87 | ADest.Pen.Width:= DPIAdjustment(4);
88 | ADest.Brush.Style := bsSolid;
89 | ADest.Pen.Color := Palette.BtnShadow;
90 |
91 | ADest.Rectangle(Bounds(1, 1, ASize.cx, ASize.cy));
92 |
93 | end;
94 |
95 | procedure TCDDrawerOvoNote.DrawCheckBox(ADest: TCanvas; ASize: TSize;
96 | AState: TCDControlState; AStateEx: TCDControlStateEx);
97 | var
98 | lColor: TColor;
99 | lSquareHeight, lValue3: Integer;
100 | lTextHeight, lTextY: Integer;
101 | begin
102 |
103 | DrawCheckBoxSquare(ADest, Point(0, 0), ASize, AState, AStateEx);
104 |
105 | if (csfOn in AState) or (csfPartiallyOn in AState) then
106 | DrawTickmark(ADest, Point(Asize.cx, ASize.cy), AState);
107 |
108 | end;
109 |
110 |
111 |
112 | initialization
113 | RegisterDrawer(TCDDrawerOvoNote.Create, dsExtra2);
114 | end.
115 |
116 |
117 |
--------------------------------------------------------------------------------
/common/todo_parser.pas:
--------------------------------------------------------------------------------
1 | { Ovonote - My implementation of Todo.txt concept
2 |
3 | Copyright (C) 2015 Marco Caselli
4 |
5 | This source is free software; you can redistribute it and/or modify it under
6 | the terms of the GNU General Public License as published by the Free
7 | Software Foundation; either version 2 of the License, or (at your option)
8 | any later version.
9 |
10 | This code is distributed in the hope that it will be useful, but WITHOUT ANY
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | details.
14 |
15 | A copy of the GNU General Public License is available on the World Wide Web
16 | at . You can also obtain it by writing
17 | to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 | MA 02111-1307, USA.
19 | }
20 | unit todo_parser;
21 |
22 | {$mode objfpc}{$H+}
23 |
24 | interface
25 |
26 | uses
27 | Classes, SysUtils, contnrs;
28 |
29 | type
30 | THighLightKind = (hlkNone, hlkHTML);
31 |
32 | // forward
33 | TTaskList = class;
34 |
35 | { TTask }
36 | TTask = class
37 | private
38 | FCompletion: TDate;
39 | FContexts: TStringList;
40 | FCreation: TDate;
41 | FDone: boolean;
42 | FDue: TDate;
43 | FLink: string;
44 | FModified: boolean;
45 | FOwner: TTaskList;
46 | FPriority: char;
47 | FProjects: TStringList;
48 | FRow: integer;
49 | FTask: string;
50 | procedure ExtractProjectsAndContexts(row: string);
51 | procedure SetCompletion(AValue: TDate);
52 | procedure SetContexts(AValue: TStringList);
53 | procedure SetCreation(AValue: TDate);
54 | procedure SetDone(AValue: boolean);
55 | procedure SetDue(AValue: TDate);
56 | procedure SetLink(AValue: string);
57 | procedure SetModified(AValue: boolean);
58 | procedure SetPriority(AValue: char);
59 | procedure SetProjects(AValue: TStringList);
60 | procedure SetRow(AValue: integer);
61 | procedure SetTask(AValue: string);
62 | function SortKey: DWORD;
63 | public
64 | property Owner: TTaskList read FOwner;
65 | property Modified: boolean read FModified write SetModified;
66 | property Row: integer read FRow write SetRow;
67 | property Task: string read FTask write SetTask;
68 | property Priority: char read FPriority write SetPriority;
69 | property Done: boolean read FDone write SetDone;
70 | property Projects: TStringList read FProjects write SetProjects;
71 | property Contexts: TStringList read FContexts write SetContexts;
72 | property Due: TDate read FDue write SetDue;
73 | property Completion: TDate read FCompletion write SetCompletion;
74 | property Creation: TDate read FCreation write SetCreation;
75 | property Link: string read FLink write SetLink;
76 | constructor Create(aOwner: TTaskList);
77 | destructor Destroy; override;
78 | end;
79 |
80 | { TTaskList }
81 |
82 | TTaskList = class(TObjectList)
83 | private
84 | fMasterModified: boolean;
85 | FOnChange: TNotifyEvent;
86 | function GetModified: boolean;
87 | function HtmlRender(TaskText: string): string;
88 | procedure SetModified(AValue: boolean);
89 | procedure SetOnChange(AValue: TNotifyEvent);
90 | protected
91 | procedure Notify(Ptr: Pointer; Action: TListNotification); override;
92 | procedure DoChange(Task: TTask);
93 | public
94 | property Modified: boolean read GetModified write SetModified;
95 | procedure LoadFromStream(Data: TStream);
96 | procedure SaveToStream(Data: TStream);
97 | procedure AppendToStream(Data: TStream);
98 | function RowFromItem(Task: TTask; HighLightKind: THighLightKind = hlkNone): string;
99 | function ItemFromRow(row: string): TTask;
100 | procedure GetContexts(TaskList: TStrings; ExcludeCompleted: boolean);
101 | procedure GetProjects(TaskList: TStrings; ExcludeCompleted: boolean);
102 | procedure Tasksort;
103 | property OnChange: TNotifyEvent read FOnChange write SetOnChange;
104 | constructor Create; reintroduce;
105 | destructor Destroy; override;
106 |
107 | end;
108 |
109 | function ExtractDate(strDate: string): TdateTime;
110 |
111 | implementation
112 |
113 | { TTaskList }
114 | uses strutils, Math, RegExpr;
115 |
116 | function TaskCompare(Item1, Item2: Pointer): integer;
117 | var
118 | Task1: TTask absolute item1;
119 | Task2: TTask absolute item2;
120 | begin
121 | Result := CompareValue(Ord(task1.done), Ord(task2.done));
122 | if Result = 0 then
123 | Result := CompareValue(task1.SortKey, Task2.SortKey);
124 | if Result = 0 then
125 | Result := CompareValue(ifthen(Task1.due = 0, MaxDateTime, task1.Due),
126 | ifthen(Task2.due = 0, MaxDateTime, task2.Due));
127 |
128 | if Result = 0 then
129 | Result := CompareValue(task1.Row, task2.Row);
130 |
131 | end;
132 |
133 | procedure TTaskList.SetModified(AValue: boolean);
134 | var
135 | i: integer;
136 | begin
137 | fMasterModified := AValue;
138 |
139 | for i := 0 to Count - 1 do
140 | TTask(Items[i]).Modified := False;
141 |
142 | end;
143 |
144 | procedure TTaskList.Notify(Ptr: Pointer; Action: TListNotification);
145 | begin
146 | inherited Notify(Ptr, Action);
147 | fMasterModified := True;
148 | DoChange(TTask(Ptr));
149 | end;
150 |
151 | procedure TTaskList.DoChange(Task: TTask);
152 | begin
153 | if Assigned(FOnChange) then
154 | FOnChange(self);
155 | end;
156 |
157 | function TTaskList.GetModified: boolean;
158 | var
159 | i: integer;
160 | begin
161 | Result := fMasterModified;
162 | if not fMasterModified then
163 | for i := 0 to Count - 1 do
164 | if TTask(Items[i]).Modified then
165 | begin
166 | Result := True;
167 | break;
168 | end;
169 |
170 | end;
171 |
172 | procedure TTaskList.LoadFromStream(Data: TStream);
173 | var
174 | Lista: TStringList;
175 | i, r: integer;
176 | aTask: TTask;
177 | begin
178 | lista := TStringList.Create;
179 | r := 1;
180 | try
181 | Data.position := 0;
182 | Lista.LoadFromStream(Data, TEncoding.UTF8);
183 | for i := 0 to lista.Count - 1 do
184 | begin
185 | if trim(Lista[i]) = emptystr then
186 | Continue;
187 |
188 | atask := ItemFromRow(Lista[i]);
189 | if Assigned(aTask) then
190 | begin
191 | ATask.Row := R;
192 | add(aTask);
193 | Inc(r);
194 | end;
195 | end;
196 |
197 | finally
198 | lista.Free;
199 | end;
200 | Modified := False;
201 |
202 | end;
203 |
204 | function TTaskList.HtmlRender(TaskText: string): string;
205 | var
206 | Words: TStringArray;
207 | i: integer;
208 | Parola: string;
209 |
210 | function IsKey: boolean; inline;
211 | var
212 | ps: integer;
213 | begin
214 | ps := Pos(':', Parola);
215 | Result := (ps > 0) and (ps < Length(trim(Parola)));
216 | end;
217 |
218 | begin
219 |
220 | Result := '';
221 | Words := TaskText.Split(' ');
222 | for i := 0 to length(Words) -1 do
223 | begin
224 | Parola := Words[i];
225 | if length(parola) > 0 then
226 | if Parola[1] in ['+', '@'] then
227 | Result := Result + '' + Parola + ' '
228 | else
229 | if IsKey then
230 | Result := Result + '' + Parola + ' '
231 | else
232 | Result := Result + parola + ' ';
233 | end;
234 | Result := trim(Result);
235 | end;
236 |
237 | function TTaskList.RowFromItem(Task: TTask; HighLightKind: THighLightKind = hlkNone): string;
238 | //var
239 | // i: integer;
240 | // CurrString: string;
241 | begin
242 | Result := '';
243 | if Task.Done then
244 | begin
245 | Result := 'x ';
246 | if Task.Completion > 0 then
247 | Result := Result + FormatDateTime('YYYY-MM-DD ', Task.Completion);
248 | end
249 | else
250 | if Task.Priority <> #00 then
251 | Result := '(' + Task.Priority + ') ';
252 |
253 | if Task.Creation <> 0 then
254 | Result := Result + FormatDateTime('YYYY-MM-DD ', Task.Creation);
255 |
256 | Result := Result + Task.Task;
257 |
258 | if Task.Due <> 0 then
259 | Result := Result + ' due:' + FormatDateTime('YYYY-MM-DD', Task.Due)+' ';
260 |
261 | if Task.Done and (Task.Priority <> #00) then
262 | Result := Result + ' pri:' + Task.Priority;
263 |
264 | if task.Link <> '' then
265 | Result := Result + ' ' + task.link;
266 |
267 | case HighLightKind of
268 | hlkHTML: Result := HtmlRender(Result );
269 | end;
270 | Result := trim(Result);
271 |
272 | end;
273 |
274 | procedure TTaskList.SaveToStream(Data: TStream);
275 | var
276 | row: string;
277 | i: integer;
278 | begin
279 | Data.Size := 0;
280 | AppendToStream(Data);
281 |
282 | end;
283 |
284 | procedure TTaskList.AppendToStream(Data: TStream);
285 | var
286 | row: string;
287 | i: integer;
288 | begin
289 | for i := 0 to Count - 1 do
290 | begin
291 | row := RowFromItem(TTask(Items[i]));
292 | Data.Write(row[1], Length(row));
293 | Row := sLineBreak;
294 | Data.Write(Row[1], SizeOf(sLineBreak));
295 | end;
296 |
297 | Modified := False;
298 |
299 | end;
300 |
301 | function ExtractDate(strDate: string): TdateTime;
302 | begin
303 | if not TryStrToDate(strDate, Result, 'YYYY-MM-DD', '-') then
304 | Result := 0;
305 |
306 | end;
307 |
308 |
309 | function TTaskList.ItemFromRow(row: string): TTask;
310 | var
311 | i: integer;
312 | CurrString: string;
313 | wDate: TDate;
314 | Words: TStringArray;
315 | begin
316 | Result := TTask.Create(self);
317 | Words := row.Split(' ');
318 | for i := 0 to Length(Words) - 1 do
319 | begin
320 | CurrString := Words[i];
321 | // handle positional
322 | case i of
323 | 0: begin
324 | if (CurrString = 'x') then
325 | begin
326 | Result.FDone := True;
327 | Continue;
328 | end
329 | else if ExecRegExpr('^\([A-Z]\)$', CurrString) then
330 | begin
331 | Result.Priority := CurrString[2];
332 | Continue;
333 | end
334 | else
335 | Result.Priority := #00;
336 |
337 | wDate := ExtractDate(CurrString);
338 | if wDate <> 0 then
339 | begin
340 | Result.Creation := wDate;
341 | Continue;
342 | end;
343 |
344 | end;
345 | 1: begin
346 | wDate := ExtractDate(CurrString);
347 | if wDate <> 0 then
348 | begin
349 | if Result.done then
350 | Result.completion := wDate
351 | else
352 | Result.Creation := wDate;
353 | Continue;
354 | end;
355 | end;
356 | 2: if Result.Done and (Result.Completion <> 0) then
357 | begin
358 | wDate := ExtractDate(CurrString);
359 | if wDate <> 0 then
360 | begin
361 | Result.Creation := wDate;
362 | Continue;
363 | end;
364 | end;
365 | end;
366 | if Length(CurrString) >= 1 then
367 | if AnsiStartsStr('due:', CurrString) then
368 | Result.Due := ExtractDate(Copy(CurrString, 5, Length(CurrString)))
369 | else if AnsiStartsStr('pri:', CurrString) then
370 | Result.priority := Copy(CurrString, 5, 1)[1]
371 | else
372 | if (AnsiStartsStr('http:', CurrString) or
373 | AnsiStartsStr('https:', CurrString)) then
374 | Result.Link := CurrString
375 | // // // // //
376 | else
377 | begin
378 | Result.FTask := Result.FTask + CurrString + ' ';
379 | if CurrString[1] = '+' then
380 | Result.Projects.Add(CurrString)
381 | else
382 | if CurrString[1] = '@' then
383 | Result.Contexts.Add(CurrString);
384 |
385 | end;
386 | end;
387 | end;
388 |
389 | procedure TTaskList.GetContexts(TaskList: TStrings; ExcludeCompleted: boolean);
390 | var
391 | i: integer;
392 | Task: TTask;
393 | IntList: TStringList;
394 | begin
395 | TaskList.Clear;
396 | IntList := TStringList.Create;
397 | IntList.Sorted := True;
398 | IntList.Duplicates := dupIgnore;
399 |
400 | for i := 0 to Count - 1 do
401 | begin
402 | Task := TTask(Items[i]);
403 | if Task.Done and ExcludeCompleted then
404 | Continue;
405 | IntList.AddStrings(Task.Contexts);
406 | end;
407 | TaskList.Assign(IntList);
408 | IntList.Free;
409 |
410 | end;
411 |
412 | procedure TTaskList.GetProjects(TaskList: TStrings; ExcludeCompleted: boolean);
413 | var
414 | i: integer;
415 | Task: TTask;
416 | IntList: TStringList;
417 | begin
418 | TaskList.Clear;
419 | IntList := TStringList.Create;
420 | IntList.Sorted := True;
421 | IntList.Duplicates := dupIgnore;
422 |
423 | for i := 0 to Count - 1 do
424 | begin
425 | Task := TTask(Items[i]);
426 | if Task.Done and ExcludeCompleted then
427 | Continue;
428 | IntList.AddStrings(Task.Projects);
429 | end;
430 | TaskList.Assign(IntList);
431 | IntList.Free;
432 |
433 | end;
434 |
435 | procedure TTaskList.Tasksort;
436 | begin
437 | Sort(@TaskCompare);
438 | end;
439 |
440 | procedure TTaskList.SetOnChange(AValue: TNotifyEvent);
441 | begin
442 | if FOnChange = AValue then Exit;
443 | FOnChange := AValue;
444 | end;
445 |
446 |
447 | constructor TTaskList.Create;
448 | begin
449 | inherited Create(True);
450 | fMasterModified := False;
451 | end;
452 |
453 | destructor TTaskList.Destroy;
454 | begin
455 | inherited Destroy;
456 | end;
457 |
458 | { TTask }
459 |
460 | procedure TTask.SetCompletion(AValue: TDate);
461 | begin
462 | if FCompletion = AValue then
463 | Exit;
464 | FCompletion := AValue;
465 | SetModified(True);
466 | end;
467 |
468 | procedure TTask.SetContexts(AValue: TStringList);
469 | begin
470 | if FContexts = AValue then
471 | Exit;
472 | FContexts := AValue;
473 | SetModified(True);
474 | end;
475 |
476 | procedure TTask.SetCreation(AValue: TDate);
477 | begin
478 | if FCreation = AValue then Exit;
479 | FCreation := AValue;
480 | SetModified(True);
481 | end;
482 |
483 | procedure TTask.SetDone(AValue: boolean);
484 | begin
485 | if FDone = AValue then
486 | Exit;
487 | FDone := AValue;
488 | if FDone then
489 | FCompletion := trunc(Now)
490 | else
491 | FCompletion := 0;
492 | SetModified(True);
493 |
494 | end;
495 |
496 | procedure TTask.SetDue(AValue: TDate);
497 | begin
498 | if FDue = AValue then
499 | Exit;
500 | FDue := AValue;
501 | SetModified(True);
502 | end;
503 |
504 | procedure TTask.SetLink(AValue: string);
505 | begin
506 | if FLink = AValue then
507 | Exit;
508 | FLink := AValue;
509 | SetModified(True);
510 | end;
511 |
512 | procedure TTask.SetModified(AValue: boolean);
513 | begin
514 | FModified := AValue;
515 | if (FModified) then
516 | FOwner.DoChange(self);
517 |
518 | end;
519 |
520 | procedure TTask.SetPriority(AValue: char);
521 | begin
522 | if FPriority = AValue then
523 | Exit;
524 | FPriority := AValue;
525 | SetModified(True);
526 | end;
527 |
528 | procedure TTask.SetProjects(AValue: TStringList);
529 | begin
530 | if FProjects = AValue then
531 | Exit;
532 | FProjects := AValue;
533 | SetModified(True);
534 | end;
535 |
536 | procedure TTask.SetRow(AValue: integer);
537 | begin
538 | if FRow = AValue then Exit;
539 | FRow := AValue;
540 | SetModified(True);
541 | end;
542 |
543 | procedure TTask.SetTask(AValue: string);
544 | begin
545 | if FTask = AValue then
546 | Exit;
547 | FTask := AValue;
548 | ExtractProjectsAndContexts(AValue);
549 | SetModified(True);
550 | end;
551 |
552 | function TTask.SortKey: DWORD;
553 | begin
554 | Result := $ffffFFFF;
555 | if Priority <> #00 then
556 | Result := Result and (byte(Priority))
557 | else
558 | Result := Result and (byte(Ord('M')));
559 |
560 | end;
561 |
562 | constructor TTask.Create(aOwner: TTaskList);
563 | begin
564 | FProjects := TStringList.Create;
565 | FContexts := TStringList.Create;
566 | FCompletion := 0;
567 | FCreation := 0;
568 | FTask := '';
569 | FDone := False;
570 | FDue := 0;
571 | FPriority := #00;
572 | FOwner := aOwner;
573 | end;
574 |
575 |
576 | destructor TTask.Destroy;
577 | begin
578 | FProjects.Free;
579 | FContexts.Free;
580 |
581 | end;
582 |
583 | procedure TTask.ExtractProjectsAndContexts(row: string);
584 | var
585 | i: integer;
586 | CurrString: string;
587 | Words: TStringArray;
588 | begin
589 | fProjects.Clear;
590 | fContexts.Clear;
591 |
592 | Words := row.split(' ');
593 | for i := 0 to length(Words) - 1 do
594 | begin
595 | CurrString := Words[i];
596 |
597 | if Length(CurrString) < 2 then
598 | Continue;
599 |
600 | if CurrString[1] = '+' then
601 | fProjects.Add(CurrString)
602 | else
603 | if CurrString[1] = '@' then
604 | fContexts.Add(CurrString);
605 |
606 | end;
607 | end;
608 |
609 |
610 | end.
611 |
--------------------------------------------------------------------------------
/common/todotxtsyn_highlighter.pas:
--------------------------------------------------------------------------------
1 | { Ovonote - My implementation of Todo.txt concept
2 |
3 | Copyright (C) 2015 Marco Caselli
4 |
5 | This source is free software; you can redistribute it and/or modify it under
6 | the terms of the GNU General Public License as published by the Free
7 | Software Foundation; either version 2 of the License, or (at your option)
8 | any later version.
9 |
10 | This code is distributed in the hope that it will be useful, but WITHOUT ANY
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | details.
14 |
15 | A copy of the GNU General Public License is available on the World Wide Web
16 | at . You can also obtain it by writing
17 | to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 | MA 02111-1307, USA.
19 | }
20 | {+-----------------------------------------------------------------------------+
21 | | Class: TTodoSyn
22 | | Created: 2014-11-14
23 | | Last change: 2014-11-14
24 | | Author: Marco Caselli
25 | | Description: Syntax Parser/Highlighter
26 | | Version: 0.1
27 | |
28 | | Copyright (c) 2014 Marco Caselli. All rights reserved.
29 | |
30 | | Generated with SynGen.
31 | +----------------------------------------------------------------------------+}
32 |
33 | unit todotxtsyn_highlighter;
34 |
35 | interface
36 |
37 | uses
38 | Classes, SysUtils,
39 | Graphics,
40 | SynEditTypes, SynEditHighlighter;
41 |
42 | type
43 | TtkTokenKind = (
44 | tkContext,
45 | tkText,
46 | tkPriority,
47 | tkProject,
48 | tkProperty,
49 | tkLinks,
50 | tkSpace,
51 | tkNull,
52 | tkDone);
53 |
54 | TProcTableProc = procedure of object;
55 |
56 | type
57 |
58 | { TTodoSyn }
59 |
60 | TTodoSyn = class(TSynCustomHighlighter)
61 | private
62 | fLine: PChar;
63 | fLineNumber: integer;
64 | fLinkAttri: TSynHighlighterAttributes;
65 | fProcTable: array[#0..#255] of TProcTableProc;
66 | Run: longint;
67 | fTokenPos: integer;
68 | fTokenID: TtkTokenKind;
69 | fContextAttri: TSynHighlighterAttributes;
70 | fTextAttri: TSynHighlighterAttributes;
71 | fPriorityAttri: TSynHighlighterAttributes;
72 | fProjectAttri: TSynHighlighterAttributes;
73 | fPropertyAttri: TSynHighlighterAttributes;
74 | fDoneAttri: TSynHighlighterAttributes;
75 | procedure CRProc;
76 | procedure ContextProc;
77 | procedure TextProc;
78 | procedure DoneProc;
79 | procedure LFProc;
80 | procedure NullProc;
81 | procedure PriorityProc;
82 | procedure PropertyProc;
83 | procedure ProjectProc;
84 | procedure SpaceProc;
85 | procedure MakeMethodTables;
86 | protected
87 | function GetIdentChars: TSynIdentChars; override;
88 | public
89 | class function GetLanguageName: string; override;
90 | function IsKeyword(const AKeyword: string): boolean; override;
91 | function IsLink(const AKeyword: string): boolean;
92 |
93 | public
94 | constructor Create(AOwner: TComponent); override;
95 | function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
96 | override;
97 | function GetEOL: boolean; override;
98 | function GetTokenID: TtkTokenKind;
99 | procedure SetLine(const NewValue: string; LineNumber: integer); override;
100 | function GetToken: string; override;
101 | procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
102 | function GetTokenAttribute: TSynHighlighterAttributes; override;
103 | function GetTokenKind: integer; override;
104 | function GetTokenPos: integer; override;
105 | procedure Next; override;
106 | published
107 | property ContextAttri: TSynHighlighterAttributes read fContextAttri write fContextAttri;
108 | property DoneAttri: TSynHighlighterAttributes read fDoneAttri write fDoneAttri;
109 | property TextAttri: TSynHighlighterAttributes read fTextAttri write fTextAttri;
110 | property PriorityAttri: TSynHighlighterAttributes read fPriorityAttri write fPriorityAttri;
111 | property ProjectAttri: TSynHighlighterAttributes read fProjectAttri write fProjectAttri;
112 | property PropertyAttri: TSynHighlighterAttributes read fPropertyAttri write fPropertyAttri;
113 | property LinkAttri: TSynHighlighterAttributes read fLinkAttri write fLinkAttri;
114 |
115 | end;
116 |
117 | implementation
118 | uses
119 | strutils;
120 |
121 | const
122 | SPACES_SET = [#1..#9, #11, #12, #14..#32];
123 | TOKENTERM_SET = [#0..#32];
124 |
125 | const
126 | KeysCount = 4;
127 | Keys: array[1..KeysCount] of string = (
128 | 'DUE:','H:','PRI:','PERC:');
129 |
130 | LinksCount = 5;
131 | Links: array[1..LinksCount] of string = (
132 | 'FTP:','HTTP:','HTTPS:','MAILTO:','OUTLOOK:');
133 |
134 |
135 |
136 | procedure TTodoSyn.MakeMethodTables;
137 | var
138 | I: char;
139 | begin
140 | for I := #0 to #255 do
141 | case I of
142 | #0: fProcTable[i] := @NullProc;
143 | #10: fProcTable[I] := @LFProc;
144 | #13: fProcTable[I] := @CRProc;
145 | '+': fProcTable[I] := @ProjectProc;
146 | '(': fProcTable[I] := @PriorityProc;
147 | 'x': fProcTable[I] := @DoneProc;
148 | '@': fProcTable[I] := @ContextProc;
149 | 'A'..'Z', 'a'..'w', 'y'..'z': fProcTable[I] := @PropertyProc;
150 | #1..#9, #11, #12, #14..#32: fProcTable[I] := @SpaceProc;
151 | else
152 | fProcTable[I] := @TextProc;
153 | end;
154 | end;
155 |
156 | const
157 |
158 | SYNS_AttrContext = 'Context';
159 | SYNS_AttrIdentifiers = 'Identifier';
160 | SYNS_AttrPriority = 'Priority';
161 | SYNS_AttrProject = 'Project';
162 | SYNS_AttrProperty = 'Property';
163 | SYNS_DoneProperty = 'Done';
164 | SYNS_LinkProperty = 'Link';
165 |
166 |
167 | constructor TTodoSyn.Create(AOwner: TComponent);
168 | begin
169 | inherited Create(AOwner);
170 | // YOU SHOULD ADD AT LEAST ONE OR TWO DIFFERENT DEFAULT ATTRIBUTES
171 | fContextAttri := TSynHighLighterAttributes.Create(SYNS_AttrContext);
172 | AddAttribute(fContextAttri);
173 | fDoneAttri := TSynHighLighterAttributes.Create(SYNS_DoneProperty);
174 | AddAttribute(fDoneAttri);
175 | fTextAttri := TSynHighLighterAttributes.Create(SYNS_AttrIdentifiers);
176 | AddAttribute(fTextAttri);
177 | fPriorityAttri := TSynHighLighterAttributes.Create(SYNS_AttrPriority);
178 | AddAttribute(fPriorityAttri);
179 | fProjectAttri := TSynHighLighterAttributes.Create(SYNS_AttrProject);
180 | AddAttribute(fProjectAttri);
181 | fPropertyAttri := TSynHighLighterAttributes.Create(SYNS_AttrProperty);
182 | AddAttribute(fPropertyAttri);
183 | fLinkAttri := TSynHighLighterAttributes.Create(SYNS_LinkProperty);
184 | AddAttribute(fLinkAttri);
185 |
186 | SetAttributesOnChange(@DefHighlightChange);
187 |
188 | fDefaultFilter := 'Todo.txt Files (*.txt)|*.txt';
189 | MakeMethodTables;
190 |
191 | end;
192 |
193 | procedure TTodoSyn.SetLine(const NewValue: string; LineNumber: integer);
194 | begin
195 | inherited;
196 | fLine := PChar(NewValue);
197 | Run := 0;
198 | fLineNumber := LineNumber;
199 | Next;
200 | end;
201 |
202 | procedure TTodoSyn.PropertyProc;
203 | begin
204 | while not(fLine[Run] in TOKENTERM_SET) do inc(run);
205 | if IsKeyWord(GetToken) then begin
206 | fTokenId := tkProperty;
207 | Exit;
208 | end
209 | else
210 | if IsLink(GetToken) then begin
211 | fTokenId := tkLinks;
212 | Exit;
213 | end
214 |
215 | else fTokenId := tkText;
216 |
217 | end;
218 |
219 | procedure TTodoSyn.CRProc;
220 | begin
221 | fTokenID := tkSpace;
222 | case FLine[Run + 1] of
223 | #10: Inc(Run, 2);
224 | else
225 | Inc(Run);
226 | end;
227 | end;
228 |
229 | procedure TTodoSyn.ContextProc;
230 | begin
231 | if (fTokenPos = 0) or ((fTokenPos > 0) and (fProcTable[fLine[Run - 1]] = @SpaceProc)) then
232 | begin
233 | fTokenID := tkContext;
234 | while (fProcTable[fLine[Run]] <> @SpaceProc) and (fProcTable[fLine[Run]] <> @NullProc) do
235 | Inc(Run);
236 | end
237 | else
238 | begin
239 | fTokenID := tkText;
240 | Inc(run);
241 | end;
242 |
243 | end;
244 |
245 |
246 | procedure TTodoSyn.ProjectProc;
247 | begin
248 | if (fTokenPos = 0) or ((fTokenPos > 0) and (fProcTable[fLine[Run - 1]] = @SpaceProc)) then
249 | begin
250 | fTokenID := tkProject;
251 | while (fProcTable[fLine[Run]] <> @SpaceProc) and (fProcTable[fLine[Run]] <> @NullProc) do
252 | Inc(Run);
253 | end
254 | else
255 | begin
256 | fTokenID := tkText;
257 | Inc(run);
258 | end;
259 |
260 | end;
261 |
262 | procedure TTodoSyn.TextProc;
263 | begin
264 | inc(Run);
265 | while (fLine[Run] in [#128..#191]) OR // continued utf8 subcode
266 | ((fLine[Run]<>#0) and (fProcTable[fLine[Run]] = @TextProc)) do inc(Run);
267 | fTokenID := tkText;
268 |
269 | end;
270 |
271 | procedure TTodoSyn.DoneProc;
272 | begin
273 | if (fTokenPos = 0) and (fLine[run] = 'x') and (FLine[Run + 1] in SPACES_SET) then
274 | begin
275 | fTokenID := tkDone;
276 | repeat
277 | Inc(Run);
278 | until (fLine[Run] in [#0, #10, #13]);
279 | end
280 | else
281 | TextProc;
282 | end;
283 |
284 | procedure TTodoSyn.LFProc;
285 | begin
286 | fTokenID := tkSpace;
287 | Inc(Run);
288 | end;
289 |
290 | procedure TTodoSyn.PriorityProc;
291 | begin
292 | Inc(run);
293 | if (fTokenPos = 0) and (fLine[Run] in ['A'..'Z']) and (fLine[Run + 1] = ')') then
294 | begin
295 | Inc(run, 2);
296 | fTokenID := tkPriority;
297 | end
298 | else
299 | fTokenID := tkText;
300 | end;
301 |
302 | procedure TTodoSyn.SpaceProc;
303 | begin
304 | inc(Run);
305 | fTokenID := tkSpace;
306 | while FLine[Run] in [#1..#9, #11, #12, #14..#32] do inc(Run);
307 | end;
308 |
309 | procedure TTodoSyn.Next;
310 | begin
311 | fTokenPos := Run;
312 | fProcTable[fLine[Run]];
313 | end;
314 |
315 | function TTodoSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
316 | begin
317 | case Index of
318 | SYN_ATTR_COMMENT : Result := fTextAttri;
319 | SYN_ATTR_IDENTIFIER: Result := fTextAttri;
320 | SYN_ATTR_KEYWORD : Result := fProjectAttri;
321 | SYN_ATTR_STRING : Result := fTextAttri;
322 | SYN_ATTR_WHITESPACE: Result := fTextAttri;
323 | else Result := fTextAttri;
324 | end;
325 | end;
326 |
327 | procedure TTodoSyn.NullProc;
328 | begin
329 | fTokenID := tkNull;
330 | end;
331 |
332 | function TTodoSyn.GetEOL: boolean;
333 | begin
334 | Result := fTokenID = tkNull;
335 | end;
336 |
337 | function TTodoSyn.GetToken: string;
338 | var
339 | Len: longint;
340 | begin
341 | Len := Run - fTokenPos;
342 | SetString(Result, (FLine + fTokenPos), Len);
343 | end;
344 |
345 | procedure TTodoSyn.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
346 | begin
347 | TokenLength := Run - fTokenPos;
348 | TokenStart := FLine + fTokenPos;
349 | end;
350 |
351 | function TTodoSyn.GetTokenID: TtkTokenKind;
352 | begin
353 | Result := fTokenId;
354 | end;
355 |
356 | function TTodoSyn.GetTokenAttribute: TSynHighlighterAttributes;
357 | begin
358 | case GetTokenID of
359 | tkDone: Result := fDoneAttri;
360 | tkContext: Result := fContextAttri;
361 | tkText: Result := fTextAttri;
362 | tkPriority: Result := fPriorityAttri;
363 | tkProject: Result := fProjectAttri;
364 | tkProperty: Result := fPropertyAttri;
365 | tkLinks: Result := fLinkAttri;
366 | else
367 | Result := nil;
368 | end;
369 | end;
370 |
371 | function TTodoSyn.GetTokenKind: integer;
372 | begin
373 | Result := Ord(fTokenId);
374 | end;
375 |
376 | function TTodoSyn.GetTokenPos: integer;
377 | begin
378 | Result := fTokenPos;
379 | end;
380 |
381 | function TTodoSyn.GetIdentChars: TSynIdentChars;
382 | begin
383 | Result := ['_', '0'..'9', 'a'..'z', 'A'..'Z', ':', '-','/','.','%'];
384 |
385 | end;
386 |
387 | class function TTodoSyn.GetLanguageName: string;
388 | begin
389 | Result := 'TODO.TXT';
390 | end;
391 |
392 | function TTodoSyn.IsKeyword(const AKeyword: string): boolean;
393 | var
394 | i: Integer;
395 | begin
396 | i := Pos(':',AKeyword);
397 | if (i > 0) and (i < Length(AKeyword)) then
398 | begin
399 | Exit(True);
400 | end;
401 | Result := False;
402 | end;
403 |
404 | function TTodoSyn.IsLink(const AKeyword: string): boolean;
405 | var
406 | i: Integer;
407 | begin
408 | for i := 1 to LinksCount do if AnsiStartsText(Links[i],AKeyWord) then
409 | begin
410 | Exit(True);
411 | end;
412 | Result := False;
413 | end;
414 |
415 |
416 | initialization
417 | RegisterPlaceableHighlighter(TTodoSyn);
418 | end.
419 |
--------------------------------------------------------------------------------
/fovonote.lrj:
--------------------------------------------------------------------------------
1 | {"version":1,"strings":[
2 | {"hash":114579189,"name":"tfrmovonote.caption","sourcebytes":[79,118,111,78,111,116,101],"value":"OvoNote"},
3 | {"hash":261705412,"name":"tfrmovonote.cbexcludecompleted.caption","sourcebytes":[69,120,99,108,117,100,101,32,99,111,109,112,108,101,116,101,100],"value":"Exclude completed"},
4 | {"hash":308805,"name":"tfrmovonote.gridtask.columns[0].title.caption","sourcebytes":[68,111,110,101],"value":"Done"},
5 | {"hash":22350,"name":"tfrmovonote.gridtask.columns[1].title.caption","sourcebytes":[80,114,46],"value":"Pr."},
6 | {"hash":370843,"name":"tfrmovonote.gridtask.columns[2].title.caption","sourcebytes":[84,97,115,107],"value":"Task"},
7 | {"hash":19381,"name":"tfrmovonote.gridtask.columns[3].title.caption","sourcebytes":[68,117,101],"value":"Due"},
8 | {"hash":106613523,"name":"tfrmovonote.gridtask.columns[4].title.caption","sourcebytes":[67,111,110,116,101,120,116,115],"value":"Contexts"},
9 | {"hash":157335491,"name":"tfrmovonote.gridtask.columns[5].title.caption","sourcebytes":[80,114,111,106,101,99,116,115],"value":"Projects"},
10 | {"hash":340043,"name":"tfrmovonote.gridtask.columns[6].title.caption","sourcebytes":[76,105,110,107],"value":"Link"},
11 | {"hash":78392485,"name":"tfrmovonote.gridtask.columns[7].title.caption","sourcebytes":[68,101,108,101,116,101],"value":"Delete"},
12 | {"hash":32,"name":"tfrmovonote.edtpriority.text","sourcebytes":[32],"value":" "},
13 | {"hash":370843,"name":"tfrmovonote.edttask.text","sourcebytes":[84,97,115,107],"value":"Task"},
14 | {"hash":342540,"name":"tfrmovonote.dtpduedate.textfornulldate","sourcebytes":[78,85,76,76],"value":"NULL"},
15 | {"hash":160486425,"name":"tfrmovonote.toolbutton9.caption","sourcebytes":[84,111,111,108,66,117,116,116,111,110,57],"value":"ToolButton9"},
16 | {"hash":146640072,"name":"tfrmovonote.fileopen1.caption","sourcebytes":[82,101,102,114,101,115,104],"value":"Refresh"},
17 | {"hash":121507189,"name":"tfrmovonote.fileopen1.hint","sourcebytes":[82,101,108,111,97,100,32,102,105,108,101],"value":"Reload file"},
18 | {"hash":366789,"name":"tfrmovonote.filesaveas1.caption","sourcebytes":[83,97,118,101],"value":"Save"},
19 | {"hash":209098661,"name":"tfrmovonote.filesaveas1.hint","sourcebytes":[83,97,118,101,32,102,105,108,101],"value":"Save file"},
20 | {"hash":143257733,"name":"tfrmovonote.actarchive.caption","sourcebytes":[65,114,99,104,105,118,101],"value":"Archive"},
21 | {"hash":42443555,"name":"tfrmovonote.actarchive.hint","sourcebytes":[65,114,99,104,105,118,101,32,99,111,109,112,108,101,116,101,100,32,116,97,115,107,115],"value":"Archive completed tasks"},
22 | {"hash":18340,"name":"tfrmovonote.actadd.caption","sourcebytes":[65,100,100],"value":"Add"},
23 | {"hash":116497323,"name":"tfrmovonote.actadd.hint","sourcebytes":[65,100,100,32,97,32,110,101,119,32,116,97,115,107],"value":"Add a new task"},
24 | {"hash":78392485,"name":"tfrmovonote.actdelete.caption","sourcebytes":[68,101,108,101,116,101],"value":"Delete"},
25 | {"hash":171797083,"name":"tfrmovonote.actdelete.hint","sourcebytes":[68,101,108,101,116,101,32,116,97,115,107],"value":"Delete task"},
26 | {"hash":310020,"name":"tfrmovonote.actedit.caption","sourcebytes":[69,100,105,116],"value":"Edit"},
27 | {"hash":225269106,"name":"tfrmovonote.actedit.hint","sourcebytes":[73,110,116,101,114,110,97,108,32,116,101,120,116,32,101,100,105,116,111,114],"value":"Internal text editor"},
28 | {"hash":213582195,"name":"tfrmovonote.actsettings.caption","sourcebytes":[83,101,116,116,105,110,103,115],"value":"Settings"},
29 | {"hash":213582195,"name":"tfrmovonote.actsettings.hint","sourcebytes":[83,101,116,116,105,110,103,115],"value":"Settings"},
30 | {"hash":110724720,"name":"tfrmovonote.actshowdone.caption","sourcebytes":[83,104,111,119,32,65,114,99,104,105,118,101,100,32],"value":"Show Archived "},
31 | {"hash":108212507,"name":"tfrmovonote.actshowdone.hint","sourcebytes":[83,104,111,119,32,65,114,99,104,105,118,101,100,32,84,97,115,107],"value":"Show Archived Task"},
32 | {"hash":155193957,"name":"tfrmovonote.actterminate.caption","sourcebytes":[84,101,114,109,105,110,97,116,101],"value":"Terminate"},
33 | {"hash":146468846,"name":"tfrmovonote.actterminate.hint","sourcebytes":[67,108,111,115,101,32,97,112,112,108,105,99,97,116,105,111,110],"value":"Close application"}
34 | ]}
35 |
--------------------------------------------------------------------------------
/fovonote.lrt:
--------------------------------------------------------------------------------
1 | TFRMOVONOTE.TOOLBUTTON6.HINT=Edit as text
2 | TFRMOVONOTE.TOOLBUTTON9.CAPTION=ToolButton9
3 | TFRMOVONOTE.EDTPRIORITY.TEXT=
4 | TFRMOVONOTE.EDTTASK.TEXT=edtTask
5 | TFRMOVONOTE.FILEOPEN1.CAPTION=Refresh
6 | TFRMOVONOTE.FILEOPEN1.HINT=Reload file
7 | TFRMOVONOTE.FILESAVEAS1.CAPTION=Save
8 | TFRMOVONOTE.FILESAVEAS1.HINT=Save file
9 | TFRMOVONOTE.ACTARCHIVE.CAPTION=Archive
10 | TFRMOVONOTE.ACTARCHIVE.HINT=Archive completed tasks
11 | TFRMOVONOTE.ACTADD.CAPTION=Add
12 | TFRMOVONOTE.ACTADD.HINT=Add a new task
13 | TFRMOVONOTE.ACTDELETE.CAPTION=Delete
14 | TFRMOVONOTE.ACTDELETE.HINT=Delete task
15 | TFRMOVONOTE.ACTEDIT.CAPTION=Edit
16 | TFRMOVONOTE.ACTEDIT.HINT=Internal text editor
17 | TFRMOVONOTE.ACTSETTINGS.CAPTION=Settings
18 | TFRMOVONOTE.ACTSETTINGS.HINT=Settings
19 | TFRMOVONOTE.ACTSHOWDONE.CAPTION=Show Archived
20 | TFRMOVONOTE.ACTTERMINATE.CAPTION=actTerminate
21 | TFRMOVONOTE.ACTTERMINATE.HINT=Close application
22 | TFRMOVONOTE.MENUITEM1.CAPTION=Exit
23 |
--------------------------------------------------------------------------------
/fovonote.pas:
--------------------------------------------------------------------------------
1 | { Ovonote - My implementation of Todo.txt concept
2 |
3 | Copyright (C) 2015 Marco Caselli
4 |
5 | This source is free software; you can redistribute it and/or modify it under
6 | the terms of the GNU General Public License as published by the Free
7 | Software Foundation; either version 2 of the License, or (at your option)
8 | any later version.
9 |
10 | This code is distributed in the hope that it will be useful, but WITHOUT ANY
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | details.
14 |
15 | A copy of the GNU General Public License is available on the World Wide Web
16 | at . You can also obtain it by writing
17 | to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 | MA 02111-1307, USA.
19 | }
20 | unit fovonote;
21 |
22 | {$mode objfpc}{$H+}
23 |
24 | interface
25 |
26 | uses
27 | types, Classes, SysUtils, FileUtil, DateTimePicker, lcltype, lclintf, Forms, Controls,
28 | Graphics, Dialogs, StdCtrls, ComCtrls, Grids, ExtCtrls, ActnList, Menus,
29 | MaskEdit, Buttons, todo_parser, udatamodule, usettings,
30 | DefaultTranslator, ExtDlgs, uniqueInstance, ImgList;
31 |
32 | Const
33 | AppNameServerID = 'ovonote-MC';
34 | { TfrmOvoNote }
35 |
36 | type
37 | TfrmOvoNote = class(TForm)
38 | actArchive: TAction;
39 | actAdd: TAction;
40 | actDelete: TAction;
41 | actEdit: TAction;
42 | actTerminate: TAction;
43 | actShowDone: TAction;
44 | actSettings: TAction;
45 | ActionList: TActionList;
46 | bSearch: TSpeedButton;
47 | cbExcludeCompleted: TCheckBox;
48 | edtNewTask: TEdit;
49 | edtSearch: TEdit;
50 | edtTask: TEdit;
51 | gridTask: TStringGrid;
52 | FileOpen1: TAction;
53 | FileSaveAs1: Taction;
54 | lbContexts: TListBox;
55 | lbProjects: TListBox;
56 | edtPriority: TMaskEdit;
57 | mList: TMemo;
58 | MenuItem1: TMenuItem;
59 | MenuItem2: TMenuItem;
60 | mnuFile: TMenuItem;
61 | pnlTop: TPanel;
62 | pnlSearch: TPanel;
63 | pnlFilter: TPanel;
64 | pnlNew: TPanel;
65 | pnlTasks: TPanel;
66 | SpeedButton1: TSpeedButton;
67 | sbTerminate: TSpeedButton;
68 | TimerAutoSave: TTimer;
69 | dtpDueDate: TDateTimePicker;
70 | ToolBar1: TToolBar;
71 | ToolButton1: TToolButton;
72 | ToolButton11: TToolButton;
73 | ToolButton2: TToolButton;
74 | ToolButton3: TToolButton;
75 | ToolButton4: TToolButton;
76 | ToolButton5: TToolButton;
77 | ToolButton6: TToolButton;
78 | ToolButton7: TToolButton;
79 | ToolButton8: TToolButton;
80 | ToolButton9: TToolButton;
81 | TrayIcon: TTrayIcon;
82 | TrayMenu: TPopupMenu;
83 | procedure actAddExecute(Sender: TObject);
84 | procedure actArchiveExecute(Sender: TObject);
85 | procedure actDeleteExecute(Sender: TObject);
86 | procedure actEditExecute(Sender: TObject);
87 | procedure ActionListUpdate(AAction: TBasicAction; var Handled: Boolean);
88 | procedure actSettingsExecute(Sender: TObject);
89 | procedure actShowDoneExecute(Sender: TObject);
90 | procedure actTerminateExecute(Sender: TObject);
91 | procedure bSearchClick(Sender: TObject);
92 | procedure cbExcludeCompletedClick(Sender: TObject);
93 | procedure edtNewTaskKeyDown(Sender: TObject; var Key: Word;
94 | Shift: TShiftState);
95 | procedure edtSearchChange(Sender: TObject);
96 | procedure edtPriorityKeyPress(Sender: TObject; var Key: char);
97 | procedure edtSearchKeyDown(Sender: TObject; var Key: Word;
98 | Shift: TShiftState);
99 | procedure edtTaskKeyPress(Sender: TObject; var Key: char);
100 | procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
101 | procedure FormCreate(Sender: TObject);
102 | procedure FormDestroy(Sender: TObject);
103 | procedure gridTaskButtonClick(Sender: TObject; aCol, aRow: Integer);
104 | procedure gridTaskCheckboxToggled(Sender: TObject; aCol, aRow: integer; aState: TCheckboxState);
105 | procedure gridTaskDrawCell(Sender: TObject; aCol, aRow: Integer;
106 | aRect: TRect; aState: TGridDrawState);
107 | procedure gridTaskExit(Sender: TObject);
108 | procedure gridTaskHeaderClick(Sender: TObject; IsColumn: Boolean;
109 | Index: Integer);
110 | procedure gridTaskPrepareCanvas(Sender: TObject; aCol, aRow: integer; aState: TGridDrawState);
111 | procedure gridTaskSelectEditor(Sender: TObject; aCol, aRow: integer; var Editor: TWinControl);
112 | procedure gridTaskSetEditText(Sender: TObject; ACol, ARow: integer; const Value: string);
113 | procedure FileOpen1Execute(Sender: TObject);
114 | procedure FileSaveAs1Execute(Sender: TObject);
115 | procedure FormResize(Sender: TObject);
116 | procedure FormShow(Sender: TObject);
117 | procedure gridTaskUserCheckboxImage(Sender: TObject; const aCol, aRow: Integer; const CheckedState: TCheckBoxState;
118 | var ImageList: TCustomImageList; var ImageIndex: TImageIndex);
119 | procedure lbProjectsSelectionChange(Sender: TObject; User: boolean);
120 | procedure TimerAutoSaveTimer(Sender: TObject);
121 | procedure TrayIconDblClick(Sender: TObject);
122 | private
123 | fLoading : boolean;
124 | TaskList: TTaskList;
125 | UniqueInstanceI: TUniqueInstance;
126 |
127 | procedure CheckAutoSave;
128 | procedure LoadFile;
129 | procedure LoadToGrid(FilterProject, FilterContext, FilterText: string; ExcludeCompleted: boolean); overload;
130 | procedure LoadToGrid(FilterProject, FilterContext: Integer); overload;
131 | procedure LoadToGrid(); overload;
132 | procedure ReloadFilters;
133 | procedure ResizeGrid;
134 | procedure TaskListChange(Sender: TObject);
135 | procedure TasktoGridRow(Task: TTask; Arow: Integer);
136 | procedure UniqueInstanceIOtherInstance(Sender: TObject;
137 | ParamCount: Integer; Parameters: array of String);
138 |
139 | end;
140 |
141 | var
142 | frmOvoNote: TfrmOvoNote;
143 |
144 | implementation
145 |
146 | uses uRawEdit, strutils;
147 |
148 | COnst
149 | COL_DONE = 1;
150 | COL_PRIORITY = 2;
151 | COL_TASK = 3;
152 | COL_DUE = 4;
153 | COL_CONTEXT = 5;
154 | COL_PROJECT = 6;
155 | COL_LINK = 7;
156 | COL_DELETE = 8;
157 |
158 |
159 | {$R *.lfm}
160 |
161 | { TfrmOvoNote }
162 | procedure TfrmOvoNote.TasktoGridRow(Task: TTask; Arow: Integer);
163 | begin
164 | if Task.Done then
165 | gridTask.Cells[COL_DONE, aRow] := '1'
166 | else
167 | gridTask.Cells[COL_DONE, aRow] := '0';
168 |
169 | gridTask.Cells[COL_PRIORITY, aRow] := ' ' + Task.Priority + ' ';
170 | gridTask.Cells[COL_TASK, aRow] := Task.Task;
171 |
172 | if Task.Due <> 0 then
173 | gridTask.Cells[COL_DUE, aRow] := DateToStr(task.Due)
174 | else
175 | gridTask.Cells[COL_DUE, aRow] := '';
176 |
177 | gridTask.Cells[COL_CONTEXT, aRow] := Task.Contexts.Text;
178 | gridTask.Cells[COL_PROJECT, aRow] := Task.Projects.Text;
179 | gridTask.Cells[COL_LINK, aRow] := ' '+copy(Task.link, 1, pos(':', task.link)) + ' ';
180 | gridTask.Objects[0, aRow]:= Task;
181 |
182 |
183 | end;
184 |
185 | procedure TfrmOvoNote.LoadToGrid(FilterProject,FilterContext, FilterText:string; ExcludeCompleted: boolean);
186 | var
187 | i: integer;
188 | Task: TTask;
189 | Idx: integer;
190 | r: TGridRect;
191 | FoundTasks:Integer;
192 | begin
193 | TaskList.TaskSort;
194 | fLoading:= true;
195 | idx := -1;
196 | try
197 | Task := TTask(gridTask.objects[0,gridTask.Selection.Top]);
198 | if Assigned(Task) then
199 | idx := Task.Row;
200 | except
201 | idx := -1;
202 | end;
203 |
204 | FoundTasks := 0;
205 |
206 | try
207 |
208 | gridTask.RowCount:= 2;
209 | for i := 0 to TaskList.Count - 1 do
210 | begin
211 | Task := TTask(TaskList.Items[i]);
212 | if (Task.Done and ExcludeCompleted) then
213 | Continue;
214 | if FilterProject <> EmptyStr then
215 | if Task.Projects.IndexOf(FilterProject) < 0 then
216 | Continue;
217 |
218 | if FilterContext <> EmptyStr then
219 | if Task.Contexts.IndexOf(FilterContext) < 0 then
220 | Continue;
221 |
222 | if FilterText <> EmptyStr then
223 | if not AnsiContainsText(Task.Task, FilterText) then
224 | Continue;
225 | inc(FoundTasks);
226 | TasktoGridRow(Task, gridTask.RowCount -1);
227 | gridTask.RowCount:= gridTask.RowCount +1;
228 | end;
229 |
230 | gridTask.RowCount:= gridTask.RowCount -1;
231 | if (idx <> -1) and (FoundTasks > 0) then
232 | for i := 1 To gridTask.RowCount -1 do
233 | begin
234 | if TTask(gridTask.objects[0,i]).Row = idx then
235 | begin
236 | r.Top := i;
237 | r.Bottom := i;
238 | r.Left:=COL_DONE;
239 | r.Right:=COL_LINK;
240 | gridTask.Selection := r;
241 | Break;
242 | end;
243 | end;
244 |
245 | finally
246 | fLoading:=false;;
247 | end;
248 | ReloadFilters;
249 | end;
250 |
251 | procedure TfrmOvoNote.LoadToGrid(FilterProject, FilterContext: Integer);
252 | VAR
253 | st1, st2: string;
254 | begin
255 | if FilterProject > 0 then
256 | st1 := lbProjects.Items[lbProjects.ItemIndex]
257 | else
258 | st1 := '';
259 |
260 | if FilterContext > 0 then
261 | st2 := lbContexts.Items[lbContexts.ItemIndex]
262 | else
263 | st2 := '';
264 |
265 | LoadToGrid(st1, st2, edtSearch.Text, cbExcludeCompleted.Checked);
266 | lbProjects.ItemIndex := FilterProject;
267 | lbContexts.ItemIndex := FilterContext;
268 |
269 | end;
270 |
271 | procedure TfrmOvoNote.LoadToGrid;
272 | begin
273 | LoadToGrid(lbProjects.ItemIndex, lbContexts.ItemIndex);
274 | end;
275 |
276 | procedure TfrmOvoNote.ReloadFilters;
277 | begin
278 | TaskList.GetContexts(lbContexts.Items, cbExcludeCompleted.Checked);
279 | lbContexts.Items.Insert(0,ALL_ELEMENT);
280 | TaskList.GetProjects(lbProjects.Items, cbExcludeCompleted.Checked);
281 | lbProjects.Items.Insert(0,ALL_ELEMENT);
282 |
283 | end;
284 |
285 | procedure TfrmOvoNote.LoadFile;
286 | var
287 | TodoFile: TFileStream;
288 | Mode: Word;
289 | begin
290 | if not Assigned(TaskList) then
291 | begin
292 | TaskList := TTaskList.Create;
293 | TaskList.OnChange := @TaskListChange;
294 | end;
295 |
296 | Mode := fmOpenRead;
297 | if not FileExists(dm.FilePath+FILE_TODO) then
298 | inc(mode, fmCreate);
299 |
300 | TodoFile := TFileStream.Create(dm.FilePath+FILE_TODO, Mode);
301 | TodoFile.Position := 0;
302 | TaskList.Clear;
303 | TaskList.LoadFromStream(TodoFile);
304 |
305 | gridTask.RowCount := TaskList.Count + 1;
306 | LoadToGrid('','','', true);
307 |
308 | gridTask.Invalidate;
309 | ReloadFilters;
310 |
311 | TodoFile.Free;
312 | end;
313 |
314 | procedure TfrmOvoNote.gridTaskCheckboxToggled(Sender: TObject; aCol, aRow: integer; aState: TCheckboxState);
315 | var
316 | Task: TTask;
317 | begin
318 | Task := TTask(gridTask.Objects[0,arow]);
319 | if aCol = COL_DELETE then
320 | begin
321 | TaskList.Delete(aRow-1);
322 | LoadToGrid();
323 | end
324 | else
325 | begin
326 | Task.Done:=aState = cbChecked;
327 | TasktoGridRow(Task, aRow);
328 | end;
329 | end;
330 |
331 | procedure TfrmOvoNote.gridTaskHeaderClick(Sender: TObject; IsColumn: Boolean;
332 | Index: Integer);
333 | var
334 | r: TGridRect;
335 | begin
336 | If not IsColumn then
337 | begin
338 | r.Top:=Index;
339 | r.Bottom:=index;
340 | r.Left:=COL_DONE;
341 | r.Right:=COL_LINK;
342 | gridTask.Selection := r;
343 |
344 | end;
345 | end;
346 |
347 | procedure TfrmOvoNote.gridTaskButtonClick(Sender: TObject; aCol, aRow: Integer);
348 | var
349 | Task: TTask;
350 | begin
351 | if aCol = COL_LINK then
352 | begin
353 | Task := TTask(gridTask.Objects[0, Arow]);
354 | OpenDocument(Task.link);
355 | end;
356 | end;
357 |
358 | procedure TfrmOvoNote.actArchiveExecute(Sender: TObject);
359 | var
360 | Arch: TTaskList;
361 | Task: TTask;
362 | DoneStream: TFileStream;
363 | i:integer;
364 | Mode: word;
365 | begin
366 | Arch := tTaskList.Create;
367 |
368 | for i:= TaskList.Count -1 downto 0 do
369 | begin
370 | Task := TTask(TaskList.Items[i]);
371 | if Task.Done then
372 | begin
373 | TaskList.Extract(Task);
374 | Arch.Add(Task);
375 | end;
376 | end;
377 |
378 | if FileExists(dm.FilePath+FILE_DONE) then
379 | begin
380 | CopyFile(dm.FilePath+FILE_DONE, ChangeFileExt(dm.FilePath+FILE_DONE,'.bak'));
381 | Mode := fmOpenReadWrite
382 | end
383 | else
384 | Mode:= fmOpenWrite+ fmCreate;
385 |
386 | DoneStream:= TFileStream.Create(dm.FilePath+FILE_DONE, mode);
387 |
388 | DoneStream.Seek(0,soEnd);
389 | Arch.AppendToStream(DoneStream);
390 | DoneStream.free;
391 | FileSaveAs1.Execute;
392 | LoadToGrid();
393 |
394 | end;
395 |
396 | procedure TfrmOvoNote.actDeleteExecute(Sender: TObject);
397 | var
398 | x: integer;
399 | begin
400 | x:=gridTask.Selection.top;
401 | TaskList.Remove(gridTask.Objects[0, x]);
402 | LoadToGrid();
403 | ResizeGrid;
404 | end;
405 |
406 | Procedure TfrmOvoNote.CheckAutoSave;
407 | begin
408 | if dm.AutoSave and TaskList.Modified then
409 | FileSaveAs1.Execute;
410 |
411 | end;
412 |
413 | procedure TfrmOvoNote.actEditExecute(Sender: TObject);
414 | begin
415 |
416 | CheckAutoSave;
417 |
418 | if TaskList.Modified then
419 | Case MessageDlg(RS_SAVE,mtWarning, mbYesNoCancel,0) of
420 | mrYes : FileSaveAs1.Execute;
421 | mrCancel : exit;
422 | end;
423 |
424 | fRawEdit:=TfRawEdit.Create(Self, false);
425 | try
426 | if fRawEdit.showModal = mrModified then
427 | FileOpen1.Execute;
428 | finally
429 | fRawEdit.free;
430 | end;
431 | FileOpen1.Execute;
432 | end;
433 |
434 | procedure TfrmOvoNote.ActionListUpdate(AAction: TBasicAction;
435 | var Handled: Boolean);
436 | begin
437 | FileSaveAs1.Enabled:= TaskList.Modified;
438 | end;
439 |
440 | procedure TfrmOvoNote.actSettingsExecute(Sender: TObject);
441 | begin
442 | if not Assigned(fSettings) then
443 | fSettings:= TfSettings.Create(Self);
444 | fSettings.Show;
445 | end;
446 |
447 | procedure TfrmOvoNote.actShowDoneExecute(Sender: TObject);
448 | begin
449 | try
450 | fRawEdit:=TfRawEdit.Create(Self, True);
451 | fRawEdit.showModal;
452 | finally
453 | fRawEdit.free;
454 | end;
455 | end;
456 |
457 | procedure TfrmOvoNote.actTerminateExecute(Sender: TObject);
458 | begin
459 | Application.Terminate;
460 | end;
461 |
462 | procedure TfrmOvoNote.bSearchClick(Sender: TObject);
463 | begin
464 | edtSearch.Text:='';
465 | LoadToGrid();
466 | end;
467 |
468 | procedure TfrmOvoNote.cbExcludeCompletedClick(Sender: TObject);
469 | begin
470 | LoadToGrid();
471 | ReloadFilters;
472 | end;
473 |
474 | procedure TfrmOvoNote.edtNewTaskKeyDown(Sender: TObject; var Key: Word;
475 | Shift: TShiftState);
476 | begin
477 | case key of
478 | VK_RETURN : if edtNewTask.Text <> EmptyStr then
479 | actAdd.Execute;
480 | VK_ESCAPE : edtNewTask.Clear;
481 | end;
482 | end;
483 |
484 | procedure TfrmOvoNote.edtSearchChange(Sender: TObject);
485 | begin
486 | if edtSearch.Text = '' then
487 | dm.imglSmall.GetBitmap(0, bSearch.Glyph)
488 | else
489 | begin
490 | dm.imglSmall.GetBitmap(1, bSearch.Glyph);
491 | end;
492 |
493 | LoadToGrid();
494 |
495 | end;
496 |
497 | procedure TfrmOvoNote.edtPriorityKeyPress(Sender: TObject; var Key: char);
498 | begin
499 | if (upcase(key) in [#32, 'A'..'Z']) then
500 | edtPriority.Text:= upcase(KEY);
501 | if Key = #27 then
502 | edtTask.Undo;
503 |
504 | end;
505 |
506 | procedure TfrmOvoNote.edtSearchKeyDown(Sender: TObject; var Key: Word;
507 | Shift: TShiftState);
508 | begin
509 | case key of
510 | VK_ESCAPE : edtSearch.Clear;
511 | end;
512 | end;
513 |
514 | procedure TfrmOvoNote.edtTaskKeyPress(Sender: TObject; var Key: char);
515 | begin
516 |
517 | case key of
518 | #13 : begin
519 | gridTaskSetEditText(gridTask,gridTask.Col, gridTask.Row, edtTask.Text);
520 | gridTask.EditorMode :=false;
521 | end;
522 | #27 : edtTask.Undo;
523 | end;
524 | end;
525 |
526 | procedure TfrmOvoNote.FormClose(Sender: TObject; var CloseAction: TCloseAction);
527 | begin
528 | Application.ShowMainForm:=False;
529 | CheckAutoSave;
530 | if TaskList.Modified then
531 | Case MessageDlg(RS_SAVE,mtWarning, mbYesNoCancel,0) of
532 | mrYes : FileSaveAs1.Execute;
533 | mrCancel : exit;
534 | end;
535 |
536 | CloseAction:=caHide;
537 | end;
538 |
539 | procedure TfrmOvoNote.UniqueInstanceIOtherInstance(Sender: TObject;
540 | ParamCount: Integer; Parameters: array of String);
541 | begin
542 | //
543 | Self.show;
544 | end;
545 |
546 | procedure TfrmOvoNote.FormCreate(Sender: TObject);
547 | begin
548 |
549 | UniqueInstanceI:= TUniqueInstance.Create(Self);
550 | with UniqueInstanceI do
551 | begin
552 | Identifier := AppNameServerID;
553 | UpdateInterval := 500;
554 | OnOtherInstance := @UniqueInstanceIOtherInstance;
555 | Enabled := True;
556 | Loaded;
557 | end;
558 |
559 | end;
560 |
561 | procedure TfrmOvoNote.FormDestroy(Sender: TObject);
562 | begin
563 | TaskList.Free ;
564 | UniqueInstanceI.free;
565 | end;
566 |
567 | procedure TfrmOvoNote.actAddExecute(Sender: TObject);
568 | var
569 | Task : TTask;
570 | begin
571 | if edtNewTask.Text = EmptyStr then
572 | exit;
573 |
574 | Task := TaskList.ItemFromRow(edtNewTask.Text);
575 | edtNewTask.Clear;
576 | TaskList.Add(Task);
577 | task.Modified:= true;
578 | LoadToGrid();
579 |
580 | end;
581 |
582 | procedure TfrmOvoNote.gridTaskPrepareCanvas(Sender: TObject; aCol, aRow: integer; aState: TGridDrawState);
583 | var
584 | MyTextStyle: TTextStyle;
585 | Task: TTask;
586 | begin
587 | if (aRow = 0) or not assigned(TaskList) or (TaskList.Count = 0) then
588 | exit;
589 | Task := TTask(gridTask.Objects[0,Arow]);
590 | if not Assigned(Task) then
591 | exit;
592 | gridTask.Canvas.Font := gridTask.Font;
593 | case aCol of
594 | COL_DONE:
595 | begin
596 | end;
597 | COL_PRIORITY:
598 | begin
599 | gridTask.Canvas.Font.Size := 15;
600 | end;
601 | COL_TASK:
602 | begin
603 | end;
604 | else
605 | begin
606 | MyTextStyle := gridTask.Canvas.TextStyle;
607 | MyTextStyle.SingleLine := False;
608 | gridTask.Canvas.TextStyle := MyTextStyle;
609 | end;
610 | end;
611 |
612 | if Task.Done then
613 | gridTask.Canvas.Font.Color := clGrayText;
614 | end;
615 |
616 | procedure TfrmOvoNote.gridTaskDrawCell(Sender: TObject; aCol, aRow: Integer;
617 | aRect: TRect; aState: TGridDrawState);
618 |
619 | var
620 | X, i: integer;
621 | Parola:string;
622 | Words: TStringArray;
623 | Function IsKey: boolean; inline;
624 | var
625 | ps:integer;
626 | begin
627 | ps := Pos(':',Parola);
628 | result :=(ps > 0) and (ps < Length(trim(Parola)));
629 | end;
630 |
631 | begin
632 | if (aRow > 0) and ((aCol = COL_DONE) ) then
633 | begin
634 | aState:= [gdFixed];
635 | end;
636 | if (aRow > 0) and ( (aCol = COL_PRIORITY)) then
637 | begin
638 | aState:= [gdSelected];
639 | end;
640 |
641 | if (aRow > 0) and (aCol in [ COL_TASK, COL_PRIORITY]) then
642 | begin
643 | //
644 | x:= aRect.Left +2;
645 |
646 | gridTask.Canvas.FillRect(Arect);
647 | Words := gridTask.Cells[aCol,aRow].split(' ');
648 | for i:= 0 to length(Words)-1 do
649 | begin
650 | Parola:=Words[i];
651 | if length(parola) > 0 then
652 | begin
653 | if Parola[1] in ['+','@'] then
654 | begin
655 | gridTask.Canvas.Brush.Color := clDefault;
656 | gridTask.Canvas.Font.Style:=[fsBold];
657 | gridTask.Canvas.TextOut(X, arect.top+1, Parola);
658 | end
659 | else
660 | if IsKey then
661 | begin
662 | gridTask.Canvas.Font.Style:=[];
663 | gridTask.Canvas.Brush.Color := clInactiveCaption;
664 | gridTask.Canvas.TextOut(X, arect.top+1, Parola);
665 | end
666 | else
667 | begin
668 | gridTask.Canvas.Font.Style:=[];
669 | gridTask.Canvas.Brush.Color := clDefault;
670 | gridTask.Canvas.TextOut(X, arect.top, Parola);
671 | end;
672 |
673 | inc(x, gridTask.Canvas.GetTextWidth(Parola+' '));
674 |
675 | end;
676 |
677 | end;
678 | end
679 | else
680 | gridTask.DefaultDrawCell(aCol, aRow, aRect, aState);
681 | end;
682 |
683 | procedure TfrmOvoNote.gridTaskExit(Sender: TObject);
684 | begin
685 | gridTask.EditorMode := false;
686 | end;
687 |
688 | procedure TfrmOvoNote.gridTaskSelectEditor(Sender: TObject; aCol, aRow: integer; var Editor: TWinControl);
689 | var
690 | aRect: Trect;
691 | Task: TTask;
692 | begin
693 | aRect := gridTask.CellRect(aCol, aRow);
694 | Task := TTask(gridTask.Objects[0,aROW]);
695 | if not Assigned(Task) or fLoading then
696 | begin
697 | Editor:= nil;
698 | exit;
699 | end;
700 |
701 | case acol of
702 | COL_DONE:
703 | begin
704 | end;
705 | COL_task:
706 | begin
707 | edtTask.BoundsRect := aRect;
708 | Editor := edtTask;
709 | edtTask.Text := task.Task;
710 | end;
711 |
712 | COL_PRIORITY:
713 | begin
714 | edtPriority.BoundsRect := aRect;
715 | edtPriority.Font.Size := -15;
716 |
717 | Editor := edtPriority;
718 | edtPriority.Text := task.Priority;
719 | end;
720 | COL_CONTEXT:
721 | begin
722 | editor := nil;
723 | //mList.BoundsRect := aRect;
724 | //Editor := mList;
725 | //mList.Text := Task.Contexts.Text;
726 | end;
727 | COL_PROJECT:
728 | begin
729 | editor := nil;
730 | //mList.BoundsRect := aRect;
731 | //Editor := mList;
732 | //mList.Text := Task.Projects.Text;
733 | end;
734 |
735 | COL_DUE:
736 | begin
737 | dtpDueDate.BoundsRect := aRect;
738 | Editor := dtpDueDate;
739 | if Task.Due <> 0 then
740 | dtpDueDate.Date := Task.Due
741 | else
742 | dtpDueDate.Date := NullDate;
743 | end;
744 |
745 | end;
746 | end;
747 |
748 | procedure TfrmOvoNote.gridTaskSetEditText(Sender: TObject; ACol, ARow: integer; const Value: string);
749 | var
750 | Task: TTask;
751 | begin
752 | if (aRow = 0) or not assigned(TaskList) or (TaskList.Count = 0) or fLoading then
753 | exit;
754 | Task := TTask(gridTask.Objects[0,Arow]);
755 |
756 | case ACol of
757 | COL_DONE:
758 | begin
759 | end;
760 | COL_PRIORITY:
761 | begin
762 | Task.Priority := (trim(edtPriority.Text)+#00)[1];
763 | end;
764 | COL_TASK:
765 | begin
766 | Task.Task := edtTask.Text;
767 | end;
768 | COL_DUE:
769 | begin
770 | if dtpDueDate.Date = NullDate then
771 | Task.Due := 0
772 | else
773 | Task.Due := dtpDueDate.Date;
774 | end;
775 | COL_CONTEXT:
776 | begin
777 | Task.Contexts.Text := mList.Lines.Text;
778 | end;
779 | COL_PROJECT:
780 | begin
781 | Task.Projects.Text := mList.Lines.Text;
782 | end;
783 | COL_LINK:
784 | begin
785 | end;
786 | end;
787 |
788 | TasktoGridRow(Task, ARow);
789 | ReloadFilters;
790 | gridTask.InvalidateRow(ARow);
791 |
792 |
793 | end;
794 |
795 | procedure TfrmOvoNote.TaskListChange(Sender: TObject);
796 | begin
797 | if dm.AutoSave then
798 | begin
799 | TimerAutoSave.Enabled:=false;
800 | TimerAutoSave.Enabled:=True;
801 | end;
802 | end;
803 |
804 | procedure TfrmOvoNote.FileOpen1Execute(Sender: TObject);
805 | begin
806 | LoadFile;
807 | end;
808 |
809 | procedure TfrmOvoNote.FileSaveAs1Execute(Sender: TObject);
810 | var
811 | TodoFile: TFileStream;
812 | Mode: Word;
813 | begin
814 | if FileExists(dm.FilePath+FILE_TODO) then
815 | begin
816 | CopyFile(dm.FilePath+FILE_TODO, ChangeFileExt(dm.FilePath+FILE_TODO,'.bak'));
817 | Mode := fmOpenReadWrite
818 | end
819 | else
820 | Mode:= fmOpenWrite+ fmCreate;
821 |
822 | CopyFile(dm.FilePath+FILE_TODO, ChangeFileExt(dm.FilePath+FILE_TODO,'.bak'));
823 |
824 | TodoFile := TFileStream.Create(dm.FilePath+FILE_TODO, Mode);
825 | TaskList.SaveToStream(TodoFile);
826 | TaskList.Modified:= false;
827 | TodoFile.Free;
828 | end;
829 |
830 | procedure TfrmOvoNote.FormResize(Sender: TObject);
831 | begin
832 | ResizeGrid;
833 | lbProjects.Height := pnlFilter.ClientHeight div 2;
834 | end;
835 |
836 |
837 | procedure TfrmOvoNote.ResizeGrid;
838 | var
839 | i, TotSize: integer;
840 | begin
841 | gridTask.AutoSizeColumns;
842 |
843 | gridTask.ColWidths[0]:= 15;
844 | gridTask.ColWidths[COL_DUE]:= dtpDueDate.Width;
845 | totSize := gridTask.ColWidths[0];
846 |
847 |
848 | for i := 1 to gridTask.Columns.Count do
849 | Inc(TotSize, gridTask.ColWidths[i]);
850 |
851 | if TotSize < gridTask.ClientWidth then
852 | gridTask.ColWidths[COL_TASK] := gridTask.ColWidths[COL_TASK] + (gridTask.ClientWidth - (TotSize + 10));
853 | end;
854 |
855 | procedure TfrmOvoNote.FormShow(Sender: TObject);
856 | begin
857 | LoadFile;
858 | ResizeGrid;
859 | pnlSearch.Align:=alRight;
860 |
861 | end;
862 |
863 | procedure TfrmOvoNote.gridTaskUserCheckboxImage(Sender: TObject; const aCol, aRow: Integer;
864 | const CheckedState: TCheckBoxState; var ImageList: TCustomImageList; var ImageIndex: TImageIndex);
865 | begin
866 | ImageList := dm.imglSmall;
867 |
868 | if aCol = COL_DELETE then
869 | begin
870 | ImageIndex := 1;
871 | end
872 | else
873 | if CheckedState = cbChecked then
874 | ImageIndex := 2
875 | else
876 | ImageIndex := 3;
877 |
878 | end;
879 |
880 | procedure TfrmOvoNote.lbProjectsSelectionChange(Sender: TObject; User: boolean);
881 | begin
882 | if user then
883 | LoadToGrid();
884 | end;
885 |
886 | procedure TfrmOvoNote.TimerAutoSaveTimer(Sender: TObject);
887 | begin
888 | TimerAutoSave.Enabled:=false;
889 | CheckAutoSave;
890 |
891 | end;
892 |
893 | procedure TfrmOvoNote.TrayIconDblClick(Sender: TObject);
894 | begin
895 | if Visible then
896 | Hide
897 | else
898 | begin
899 | Show;
900 | BringToFront;
901 | end;
902 | end;
903 |
904 | end.
905 |
--------------------------------------------------------------------------------
/images/archive_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/archive_d.png
--------------------------------------------------------------------------------
/images/checked_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/checked_d.png
--------------------------------------------------------------------------------
/images/delete_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/delete_d.png
--------------------------------------------------------------------------------
/images/document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/document.png
--------------------------------------------------------------------------------
/images/document_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/document_d.png
--------------------------------------------------------------------------------
/images/find.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/find.png
--------------------------------------------------------------------------------
/images/ovonote.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/ovonote.ico
--------------------------------------------------------------------------------
/images/ovonote.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/ovonote.xcf
--------------------------------------------------------------------------------
/images/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/plus.png
--------------------------------------------------------------------------------
/images/plus_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/plus_d.png
--------------------------------------------------------------------------------
/images/reload_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/reload_d.png
--------------------------------------------------------------------------------
/images/remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/remove.png
--------------------------------------------------------------------------------
/images/remove_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/remove_d.png
--------------------------------------------------------------------------------
/images/safe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/safe.png
--------------------------------------------------------------------------------
/images/safe_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/safe_d.png
--------------------------------------------------------------------------------
/images/save_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/save_d.png
--------------------------------------------------------------------------------
/images/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/settings.png
--------------------------------------------------------------------------------
/images/settings_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/settings_d.png
--------------------------------------------------------------------------------
/images/unchecked_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/unchecked_d.png
--------------------------------------------------------------------------------
/images/web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/web.png
--------------------------------------------------------------------------------
/images/web_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/images/web_d.png
--------------------------------------------------------------------------------
/language/ovonote.it.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | #: tfrmovonote.actadd.caption
5 | msgid "Add"
6 | msgstr "Aggiungi"
7 |
8 | #: tfrmovonote.actadd.hint
9 | msgid "Add a new task"
10 | msgstr "Aggiungi una nuova attività"
11 |
12 | #: tfrmovonote.actarchive.caption
13 | msgid "Archive"
14 | msgstr "Archivia"
15 |
16 | #: tfrmovonote.actarchive.hint
17 | msgid "Archive completed tasks"
18 | msgstr "Archivia attività completate"
19 |
20 | #: tfrmovonote.actdelete.caption
21 | msgctxt "tfrmovonote.actdelete.caption"
22 | msgid "Delete"
23 | msgstr "Elimina"
24 |
25 | #: tfrmovonote.actdelete.hint
26 | msgid "Delete task"
27 | msgstr "Elimina attività"
28 |
29 | #: tfrmovonote.actedit.caption
30 | msgid "Edit"
31 | msgstr "Modifica"
32 |
33 | #: tfrmovonote.actedit.hint
34 | #, fuzzy
35 | #| msgid "Edit task"
36 | msgid "Internal text editor"
37 | msgstr "Editor testuale attività"
38 |
39 | #: tfrmovonote.actsettings.caption
40 | msgctxt "tfrmovonote.actsettings.caption"
41 | msgid "Settings"
42 | msgstr "Impostazioni"
43 |
44 | #: tfrmovonote.actsettings.hint
45 | #, fuzzy
46 | msgctxt "tfrmovonote.actsettings.hint"
47 | msgid "Settings"
48 | msgstr "Impostazioni"
49 |
50 | #: tfrmovonote.actshowdone.caption
51 | msgid "Show Archived "
52 | msgstr "Mostra Archiviati"
53 |
54 | #: tfrmovonote.actshowdone.hint
55 | msgid "Show Archived Task"
56 | msgstr "Mostra attività archiviate"
57 |
58 | #: tfrmovonote.actterminate.caption
59 | msgid "Terminate"
60 | msgstr "Chiudi"
61 |
62 | #: tfrmovonote.actterminate.hint
63 | msgid "Close application"
64 | msgstr "Chiudi applicazione"
65 |
66 | #: tfrmovonote.caption
67 | msgid "OvoNote"
68 | msgstr ""
69 |
70 | #: tfrmovonote.cbexcludecompleted.caption
71 | msgid "Exclude completed"
72 | msgstr "Escludi completati"
73 |
74 | #: tfrmovonote.dtpduedate.textfornulldate
75 | msgid "NULL"
76 | msgstr "VUOTO"
77 |
78 | #: tfrmovonote.edtpriority.text
79 | msgid " "
80 | msgstr ""
81 |
82 | #: tfrmovonote.edttask.text
83 | #, fuzzy
84 | msgctxt "tfrmovonote.edttask.text"
85 | msgid "Task"
86 | msgstr "Attività"
87 |
88 | #: tfrmovonote.fileopen1.caption
89 | msgctxt "tfrmovonote.fileopen1.caption"
90 | msgid "Refresh"
91 | msgstr "Aggiorna"
92 |
93 | #: tfrmovonote.fileopen1.hint
94 | msgctxt "TFRMOVONOTE.FILEOPEN1.HINT"
95 | msgid "Reload file"
96 | msgstr "Aggiorna file"
97 |
98 | #: tfrmovonote.filesaveas1.caption
99 | msgctxt "tfrmovonote.filesaveas1.caption"
100 | msgid "Save"
101 | msgstr "Salva"
102 |
103 | #: tfrmovonote.filesaveas1.hint
104 | msgid "Save file"
105 | msgstr "Salva file"
106 |
107 | #: tfrmovonote.gridtask.columns[0].title.caption
108 | msgid "Done"
109 | msgstr "Fatto."
110 |
111 | #: tfrmovonote.gridtask.columns[1].title.caption
112 | msgid "Pr."
113 | msgstr "Pr."
114 |
115 | #: tfrmovonote.gridtask.columns[2].title.caption
116 | msgctxt "tfrmovonote.gridtask.columns[2].title.caption"
117 | msgid "Task"
118 | msgstr "Attività"
119 |
120 | #: tfrmovonote.gridtask.columns[3].title.caption
121 | msgid "Due"
122 | msgstr "Scadenza"
123 |
124 | #: tfrmovonote.gridtask.columns[4].title.caption
125 | msgid "Contexts"
126 | msgstr "Contesto"
127 |
128 | #: tfrmovonote.gridtask.columns[5].title.caption
129 | msgid "Projects"
130 | msgstr "Progetto"
131 |
132 | #: tfrmovonote.gridtask.columns[6].title.caption
133 | msgid "Link"
134 | msgstr "Link"
135 |
136 | #: tfrmovonote.gridtask.columns[7].title.caption
137 | #, fuzzy
138 | msgctxt "tfrmovonote.gridtask.columns[7].title.caption"
139 | msgid "Delete"
140 | msgstr "Elimina"
141 |
142 | #: tfrmovonote.toolbutton9.caption
143 | msgid "ToolButton9"
144 | msgstr ""
145 |
146 | #: udatamodule.all_element
147 | msgctxt "udatamodule.all_element"
148 | msgid ""
149 | msgstr ""
150 |
151 | #: udatamodule.rs_save
152 | msgid ""
153 | "Task list have been modified.\n"
154 | "Do you want to save changes?"
155 | msgstr ""
156 | "L'elenco attività è stato modificato.\n"
157 | "Vuoi salvare le modifiche?"
158 |
159 |
--------------------------------------------------------------------------------
/language/ovonote.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | #: fovonote.all_element
5 | msgctxt "fovonote.all_element"
6 | msgid ""
7 | msgstr ""
8 |
9 | #: tdm.menuitem1.caption
10 | msgctxt "TDM.MENUITEM1.CAPTION"
11 | msgid "Close"
12 | msgstr ""
13 |
14 | #: tform1.caption
15 | msgctxt "tform1.caption"
16 | msgid "Settings"
17 | msgstr ""
18 |
19 | #: tform1.label1.caption
20 | msgctxt "tform1.label1.caption"
21 | msgid "Path to files"
22 | msgstr ""
23 |
24 | #: tfrawedit.actfilesave.caption
25 | msgctxt "tfrawedit.actfilesave.caption"
26 | msgid "Save"
27 | msgstr ""
28 |
29 | #: tfrawedit.actrefresh.caption
30 | msgctxt "tfrawedit.actrefresh.caption"
31 | msgid "Refresh"
32 | msgstr ""
33 |
34 | #: tfrawedit.actrefresh.hint
35 | msgid "Refresh file content"
36 | msgstr ""
37 |
38 | #: tfrmovonote.actadd.caption
39 | msgid "Add"
40 | msgstr ""
41 |
42 | #: tfrmovonote.actadd.hint
43 | msgid "Add a new task"
44 | msgstr ""
45 |
46 | #: tfrmovonote.actarchive.caption
47 | msgid "Archive"
48 | msgstr ""
49 |
50 | #: tfrmovonote.actarchive.hint
51 | msgid "Archive completed tasks"
52 | msgstr ""
53 |
54 | #: tfrmovonote.actdelete.caption
55 | msgctxt "tfrmovonote.actdelete.caption"
56 | msgid "Delete"
57 | msgstr ""
58 |
59 | #: tfrmovonote.actdelete.hint
60 | msgid "Delete task"
61 | msgstr ""
62 |
63 | #: tfrmovonote.actedit.caption
64 | msgid "Edit"
65 | msgstr ""
66 |
67 | #: tfrmovonote.actedit.hint
68 | msgid "Internal text editor"
69 | msgstr ""
70 |
71 | #: tfrmovonote.actsettings.caption
72 | msgctxt "tfrmovonote.actsettings.caption"
73 | msgid "Settings"
74 | msgstr ""
75 |
76 | #: tfrmovonote.actsettings.hint
77 | msgctxt "TFRMOVONOTE.ACTSETTINGS.HINT"
78 | msgid "Settings"
79 | msgstr ""
80 |
81 | #: tfrmovonote.actshowdone.caption
82 | msgid "Show Archived "
83 | msgstr ""
84 |
85 | #: tfrmovonote.actterminate.caption
86 | msgid "actTerminate"
87 | msgstr ""
88 |
89 | #: tfrmovonote.actterminate.hint
90 | msgid "Close application"
91 | msgstr ""
92 |
93 | #: tfrmovonote.edtpriority.text
94 | msgid " "
95 | msgstr ""
96 |
97 | #: tfrmovonote.edttask.text
98 | msgid "edtTask"
99 | msgstr ""
100 |
101 | #: tfrmovonote.fileopen1.caption
102 | msgctxt "tfrmovonote.fileopen1.caption"
103 | msgid "Refresh"
104 | msgstr ""
105 |
106 | #: tfrmovonote.fileopen1.hint
107 | msgctxt "TFRMOVONOTE.FILEOPEN1.HINT"
108 | msgid "Reload file"
109 | msgstr ""
110 |
111 | #: tfrmovonote.filesaveas1.caption
112 | msgctxt "tfrmovonote.filesaveas1.caption"
113 | msgid "Save"
114 | msgstr ""
115 |
116 | #: tfrmovonote.filesaveas1.hint
117 | msgid "Save file"
118 | msgstr ""
119 |
120 | #: tfrmovonote.menuitem1.caption
121 | msgctxt "tfrmovonote.menuitem1.caption"
122 | msgid "Exit"
123 | msgstr ""
124 |
125 | #: tfrmovonote.toolbutton6.hint
126 | msgid "Edit as text"
127 | msgstr ""
128 |
129 | #: tfrmovonote.toolbutton9.caption
130 | msgid "ToolButton9"
131 | msgstr ""
132 |
133 | #: tfsettings.cbautosave.caption
134 | msgid "Auto-save changes"
135 | msgstr ""
136 |
137 | #: tfsettings.label1.caption
138 | msgctxt "TFSETTINGS.LABEL1.CAPTION"
139 | msgid "Path to files"
140 | msgstr ""
141 |
142 | #: udatamodule.all_element
143 | msgctxt "udatamodule.all_element"
144 | msgid ""
145 | msgstr ""
146 |
147 | #: udatamodule.rs_save
148 | msgid ""
149 | "Task list have been modified.\n"
150 | "Do you want to save changes?\n"
151 | msgstr ""
152 |
153 |
--------------------------------------------------------------------------------
/language/ovonote.pot:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | #: tfrmovonote.actadd.caption
5 | msgid "Add"
6 | msgstr ""
7 |
8 | #: tfrmovonote.actadd.hint
9 | msgid "Add a new task"
10 | msgstr ""
11 |
12 | #: tfrmovonote.actarchive.caption
13 | msgid "Archive"
14 | msgstr ""
15 |
16 | #: tfrmovonote.actarchive.hint
17 | msgid "Archive completed tasks"
18 | msgstr ""
19 |
20 | #: tfrmovonote.actdelete.caption
21 | msgctxt "tfrmovonote.actdelete.caption"
22 | msgid "Delete"
23 | msgstr ""
24 |
25 | #: tfrmovonote.actdelete.hint
26 | msgid "Delete task"
27 | msgstr ""
28 |
29 | #: tfrmovonote.actedit.caption
30 | msgid "Edit"
31 | msgstr ""
32 |
33 | #: tfrmovonote.actedit.hint
34 | msgid "Internal text editor"
35 | msgstr ""
36 |
37 | #: tfrmovonote.actsettings.caption
38 | msgctxt "tfrmovonote.actsettings.caption"
39 | msgid "Settings"
40 | msgstr ""
41 |
42 | #: tfrmovonote.actsettings.hint
43 | msgctxt "tfrmovonote.actsettings.hint"
44 | msgid "Settings"
45 | msgstr ""
46 |
47 | #: tfrmovonote.actshowdone.caption
48 | msgid "Show Archived "
49 | msgstr ""
50 |
51 | #: tfrmovonote.actshowdone.hint
52 | msgid "Show Archived Task"
53 | msgstr ""
54 |
55 | #: tfrmovonote.actterminate.caption
56 | msgid "Terminate"
57 | msgstr ""
58 |
59 | #: tfrmovonote.actterminate.hint
60 | msgid "Close application"
61 | msgstr ""
62 |
63 | #: tfrmovonote.caption
64 | msgid "OvoNote"
65 | msgstr ""
66 |
67 | #: tfrmovonote.cbexcludecompleted.caption
68 | msgid "Exclude completed"
69 | msgstr ""
70 |
71 | #: tfrmovonote.dtpduedate.textfornulldate
72 | msgid "NULL"
73 | msgstr ""
74 |
75 | #: tfrmovonote.edtpriority.text
76 | msgid " "
77 | msgstr ""
78 |
79 | #: tfrmovonote.edttask.text
80 | msgctxt "tfrmovonote.edttask.text"
81 | msgid "Task"
82 | msgstr ""
83 |
84 | #: tfrmovonote.fileopen1.caption
85 | msgid "Refresh"
86 | msgstr ""
87 |
88 | #: tfrmovonote.fileopen1.hint
89 | msgid "Reload file"
90 | msgstr ""
91 |
92 | #: tfrmovonote.filesaveas1.caption
93 | msgid "Save"
94 | msgstr ""
95 |
96 | #: tfrmovonote.filesaveas1.hint
97 | msgid "Save file"
98 | msgstr ""
99 |
100 | #: tfrmovonote.gridtask.columns[0].title.caption
101 | msgid "Done"
102 | msgstr ""
103 |
104 | #: tfrmovonote.gridtask.columns[1].title.caption
105 | msgid "Pr."
106 | msgstr ""
107 |
108 | #: tfrmovonote.gridtask.columns[2].title.caption
109 | msgctxt "tfrmovonote.gridtask.columns[2].title.caption"
110 | msgid "Task"
111 | msgstr ""
112 |
113 | #: tfrmovonote.gridtask.columns[3].title.caption
114 | msgid "Due"
115 | msgstr ""
116 |
117 | #: tfrmovonote.gridtask.columns[4].title.caption
118 | msgid "Contexts"
119 | msgstr ""
120 |
121 | #: tfrmovonote.gridtask.columns[5].title.caption
122 | msgid "Projects"
123 | msgstr ""
124 |
125 | #: tfrmovonote.gridtask.columns[6].title.caption
126 | msgid "Link"
127 | msgstr ""
128 |
129 | #: tfrmovonote.gridtask.columns[7].title.caption
130 | msgctxt "tfrmovonote.gridtask.columns[7].title.caption"
131 | msgid "Delete"
132 | msgstr ""
133 |
134 | #: tfrmovonote.toolbutton9.caption
135 | msgid "ToolButton9"
136 | msgstr ""
137 |
138 | #: udatamodule.all_element
139 | msgid ""
140 | msgstr ""
141 |
142 | #: udatamodule.rs_save
143 | msgid ""
144 | "Task list have been modified.\n"
145 | "Do you want to save changes?"
146 | msgstr ""
147 |
148 |
--------------------------------------------------------------------------------
/ovonote.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/ovonote.ico
--------------------------------------------------------------------------------
/ovonote.lpi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
--------------------------------------------------------------------------------
/ovonote.lpr:
--------------------------------------------------------------------------------
1 | { Ovonote - My implementation of Todo.txt concept
2 |
3 | Copyright (C) 2015 Marco Caselli
4 |
5 | This source is free software; you can redistribute it and/or modify it under
6 | the terms of the GNU General Public License as published by the Free
7 | Software Foundation; either version 2 of the License, or (at your option)
8 | any later version.
9 |
10 | This code is distributed in the hope that it will be useful, but WITHOUT ANY
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | details.
14 |
15 | A copy of the GNU General Public License is available on the World Wide Web
16 | at . You can also obtain it by writing
17 | to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 | MA 02111-1307, USA.
19 | }
20 |
21 | program ovonote;
22 |
23 | {$mode objfpc}{$H+}
24 |
25 | uses
26 | {$IFDEF UNIX} {$IFDEF UseCThreads}
27 | cthreads,
28 | {$ENDIF}{$ENDIF}
29 | Interfaces, // this includes the LCL widgetset
30 | Forms, fovonote, todo_parser,
31 | todotxtsyn_highlighter, uRawEdit,
32 | DefaultTranslator, datetimectrls, usettings, udatamodule;
33 |
34 | {$R *.res}
35 |
36 | begin
37 |
38 | RequireDerivedFormResource := True;
39 | Application.Initialize;
40 | Application.CreateForm(Tdm, dm);
41 | Application.CreateForm(TfrmOvoNote, frmOvoNote);
42 | Application.Run;
43 | end.
44 |
45 |
--------------------------------------------------------------------------------
/ovonote.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/ovonote.res
--------------------------------------------------------------------------------
/udatamodule.lfm:
--------------------------------------------------------------------------------
1 | object dm: Tdm
2 | OnCreate = DataModuleCreate
3 | OnDestroy = DataModuleDestroy
4 | OldCreateOrder = False
5 | Height = 289
6 | HorizontalOffset = 1572
7 | VerticalOffset = 227
8 | Width = 298
9 | object imglSmall: TImageList
10 | Height = 22
11 | Width = 22
12 | left = 48
13 | top = 112
14 | Bitmap = {
15 | 4C7A0400000016000000160000001C0200000000000078DAEDD5D18DC2300C00
16 | 5036E808374246600426401981FFFE300223940DEE9BAF8E901118A123F412E4
17 | 20D78D133BD0A3483DC93A893AAF89E3A46DDBEE5A1FB7DBED11C7E3B1F171F2
18 | E17C8C241C3C6B623E172DB8217CFEC1C740AC3EF18EBB8FBDC4F5799658079A
19 | 0B39F81D36E7C23C63EEA9B4469FD3A17CC3E43468ED4533613BE6795C7F2F35
20 | D17CEE303655B31ED70AF786C03EC1D80ED7159EC53A3515AEA1B5A0AEA606C4
21 | 9E8C5FCA45BF0FB80E4AD3707BEE7FFB2DF578C6BDC0D84BA6CFEE9A3993BE37
22 | CC7973B45F046E9FEB7B700D7A77979B37CC339A61CC4FE12EB3C80EFFCF787D
23 | F0EE33B9EF06F87DCFB968DEA97B7714DC9D1D67A3B91DA01E8E585D9C1BD9B7
24 | 31759EA9ABECDD3165D7BAA4476776AD59B25F3173B6FFDB7D6390B5853D0D77
25 | B5E4BE086767F031B9B7126E304788921DCD986F19179B259B9A131BB92993B3
26 | 39F36923D765F2B05D321FB9C86D84F620793FA9AFC496AC29D50FB5F6640F98
27 | FED5DAB39E615C8D3D33C39D937125FBAE75A5E6CC8EF76EC2D59A139B716BCD
28 | 998D5C23EC79A73C1783B086923EE9916B157B9EB3C3FC0CA9AF55DC93297B80
29 | 7AA6FAC12AEE756C3FCDCC79B38AEF50C8E9B189DD6F8BEBF53ABE233EE5D6AE
30 | 5332DF9ADA7139345F62D2F19C5BB253CFA46E693C972B71737DA21D5FB3E76B
31 | 7297A8C312FBB6449F2D712E963AC7FF71EFACF9FEDD62FDDFE44F7CE75F5DEB
32 | E66EEEE66EEE5ADCED7BFCDEF8031F53344D
33 | }
34 | end
35 | object imglEnabled: TImageList
36 | Height = 24
37 | Width = 24
38 | left = 48
39 | top = 40
40 | Bitmap = {
41 | 4C7A0A0000001800000018000000AE0500000000000078DAED9CCD91A43A0C80
42 | 5F6D028440088440087D9EC39443E03E1742200442E03C2712D82A42200487C0
43 | 832E9952BB25CB3636DBD3C341B5DB6EF864CB92FCDBB32CCB7FCB1BC8F7F7F7
44 | 2E1F1F1FFD2AD32A052EA7647DA65A45AFA27039C707F602E2D481D8E679E5E2
45 | 5B6CA70E82FDA0C3E6336C528783BDEB20F893E3F95D8707FBFE2CC12F3C7568
46 | 9F7A30F6F7D1B1F8D8D1E13FB13A1EFA48F0FF501D4F3EE6E207EA78627F7D7D
47 | F9F07DFC248A1FC07ED2B1B15DFC08F6830E17FF00FB4907115F9567EC4C31F1
48 | E51B979E7E35127C1590DF5C3AB67A568CFD55407EA674DCD9427E5001E30BD6
49 | B1B33DF2830A181F371D236653FC4B78D9E28DB06BB94AC7F8E10CE375CDF58B
50 | 1DBB567F750139E1A96F09BE86FC5041DD62728F72F08DFF1EC96DECFC2AE07D
51 | 0D766F910C56BDAA08FEF67E23C49902DB8E81FCCD7F4A298E916F6CED2B3DF9
52 | B34F8EF0F04F6FBFC8C08FD221C5EF517965FE6AAF9B148B47EB2FCD3712F09D
53 | F3089BBFC54500BB94E628047F80785202BBF1C98304BF44EF69D087F3581F92
54 | 5F3DE62631B2E778616E123B7F3663D424AC2D4A613D6CD7B9C573737B7E2BF8
55 | 490B63ACB6F2EA007DFDB0AEE0E6FFB9C461EB31401E722D6E83C3AE7F18F98B
56 | C4942D948E8CFC7D8F23237FF9A57C4A5E917F582E7E14FFCF01F96DFCBF1E72
57 | D5FFAA7F4EBE3E306F70CD23F4997B3491396C9BC775D2FAEB00BF827F6F39F8
58 | 30473573DC3223FF3E3FCFCC5F705F64E2EF7D9191AFEDFD99C47CEE7C2D8ACF
59 | ACEB9744FEEFB53EBDF861FCD83DA5ABFE57FDDFA1FE3F919FF36C8A13D84355
60 | B05766CFD5B633A69BEB7D812BED474EE8ECE561FF4D60DFCC3EAB755E3543BD
61 | 677CEE85F602B7F24A609BFDCF1EEDB956505E58CF2CD83EA82ECA51EFA77B00
62 | A0637B6F42654F7B6DC8AE93DD0EB4373C5BE50DD876FF0E3E3F9C0D122CBB8E
63 | BD5D86F825B2496BF5F15D3F63E716E95B38BBA177B873D48EF13F73DFA08167
64 | 4B07DB9C03527E3A50BE09F1A1D0BAA660B8E25D07AA6EE02F38866AF0B11BD1
65 | 8F92D44CBBF19AAC469F43CE973517BB56DB7BA87F17982B4747BFD967D57DC4
66 | 19C6C8B02B6EFF1BDAE57BDE62C75285626060ECA1AC18F3D1D1823D348AD906
67 | AD31F76799B60E21FD6DD631841FCD8E31A121CEDBA978E84C0E86776B7B1DE8
68 | 3146B86CF5940F887EE81CED90FABD61DE7D389362FA413AB7EA85B677F6F864
69 | E54197B49E63706D7C8D880FAE4FEB8879C40D8DDDEC1D1A17E3ECBBC9D2BC38
70 | 649E7D165F3A7F7FF5FA5F7CB97F8DE4E0E73C3FBAF8EFCF4FEDFF76EE4FC9A7
71 | C616576CA5E2FF14FB5077F4AFFC2CDFE1CB7CF6D56688DFF6ECFC63FCEAC8BD
72 | 49BCBF42F18FD639371F33CEE43BFC5D9BFD31EB6EA6A2E6ED817CFC9B9106AD
73 | C71BEEB724017C8DF6F734F73B11D03147D8BFB5D68A2DAC9B6A148F1AD92A94
74 | 5FA1355D4BE4A416EDC115A17CF8BF59DBD5C47766DF6E24BE4BC1AF8FF073DB
75 | C7D1BF654CFFE6F6CF7F105F49F3C34FCF9F67F153C83F585F649D9F9C753E98
76 | D2FE1C3F95FFFC267EC8BCFD55F9BE777F5EB1FE3FC97FAEF8BDE2F78ADF2B7E
77 | DFE5FE8F740FC8673FC3E75CCD65CB98EFDEED7E57CEDFFFA2BF5F91A4EEAFC2
78 | E7D6FDDCFF2FFEC5BFF8EFC9A7C62A5C76269F2B0FB54FCAFAA7CCCF8EBF4FA5
79 | 13F0F599675FAEBB419F9F9FD52ADD2A257C56AB2C20E3F67DCCFDE7F5BD02DE
80 | 37AC01CA7B54B6490DE5375387001DDA6251D2AED2A0CF4A6036C81693079F92
81 | 1BC36EE17B7D80BDBD5B10EC3A9267CB80FBD0F29329910EE317BDD58632111F
82 | 4B0975AFC1CFB9E766F0FD12444199C46F3CEC32337D56083A3A7846AA8372F8
83 | B3E2FA003D23DAD0C177F95D6FE2DA518F23FCBB78B423C63ED8576B2B9785F4
84 | AF94A306C12F6DFFAC4194C06EE039E3FFA9E3AAB2DA3A425BFA447CCDF945A2
85 | 3CC4E5D12339A8477D5247FA1B9B0B904FDD84314CA131A640E30E95838D4C81
86 | 636F69EC47C4E8FDF7C3962FF4D4FDAE005D03AA73097C93570AEEFED826FF03
87 | A91D898D
88 | }
89 | end
90 | object imglDisabled: TImageList
91 | Height = 24
92 | Width = 24
93 | left = 152
94 | top = 40
95 | Bitmap = {
96 | 4C7A0A0000001800000018000000840500000000000078DAED9CCD91AB300C80
97 | 33DB404AA0044AA0044AA004EE7BA1044AA004CE7B4A033B430994E01278E18D
98 | 9D1146B26463B3F9F1C1F3DE92F0C9C892FC239165592ECB1BB49F9F1FD8867B
99 | 9BEEED6A5DC75A796FEADE1A78DDC15FD98B6E9C0CC336DF6F183E6473326CF6
100 | 4606C2C7D8940C8AFD9081F027C7F7A10C8EFDFFBB08FF2A94A124FD20F42F91
101 | 21794697FD84CAD88C1163FFBE327636C6F07D64ECD8DFDFDF12BEC44E42F952
102 | F64EC6CA66F8BEEC8D0C861FCADEC940F8A5D077A640FF52421D4BECEA86F01B
103 | 0F1B71C958FB5912FA6F3CE2332643693DBBECA7F1985FA08C075BE0BF8DC7FC
104 | B87EE706D9183F37BAADFE86E8B5B8B79EB0C359CFD715352E88EFC2F1EA3D62
105 | C26E6C11BEB1AD52F72D24F6340EBEB1DF23B18D5C5F79DCAFB4DE3BD046AB5F
106 | 65007FBDBF65FCACD1BABD79F2276D4B17A12FAFCF5708F9B3304670F629B68B
107 | 04FC201902FF3DD49E9C5F73BE18A1FFCEF54604BE731D81F0070F76C1AD5110
108 | FEA8FD89B3C5561207117E01EE535A1E8C63834F7C15AC4D42DA23C6336B93D0
109 | F5B399A326666F5130FB61BBCF1D5C9BDBEB5BC64E3A1DD3951557473DD69B7D
110 | 05B5FE4F786EA21CEB0269DBC45AF80C0EBD7E11ED1734736DC16424E43FCE38
111 | 12F2970FE563ED19F9875BE607F1BF0EB44FE3FF0A5AEE7FEE7F4ABE3AB06E70
112 | AD23D4C9F9A3901836EBB316E7FEEB00BFD4FFD689F8F0ECA548C837EBF394FC
113 | 058E4522FE632C12F2957D3E13994FE5D742F9D8BE7E89C417ED4F33DF9B1F7A
114 | AE94FB9FFBFF0EFD7F397ECADC14D5F4D954A3CFCAECB5DA3AD7D6AEFB192E77
115 | 1E3981DCCBE6FC8D61D7E09C15E6AB4C6E65B6F25EE62C70BD5E326C73FE3980
116 | 33D7525FBF5ADF59A07E405F1A47BF7775005AC67ADF04AEEDCEDA805E27FB39
117 | C0D9F06C5D6FB56E1F9FE9BF37B9418465F771B0AF017E0174D25963FC5F3EA1
118 | E70EC85B28BD817BA83C6A4FD89FC97FB7FABB85836DF280989D8E986D6AFF68
119 | C0BEE64A70D95A07AC6FDA5EA00F55DAC66A641CB95611CF0DF76415F8DB27BF
120 | AC28DFB59E7DD0FDEF3D63E5CD316E76AE7A08C861DC0876499D7FEBE792E65B
121 | 6C5F2A810F8C843E1ACBC724323AAD0F057CB6057BCCC77789671D7DC6DBEC63
122 | 103B9A1D73428BE4DB317FE84D0CD6F756F63E503047B874B58B07C838F48EE7
123 | E0C6BD25EEDDE4A48871E0F25603F3ECBD3D3F5971D0D53AE11C5C195B43FC83
124 | 1AD32A601D5183B99BACA17131FEA036D9B92EF659679FC517E4DF9FBAFF99CF
125 | 8F2FF0A914FD4F963FCAFC8FE047B57F3BF6C7E463730BE35B51F8AFA21FAC46
126 | 3FC767BE862FF1FAA44BE0BFDD1FC49FC3B594F07C05E31FED736A3E649CCCA7
127 | ECDDBC5B67BF7FD110EB761F3E7C67A405FBF1D6F12E8994AFC0F99EA2DE13D1
128 | 32E600FD77D65EB1D3FBA60AF8A302BAF2E597604FD721B6DE8133B86B001FEE
129 | EB2BE4B302ECED2E09F8D5417E6AFD50E35B048E6F6AFB3CDBBF62C787578F9F
130 | 67F163B4B3D7FF49D72727E607A3E9DFC18F623F1FC6F759B73F2B5F5AFBF38C
131 | FD7F25FBC9FE9BFD37FB6FF6DFB7A8FFE1EA8024E71992BC1A6383DE9FBD61FD
132 | 58B2F77F013F56FF9F857FF1FC7FE6677EE6BF211F9BABAC6BA7F11D72BDF413
133 | B3FF31E3B3637E5711F8EACCDC17535F64EA110BA4B6F7C6D50B33F5CFB02E6A
134 | C4EABF4CED92AE732A3C6548C6A2B3EABEB81ADB16E822F477F26A478DAD19FF
135 | E980ED5C897AB418B63FC231B4EC648A24E386D5F1817C4ACC66F2071553776B
136 | EAE90B50CF2DF91DA856A0979918B32B23A3B7F232E46FFF08EAF9C99A5F890E
137 | 993A48B24ED3F83553931CCADFECCF22EB6753B7C9D478BAC6978B51A3B01EDC
138 | D8A7C99F72BF21D3825C5C99C0AF4AA48E7EF4F8CD19499C2B3CDE838815478F
139 | C4A0CDBB0A81F646C6026053B5E01D1E05729B9D23069335F18C8C02BC0F5461
140 | EF0F5BB63060F55D1EB246D0E702E4DFEDBCEAEEFE7F19031735
141 | }
142 | end
143 | end
144 |
--------------------------------------------------------------------------------
/udatamodule.lrt:
--------------------------------------------------------------------------------
1 | TDM.MENUITEM1.CAPTION=Close
2 |
--------------------------------------------------------------------------------
/udatamodule.pas:
--------------------------------------------------------------------------------
1 | { Ovonote - My implementation of Todo.txt concept
2 |
3 | Copyright (C) 2015 Marco Caselli
4 |
5 | This source is free software; you can redistribute it and/or modify it under
6 | the terms of the GNU General Public License as published by the Free
7 | Software Foundation; either version 2 of the License, or (at your option)
8 | any later version.
9 |
10 | This code is distributed in the hope that it will be useful, but WITHOUT ANY
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | details.
14 |
15 | A copy of the GNU General Public License is available on the World Wide Web
16 | at . You can also obtain it by writing
17 | to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 | MA 02111-1307, USA.
19 | }
20 | unit udatamodule;
21 |
22 | {$mode objfpc}{$H+}
23 |
24 | interface
25 |
26 | uses
27 | Classes, SysUtils, FileUtil, LazConfigStorage, XMLPropStorage, Controls;
28 |
29 | Const
30 | FILE_TODO = 'todo.txt';
31 | FILE_DONE = 'done.txt';
32 |
33 | mrModified = mrNone + 100;
34 |
35 | Resourcestring
36 | ALL_ELEMENT = '';
37 | RS_SAVE = 'Task list have been modified.'+sLineBreak+
38 | 'Do you want to save changes?';
39 |
40 |
41 |
42 | type
43 | { Tdm }
44 |
45 | Tdm = class(TDataModule)
46 | imglEnabled: TImageList;
47 | imglSmall: TImageList;
48 | imglDisabled: TImageList;
49 | procedure DataModuleCreate(Sender: TObject);
50 | procedure DataModuleDestroy(Sender: TObject);
51 | private
52 | Config: TXMLConfigStorage;
53 | function getAutoSave: boolean;
54 | function getfilePath: string;
55 | procedure setAutoSave(AValue: boolean);
56 | procedure setfilePath(AValue: string);
57 | public
58 | property FilePath: string read getfilePath write setfilePath;
59 | property AutoSave: boolean read getAutoSave write setAutoSave;
60 |
61 | procedure SaveConfig;
62 | end;
63 |
64 | var
65 | dm: Tdm;
66 |
67 | implementation
68 |
69 | {$R *.lfm}
70 |
71 | { Tdm }
72 |
73 | procedure Tdm.DataModuleCreate(Sender: TObject);
74 | begin
75 | Config := TXMLConfigStorage.Create('ovonote.cfg', FileExists('ovonote.cfg'));
76 | end;
77 |
78 | procedure Tdm.DataModuleDestroy(Sender: TObject);
79 | begin
80 | Config.free;
81 | end;
82 |
83 | function Tdm.getfilePath: string;
84 | begin
85 | result := IncludeTrailingPathDelimiter(ExpandFileName(Config.GetValue('Files/Path','.')));
86 | end;
87 |
88 | function Tdm.getAutoSave: boolean;
89 | begin
90 | result := Config.GetValue('Files/AutoSave', false);
91 | end;
92 |
93 | procedure Tdm.setAutoSave(AValue: boolean);
94 | begin
95 | Config.SetValue('Files/AutoSave',aValue);
96 | end;
97 |
98 | procedure Tdm.setfilePath(AValue: string);
99 | begin
100 | Config.SetValue('Files/Path',aValue);
101 | end;
102 |
103 | procedure Tdm.SaveConfig;
104 | begin
105 | Config.WriteToDisk;
106 | end;
107 |
108 | end.
109 |
110 |
--------------------------------------------------------------------------------
/uniqueinstance/registeruniqueinstance.pas:
--------------------------------------------------------------------------------
1 | unit registeruniqueinstance;
2 |
3 | {$Mode ObjFpc}
4 | {$H+}
5 |
6 | interface
7 |
8 | uses
9 | Classes, SysUtils, LResources, LazarusPackageIntf,uniqueinstance;
10 |
11 | procedure Register;
12 |
13 | implementation
14 |
15 | procedure RegisterUnitUniqueInstance;
16 | begin
17 | RegisterComponents('System',[TUniqueInstance]);
18 | end;
19 |
20 | procedure Register;
21 |
22 | begin
23 | RegisterUnit('uniqueinstance',@RegisterUnitUniqueInstance);
24 | end;
25 |
26 | initialization
27 | {$i uniqueicon.lrs}
28 |
29 | end.
30 |
--------------------------------------------------------------------------------
/uniqueinstance/testcomponent/fmain.lfm:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 464
3 | Height = 280
4 | Top = 339
5 | Width = 340
6 | HorzScrollBar.Page = 339
7 | VertScrollBar.Page = 279
8 | ActiveControl = ListBox1
9 | BorderStyle = bsDialog
10 | Caption = 'Test UniqueInstance'
11 | ClientHeight = 280
12 | ClientWidth = 340
13 | Position = poScreenCenter
14 | LCLVersion = '1.3'
15 | object Label1: TLabel
16 | Left = 8
17 | Height = 15
18 | Top = 8
19 | Width = 145
20 | Caption = 'Waiting for new instances...'
21 | ParentColor = False
22 | end
23 | object ListBox1: TListBox
24 | Left = 8
25 | Height = 216
26 | Top = 24
27 | Width = 320
28 | ItemHeight = 0
29 | TabOrder = 0
30 | end
31 | object ButCrashApp: TButton
32 | Left = 8
33 | Height = 25
34 | Top = 248
35 | Width = 136
36 | BorderSpacing.InnerBorder = 4
37 | Caption = 'Crash Application'
38 | OnClick = ButCrashAppClick
39 | TabOrder = 1
40 | end
41 | object UniqueInstance1: TUniqueInstance
42 | Enabled = True
43 | Identifier = 'test0.1'
44 | UpdateInterval = 800
45 | OnOtherInstance = UniqueInstance1OtherInstance
46 | left = 152
47 | top = 104
48 | end
49 | end
50 |
--------------------------------------------------------------------------------
/uniqueinstance/testcomponent/fmain.pas:
--------------------------------------------------------------------------------
1 | unit fMain;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | interface
6 |
7 | uses
8 | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
9 | UniqueInstance, StdCtrls, ExtCtrls;
10 |
11 | type
12 |
13 | { TForm1 }
14 |
15 | TForm1 = class(TForm)
16 | ButCrashApp: TButton;
17 | Label1: TLabel;
18 | ListBox1: TListBox;
19 | UniqueInstance1: TUniqueInstance;
20 | procedure ButCrashAppClick(Sender: TObject);
21 | procedure UniqueInstance1OtherInstance(Sender: TObject; Count: Integer;
22 | Parameters: array of String);
23 | private
24 | { private declarations }
25 | public
26 | { public declarations }
27 | end;
28 |
29 | var
30 | Form1: TForm1;
31 |
32 | implementation
33 |
34 | {$ifdef unix}
35 | uses
36 | BaseUnix;
37 | {$endif}
38 |
39 | {$ifdef windows}
40 | uses
41 | Windows;
42 | {$endif}
43 |
44 | {$R *.lfm}
45 |
46 | { TForm1 }
47 |
48 | procedure TForm1.UniqueInstance1OtherInstance(Sender: TObject; Count: Integer;
49 | Parameters: array of String);
50 | var
51 | i:Integer;
52 | begin
53 | Label1.Caption:=Format('A new instance was created with %d parameter(s):', [Count]);
54 | ListBox1.Clear;
55 | for i := 0 to Count - 1 do
56 | ListBox1.Items.Add(Parameters[i]);
57 | BringToFront;
58 | //hack to force app bring to front
59 | FormStyle := fsSystemStayOnTop;
60 | FormStyle := fsNormal;
61 | end;
62 |
63 | procedure TForm1.ButCrashAppClick(Sender: TObject);
64 | begin
65 | {$ifdef unix}
66 | FpKill(FpGetpid, 9);
67 | {$endif}
68 | {$ifdef windows}
69 | TerminateProcess(GetCurrentProcess, 0);
70 | {$endif}
71 | end;
72 |
73 | end.
74 |
75 |
--------------------------------------------------------------------------------
/uniqueinstance/testcomponent/testinstance.lpi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/uniqueinstance/testcomponent/testinstance.lpr:
--------------------------------------------------------------------------------
1 | program testinstance;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | uses
6 | {$IFDEF UNIX}{$IFDEF UseCThreads}
7 | cthreads,
8 | {$ENDIF}{$ENDIF}
9 | Interfaces, // this includes the LCL widgetset
10 | Forms
11 | { add your units here }, fMain;
12 |
13 | {$R *.res}
14 |
15 | begin
16 | Application.Initialize;
17 | Application.CreateForm(TForm1, Form1);
18 | Application.Run;
19 | end.
20 |
--------------------------------------------------------------------------------
/uniqueinstance/testraw/project1.lpi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/uniqueinstance/testraw/project1.lpr:
--------------------------------------------------------------------------------
1 | program project1;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | uses
6 | {$IFDEF UNIX}{$IFDEF UseCThreads}
7 | cthreads,
8 | {$ENDIF}{$ENDIF}
9 | Interfaces, // this includes the LCL widgetset
10 | Forms
11 | { add your units here }, Unit1, UniqueInstanceRaw;
12 |
13 | begin
14 | if not InstanceRunning('project1ver3') then
15 | begin
16 | Application.Initialize;
17 | Application.CreateForm(TForm1, Form1);
18 | Application.Run;
19 | end;
20 | end.
21 |
--------------------------------------------------------------------------------
/uniqueinstance/testraw/unit1.lfm:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 344
3 | Height = 136
4 | Top = 152
5 | Width = 295
6 | HorzScrollBar.Page = 294
7 | VertScrollBar.Page = 135
8 | Caption = 'Test UniqueInstanceRaw'
9 | ClientHeight = 136
10 | ClientWidth = 295
11 | LCLVersion = '0.9.31'
12 | object ButCrashApp: TButton
13 | Left = 64
14 | Height = 32
15 | Top = 48
16 | Width = 158
17 | BorderSpacing.InnerBorder = 4
18 | Caption = 'Crash Application'
19 | OnClick = ButCrashAppClick
20 | TabOrder = 0
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/uniqueinstance/testraw/unit1.pas:
--------------------------------------------------------------------------------
1 | unit Unit1;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | interface
6 |
7 | uses
8 | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls;
9 |
10 | type
11 |
12 | { TForm1 }
13 |
14 | TForm1 = class(TForm)
15 | ButCrashApp: TButton;
16 | procedure ButCrashAppClick(Sender: TObject);
17 | private
18 | { private declarations }
19 | public
20 | { public declarations }
21 | end;
22 |
23 | var
24 | Form1: TForm1;
25 |
26 | implementation
27 |
28 | {$R *.lfm}
29 |
30 | {$ifdef unix}
31 | uses
32 | BaseUnix;
33 | {$endif}
34 |
35 | {$ifdef windows}
36 | uses
37 | Windows;
38 | {$endif}
39 |
40 | { TForm1 }
41 |
42 | procedure TForm1.ButCrashAppClick(Sender: TObject);
43 | begin
44 | {$ifdef unix}
45 | FpKill(FpGetpid, 9);
46 | {$endif}
47 | {$ifdef windows}
48 | TerminateProcess(GetCurrentProcess, 0);
49 | {$endif}
50 | end;
51 |
52 | initialization
53 |
54 | end.
55 |
56 |
--------------------------------------------------------------------------------
/uniqueinstance/tuniqueinstance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/varianus/ovonote/3e9bffadb5053027c921da512197f36ff0fc4d95/uniqueinstance/tuniqueinstance.png
--------------------------------------------------------------------------------
/uniqueinstance/uniqueicon.lrs:
--------------------------------------------------------------------------------
1 | LazarusResources.Add('tuniqueinstance','PNG',[
2 | #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
3 | +#0#0#9'pHYs'#0#0#14#195#0#0#14#195#1#199'o'#168'd'#0#0#1'6IDATH'#137#157#148
4 | +'1'#18#132' '#12'E'#131'C'#165#167#176#183#247'T'#244#30'a{'#251'='#202#246
5 | +#158#194'S'#172'-['#184'q'#146#240#131#236'f'#134#17#16#255#251#137'@'#160
6 | +#198#200#203#146#233#253#190#198'a]C'#203'w'#213'E9'#165#172'&'#4#128#134#161
7 | +#9#6'_('#183'R'#212#1'p'#31#129#138#137#203#245#31#0#26#134#2#162#6'J'#252'O'
8 | +#128#133't'#151#248#178'`q'#219'^/'#214#203#127#23#149';$.'#157'o'#27#206
9 | +#132#199#178'/KT'#148#198#194'X'#152'c'#154#220#242#200#22#214'5'#224#12'l'
10 | +#221#199#241#236#239#187#206#128#29'3'#196#184'''"'#138#246#0#221#2#29'!'#149
11 | +#205'7rJ9'#226#149' Zv'#19#136#8#235#142'\'#203'8'#14#162#190#247#13'('#192
12 | +#157'kn'#199'QBd8'#153#212#1#181#244#251'^'#239#26'''bU'#196'+'#147'-'#15#155
13 | +#1#173#11#143'G'#211#181'[\'#13'7'#206#137#200#156#131#154#160#247#206#30'2'
14 | +#4#225'NN)7'#159'd'#142'irOrx>'#3#145#247#147#173#155'y>'#159'v'#255'K'#231
15 | +'N'#22#229'u'#237']x'#8'`a'#223'>'#187'/'#0'.'#164#5#0#196'!@A~'#4'Xq'#23#0
16 | +'A'#21#0#18'n'#2#212'`5Q'#25#31'('#18#253#217#188'R'#195'&'#0#0#0#0'IEND'#174
17 | +'B`'#130
18 | ]);
19 |
--------------------------------------------------------------------------------
/uniqueinstance/uniqueinstance.pas:
--------------------------------------------------------------------------------
1 | unit UniqueInstance;
2 |
3 | {
4 | UniqueInstance is a component to allow only a instance by program
5 |
6 | Copyright (C) 2006 Luiz Americo Pereira Camara
7 | pascalive@bol.com.br
8 |
9 | This library is free software; you can redistribute it and/or modify it
10 | under the terms of the GNU Library General Public License as published by
11 | the Free Software Foundation; either version 2 of the License, or (at your
12 | option) any later version with the following modification:
13 |
14 | As a special exception, the copyright holders of this library give you
15 | permission to link this library with independent modules to produce an
16 | executable, regardless of the license terms of these independent modules,and
17 | to copy and distribute the resulting executable under terms of your choice,
18 | provided that you also meet, for each linked independent module, the terms
19 | and conditions of the license of that module. An independent module is a
20 | module which is not derived from or based on this library. If you modify
21 | this library, you may extend this exception to your version of the library,
22 | but you are not obligated to do so. If you do not wish to do so, delete this
23 | exception statement from your version.
24 |
25 | This program is distributed in the hope that it will be useful, but WITHOUT
26 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
28 | for more details.
29 |
30 | You should have received a copy of the GNU Library General Public License
31 | along with this library; if not, write to the Free Software Foundation,
32 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 | }
34 |
35 |
36 | {$mode objfpc}{$H+}
37 |
38 | interface
39 |
40 | uses
41 | Forms, Classes, SysUtils, simpleipc, ExtCtrls;
42 |
43 | type
44 |
45 | TOnOtherInstance = procedure (Sender : TObject; ParamCount: Integer; Parameters: array of String) of object;
46 |
47 | { TUniqueInstance }
48 |
49 | TUniqueInstance = class(TComponent)
50 | private
51 | FIdentifier: String;
52 | FOnOtherInstance: TOnOtherInstance;
53 | FUpdateInterval: Cardinal;
54 | FEnabled: Boolean;
55 | FPriorInstanceRunning: Boolean;
56 | procedure ReceiveMessage(Sender: TObject);
57 | {$ifdef unix}
58 | procedure CheckMessage(Sender: TObject);
59 | {$endif}
60 | protected
61 | procedure Loaded; override;
62 | public
63 | constructor Create(AOwner: TComponent); override;
64 | property PriorInstanceRunning: Boolean read FPriorInstanceRunning;
65 | published
66 | property Enabled: Boolean read FEnabled write FEnabled default False;
67 | property Identifier: String read FIdentifier write FIdentifier;
68 | property UpdateInterval: Cardinal read FUpdateInterval write FUpdateInterval default 1000;
69 | property OnOtherInstance: TOnOtherInstance read FOnOtherInstance write FOnOtherInstance;
70 | end;
71 |
72 | implementation
73 |
74 | uses
75 | StrUtils, UniqueInstanceBase;
76 |
77 | { TUniqueInstance }
78 |
79 | procedure TUniqueInstance.ReceiveMessage(Sender: TObject);
80 | var
81 | ParamsArray: array of String;
82 | Count: Integer;
83 |
84 | procedure FillParamsArray(const ParamsStr: String);
85 | var
86 | pos1, pos2, i: Integer;
87 | begin
88 | SetLength(ParamsArray, Count);
89 | //fill params
90 | i := 0;
91 | pos1 := 1;
92 | pos2 := pos(ParamsSeparator, ParamsStr);
93 | while pos1 < pos2 do
94 | begin
95 | ParamsArray[i] := Copy(ParamsStr, pos1, pos2 - pos1);
96 | pos1 := pos2+1;
97 | pos2 := posex(ParamsSeparator, ParamsStr, pos1);
98 | inc(i);
99 | end;
100 | end;
101 |
102 | begin
103 | if Assigned(FOnOtherInstance) then
104 | begin
105 | //MsgType stores ParamCount
106 | Count := FIPCServer.MsgType;
107 | FillParamsArray(FIPCServer.StringMessage);
108 | FOnOtherInstance(Self, Count, ParamsArray);
109 | end;
110 | end;
111 |
112 | {$ifdef unix}
113 | procedure TUniqueInstance.CheckMessage(Sender: TObject);
114 | begin
115 | FIPCServer.PeekMessage(1, True);
116 | end;
117 | {$endif}
118 |
119 | procedure TUniqueInstance.Loaded;
120 | var
121 | IPCClient: TSimpleIPCClient;
122 | {$ifdef unix}
123 | Timer: TTimer;
124 | {$endif}
125 | begin
126 | if not (csDesigning in ComponentState) and FEnabled then
127 | begin
128 | IPCClient := TSimpleIPCClient.Create(Self);
129 | IPCClient.ServerId := GetServerId(FIdentifier);
130 | if IPCClient.ServerRunning then
131 | begin
132 | //A older instance is running.
133 | FPriorInstanceRunning := True;
134 | //A instance is already running
135 | //Send a message and then exit
136 | if Assigned(FOnOtherInstance) then
137 | begin
138 | IPCClient.Active := True;
139 | IPCClient.SendStringMessage(ParamCount, GetFormattedParams);
140 | end;
141 | Application.ShowMainForm := False;
142 | Application.Terminate;
143 | end
144 | else
145 | begin
146 | InitializeUniqueServer(IPCClient.ServerID);
147 | FIPCServer.OnMessage := @ReceiveMessage;
148 | //there's no more need for IPCClient
149 | IPCClient.Destroy;
150 | {$ifdef unix}
151 | if Assigned(FOnOtherInstance) then
152 | begin
153 | Timer := TTimer.Create(Self);
154 | Timer.Interval := FUpdateInterval;
155 | Timer.OnTimer := @CheckMessage;
156 | end;
157 | {$endif}
158 | end;
159 | end;//if
160 | inherited;
161 | end;
162 |
163 | constructor TUniqueInstance.Create(AOwner: TComponent);
164 | begin
165 | inherited Create(AOwner);
166 | FUpdateInterval := 1000;
167 | end;
168 |
169 | end.
170 |
171 |
--------------------------------------------------------------------------------
/uniqueinstance/uniqueinstance_package.lpk:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/uniqueinstance/uniqueinstance_package.pas:
--------------------------------------------------------------------------------
1 | { This file was automatically created by Lazarus. Do not edit!
2 | This source is only used to compile and install the package.
3 | }
4 |
5 | unit uniqueinstance_package;
6 |
7 | interface
8 |
9 | uses
10 | UniqueInstance, UniqueInstanceRaw, registeruniqueinstance,
11 | UniqueInstanceBase, LazarusPackageIntf;
12 |
13 | implementation
14 |
15 | procedure Register;
16 | begin
17 | RegisterUnit('registeruniqueinstance', @registeruniqueinstance.Register);
18 | end;
19 |
20 | initialization
21 | RegisterPackage('uniqueinstance_package', @Register);
22 | end.
23 |
--------------------------------------------------------------------------------
/uniqueinstance/uniqueinstancebase.pas:
--------------------------------------------------------------------------------
1 | unit UniqueInstanceBase;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | interface
6 |
7 | uses
8 | Classes, SysUtils, simpleipc;
9 |
10 | const
11 | ParamsSeparator = '|';
12 |
13 | var
14 | FIPCServer: TSimpleIPCServer;
15 |
16 | procedure InitializeUniqueServer(const ServerId: String);
17 |
18 | function GetFormattedParams: String;
19 |
20 | function GetServerId(const Identifier: String): String;
21 |
22 | implementation
23 |
24 | const
25 | BaseServerId = 'tuniqueinstance_';
26 |
27 | procedure InitializeUniqueServer(const ServerId: String);
28 | begin
29 | //It's the first instance. Init the server
30 | if FIPCServer = nil then
31 | begin
32 | FIPCServer := TSimpleIPCServer.Create(nil);
33 | FIPCServer.ServerID := ServerId;
34 | FIPCServer.Global := True;
35 | FIPCServer.StartServer;
36 | end;
37 | end;
38 |
39 | function GetFormattedParams: String;
40 | var
41 | i: Integer;
42 | begin
43 | Result := '';
44 | for i := 1 to ParamCount do
45 | Result := Result + ParamStr(i) + ParamsSeparator;
46 | end;
47 |
48 | function GetServerId(const Identifier: String): String;
49 | begin
50 | if Identifier <> '' then
51 | Result := BaseServerId + Identifier
52 | else
53 | Result := BaseServerId + ExtractFileName(ParamStr(0));
54 | end;
55 |
56 | finalization
57 | FIPCServer.Free;
58 |
59 | end.
60 |
61 |
--------------------------------------------------------------------------------
/uniqueinstance/uniqueinstanceraw.pas:
--------------------------------------------------------------------------------
1 | unit UniqueInstanceRaw;
2 |
3 | {
4 | UniqueInstance is a component to allow only a instance by program
5 |
6 | Copyright (C) 2006 Luiz Americo Pereira Camara
7 | pascalive@bol.com.br
8 |
9 | This library is free software; you can redistribute it and/or modify it
10 | under the terms of the GNU Library General Public License as published by
11 | the Free Software Foundation; either version 2 of the License, or (at your
12 | option) any later version with the following modification:
13 |
14 | As a special exception, the copyright holders of this library give you
15 | permission to link this library with independent modules to produce an
16 | executable, regardless of the license terms of these independent modules,and
17 | to copy and distribute the resulting executable under terms of your choice,
18 | provided that you also meet, for each linked independent module, the terms
19 | and conditions of the license of that module. An independent module is a
20 | module which is not derived from or based on this library. If you modify
21 | this library, you may extend this exception to your version of the library,
22 | but you are not obligated to do so. If you do not wish to do so, delete this
23 | exception statement from your version.
24 |
25 | This program is distributed in the hope that it will be useful, but WITHOUT
26 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
28 | for more details.
29 |
30 | You should have received a copy of the GNU Library General Public License
31 | along with this library; if not, write to the Free Software Foundation,
32 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 | }
34 |
35 | {$mode objfpc}{$H+}
36 |
37 | interface
38 |
39 | uses
40 | Classes, SysUtils;
41 |
42 | function InstanceRunning(const Identifier: String; SendParameters: Boolean = False; DoInitServer: Boolean = True): Boolean;
43 |
44 | function InstanceRunning: Boolean;
45 |
46 | implementation
47 |
48 | uses
49 | SimpleIpc, UniqueInstanceBase;
50 |
51 | function InstanceRunning(const Identifier: String; SendParameters: Boolean; DoInitServer: Boolean): Boolean;
52 |
53 | var
54 | Client: TSimpleIPCClient;
55 |
56 | begin
57 | Client := TSimpleIPCClient.Create(nil);
58 | with Client do
59 | try
60 | ServerId := GetServerId(Identifier);
61 | Result := Client.ServerRunning;
62 | if not Result then
63 | begin
64 | if DoInitServer then
65 | InitializeUniqueServer(ServerID);
66 | end
67 | else
68 | // an instance already exists
69 | if SendParameters then
70 | begin
71 | Active := True;
72 | SendStringMessage(ParamCount, GetFormattedParams);
73 | end;
74 | finally
75 | Free;
76 | end;
77 | end;
78 |
79 | function InstanceRunning: Boolean;
80 | begin
81 | Result := InstanceRunning('');
82 | end;
83 |
84 | end.
85 |
86 |
--------------------------------------------------------------------------------
/urawedit.lfm:
--------------------------------------------------------------------------------
1 | object fRawEdit: TfRawEdit
2 | Left = 684
3 | Height = 691
4 | Top = 175
5 | Width = 842
6 | Caption = 'todo.txt'
7 | ClientHeight = 691
8 | ClientWidth = 842
9 | OnCloseQuery = FormCloseQuery
10 | LCLVersion = '1.7'
11 | Visible = False
12 | object ToolBar1: TToolBar
13 | Left = 0
14 | Height = 34
15 | Top = 0
16 | Width = 842
17 | AutoSize = True
18 | ButtonHeight = 32
19 | ButtonWidth = 33
20 | DisabledImages = dm.imglDisabled
21 | Images = dm.imglEnabled
22 | TabOrder = 0
23 | object ToolButton4: TToolButton
24 | Left = 1
25 | Height = 32
26 | Top = 2
27 | Width = 5
28 | Style = tbsDivider
29 | end
30 | object ToolButton1: TToolButton
31 | Left = 6
32 | Top = 2
33 | Action = actRefresh
34 | end
35 | object ToolButton2: TToolButton
36 | Left = 39
37 | Top = 2
38 | Action = actFileSave
39 | end
40 | end
41 | inline Editor: TSynEdit
42 | Left = 0
43 | Height = 657
44 | Top = 34
45 | Width = 842
46 | Align = alClient
47 | Font.Height = -13
48 | Font.Name = 'Courier New'
49 | Font.Pitch = fpFixed
50 | Font.Quality = fqCleartypeNatural
51 | ParentColor = False
52 | ParentFont = False
53 | TabOrder = 1
54 | Gutter.Width = 57
55 | Gutter.MouseActions = <>
56 | RightGutter.Width = 0
57 | RightGutter.MouseActions = <>
58 | Keystrokes = <
59 | item
60 | Command = ecUp
61 | ShortCut = 38
62 | end
63 | item
64 | Command = ecSelUp
65 | ShortCut = 8230
66 | end
67 | item
68 | Command = ecScrollUp
69 | ShortCut = 16422
70 | end
71 | item
72 | Command = ecDown
73 | ShortCut = 40
74 | end
75 | item
76 | Command = ecSelDown
77 | ShortCut = 8232
78 | end
79 | item
80 | Command = ecScrollDown
81 | ShortCut = 16424
82 | end
83 | item
84 | Command = ecLeft
85 | ShortCut = 37
86 | end
87 | item
88 | Command = ecSelLeft
89 | ShortCut = 8229
90 | end
91 | item
92 | Command = ecWordLeft
93 | ShortCut = 16421
94 | end
95 | item
96 | Command = ecSelWordLeft
97 | ShortCut = 24613
98 | end
99 | item
100 | Command = ecRight
101 | ShortCut = 39
102 | end
103 | item
104 | Command = ecSelRight
105 | ShortCut = 8231
106 | end
107 | item
108 | Command = ecWordRight
109 | ShortCut = 16423
110 | end
111 | item
112 | Command = ecSelWordRight
113 | ShortCut = 24615
114 | end
115 | item
116 | Command = ecPageDown
117 | ShortCut = 34
118 | end
119 | item
120 | Command = ecSelPageDown
121 | ShortCut = 8226
122 | end
123 | item
124 | Command = ecPageBottom
125 | ShortCut = 16418
126 | end
127 | item
128 | Command = ecSelPageBottom
129 | ShortCut = 24610
130 | end
131 | item
132 | Command = ecPageUp
133 | ShortCut = 33
134 | end
135 | item
136 | Command = ecSelPageUp
137 | ShortCut = 8225
138 | end
139 | item
140 | Command = ecPageTop
141 | ShortCut = 16417
142 | end
143 | item
144 | Command = ecSelPageTop
145 | ShortCut = 24609
146 | end
147 | item
148 | Command = ecLineStart
149 | ShortCut = 36
150 | end
151 | item
152 | Command = ecSelLineStart
153 | ShortCut = 8228
154 | end
155 | item
156 | Command = ecEditorTop
157 | ShortCut = 16420
158 | end
159 | item
160 | Command = ecSelEditorTop
161 | ShortCut = 24612
162 | end
163 | item
164 | Command = ecLineEnd
165 | ShortCut = 35
166 | end
167 | item
168 | Command = ecSelLineEnd
169 | ShortCut = 8227
170 | end
171 | item
172 | Command = ecEditorBottom
173 | ShortCut = 16419
174 | end
175 | item
176 | Command = ecSelEditorBottom
177 | ShortCut = 24611
178 | end
179 | item
180 | Command = ecToggleMode
181 | ShortCut = 45
182 | end
183 | item
184 | Command = ecCopy
185 | ShortCut = 16429
186 | end
187 | item
188 | Command = ecPaste
189 | ShortCut = 8237
190 | end
191 | item
192 | Command = ecDeleteChar
193 | ShortCut = 46
194 | end
195 | item
196 | Command = ecCut
197 | ShortCut = 8238
198 | end
199 | item
200 | Command = ecDeleteLastChar
201 | ShortCut = 8
202 | end
203 | item
204 | Command = ecDeleteLastChar
205 | ShortCut = 8200
206 | end
207 | item
208 | Command = ecDeleteLastWord
209 | ShortCut = 16392
210 | end
211 | item
212 | Command = ecUndo
213 | ShortCut = 32776
214 | end
215 | item
216 | Command = ecRedo
217 | ShortCut = 40968
218 | end
219 | item
220 | Command = ecLineBreak
221 | ShortCut = 13
222 | end
223 | item
224 | Command = ecSelectAll
225 | ShortCut = 16449
226 | end
227 | item
228 | Command = ecCopy
229 | ShortCut = 16451
230 | end
231 | item
232 | Command = ecBlockIndent
233 | ShortCut = 24649
234 | end
235 | item
236 | Command = ecLineBreak
237 | ShortCut = 16461
238 | end
239 | item
240 | Command = ecInsertLine
241 | ShortCut = 16462
242 | end
243 | item
244 | Command = ecDeleteWord
245 | ShortCut = 16468
246 | end
247 | item
248 | Command = ecBlockUnindent
249 | ShortCut = 24661
250 | end
251 | item
252 | Command = ecPaste
253 | ShortCut = 16470
254 | end
255 | item
256 | Command = ecCut
257 | ShortCut = 16472
258 | end
259 | item
260 | Command = ecDeleteLine
261 | ShortCut = 16473
262 | end
263 | item
264 | Command = ecDeleteEOL
265 | ShortCut = 24665
266 | end
267 | item
268 | Command = ecUndo
269 | ShortCut = 16474
270 | end
271 | item
272 | Command = ecRedo
273 | ShortCut = 24666
274 | end
275 | item
276 | Command = ecGotoMarker0
277 | ShortCut = 16432
278 | end
279 | item
280 | Command = ecGotoMarker1
281 | ShortCut = 16433
282 | end
283 | item
284 | Command = ecGotoMarker2
285 | ShortCut = 16434
286 | end
287 | item
288 | Command = ecGotoMarker3
289 | ShortCut = 16435
290 | end
291 | item
292 | Command = ecGotoMarker4
293 | ShortCut = 16436
294 | end
295 | item
296 | Command = ecGotoMarker5
297 | ShortCut = 16437
298 | end
299 | item
300 | Command = ecGotoMarker6
301 | ShortCut = 16438
302 | end
303 | item
304 | Command = ecGotoMarker7
305 | ShortCut = 16439
306 | end
307 | item
308 | Command = ecGotoMarker8
309 | ShortCut = 16440
310 | end
311 | item
312 | Command = ecGotoMarker9
313 | ShortCut = 16441
314 | end
315 | item
316 | Command = ecSetMarker0
317 | ShortCut = 24624
318 | end
319 | item
320 | Command = ecSetMarker1
321 | ShortCut = 24625
322 | end
323 | item
324 | Command = ecSetMarker2
325 | ShortCut = 24626
326 | end
327 | item
328 | Command = ecSetMarker3
329 | ShortCut = 24627
330 | end
331 | item
332 | Command = ecSetMarker4
333 | ShortCut = 24628
334 | end
335 | item
336 | Command = ecSetMarker5
337 | ShortCut = 24629
338 | end
339 | item
340 | Command = ecSetMarker6
341 | ShortCut = 24630
342 | end
343 | item
344 | Command = ecSetMarker7
345 | ShortCut = 24631
346 | end
347 | item
348 | Command = ecSetMarker8
349 | ShortCut = 24632
350 | end
351 | item
352 | Command = ecSetMarker9
353 | ShortCut = 24633
354 | end
355 | item
356 | Command = EcFoldLevel1
357 | ShortCut = 41009
358 | end
359 | item
360 | Command = EcFoldLevel2
361 | ShortCut = 41010
362 | end
363 | item
364 | Command = EcFoldLevel3
365 | ShortCut = 41011
366 | end
367 | item
368 | Command = EcFoldLevel4
369 | ShortCut = 41012
370 | end
371 | item
372 | Command = EcFoldLevel5
373 | ShortCut = 41013
374 | end
375 | item
376 | Command = EcFoldLevel6
377 | ShortCut = 41014
378 | end
379 | item
380 | Command = EcFoldLevel7
381 | ShortCut = 41015
382 | end
383 | item
384 | Command = EcFoldLevel8
385 | ShortCut = 41016
386 | end
387 | item
388 | Command = EcFoldLevel9
389 | ShortCut = 41017
390 | end
391 | item
392 | Command = EcFoldLevel0
393 | ShortCut = 41008
394 | end
395 | item
396 | Command = EcFoldCurrent
397 | ShortCut = 41005
398 | end
399 | item
400 | Command = EcUnFoldCurrent
401 | ShortCut = 41003
402 | end
403 | item
404 | Command = EcToggleMarkupWord
405 | ShortCut = 32845
406 | end
407 | item
408 | Command = ecNormalSelect
409 | ShortCut = 24654
410 | end
411 | item
412 | Command = ecColumnSelect
413 | ShortCut = 24643
414 | end
415 | item
416 | Command = ecLineSelect
417 | ShortCut = 24652
418 | end
419 | item
420 | Command = ecTab
421 | ShortCut = 9
422 | end
423 | item
424 | Command = ecShiftTab
425 | ShortCut = 8201
426 | end
427 | item
428 | Command = ecMatchBracket
429 | ShortCut = 24642
430 | end
431 | item
432 | Command = ecColSelUp
433 | ShortCut = 40998
434 | end
435 | item
436 | Command = ecColSelDown
437 | ShortCut = 41000
438 | end
439 | item
440 | Command = ecColSelLeft
441 | ShortCut = 40997
442 | end
443 | item
444 | Command = ecColSelRight
445 | ShortCut = 40999
446 | end
447 | item
448 | Command = ecColSelPageDown
449 | ShortCut = 40994
450 | end
451 | item
452 | Command = ecColSelPageBottom
453 | ShortCut = 57378
454 | end
455 | item
456 | Command = ecColSelPageUp
457 | ShortCut = 40993
458 | end
459 | item
460 | Command = ecColSelPageTop
461 | ShortCut = 57377
462 | end
463 | item
464 | Command = ecColSelLineStart
465 | ShortCut = 40996
466 | end
467 | item
468 | Command = ecColSelLineEnd
469 | ShortCut = 40995
470 | end
471 | item
472 | Command = ecColSelEditorTop
473 | ShortCut = 57380
474 | end
475 | item
476 | Command = ecColSelEditorBottom
477 | ShortCut = 57379
478 | end>
479 | MouseActions = <>
480 | MouseTextActions = <>
481 | MouseSelActions = <>
482 | Lines.Strings = (
483 | 'Editor'
484 | )
485 | VisibleSpecialChars = [vscSpace, vscTabAtLast]
486 | SelectedColor.BackPriority = 50
487 | SelectedColor.ForePriority = 50
488 | SelectedColor.FramePriority = 50
489 | SelectedColor.BoldPriority = 50
490 | SelectedColor.ItalicPriority = 50
491 | SelectedColor.UnderlinePriority = 50
492 | SelectedColor.StrikeOutPriority = 50
493 | BracketHighlightStyle = sbhsBoth
494 | BracketMatchColor.Background = clNone
495 | BracketMatchColor.Foreground = clNone
496 | BracketMatchColor.Style = [fsBold]
497 | FoldedCodeColor.Background = clNone
498 | FoldedCodeColor.Foreground = clGray
499 | FoldedCodeColor.FrameColor = clGray
500 | MouseLinkColor.Background = clNone
501 | MouseLinkColor.Foreground = clBlue
502 | LineHighlightColor.Background = clNone
503 | LineHighlightColor.Foreground = clNone
504 | OnChangeUpdating = EditorChangeUpdating
505 | inline SynLeftGutterPartList1: TSynGutterPartList
506 | object SynGutterMarks1: TSynGutterMarks
507 | Width = 24
508 | MouseActions = <>
509 | end
510 | object SynGutterLineNumber1: TSynGutterLineNumber
511 | Width = 17
512 | MouseActions = <>
513 | MarkupInfo.Background = clBtnFace
514 | MarkupInfo.Foreground = clNone
515 | DigitCount = 2
516 | ShowOnlyLineNumbersMultiplesOf = 1
517 | ZeroStart = False
518 | LeadingZeros = False
519 | end
520 | object SynGutterChanges1: TSynGutterChanges
521 | Width = 4
522 | MouseActions = <>
523 | ModifiedColor = 59900
524 | SavedColor = clGreen
525 | end
526 | object SynGutterSeparator1: TSynGutterSeparator
527 | Width = 2
528 | MouseActions = <>
529 | MarkupInfo.Background = clWhite
530 | MarkupInfo.Foreground = clGray
531 | end
532 | object SynGutterCodeFolding1: TSynGutterCodeFolding
533 | MouseActions = <>
534 | MarkupInfo.Background = clNone
535 | MarkupInfo.Foreground = clGray
536 | MouseActionsExpanded = <>
537 | MouseActionsCollapsed = <>
538 | end
539 | end
540 | end
541 | object ActionList1: TActionList
542 | Images = dm.imglEnabled
543 | OnUpdate = ActionList1Update
544 | left = 180
545 | top = 125
546 | object actRefresh: TAction
547 | Caption = 'Refresh'
548 | Hint = 'Refresh file content'
549 | ImageIndex = 1
550 | OnExecute = actRefreshExecute
551 | end
552 | object actFileSave: TAction
553 | Caption = 'Save'
554 | ImageIndex = 2
555 | OnExecute = actFileSaveExecute
556 | end
557 | end
558 | object TimerAutoSave: TTimer
559 | Enabled = False
560 | Interval = 3000
561 | OnTimer = TimerAutoSaveTimer
562 | left = 305
563 | top = 155
564 | end
565 | end
566 |
--------------------------------------------------------------------------------
/urawedit.lrt:
--------------------------------------------------------------------------------
1 | TFRAWEDIT.ACTREFRESH.CAPTION=Refresh
2 | TFRAWEDIT.ACTREFRESH.HINT=Refresh file content
3 | TFRAWEDIT.ACTFILESAVE.CAPTION=Save
4 |
--------------------------------------------------------------------------------
/urawedit.pas:
--------------------------------------------------------------------------------
1 | { Ovonote - My implementation of Todo.txt concept
2 |
3 | Copyright (C) 2015 Marco Caselli
4 |
5 | This source is free software; you can redistribute it and/or modify it under
6 | the terms of the GNU General Public License as published by the Free
7 | Software Foundation; either version 2 of the License, or (at your option)
8 | any later version.
9 |
10 | This code is distributed in the hope that it will be useful, but WITHOUT ANY
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | details.
14 |
15 | A copy of the GNU General Public License is available on the World Wide Web
16 | at . You can also obtain it by writing
17 | to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 | MA 02111-1307, USA.
19 | }
20 | unit uRawEdit;
21 |
22 | {$mode objfpc}{$H+}
23 |
24 | interface
25 |
26 | uses
27 | Classes, SysUtils, FileUtil, LCLIntf, SynEdit,
28 | Forms, Controls, Graphics, Dialogs,
29 | ComCtrls, ActnList, todotxtsyn_highlighter,
30 | DefaultTranslator, ExtCtrls, udatamodule;
31 |
32 | type
33 |
34 | { TfRawEdit }
35 |
36 | TfRawEdit = class(TForm)
37 | actRefresh: TAction;
38 | actFileSave: TAction;
39 | ActionList1: TActionList;
40 | Editor: TSynEdit;
41 | TimerAutoSave: TTimer;
42 | ToolBar1: TToolBar;
43 | ToolButton1: TToolButton;
44 | ToolButton2: TToolButton;
45 | ToolButton4: TToolButton;
46 | procedure actFileSaveExecute(Sender: TObject);
47 | procedure ActionList1Update(AAction: TBasicAction; var Handled: Boolean);
48 | procedure actRefreshExecute(Sender: TObject);
49 | procedure EditorChangeUpdating(ASender: TObject; AnUpdating: Boolean);
50 | procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
51 | procedure TimerAutoSaveTimer(Sender: TObject);
52 | private
53 | Syne : TTodoSyn;
54 | Active_File: string;
55 | Modified :boolean;
56 | procedure CheckAutoSave;
57 | public
58 | Constructor Create(AOwner: TComponent; Archived: Boolean); reintroduce;
59 | end;
60 |
61 | var
62 | fRawEdit: TfRawEdit;
63 |
64 | implementation
65 |
66 | {$R *.lfm}
67 |
68 | { TfRawEdit }
69 |
70 | constructor TfRawEdit.Create(AOwner: TComponent; Archived: Boolean);
71 | begin
72 | inherited Create(Aowner);
73 | Modified := false;
74 | if Archived then
75 | begin
76 | Active_File:=FILE_DONE;
77 | actFileSave.Enabled:=false;
78 | end
79 | else
80 | Active_File:=FILE_TODO;
81 |
82 | if FileExists(dm.FilePath+Active_File) then
83 | Editor.Lines.LoadFromFile(dm.FilePath+Active_File)
84 | else
85 | Editor.Clear;
86 |
87 | Syne := TTodoSyn.Create(Self);
88 | Editor.Highlighter := syne;
89 |
90 | syne.ProjectAttri.Style:=[fsBold];
91 | syne.ContextAttri.Style:=[fsBold];
92 | syne.LinkAttri.Style:= [fsUnderline];
93 | syne.PriorityAttri.Background:=clyellow;
94 | syne.PropertyAttri.Background:=clLtGray;
95 | syne.DoneAttri.Style:=[fsItalic];
96 |
97 |
98 | end;
99 |
100 | procedure TfRawEdit.actRefreshExecute(Sender: TObject);
101 | begin
102 | if FileExists(dm.FilePath+Active_File) then
103 | Editor.Lines.LoadFromFile(dm.FilePath+Active_File)
104 | else
105 | Editor.Clear;
106 |
107 | end;
108 |
109 | procedure TfRawEdit.EditorChangeUpdating(ASender: TObject; AnUpdating: Boolean);
110 | begin
111 | TimerAutoSave.Enabled:=false;
112 | TimerAutoSave.Enabled:=True;
113 | end;
114 |
115 | procedure TfRawEdit.CheckAutoSave;
116 | begin
117 | if dm.AutoSave and Editor.Modified then
118 | actFileSave.Execute;
119 | end;
120 |
121 | procedure TfRawEdit.FormCloseQuery(Sender: TObject; var CanClose: boolean);
122 | begin
123 | CanClose := true;
124 | CheckAutoSave;
125 |
126 | if Editor.Modified then
127 | Case MessageDlg(RS_SAVE,mtWarning, mbYesNoCancel,0) of
128 | mrYes : begin
129 | actFileSave.Execute;
130 | end;
131 | mrCancel : CanClose:= false;
132 | end;
133 |
134 | if Modified then
135 | ModalResult:= mrModified;
136 |
137 | end;
138 |
139 | procedure TfRawEdit.TimerAutoSaveTimer(Sender: TObject);
140 | begin
141 | TimerAutoSave.Enabled:=false;
142 | CheckAutoSave;
143 | end;
144 |
145 | procedure TfRawEdit.actFileSaveExecute(Sender: TObject);
146 | begin
147 | Editor.Lines.SavetoFile(dm.FilePath+Active_File);
148 | Modified:=True;
149 | Editor.Modified:=false;
150 | end;
151 |
152 | procedure TfRawEdit.ActionList1Update(AAction: TBasicAction;
153 | var Handled: Boolean);
154 | begin
155 | actFileSave.Enabled:= Editor.Modified;
156 | end;
157 |
158 | end.
159 |
160 |
--------------------------------------------------------------------------------
/usettings.lfm:
--------------------------------------------------------------------------------
1 | object fSettings: TfSettings
2 | Left = 2148
3 | Height = 278
4 | Top = 470
5 | Width = 584
6 | Caption = 'Settings'
7 | ClientHeight = 278
8 | ClientWidth = 584
9 | OnShow = FormShow
10 | Visible = False
11 | object Panel1: TPanel
12 | Left = 0
13 | Height = 430
14 | Top = 0
15 | Width = 664
16 | Align = alClient
17 | ClientHeight = 430
18 | ClientWidth = 664
19 | TabOrder = 0
20 | object DirectoryEdit1: TDirectoryEdit
21 | Left = 8
22 | Height = 23
23 | Top = 40
24 | Width = 559
25 | ShowHidden = False
26 | ButtonWidth = 23
27 | NumGlyphs = 1
28 | MaxLength = 0
29 | TabOrder = 0
30 | end
31 | object Label1: TLabel
32 | Left = 12
33 | Height = 15
34 | Top = 16
35 | Width = 62
36 | Caption = 'Path to files'
37 | ParentColor = False
38 | end
39 | object ButtonPanel1: TButtonPanel
40 | Left = 7
41 | Height = 34
42 | Top = 389
43 | Width = 650
44 | OKButton.Name = 'OKButton'
45 | OKButton.DefaultCaption = True
46 | OKButton.OnClick = OKButtonClick
47 | HelpButton.Name = 'HelpButton'
48 | HelpButton.DefaultCaption = True
49 | CloseButton.Name = 'CloseButton'
50 | CloseButton.DefaultCaption = True
51 | CancelButton.Name = 'CancelButton'
52 | CancelButton.DefaultCaption = True
53 | CancelButton.OnClick = CancelButtonClick
54 | TabOrder = 1
55 | ShowButtons = [pbOK, pbCancel]
56 | end
57 | object cbAutosave: TCheckBox
58 | Left = 12
59 | Height = 19
60 | Top = 80
61 | Width = 121
62 | Caption = 'Auto-save changes'
63 | TabOrder = 2
64 | end
65 | end
66 | end
67 |
--------------------------------------------------------------------------------
/usettings.lrt:
--------------------------------------------------------------------------------
1 | TFSETTINGS.LABEL1.CAPTION=Path to files
2 | TFSETTINGS.CBAUTOSAVE.CAPTION=Auto-save changes
3 |
--------------------------------------------------------------------------------
/usettings.pas:
--------------------------------------------------------------------------------
1 | { Ovonote - My implementation of Todo.txt concept
2 |
3 | Copyright (C) 2015 Marco Caselli
4 |
5 | This source is free software; you can redistribute it and/or modify it under
6 | the terms of the GNU General Public License as published by the Free
7 | Software Foundation; either version 2 of the License, or (at your option)
8 | any later version.
9 |
10 | This code is distributed in the hope that it will be useful, but WITHOUT ANY
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | details.
14 |
15 | A copy of the GNU General Public License is available on the World Wide Web
16 | at . You can also obtain it by writing
17 | to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 | MA 02111-1307, USA.
19 | }
20 | unit usettings;
21 |
22 | {$mode objfpc}{$H+}
23 |
24 | interface
25 |
26 | uses
27 | Classes, SysUtils, FileUtil, IDEWindowIntf, Forms, Controls, Graphics,
28 | Dialogs, IniPropStorage, ExtCtrls, StdCtrls, EditBtn, ButtonPanel,
29 | udatamodule;
30 |
31 | type
32 |
33 | { TfSettings }
34 |
35 | TfSettings = class(TForm)
36 | ButtonPanel1: TButtonPanel;
37 | cbAutosave: TCheckBox;
38 | DirectoryEdit1: TDirectoryEdit;
39 | Label1: TLabel;
40 | Panel1: TPanel;
41 | procedure CancelButtonClick(Sender: TObject);
42 | procedure FormShow(Sender: TObject);
43 | procedure OKButtonClick(Sender: TObject);
44 | private
45 | { private declarations }
46 | public
47 | { public declarations }
48 | end;
49 |
50 | var
51 | fSettings: TfSettings;
52 |
53 | implementation
54 |
55 | {$R *.lfm}
56 |
57 | { TfSettings }
58 |
59 | procedure TfSettings.FormShow(Sender: TObject);
60 | begin
61 | DirectoryEdit1.Directory := dm.FilePath;
62 |
63 | end;
64 |
65 | procedure TfSettings.CancelButtonClick(Sender: TObject);
66 | begin
67 | ModalResult:=mrCancel;
68 | Close;
69 | end;
70 |
71 | procedure TfSettings.OKButtonClick(Sender: TObject);
72 | begin
73 | dm.FilePath:= IncludeTrailingPathDelimiter(DirectoryEdit1.Directory);
74 | dm.SaveConfig;
75 | Close;
76 | end;
77 |
78 | end.
79 |
80 |
--------------------------------------------------------------------------------