├── .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 | ![Manage todo items with cool GUI](http://ovoplayer.altervista.org/images/CoolGui-OvoNote.png) 13 | 14 | or with integrated text editor, with syntax highlighting! 15 | ![or with integrated text editor, with syntax highlighting!](http://ovoplayer.altervista.org/images/RawEdit-OvoNote.png) 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 | <ResourceType Value="res"/> 13 | <UseXPManifest Value="True"/> 14 | <Icon Value="0"/> 15 | </General> 16 | <i18n> 17 | <EnableI18N Value="True"/> 18 | <OutDir Value="language"/> 19 | </i18n> 20 | <VersionInfo> 21 | <UseVersionInfo Value="True"/> 22 | <MajorVersionNr Value="1"/> 23 | <Language Value="0410"/> 24 | <Attributes pvaPreRelease="True"/> 25 | </VersionInfo> 26 | <BuildModes Count="4"> 27 | <Item1 Name="Debug" Default="True"/> 28 | <Item2 Name="Release"> 29 | <CompilerOptions> 30 | <Version Value="11"/> 31 | <PathDelim Value="\"/> 32 | <Target> 33 | <Filename Value="bin\ovonote"/> 34 | </Target> 35 | <SearchPaths> 36 | <IncludeFiles Value="$(ProjOutDir)"/> 37 | <OtherUnitFiles Value="common;uniqueinstance"/> 38 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 39 | </SearchPaths> 40 | <CodeGeneration> 41 | <SmartLinkUnit Value="True"/> 42 | <Optimizations> 43 | <OptimizationLevel Value="3"/> 44 | </Optimizations> 45 | </CodeGeneration> 46 | <Linking> 47 | <Debugging> 48 | <GenerateDebugInfo Value="False"/> 49 | <StripSymbols Value="True"/> 50 | </Debugging> 51 | <LinkSmart Value="True"/> 52 | <Options> 53 | <Win32> 54 | <GraphicApplication Value="True"/> 55 | </Win32> 56 | </Options> 57 | </Linking> 58 | </CompilerOptions> 59 | </Item2> 60 | <Item3 Name="Debug-64"> 61 | <CompilerOptions> 62 | <Version Value="11"/> 63 | <PathDelim Value="\"/> 64 | <Target> 65 | <Filename Value="bin\ovonote"/> 66 | </Target> 67 | <SearchPaths> 68 | <IncludeFiles Value="$(ProjOutDir)"/> 69 | <OtherUnitFiles Value="common;uniqueinstance"/> 70 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 71 | </SearchPaths> 72 | <Parsing> 73 | <SyntaxOptions> 74 | <IncludeAssertionCode Value="True"/> 75 | </SyntaxOptions> 76 | </Parsing> 77 | <CodeGeneration> 78 | <Checks> 79 | <IOChecks Value="True"/> 80 | <RangeChecks Value="True"/> 81 | <OverflowChecks Value="True"/> 82 | <StackChecks Value="True"/> 83 | </Checks> 84 | <TargetCPU Value="x86_64"/> 85 | </CodeGeneration> 86 | <Linking> 87 | <Debugging> 88 | <DebugInfoType Value="dsDwarf2Set"/> 89 | <UseExternalDbgSyms Value="True"/> 90 | </Debugging> 91 | <Options> 92 | <Win32> 93 | <GraphicApplication Value="True"/> 94 | </Win32> 95 | </Options> 96 | </Linking> 97 | </CompilerOptions> 98 | </Item3> 99 | <Item4 Name="Release-64"> 100 | <CompilerOptions> 101 | <Version Value="11"/> 102 | <PathDelim Value="\"/> 103 | <Target> 104 | <Filename Value="bin\ovonote"/> 105 | </Target> 106 | <SearchPaths> 107 | <IncludeFiles Value="$(ProjOutDir)"/> 108 | <OtherUnitFiles Value="common;uniqueinstance"/> 109 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 110 | </SearchPaths> 111 | <CodeGeneration> 112 | <SmartLinkUnit Value="True"/> 113 | <TargetCPU Value="x86_64"/> 114 | <Optimizations> 115 | <OptimizationLevel Value="3"/> 116 | </Optimizations> 117 | </CodeGeneration> 118 | <Linking> 119 | <Debugging> 120 | <GenerateDebugInfo Value="False"/> 121 | <StripSymbols Value="True"/> 122 | </Debugging> 123 | <LinkSmart Value="True"/> 124 | <Options> 125 | <Win32> 126 | <GraphicApplication Value="True"/> 127 | </Win32> 128 | </Options> 129 | </Linking> 130 | </CompilerOptions> 131 | </Item4> 132 | </BuildModes> 133 | <PublishOptions> 134 | <Version Value="2"/> 135 | </PublishOptions> 136 | <RunParams> 137 | <FormatVersion Value="2"/> 138 | <Modes Count="1"> 139 | <Mode0 Name="default"/> 140 | </Modes> 141 | </RunParams> 142 | <RequiredPackages Count="5"> 143 | <Item1> 144 | <PackageName Value="DateTimeCtrls"/> 145 | </Item1> 146 | <Item2> 147 | <PackageName Value="IDEIntf"/> 148 | </Item2> 149 | <Item3> 150 | <PackageName Value="SynEdit"/> 151 | </Item3> 152 | <Item4> 153 | <PackageName Value="LazUtils"/> 154 | </Item4> 155 | <Item5> 156 | <PackageName Value="LCL"/> 157 | </Item5> 158 | </RequiredPackages> 159 | <Units Count="7"> 160 | <Unit0> 161 | <Filename Value="ovonote.lpr"/> 162 | <IsPartOfProject Value="True"/> 163 | </Unit0> 164 | <Unit1> 165 | <Filename Value="fovonote.pas"/> 166 | <IsPartOfProject Value="True"/> 167 | <ComponentName Value="frmOvoNote"/> 168 | <HasResources Value="True"/> 169 | <ResourceBaseClass Value="Form"/> 170 | </Unit1> 171 | <Unit2> 172 | <Filename Value="urawedit.pas"/> 173 | <IsPartOfProject Value="True"/> 174 | <ComponentName Value="fRawEdit"/> 175 | <HasResources Value="True"/> 176 | <ResourceBaseClass Value="Form"/> 177 | <UnitName Value="uRawEdit"/> 178 | </Unit2> 179 | <Unit3> 180 | <Filename Value="usettings.pas"/> 181 | <IsPartOfProject Value="True"/> 182 | <ComponentName Value="fSettings"/> 183 | <HasResources Value="True"/> 184 | <ResourceBaseClass Value="Form"/> 185 | </Unit3> 186 | <Unit4> 187 | <Filename Value="udatamodule.pas"/> 188 | <IsPartOfProject Value="True"/> 189 | <ComponentName Value="dm"/> 190 | <HasResources Value="True"/> 191 | <ResourceBaseClass Value="DataModule"/> 192 | </Unit4> 193 | <Unit5> 194 | <Filename Value="common\todo_parser.pas"/> 195 | <IsPartOfProject Value="True"/> 196 | </Unit5> 197 | <Unit6> 198 | <Filename Value="common\usstringparser.pas"/> 199 | <IsPartOfProject Value="True"/> 200 | <UnitName Value="USStringParser"/> 201 | </Unit6> 202 | </Units> 203 | </ProjectOptions> 204 | <CompilerOptions> 205 | <Version Value="11"/> 206 | <PathDelim Value="\"/> 207 | <Target> 208 | <Filename Value="bin\ovonote"/> 209 | </Target> 210 | <SearchPaths> 211 | <IncludeFiles Value="$(ProjOutDir)"/> 212 | <OtherUnitFiles Value="common;uniqueinstance"/> 213 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 214 | </SearchPaths> 215 | <Parsing> 216 | <SyntaxOptions> 217 | <IncludeAssertionCode Value="True"/> 218 | </SyntaxOptions> 219 | </Parsing> 220 | <CodeGeneration> 221 | <Checks> 222 | <IOChecks Value="True"/> 223 | <RangeChecks Value="True"/> 224 | <OverflowChecks Value="True"/> 225 | <StackChecks Value="True"/> 226 | </Checks> 227 | </CodeGeneration> 228 | <Linking> 229 | <Debugging> 230 | <DebugInfoType Value="dsDwarf2Set"/> 231 | </Debugging> 232 | <Options> 233 | <Win32> 234 | <GraphicApplication Value="True"/> 235 | </Win32> 236 | </Options> 237 | </Linking> 238 | </CompilerOptions> 239 | <Debugging> 240 | <Exceptions Count="3"> 241 | <Item1> 242 | <Name Value="EAbort"/> 243 | </Item1> 244 | <Item2> 245 | <Name Value="ECodetoolError"/> 246 | </Item2> 247 | <Item3> 248 | <Name Value="EFOpenError"/> 249 | </Item3> 250 | </Exceptions> 251 | </Debugging> 252 | </CONFIG> 253 | -------------------------------------------------------------------------------- /ovonote.lpr: -------------------------------------------------------------------------------- 1 | { Ovonote - My implementation of Todo.txt concept <http://todotxt.com/> 2 | 3 | Copyright (C) 2015 Marco Caselli <marcocas at gmail dot com> 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 <http://www.gnu.org/copyleft/gpl.html>. 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 <http://todotxt.com/> 2 | 3 | Copyright (C) 2015 Marco Caselli <marcocas at gmail dot com> 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 <http://www.gnu.org/copyleft/gpl.html>. 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 = '<All>'; 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 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="9"/> 5 | <PathDelim Value="\"/> 6 | <General> 7 | <Flags> 8 | <LRSInOutputDirectory Value="False"/> 9 | </Flags> 10 | <SessionStorage Value="InProjectDir"/> 11 | <MainUnit Value="0"/> 12 | <ResourceType Value="res"/> 13 | <UseXPManifest Value="True"/> 14 | <Icon Value="0"/> 15 | </General> 16 | <VersionInfo> 17 | <StringTable ProductVersion=""/> 18 | </VersionInfo> 19 | <BuildModes Count="1"> 20 | <Item1 Name="default" Default="True"/> 21 | </BuildModes> 22 | <PublishOptions> 23 | <Version Value="2"/> 24 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 25 | <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> 26 | </PublishOptions> 27 | <RunParams> 28 | <local> 29 | <FormatVersion Value="1"/> 30 | <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/> 31 | </local> 32 | </RunParams> 33 | <RequiredPackages Count="2"> 34 | <Item1> 35 | <PackageName Value="LCL"/> 36 | </Item1> 37 | <Item2> 38 | <PackageName Value="uniqueinstance_package"/> 39 | </Item2> 40 | </RequiredPackages> 41 | <Units Count="2"> 42 | <Unit0> 43 | <Filename Value="testinstance.lpr"/> 44 | <IsPartOfProject Value="True"/> 45 | <UnitName Value="testinstance"/> 46 | </Unit0> 47 | <Unit1> 48 | <Filename Value="fmain.pas"/> 49 | <IsPartOfProject Value="True"/> 50 | <ComponentName Value="Form1"/> 51 | <HasResources Value="True"/> 52 | <ResourceBaseClass Value="Form"/> 53 | <UnitName Value="fMain"/> 54 | </Unit1> 55 | </Units> 56 | </ProjectOptions> 57 | <CompilerOptions> 58 | <Version Value="11"/> 59 | <PathDelim Value="\"/> 60 | <SearchPaths> 61 | <SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType)"/> 62 | </SearchPaths> 63 | <Parsing> 64 | <SyntaxOptions> 65 | <UseAnsiStrings Value="False"/> 66 | </SyntaxOptions> 67 | </Parsing> 68 | <Linking> 69 | <Options> 70 | <Win32> 71 | <GraphicApplication Value="True"/> 72 | </Win32> 73 | </Options> 74 | </Linking> 75 | <Other> 76 | <CompilerMessages> 77 | <UseMsgFile Value="True"/> 78 | </CompilerMessages> 79 | <CompilerPath Value="$(CompPath)"/> 80 | </Other> 81 | </CompilerOptions> 82 | </CONFIG> 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 | <?xml version="1.0"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="9"/> 5 | <PathDelim Value="\"/> 6 | <General> 7 | <Flags> 8 | <LRSInOutputDirectory Value="False"/> 9 | </Flags> 10 | <SessionStorage Value="InProjectDir"/> 11 | <MainUnit Value="0"/> 12 | <ResourceType Value="res"/> 13 | </General> 14 | <VersionInfo> 15 | <StringTable ProductVersion=""/> 16 | </VersionInfo> 17 | <BuildModes Count="1"> 18 | <Item1 Name="default" Default="True"/> 19 | </BuildModes> 20 | <PublishOptions> 21 | <Version Value="2"/> 22 | <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> 23 | <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> 24 | </PublishOptions> 25 | <RunParams> 26 | <local> 27 | <FormatVersion Value="1"/> 28 | <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/> 29 | </local> 30 | </RunParams> 31 | <RequiredPackages Count="2"> 32 | <Item1> 33 | <PackageName Value="uniqueinstance_package"/> 34 | </Item1> 35 | <Item2> 36 | <PackageName Value="LCL"/> 37 | </Item2> 38 | </RequiredPackages> 39 | <Units Count="2"> 40 | <Unit0> 41 | <Filename Value="project1.lpr"/> 42 | <IsPartOfProject Value="True"/> 43 | <UnitName Value="project1"/> 44 | </Unit0> 45 | <Unit1> 46 | <Filename Value="unit1.pas"/> 47 | <IsPartOfProject Value="True"/> 48 | <ComponentName Value="Form1"/> 49 | <ResourceBaseClass Value="Form"/> 50 | <UnitName Value="Unit1"/> 51 | </Unit1> 52 | </Units> 53 | </ProjectOptions> 54 | <CompilerOptions> 55 | <Version Value="10"/> 56 | <PathDelim Value="\"/> 57 | <SearchPaths> 58 | <SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType)"/> 59 | </SearchPaths> 60 | <Parsing> 61 | <SyntaxOptions> 62 | <UseAnsiStrings Value="False"/> 63 | </SyntaxOptions> 64 | </Parsing> 65 | <Linking> 66 | <Debugging> 67 | <UseHeaptrc Value="True"/> 68 | </Debugging> 69 | <Options> 70 | <Win32> 71 | <GraphicApplication Value="True"/> 72 | </Win32> 73 | </Options> 74 | </Linking> 75 | <Other> 76 | <CompilerMessages> 77 | <UseMsgFile Value="True"/> 78 | </CompilerMessages> 79 | <CompilerPath Value="$(CompPath)"/> 80 | </Other> 81 | </CompilerOptions> 82 | </CONFIG> -------------------------------------------------------------------------------- /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 | <?xml version="1.0"?> 2 | <CONFIG> 3 | <Package Version="4"> 4 | <PathDelim Value="\"/> 5 | <Name Value="uniqueinstance_package"/> 6 | <AddToProjectUsesSection Value="True"/> 7 | <Author Value="Luiz Am�rico Pereira C�mara"/> 8 | <CompilerOptions> 9 | <Version Value="11"/> 10 | <PathDelim Value="\"/> 11 | <SearchPaths> 12 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/> 13 | </SearchPaths> 14 | <Parsing> 15 | <SyntaxOptions> 16 | <UseAnsiStrings Value="False"/> 17 | </SyntaxOptions> 18 | </Parsing> 19 | <CodeGeneration> 20 | <Optimizations> 21 | <OptimizationLevel Value="2"/> 22 | </Optimizations> 23 | </CodeGeneration> 24 | <Other> 25 | <CompilerMessages> 26 | <UseMsgFile Value="True"/> 27 | </CompilerMessages> 28 | <CompilerPath Value="$(CompPath)"/> 29 | </Other> 30 | </CompilerOptions> 31 | <Description Value="UniqueInstance provides a component to limits one instance per application"/> 32 | <License Value="Modified LGPL"/> 33 | <Version Major="1"/> 34 | <Files Count="4"> 35 | <Item1> 36 | <Filename Value="uniqueinstance.pas"/> 37 | <UnitName Value="UniqueInstance"/> 38 | </Item1> 39 | <Item2> 40 | <Filename Value="uniqueinstanceraw.pas"/> 41 | <UnitName Value="UniqueInstanceRaw"/> 42 | </Item2> 43 | <Item3> 44 | <Filename Value="registeruniqueinstance.pas"/> 45 | <HasRegisterProc Value="True"/> 46 | <UnitName Value="registeruniqueinstance"/> 47 | </Item3> 48 | <Item4> 49 | <Filename Value="uniqueinstancebase.pas"/> 50 | <UnitName Value="UniqueInstanceBase"/> 51 | </Item4> 52 | </Files> 53 | <Type Value="RunAndDesignTime"/> 54 | <RequiredPkgs Count="1"> 55 | <Item1> 56 | <PackageName Value="LCL"/> 57 | </Item1> 58 | </RequiredPkgs> 59 | <UsageOptions> 60 | <UnitPath Value="$(PkgOutDir)"/> 61 | </UsageOptions> 62 | <PublishOptions> 63 | <Version Value="2"/> 64 | <IgnoreBinaries Value="False"/> 65 | </PublishOptions> 66 | </Package> 67 | </CONFIG> 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 <http://todotxt.com/> 2 | 3 | Copyright (C) 2015 Marco Caselli <marcocas at gmail dot com> 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 <http://www.gnu.org/copyleft/gpl.html>. 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 <http://todotxt.com/> 2 | 3 | Copyright (C) 2015 Marco Caselli <marcocas at gmail dot com> 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 <http://www.gnu.org/copyleft/gpl.html>. 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 | --------------------------------------------------------------------------------