From 9a68801679c4a972e4b1d0db8e78f4f44fc23110 Mon Sep 17 00:00:00 2001 From: Robert Vokac Date: Sat, 10 Feb 2024 10:35:02 +0000 Subject: [PATCH] Several improvements --- .gitignore | 36 +- LICENCE | 674 ++++++++ Readme.md | 118 +- build.sh | 2 +- modules/time-calc-app/nbactions.xml | 20 + modules/time-calc-app/pom.xml | 108 +- .../org/nanoboot/utils/timecalc/app/Main.java | 32 +- .../utils/timecalc/app/TimeCalcApp.java | 186 +-- .../utils/timecalc/app/TimeCalcConf.java | 148 +- .../utils/timecalc/app/TimeCalcException.java | 22 +- .../utils/timecalc/app/TimeCalcManager.java | 1006 ++++++------ .../utils/timecalc/entity/Activity.java | 52 +- .../utils/timecalc/entity/Visibility.java | 58 +- .../utils/timecalc/entity/WorkingDay.java | 62 +- .../api/WorkingDayRepositoryApi.java | 16 +- .../WorkingDayRepositorySQLiteImpl.java | 20 +- .../timecalc/swing/common/AboutButton.java | 60 +- .../swing/common/ComponentRegistry.java | 62 +- .../timecalc/swing/common/TimeCalcButton.java | 78 +- .../timecalc/swing/common/TimeCalcWindow.java | 60 +- .../utils/timecalc/swing/common/Toaster.java | 936 +++++------ .../timecalc/swing/common/WeatherWindow.java | 320 ++-- .../utils/timecalc/swing/common/Widget.java | 188 +-- .../timecalc/swing/progress/AnalogClock.java | 428 ++--- .../timecalc/swing/progress/Battery.java | 466 +++--- .../timecalc/swing/progress/DayBattery.java | 22 +- .../timecalc/swing/progress/HourBattery.java | 66 +- .../timecalc/swing/progress/MonthBattery.java | 40 +- .../swing/progress/ProgressCircle.java | 94 +- .../swing/progress/ProgressSquare.java | 166 +- .../utils/timecalc/swing/progress/Time.java | 142 +- .../WalkingHumanProgressAsciiArt.java | 342 ++-- .../timecalc/swing/progress/WeekBattery.java | 38 +- .../timecalc/utils/binding/NumberBinding.java | 16 +- .../timecalc/utils/common/Constants.java | 34 +- .../timecalc/utils/common/DateFormats.java | 50 +- .../timecalc/utils/common/FileConstants.java | 32 +- .../timecalc/utils/common/HttpProxy.java | 108 +- .../utils/timecalc/utils/common/Jokes.java | 158 +- .../utils/timecalc/utils/common/JokesTxt.java | 56 +- .../timecalc/utils/common/NumberFormats.java | 36 +- .../utils/timecalc/utils/common/TimeHM.java | 98 +- .../utils/timecalc/utils/common/Utils.java | 246 +-- .../utils/property/BooleanProperty.java | 78 +- .../property/BooleanReadOnlyProperty.java | 46 +- .../utils/property/ChangeListener.java | 18 +- .../utils/property/IntegerProperty.java | 32 +- .../utils/property/InvalidationListener.java | 4 +- .../utils/property/ObjectProperty.java | 32 +- .../timecalc/utils/property/Property.java | 182 +-- .../utils/property/PropertyWrapper.java | 38 +- .../utils/property/ReadOnlyProperty.java | 76 +- .../utils/property/StringProperty.java | 32 +- .../property/StringReadOnlyProperty.java | 30 +- .../utils/property/WriteOnlyProperty.java | 68 +- .../src/main/resources/install.xml | 46 +- .../src/main/resources/vtipy.txt | 1397 ----------------- modules/time-calc-swing/pom.xml | 30 +- .../time-calc-swing/src/main/java/.gitkeep | 2 +- .../src/main/resources/.gitkeep | 2 +- .../time-calc-swing/src/test/java/.gitkeep | 2 +- pom.xml | 2 +- timecalc.conf | 16 +- 63 files changed, 4161 insertions(+), 4874 deletions(-) create mode 100644 LICENCE create mode 100644 modules/time-calc-app/nbactions.xml delete mode 100644 modules/time-calc-app/src/main/resources/vtipy.txt diff --git a/.gitignore b/.gitignore index 9545d80..cf94503 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,18 @@ -### IntelliJ IDEA ### -.idea -logs/* -*.iws -*.iml -*.ipr - -target/ -starttime.txt -overtime.txt -highlighted -proxy.txt -out.txt -pocasi.txt -test.txt -timecalc.conf -focus.txt -dist/* +### IntelliJ IDEA ### +.idea +logs/* +*.iws +*.iml +*.ipr + +target/ +starttime.txt +overtime.txt +highlighted +proxy.txt +out.txt +pocasi.txt +test.txt +timecalc.conf +focus.txt +dist/* diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENCE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Readme.md b/Readme.md index 5d14116..f4451cd 100644 --- a/Readme.md +++ b/Readme.md @@ -1,59 +1,59 @@ -# Time Calc - -## Introduction - -Time Calc is a desktop application used to track the remaining time until the end of some activity - like working hours. - -_Time Calc is written in Java programming language and uses the Swing framework._ - -![Tux, the Linux mascot](images/screenshot.png) -## Usage - -### Start of application - -When "Time Calc" is started", user is asked for: - - start time ... like 7:30 - - overtime ... like 0:45 ... overtime is optional and the default value is 0:00 - -### Restart of application - -You can restart the app, if you press the **"Restart"** button. - - Then you are asked again for start time and overtime. - -### End of application - -You can stop the app, if you press the **"Exit"** button or click on the exit window button. -- Then application is stopped. - - -## Special files - -If these files are present, something special happens. - -### starttime.txt - -This file contains the default start time - used during the previous run of the app. -If file starttime.txt does not exist, then the default start time is 7:00. - -### overtime.txt - -This file contains the default overtime - used during the previous run of the app. -If file overtime.txt does not exist, then the default overtime is 0:00. - -### test.txt -If file test.txt exists, then user is not asked for start time and overtime. Instead, the values in files starttime.txt and overtime.txt are used. - -## Key shortcuts - -## Command button - -## Todos - - * Config window - * Split to Maven modules - * Junit, Mockito, etc. - * Checkstyle - * Sonarlint - * Sonarqube - * Add SQLite support and store times of arrivals and departures and time of activities - +# Time Calc + +## Introduction + +Time Calc is a desktop application used to track the remaining time until the end of some activity - like working hours. + +_Time Calc is written in Java programming language and uses the Swing framework._ + +![Tux, the Linux mascot](images/screenshot.png) +## Usage + +### Start of application + +When "Time Calc" is started", user is asked for: + - start time ... like 7:30 + - overtime ... like 0:45 ... overtime is optional and the default value is 0:00 + +### Restart of application + +You can restart the app, if you press the **"Restart"** button. + - Then you are asked again for start time and overtime. + +### End of application + +You can stop the app, if you press the **"Exit"** button or click on the exit window button. +- Then application is stopped. + + +## Special files + +If these files are present, something special happens. + +### starttime.txt + +This file contains the default start time - used during the previous run of the app. +If file starttime.txt does not exist, then the default start time is 7:00. + +### overtime.txt + +This file contains the default overtime - used during the previous run of the app. +If file overtime.txt does not exist, then the default overtime is 0:00. + +### test.txt +If file test.txt exists, then user is not asked for start time and overtime. Instead, the values in files starttime.txt and overtime.txt are used. + +## Key shortcuts + +## Command button + +## Todos + + * Config window + * Split to Maven modules + * Junit, Mockito, etc. + * Checkstyle + * Sonarlint + * Sonarqube + * Add SQLite support and store times of arrivals and departures and time of activities + diff --git a/build.sh b/build.sh index b9ae6fe..d774b8f 100644 --- a/build.sh +++ b/build.sh @@ -56,6 +56,6 @@ echo ... 4. Moving new jar file to dist directory mv ./modules/time-calc-app/target/time-calc-app-$ORIG_VERSION-jar-with-all-dependencies.jar ./dist/time-calc-$VERSION.jar rm ./modules/time-calc-app/target/time-calc-app-$ORIG_VERSION.jar -cp ./dist/time-calc-$VERSION.jar C:/Users/Robert/Desktop/rv +cp ./dist/time-calc-$VERSION.jar C:/Users/Robert Vokac/Desktop/rv diff --git a/modules/time-calc-app/nbactions.xml b/modules/time-calc-app/nbactions.xml new file mode 100644 index 0000000..07b88c7 --- /dev/null +++ b/modules/time-calc-app/nbactions.xml @@ -0,0 +1,20 @@ + + + + run + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:3.1.0:exec + + + + ${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs} + + org.nanoboot.utils.timecalc.app.Main + java + + + diff --git a/modules/time-calc-app/pom.xml b/modules/time-calc-app/pom.xml index 68ae852..e72285b 100644 --- a/modules/time-calc-app/pom.xml +++ b/modules/time-calc-app/pom.xml @@ -1,55 +1,55 @@ - - - 4.0.0 - - - ./../../pom.xml - org.nanoboot.utils - time-calc - 0.1.0-SNAPSHOT - - - time-calc-app - - time-calc-app - time-calc-app - jar - - - - - maven-assembly-plugin - - - - org.nanoboot.utils.timecalc.app.Main - true - - - ${timestamp} - - - - - - - ./src/main/resources/install.xml - - - - - make-assembly - package - - single - - - - - - - - + + + 4.0.0 + + + ./../../pom.xml + org.nanoboot.utils + time-calc + 0.1.0-SNAPSHOT + + + time-calc-app + + time-calc-app + time-calc-app + jar + + + + + maven-assembly-plugin + + + + org.nanoboot.utils.timecalc.app.Main + true + + + ${timestamp} + + + + + + + ./src/main/resources/install.xml + + + + + make-assembly + package + + single + + + + + + + + \ No newline at end of file diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/Main.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/Main.java index 19dd465..c523767 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/Main.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/Main.java @@ -1,16 +1,16 @@ -package org.nanoboot.utils.timecalc.app; - -import java.io.IOException; - -/** - * @author Robert - * @since 31.01.2024 - */ -public class Main { - - public static void main(String[] args) throws IOException { - TimeCalcApp timeCalcApp = new TimeCalcApp(); - timeCalcApp.start(args); - } -} - +package org.nanoboot.utils.timecalc.app; + +import java.io.IOException; + +/** + * @author Robert Vokac + * @since 31.01.2024 + */ +public class Main { + + public static void main(String[] args) throws IOException { + TimeCalcApp timeCalcApp = new TimeCalcApp(); + timeCalcApp.start(args); + } +} + diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java index 3e26392..0683ec9 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcApp.java @@ -1,93 +1,93 @@ -package org.nanoboot.utils.timecalc.app; - -import org.nanoboot.utils.timecalc.entity.Visibility; -import org.nanoboot.utils.timecalc.utils.common.Constants; -import org.nanoboot.utils.timecalc.utils.common.FileConstants; -import org.nanoboot.utils.timecalc.utils.property.BooleanProperty; -import org.nanoboot.utils.timecalc.utils.property.ReadOnlyProperty; -import org.nanoboot.utils.timecalc.utils.property.StringProperty; -import org.nanoboot.utils.timecalc.utils.common.Utils; - -import javax.swing.JOptionPane; -import java.io.IOException; - -/** - * @author Robert - * @since 31.01.2024 - */ -public class TimeCalcApp { - - private long startNanoTime = 0l; - public StringProperty visibilityProperty = new StringProperty("timeCalcApp.visibilityReadWriteProperty", Visibility.WEAKLY_COLORED.name()); - public BooleanProperty - wavesProperty = new BooleanProperty("waves", true); - - public void start(String[] args) throws IOException { - if(startNanoTime != 0l) { - throw new TimeCalcException("TimeCalcApp was already started."); - } - startNanoTime = System.nanoTime(); - while (true) { - boolean test = FileConstants.TEST_TXT.exists(); - String oldStartTime = Utils.readTextFromFile( - FileConstants.STARTTIME_TXT); - String oldOvertime = Utils.readTextFromFile( - FileConstants.OVERTIME_TXT); - String newStartTime = - test ? (oldStartTime != null ? oldStartTime : - Constants.DEFAULT_START_TIME) : - (String) JOptionPane.showInputDialog( - null, - "Start Time:", - "Start Time", - JOptionPane.PLAIN_MESSAGE, - null, - null, - oldStartTime == null ? - Constants.DEFAULT_START_TIME : - oldStartTime - ); - String newOvertime = - test ? (oldOvertime != null ? oldOvertime : - Constants.DEFAULT_OVERTIME) : - (String) JOptionPane.showInputDialog( - null, - "Overtime:", - "Overtime", - JOptionPane.PLAIN_MESSAGE, - null, - null, - oldOvertime == null ? - Constants.DEFAULT_OVERTIME : - oldOvertime - ); - - Utils.writeTextToFile(FileConstants.STARTTIME_TXT, newStartTime); - Utils.writeTextToFile(FileConstants.OVERTIME_TXT, newOvertime); - try { - TimeCalcManager timeCalc = - new TimeCalcManager(newStartTime, newOvertime, this); - } catch (Exception e) { - JOptionPane.showMessageDialog(null, "Error: " + e.getMessage(), - e.getMessage(), JOptionPane.ERROR_MESSAGE); - } - } - - } - - public long getCountOfMinutesSinceAppStarted() { - return getCountOfSecondsSinceAppStarted() / 60l; - } - public long getCountOfSecondsSinceAppStarted() { - return getCountOfMillisecondsSinceAppStarted() / 1000000000l; - } - public long getCountOfMillisecondsSinceAppStarted() { - if(startNanoTime == 0l) { - throw new TimeCalcException("TimeCalcApp was not yet started."); - } - return System.nanoTime() - startNanoTime; - } - -} - - +package org.nanoboot.utils.timecalc.app; + +import org.nanoboot.utils.timecalc.entity.Visibility; +import org.nanoboot.utils.timecalc.utils.common.Constants; +import org.nanoboot.utils.timecalc.utils.common.FileConstants; +import org.nanoboot.utils.timecalc.utils.property.BooleanProperty; +import org.nanoboot.utils.timecalc.utils.property.ReadOnlyProperty; +import org.nanoboot.utils.timecalc.utils.property.StringProperty; +import org.nanoboot.utils.timecalc.utils.common.Utils; + +import javax.swing.JOptionPane; +import java.io.IOException; + +/** + * @author Robert Vokac + * @since 31.01.2024 + */ +public class TimeCalcApp { + + private long startNanoTime = 0l; + public StringProperty visibilityProperty = new StringProperty("timeCalcApp.visibilityReadWriteProperty", Visibility.WEAKLY_COLORED.name()); + public BooleanProperty + wavesProperty = new BooleanProperty("waves", true); + + public void start(String[] args) throws IOException { + if(startNanoTime != 0l) { + throw new TimeCalcException("TimeCalcApp was already started."); + } + startNanoTime = System.nanoTime(); + while (true) { + boolean test = FileConstants.TEST_TXT.exists(); + String oldStartTime = Utils.readTextFromFile( + FileConstants.STARTTIME_TXT); + String oldOvertime = Utils.readTextFromFile( + FileConstants.OVERTIME_TXT); + String newStartTime = + test ? (oldStartTime != null ? oldStartTime : + Constants.DEFAULT_START_TIME) : + (String) JOptionPane.showInputDialog( + null, + "Start Time:", + "Start Time", + JOptionPane.PLAIN_MESSAGE, + null, + null, + oldStartTime == null ? + Constants.DEFAULT_START_TIME : + oldStartTime + ); + String newOvertime = + test ? (oldOvertime != null ? oldOvertime : + Constants.DEFAULT_OVERTIME) : + (String) JOptionPane.showInputDialog( + null, + "Overtime:", + "Overtime", + JOptionPane.PLAIN_MESSAGE, + null, + null, + oldOvertime == null ? + Constants.DEFAULT_OVERTIME : + oldOvertime + ); + + Utils.writeTextToFile(FileConstants.STARTTIME_TXT, newStartTime); + Utils.writeTextToFile(FileConstants.OVERTIME_TXT, newOvertime); + try { + TimeCalcManager timeCalc = + new TimeCalcManager(newStartTime, newOvertime, this); + } catch (Exception e) { + JOptionPane.showMessageDialog(null, "Error: " + e.getMessage(), + e.getMessage(), JOptionPane.ERROR_MESSAGE); + } + } + + } + + public long getCountOfMinutesSinceAppStarted() { + return getCountOfSecondsSinceAppStarted() / 60l; + } + public long getCountOfSecondsSinceAppStarted() { + return getCountOfMillisecondsSinceAppStarted() / 1000000000l; + } + public long getCountOfMillisecondsSinceAppStarted() { + if(startNanoTime == 0l) { + throw new TimeCalcException("TimeCalcApp was not yet started."); + } + return System.nanoTime() - startNanoTime; + } + +} + + diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcConf.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcConf.java index c7ae5f1..4eb9954 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcConf.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcConf.java @@ -1,74 +1,74 @@ -package org.nanoboot.utils.timecalc.app; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Properties; - -/** - * @author Robert - * @since 20.02.2024 - */ -public class TimeCalcConf { - private static final String CLOCK_HANDS_LONG = "clock.hands.long"; - private static final String JOKE_VISIBLE = "jokes.visible"; - private static final String BATTERY_WAVES_ENABLED = "battery.waves.enabled"; - private static final String EVERYTHING_HIDDEN = "everything-hidden"; - private static final String TOASTS_ENABLED = "toasts.enabled"; - - private static TimeCalcConf INSTANCE; - private final Properties properties = new Properties(); - - private TimeCalcConf() { - if (!new File("timecalc.conf").exists()) { - //nothing to do; - return; - } - try { - this.properties.load(new FileInputStream("timecalc.conf")); - } catch (IOException e) { - System.err.println(e); - } - } - - public static TimeCalcConf getInstance() { - if (INSTANCE == null) { - INSTANCE = new TimeCalcConf(); - } - return INSTANCE; - } - - public boolean areClockHandsLong() { - return getBooleanProperty(CLOCK_HANDS_LONG, true); - } - - public boolean isJokeVisible() { - return getBooleanProperty(JOKE_VISIBLE, true); - } - - public boolean areBatteryWavesEnabled() { - return getBooleanProperty(BATTERY_WAVES_ENABLED, true); - } - - public boolean isEverythingHidden() { - return getBooleanProperty(EVERYTHING_HIDDEN, false); - } - - public boolean areToastsEnabled() { - return getBooleanProperty(TOASTS_ENABLED, true); - } - - private boolean getBooleanProperty(String key, boolean defaultValue) { - if (!properties.containsKey(key)) { - return defaultValue; - } - return properties.get(key).equals("true"); - } - public void load() { - //to be implemented - } - public void save() { - //to be implemented - } - -} +package org.nanoboot.utils.timecalc.app; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +/** + * @author Robert Vokac + * @since 20.02.2024 + */ +public class TimeCalcConf { + private static final String CLOCK_HANDS_LONG = "clock.hands.long"; + private static final String JOKE_VISIBLE = "jokes.visible"; + private static final String BATTERY_WAVES_ENABLED = "battery.waves.enabled"; + private static final String EVERYTHING_HIDDEN = "everything-hidden"; + private static final String TOASTS_ENABLED = "toasts.enabled"; + + private static TimeCalcConf INSTANCE; + private final Properties properties = new Properties(); + + private TimeCalcConf() { + if (!new File("timecalc.conf").exists()) { + //nothing to do; + return; + } + try { + this.properties.load(new FileInputStream("timecalc.conf")); + } catch (IOException e) { + System.err.println(e); + } + } + + public static TimeCalcConf getInstance() { + if (INSTANCE == null) { + INSTANCE = new TimeCalcConf(); + } + return INSTANCE; + } + + public boolean areClockHandsLong() { + return getBooleanProperty(CLOCK_HANDS_LONG, true); + } + + public boolean isJokeVisible() { + return getBooleanProperty(JOKE_VISIBLE, true); + } + + public boolean areBatteryWavesEnabled() { + return getBooleanProperty(BATTERY_WAVES_ENABLED, true); + } + + public boolean isEverythingHidden() { + return getBooleanProperty(EVERYTHING_HIDDEN, false); + } + + public boolean areToastsEnabled() { + return getBooleanProperty(TOASTS_ENABLED, true); + } + + private boolean getBooleanProperty(String key, boolean defaultValue) { + if (!properties.containsKey(key)) { + return defaultValue; + } + return properties.get(key).equals("true"); + } + public void load() { + //to be implemented + } + public void save() { + //to be implemented + } + +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcException.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcException.java index a620ff3..00340b7 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcException.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcException.java @@ -1,11 +1,11 @@ -package org.nanoboot.utils.timecalc.app; - -/** - * @author Robert - * @since 21.02.2024 - */ -public class TimeCalcException extends RuntimeException{ - public TimeCalcException(String msg) { - super(msg); - } -} +package org.nanoboot.utils.timecalc.app; + +/** + * @author Robert Vokac + * @since 21.02.2024 + */ +public class TimeCalcException extends RuntimeException{ + public TimeCalcException(String msg) { + super(msg); + } +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcManager.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcManager.java index e8f1384..b25051c 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcManager.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/app/TimeCalcManager.java @@ -1,503 +1,503 @@ -package org.nanoboot.utils.timecalc.app; - -import org.nanoboot.utils.timecalc.entity.Visibility; -import org.nanoboot.utils.timecalc.swing.common.AboutButton; -import org.nanoboot.utils.timecalc.swing.common.ComponentRegistry; -import org.nanoboot.utils.timecalc.swing.common.TimeCalcButton; -import org.nanoboot.utils.timecalc.swing.common.TimeCalcWindow; -import org.nanoboot.utils.timecalc.swing.common.Toaster; -import org.nanoboot.utils.timecalc.swing.common.WeatherWindow; -import org.nanoboot.utils.timecalc.swing.progress.AnalogClock; -import org.nanoboot.utils.timecalc.swing.progress.Battery; -import org.nanoboot.utils.timecalc.swing.progress.DayBattery; -import org.nanoboot.utils.timecalc.swing.progress.HourBattery; -import org.nanoboot.utils.timecalc.swing.progress.MonthBattery; -import org.nanoboot.utils.timecalc.swing.progress.ProgressCircle; -import org.nanoboot.utils.timecalc.swing.progress.ProgressSquare; -import org.nanoboot.utils.timecalc.swing.progress.Time; -import org.nanoboot.utils.timecalc.swing.progress.WalkingHumanProgressAsciiArt; -import org.nanoboot.utils.timecalc.swing.progress.WeekBattery; -import org.nanoboot.utils.timecalc.utils.common.Constants; -import org.nanoboot.utils.timecalc.utils.common.DateFormats; -import org.nanoboot.utils.timecalc.utils.common.Jokes; -import org.nanoboot.utils.timecalc.utils.common.TimeHM; -import org.nanoboot.utils.timecalc.utils.common.Utils; - -import javax.swing.JOptionPane; -import java.awt.Color; -import java.awt.Font; -import java.awt.Rectangle; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.time.DayOfWeek; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.Calendar; -import java.util.Date; - -/** - * @author Robert - * @since 08.02.2024 - */ -public class TimeCalcManager { - private static final int MARGIN = 10; - public static final Color BG = new Color(238, 238, 238); - public static final Color FG = new Color(210, 210, 210); - - private final String windowTitle; - private final int totalMinutes; - - private final TimeHM startTime; - private final TimeHM overtime; - private final TimeHM endTime; - private final TimeCalcApp timeCalcApp; - private boolean stopBeforeEnd = false; - private Time time = new Time(); - - public TimeCalcManager(String startTimeIn, String overTimeIn, - TimeCalcApp timeCalcApp) { - this.timeCalcApp = timeCalcApp; -// Utils.everythingHidden -// .setValue(TimeCalcConf.getInstance().isEverythingHidden()); -// Utils.toastsAreEnabled -// .setValue(TimeCalcConf.getInstance().areToastsEnabled()); - - overTimeIn = (overTimeIn == null || overTimeIn.isEmpty()) ? - Constants.DEFAULT_OVERTIME : overTimeIn; - - this.startTime = new TimeHM(startTimeIn); - this.overtime = new TimeHM(overTimeIn); - - this.endTime = new TimeHM(startTime.getHour() + Constants.WORKING_HOURS_LENGTH + overtime.getHour(), - startTime.getMinute() + Constants.WORKING_MINUTES_LENGTH + overtime.getMinute()); - - this.totalMinutes = TimeHM.countDiffInMinutes(startTime, endTime); - int totalSeconds = totalMinutes * TimeHM.SECONDS_PER_MINUTE; - int totalMilliseconds = totalSeconds * TimeHM.MILLISECONDS_PER_SECOND; - - TimeCalcWindow window = new TimeCalcWindow(); - - TimeCalcButton commandButton = new TimeCalcButton("Command"); - TimeCalcButton weatherButton = new TimeCalcButton("Weather"); - TimeCalcButton jokeButton = new TimeCalcButton("Joke"); - TimeCalcButton restartButton = new TimeCalcButton("Restart"); - TimeCalcButton exitButton = new TimeCalcButton("Exit"); - AboutButton aboutButton = new AboutButton(); - - //window.add(weatherButton); - window.addAll(commandButton, jokeButton, restartButton, - exitButton); - window.addKeyListener(new KeyAdapter() { - // Key Pressed method - public void keyPressed(KeyEvent e) { - Visibility visibility = Visibility.valueOf(timeCalcApp.visibilityProperty.getValue()); - if (e.getKeyCode() == KeyEvent.VK_UP) { - timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); - } - if (e.getKeyCode() == KeyEvent.VK_DOWN) { - timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); - } - if (e.getKeyCode() == KeyEvent.VK_H) { - if(visibility.isNone()) { - timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); - } else { - timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); - } - } - if (e.getKeyCode() == KeyEvent.VK_G) { - if(visibility.isGray()) { - timeCalcApp.visibilityProperty.setValue(Visibility.WEAKLY_COLORED.name()); - } else { - timeCalcApp.visibilityProperty.setValue(Visibility.GRAY.name()); - } - } - - if (e.getKeyCode() == KeyEvent.VK_C) { - if(visibility.isStronglyColored()) { - timeCalcApp.visibilityProperty.setValue(Visibility.WEAKLY_COLORED.name()); - } else { - timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); - } - } - if (e.getKeyCode() == KeyEvent.VK_V) { - if(visibility.isNone()) { - timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); - } else { - timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); - } - } - if (e.getKeyCode() == KeyEvent.VK_SPACE) { - if(visibility.isStronglyColored()) { - timeCalcApp.visibilityProperty.setValue(Visibility.WEAKLY_COLORED.name()); - } - if(visibility.isWeaklyColored()) { - timeCalcApp.visibilityProperty.setValue(Visibility.GRAY.name()); - } - if(visibility.isGray()) { - timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); - } - if(visibility.isNone()) { - timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); - } - } - if (e.getKeyCode() == KeyEvent.VK_R) { - commandButton.doClick(); - } - if (e.getKeyCode() == KeyEvent.VK_T) { - Utils.toastsAreEnabled.flip(); - } - - window.repaint(); - } - }); - WalkingHumanProgressAsciiArt walkingHumanProgressAsciiArt = new WalkingHumanProgressAsciiArt(); - walkingHumanProgressAsciiArt.setBounds(MARGIN, MARGIN + 210 + MARGIN, 450, 180); - - window.add(walkingHumanProgressAsciiArt); - weatherButton - .setBounds(20, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); - commandButton.setBounds(20, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); - - jokeButton.setBounds(140, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); - restartButton - .setBounds(280, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); - exitButton.setBounds(390, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); - aboutButton.setBounds(exitButton.getX(), - exitButton.getY() + exitButton.getHeight() + MARGIN); - - window.setLayout(null); - - window.setVisible(true); - - this.windowTitle = createWindowTitle(); - window.setTitle(windowTitle); - - weatherButton - .addActionListener(e -> new WeatherWindow().setVisible(true)); - commandButton - .addActionListener(e -> - { - String commands = (String) JOptionPane.showInputDialog( - null, - "Run a command:", - "Command launching", - JOptionPane.PLAIN_MESSAGE, - null, - null, - "test" - ); - String[] commandsAsArray = commands.split(" "); - switch (commandsAsArray[0]) { - case "test": - JOptionPane.showMessageDialog(null, "Test"); - break; - case "color": - timeCalcApp.visibilityProperty.setValue(commandsAsArray[1].equals("1") ? Visibility.STRONGLY_COLORED.name() : Visibility.WEAKLY_COLORED.name()); - break; - case "gray": - timeCalcApp.visibilityProperty.setValue(commandsAsArray[1].equals("1") ? Visibility.GRAY.name() : Visibility.WEAKLY_COLORED.name()); - break; - case "waves": - timeCalcApp.wavesProperty.setValue(commandsAsArray[1].equals("1")); - break; - case "uptime": - JOptionPane.showMessageDialog(null, - timeCalcApp.getCountOfMinutesSinceAppStarted() - + " minutes"); - break; - case "toast": - Toaster t = new Toaster(); - t.setToasterWidth(800); - t.setToasterHeight(800); - t.setDisplayTime(60000 * 5); - t.setToasterColor(Color.GRAY); - Font font = new Font("sans", Font.PLAIN, 12); - t.setToasterMessageFont(font); - t.setDisplayTime(5000); - t.showToaster(commands.substring(6)); - break; - case "toasts": - Utils.toastsAreEnabled - .setValue(commandsAsArray[1].equals("1")); - break; - default: - JOptionPane.showMessageDialog(null, - "Unknown command: " + commandsAsArray[0]); - } - }); - - jokeButton.addActionListener(e -> { - for (int i = 1; i <= 1; i++) { - Jokes.showRandom(); - } - }); - exitButton.addActionListener(e -> System.exit(0)); - restartButton.addActionListener(e -> { - window.setVisible(false); - stopBeforeEnd = true; - }); - - AnalogClock analogClock = new AnalogClock(startTime, endTime); - analogClock.setBounds(MARGIN, MARGIN, 200); - - window.add(analogClock); - - ProgressSquare progressSquare = new ProgressSquare(); - progressSquare - .setBounds(MARGIN + analogClock.getWidth() + MARGIN, MARGIN, - 200); - - window.add(progressSquare); - - ProgressCircle progressCircle = new ProgressCircle(); - progressCircle - .setBounds( - MARGIN + progressSquare.getBounds().x + progressSquare - .getWidth() + MARGIN, MARGIN, 80); - - window.add(progressCircle); - - Battery dayBattery = new DayBattery(progressCircle.getBounds().x, - progressCircle.getY() + MARGIN + progressCircle.getHeight(), 140); - window.add(dayBattery); - - - Battery weekBattery = new WeekBattery( - dayBattery.getBounds().x + dayBattery.getWidth() + MARGIN * 2, - dayBattery.getY(), 140); - window.add(weekBattery); - - Calendar calNow = Calendar.getInstance(); - calNow.setTime(new Date()); - - int currentDayOfMonth = calNow.get(Calendar.DAY_OF_MONTH); - - int workDaysDone = 0; - int workDaysTodo = 0; - int workDaysTotal; - for (int dayOfMonth = 1; - dayOfMonth <= calNow.getActualMaximum(Calendar.DAY_OF_MONTH); - dayOfMonth++) { - DayOfWeek dayOfWeek = LocalDate.of(calNow.get(Calendar.YEAR), - calNow.get(Calendar.MONTH) + 1, dayOfMonth).getDayOfWeek(); - boolean weekend = - dayOfWeek.toString().equals("SATURDAY") || dayOfWeek - .toString().equals("SUNDAY"); - if (dayOfMonth < currentDayOfMonth && !weekend) { - ++workDaysDone; - } - if (dayOfMonth > currentDayOfMonth && !weekend) { - ++workDaysTodo; - } - } - String currentDayOfWeekAsString = LocalDate - .of(calNow.get(Calendar.YEAR), calNow.get(Calendar.MONTH) + 1, - currentDayOfMonth).getDayOfWeek().toString(); - boolean nowIsWeekend = currentDayOfWeekAsString.equals("SATURDAY") - || currentDayOfWeekAsString.equals("SUNDAY"); - workDaysTotal = workDaysDone + (nowIsWeekend ? 0 : 1) + workDaysTodo; - - Battery monthBattery = new MonthBattery( - dayBattery.getBounds().x + dayBattery.getWidth(), - dayBattery.getY() + weekBattery.getHeight() + MARGIN, 140); - window.add(monthBattery); - - Battery hourBattery = new HourBattery(monthBattery.getBounds().x, - monthBattery.getY() + monthBattery.getHeight() + MARGIN, 140); - window.add(hourBattery); - - Rectangle dayRectangle = dayBattery.getBounds(); - hourBattery.setBounds(dayRectangle); - hourBattery.setBounds(hourBattery.getX() + 2 * MARGIN, hourBattery.getY(), hourBattery.getWidth(), hourBattery.getHeight()); - dayBattery.setBounds(hourBattery.getX() + hourBattery.getWidth() + MARGIN, hourBattery.getY(), hourBattery.getWidth(), hourBattery.getHeight()); - weekBattery.setBounds(hourBattery.getX(), hourBattery.getY() + hourBattery.getHeight() + MARGIN, hourBattery.getWidth(), hourBattery.getHeight()); - monthBattery.setBounds(hourBattery.getX() + hourBattery.getWidth() + MARGIN, hourBattery.getY() + hourBattery.getHeight() + MARGIN, hourBattery.getWidth(), hourBattery.getHeight()); - - hourBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); - dayBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); - weekBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); - monthBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); - - ComponentRegistry componentRegistry = new ComponentRegistry(); - componentRegistry.addAll( - walkingHumanProgressAsciiArt, - progressSquare, - progressCircle, - analogClock, - dayBattery, - weekBattery, - monthBattery, - hourBattery, - jokeButton, - commandButton, - restartButton, - exitButton - ); - walkingHumanProgressAsciiArt.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - progressSquare.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - progressCircle.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - analogClock.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - dayBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - weekBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - monthBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - hourBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - jokeButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - commandButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - restartButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - exitButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); - - jokeButton.setVisible(!Visibility.valueOf(jokeButton.visibilityProperty.getValue()).isNone()); - commandButton.setVisible(!Visibility.valueOf(commandButton.visibilityProperty.getValue()).isNone()); - restartButton.setVisible(!Visibility.valueOf(restartButton.visibilityProperty.getValue()).isNone()); - exitButton.setVisible(!Visibility.valueOf(exitButton.visibilityProperty.getValue()).isNone()); - -// timeCalcApp.visibilityProperty.addListener((Property p, String oldValue, String newValue)-> { -// System.out.println("Visibility of timeCalcApp was changed FROM " + oldValue + " TO " + newValue); -// } ); -// analogClock.visibilityProperty.addListener((Property p, String oldValue, String newValue)-> { -// System.out.println("Visibility of analogClock was changed FROM " + oldValue + " TO " + newValue); -// } ); - window.setSize(520 + 20 + 100, exitButton.getY() + 3 * exitButton.getHeight() + MARGIN); - while (true) { - //time.writeString(); - if(Math.random() > 0.95) { - window.requestFocus(); - } - if (stopBeforeEnd) { - window.setVisible(false); - window.dispose(); - break; - } - - Visibility visibility = Visibility.valueOf(timeCalcApp.visibilityProperty.getValue()); - componentRegistry.setVisible(visibility.isNotNone()); - if (!visibility.isStronglyColored() || visibility.isGray()) { - jokeButton.setBackground(BG); - commandButton.setBackground(BG); - restartButton.setBackground(BG); - exitButton.setBackground(BG); - - jokeButton.setForeground(FG); - commandButton.setForeground(FG); - restartButton.setForeground(FG); - exitButton.setForeground(FG); - } else { - jokeButton.setOriginalBackground(); - commandButton.setOriginalBackground(); - restartButton.setOriginalBackground(); - exitButton.setOriginalBackground(); - // - jokeButton.setOriginalForeground(); - commandButton.setOriginalForeground(); - restartButton.setOriginalForeground(); - exitButton.setOriginalForeground(); - } - jokeButton.setVisible( - TimeCalcConf.getInstance().isJokeVisible() - && !visibility.isNone()); - - window.setTitle(visibility.isNone() ? "" : windowTitle); - - LocalDateTime now = LocalDateTime.now(); - String nowString = - DateFormats.DATE_TIME_FORMATTER_HHmmssSSS.format(now); - - int hourNow = Integer.parseInt(nowString.split(":")[0]); - int minuteNow = Integer.parseInt(nowString.split(":")[1]); - - int secondNow = Integer.parseInt(nowString.split(":")[2]); - int millisecondNow = Integer.parseInt(nowString.split(":")[3]); - TimeHM timeRemains = new TimeHM(endTime.getHour() - hourNow, endTime.getMinute() - minuteNow); - - int secondsRemains = 60 - secondNow; - int millisecondsRemains = 1000 - millisecondNow; - - int hourDone = Constants.WORKING_HOURS_LENGTH + overtime.getHour() - timeRemains.getHour(); - int minutesDone = Constants.WORKING_MINUTES_LENGTH + overtime.getMinute() - timeRemains.getMinute(); - int secondsDone = secondNow; - int millisecondsDone = millisecondNow; - - int totalMinutesDone = hourDone * 60 + minutesDone; - int totalSecondsDone = totalMinutesDone * 60 + secondsDone; - int totalMillisecondsDone = - totalSecondsDone * 1000 + millisecondsDone; - - double done = ((double) totalMillisecondsDone) - / ((double) totalMilliseconds); - progressSquare.setDonePercent(done); - progressCircle.setDonePercent(done); - dayBattery.setDonePercent(done); - - int weekDayWhenMondayIsOne = calNow.get(Calendar.DAY_OF_WEEK) - 1; - weekBattery.setDonePercent(WeekBattery.getWeekProgress(weekDayWhenMondayIsOne, done)); - weekBattery.setLabel( - nowIsWeekend ? "5/5" : (weekDayWhenMondayIsOne + "/5")); - - monthBattery.setDonePercent(MonthBattery.getMonthProgress(weekDayWhenMondayIsOne, workDaysDone, workDaysTotal, done)); - monthBattery.setLabel( - (nowIsWeekend ? workDaysDone : workDaysDone + 1) + "/" - + (workDaysTotal)); - - hourBattery.setDonePercent(HourBattery.getHourProgress(timeRemains, secondsRemains, - millisecondsRemains)); - if (!nowIsWeekend) { - hourBattery.setLabel( - hourDone + "/" + ( - totalMinutes / 60)); - } - - int totalSecondsRemains = - (timeRemains.getHour() * 60 * 60 + timeRemains.getMinute() * 60 - + secondsRemains); - int totalMillisecondsRemains = - totalSecondsRemains * 1000 + millisecondsRemains; - double totalSecondsRemainsDouble = - ((double) totalMillisecondsRemains) / 1000; - -// if (timeRemains.getHour() == 0 && timeRemains.getMinute() <= 3) { -// Utils.highlighted.set(true); -// walkingHumanProgressAsciiArt.setForeground(Color.BLUE); -// } - - if (timeRemains.getHour() <= 0 && timeRemains.getMinute() <= 0) { - Toaster toasterManager = new Toaster(); - toasterManager.setDisplayTime(30000); - toasterManager.showToaster( - "Congratulation :-) It is the time to go home."); - walkingHumanProgressAsciiArt.printPercentToAscii(done, timeRemains.getHour(), timeRemains.getMinute(), done,totalSecondsRemainsDouble, endTime); - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - - } - while (!stopBeforeEnd) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - - } - } - } else { - walkingHumanProgressAsciiArt.printPercentToAscii(done, timeRemains.getHour(), timeRemains.getMinute(), done,totalSecondsRemainsDouble, endTime); - } - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - - } - - walkingHumanProgressAsciiArt.setForeground( - visibility.isStronglyColored() || walkingHumanProgressAsciiArt - .getClientProperty("mouseEntered").equals("true") ? - Color.BLACK : Color.LIGHT_GRAY); - } - window.setVisible(false); - window.dispose(); - } - - private String createWindowTitle() { - return "Time Calc " + Utils.getVersion(); - } - -} +package org.nanoboot.utils.timecalc.app; + +import org.nanoboot.utils.timecalc.entity.Visibility; +import org.nanoboot.utils.timecalc.swing.common.AboutButton; +import org.nanoboot.utils.timecalc.swing.common.ComponentRegistry; +import org.nanoboot.utils.timecalc.swing.common.TimeCalcButton; +import org.nanoboot.utils.timecalc.swing.common.TimeCalcWindow; +import org.nanoboot.utils.timecalc.swing.common.Toaster; +import org.nanoboot.utils.timecalc.swing.common.WeatherWindow; +import org.nanoboot.utils.timecalc.swing.progress.AnalogClock; +import org.nanoboot.utils.timecalc.swing.progress.Battery; +import org.nanoboot.utils.timecalc.swing.progress.DayBattery; +import org.nanoboot.utils.timecalc.swing.progress.HourBattery; +import org.nanoboot.utils.timecalc.swing.progress.MonthBattery; +import org.nanoboot.utils.timecalc.swing.progress.ProgressCircle; +import org.nanoboot.utils.timecalc.swing.progress.ProgressSquare; +import org.nanoboot.utils.timecalc.swing.progress.Time; +import org.nanoboot.utils.timecalc.swing.progress.WalkingHumanProgressAsciiArt; +import org.nanoboot.utils.timecalc.swing.progress.WeekBattery; +import org.nanoboot.utils.timecalc.utils.common.Constants; +import org.nanoboot.utils.timecalc.utils.common.DateFormats; +import org.nanoboot.utils.timecalc.utils.common.Jokes; +import org.nanoboot.utils.timecalc.utils.common.TimeHM; +import org.nanoboot.utils.timecalc.utils.common.Utils; + +import javax.swing.JOptionPane; +import java.awt.Color; +import java.awt.Font; +import java.awt.Rectangle; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Calendar; +import java.util.Date; + +/** + * @author Robert Vokac + * @since 08.02.2024 + */ +public class TimeCalcManager { + private static final int MARGIN = 10; + public static final Color BG = new Color(238, 238, 238); + public static final Color FG = new Color(210, 210, 210); + + private final String windowTitle; + private final int totalMinutes; + + private final TimeHM startTime; + private final TimeHM overtime; + private final TimeHM endTime; + private final TimeCalcApp timeCalcApp; + private boolean stopBeforeEnd = false; + private Time time = new Time(); + + public TimeCalcManager(String startTimeIn, String overTimeIn, + TimeCalcApp timeCalcApp) { + this.timeCalcApp = timeCalcApp; +// Utils.everythingHidden +// .setValue(TimeCalcConf.getInstance().isEverythingHidden()); +// Utils.toastsAreEnabled +// .setValue(TimeCalcConf.getInstance().areToastsEnabled()); + + overTimeIn = (overTimeIn == null || overTimeIn.isEmpty()) ? + Constants.DEFAULT_OVERTIME : overTimeIn; + + this.startTime = new TimeHM(startTimeIn); + this.overtime = new TimeHM(overTimeIn); + + this.endTime = new TimeHM(startTime.getHour() + Constants.WORKING_HOURS_LENGTH + overtime.getHour(), + startTime.getMinute() + Constants.WORKING_MINUTES_LENGTH + overtime.getMinute()); + + this.totalMinutes = TimeHM.countDiffInMinutes(startTime, endTime); + int totalSeconds = totalMinutes * TimeHM.SECONDS_PER_MINUTE; + int totalMilliseconds = totalSeconds * TimeHM.MILLISECONDS_PER_SECOND; + + TimeCalcWindow window = new TimeCalcWindow(); + + TimeCalcButton commandButton = new TimeCalcButton("Command"); + TimeCalcButton weatherButton = new TimeCalcButton("Weather"); + TimeCalcButton jokeButton = new TimeCalcButton("Joke"); + TimeCalcButton restartButton = new TimeCalcButton("Restart"); + TimeCalcButton exitButton = new TimeCalcButton("Exit"); + AboutButton aboutButton = new AboutButton(); + + //window.add(weatherButton); + window.addAll(commandButton, jokeButton, restartButton, + exitButton); + window.addKeyListener(new KeyAdapter() { + // Key Pressed method + public void keyPressed(KeyEvent e) { + Visibility visibility = Visibility.valueOf(timeCalcApp.visibilityProperty.getValue()); + if (e.getKeyCode() == KeyEvent.VK_UP) { + timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); + } + if (e.getKeyCode() == KeyEvent.VK_DOWN) { + timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); + } + if (e.getKeyCode() == KeyEvent.VK_H) { + if(visibility.isNone()) { + timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); + } else { + timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); + } + } + if (e.getKeyCode() == KeyEvent.VK_G) { + if(visibility.isGray()) { + timeCalcApp.visibilityProperty.setValue(Visibility.WEAKLY_COLORED.name()); + } else { + timeCalcApp.visibilityProperty.setValue(Visibility.GRAY.name()); + } + } + + if (e.getKeyCode() == KeyEvent.VK_C) { + if(visibility.isStronglyColored()) { + timeCalcApp.visibilityProperty.setValue(Visibility.WEAKLY_COLORED.name()); + } else { + timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); + } + } + if (e.getKeyCode() == KeyEvent.VK_V) { + if(visibility.isNone()) { + timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); + } else { + timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); + } + } + if (e.getKeyCode() == KeyEvent.VK_SPACE) { + if(visibility.isStronglyColored()) { + timeCalcApp.visibilityProperty.setValue(Visibility.WEAKLY_COLORED.name()); + } + if(visibility.isWeaklyColored()) { + timeCalcApp.visibilityProperty.setValue(Visibility.GRAY.name()); + } + if(visibility.isGray()) { + timeCalcApp.visibilityProperty.setValue(Visibility.NONE.name()); + } + if(visibility.isNone()) { + timeCalcApp.visibilityProperty.setValue(Visibility.STRONGLY_COLORED.name()); + } + } + if (e.getKeyCode() == KeyEvent.VK_R) { + commandButton.doClick(); + } + if (e.getKeyCode() == KeyEvent.VK_T) { + Utils.toastsAreEnabled.flip(); + } + + window.repaint(); + } + }); + WalkingHumanProgressAsciiArt walkingHumanProgressAsciiArt = new WalkingHumanProgressAsciiArt(); + walkingHumanProgressAsciiArt.setBounds(MARGIN, MARGIN + 210 + MARGIN, 450, 180); + + window.add(walkingHumanProgressAsciiArt); + weatherButton + .setBounds(20, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); + commandButton.setBounds(20, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); + + jokeButton.setBounds(140, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); + restartButton + .setBounds(280, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); + exitButton.setBounds(390, walkingHumanProgressAsciiArt.getY() + walkingHumanProgressAsciiArt.getHeight() + MARGIN); + aboutButton.setBounds(exitButton.getX(), + exitButton.getY() + exitButton.getHeight() + MARGIN); + + window.setLayout(null); + + window.setVisible(true); + + this.windowTitle = createWindowTitle(); + window.setTitle(windowTitle); + + weatherButton + .addActionListener(e -> new WeatherWindow().setVisible(true)); + commandButton + .addActionListener(e -> + { + String commands = (String) JOptionPane.showInputDialog( + null, + "Run a command:", + "Command launching", + JOptionPane.PLAIN_MESSAGE, + null, + null, + "test" + ); + String[] commandsAsArray = commands.split(" "); + switch (commandsAsArray[0]) { + case "test": + JOptionPane.showMessageDialog(null, "Test"); + break; + case "color": + timeCalcApp.visibilityProperty.setValue(commandsAsArray[1].equals("1") ? Visibility.STRONGLY_COLORED.name() : Visibility.WEAKLY_COLORED.name()); + break; + case "gray": + timeCalcApp.visibilityProperty.setValue(commandsAsArray[1].equals("1") ? Visibility.GRAY.name() : Visibility.WEAKLY_COLORED.name()); + break; + case "waves": + timeCalcApp.wavesProperty.setValue(commandsAsArray[1].equals("1")); + break; + case "uptime": + JOptionPane.showMessageDialog(null, + timeCalcApp.getCountOfMinutesSinceAppStarted() + + " minutes"); + break; + case "toast": + Toaster t = new Toaster(); + t.setToasterWidth(800); + t.setToasterHeight(800); + t.setDisplayTime(60000 * 5); + t.setToasterColor(Color.GRAY); + Font font = new Font("sans", Font.PLAIN, 12); + t.setToasterMessageFont(font); + t.setDisplayTime(5000); + t.showToaster(commands.substring(6)); + break; + case "toasts": + Utils.toastsAreEnabled + .setValue(commandsAsArray[1].equals("1")); + break; + default: + JOptionPane.showMessageDialog(null, + "Unknown command: " + commandsAsArray[0]); + } + }); + + jokeButton.addActionListener(e -> { + for (int i = 1; i <= 1; i++) { + Jokes.showRandom(); + } + }); + exitButton.addActionListener(e -> System.exit(0)); + restartButton.addActionListener(e -> { + window.setVisible(false); + stopBeforeEnd = true; + }); + + AnalogClock analogClock = new AnalogClock(startTime, endTime); + analogClock.setBounds(MARGIN, MARGIN, 200); + + window.add(analogClock); + + ProgressSquare progressSquare = new ProgressSquare(); + progressSquare + .setBounds(MARGIN + analogClock.getWidth() + MARGIN, MARGIN, + 200); + + window.add(progressSquare); + + ProgressCircle progressCircle = new ProgressCircle(); + progressCircle + .setBounds( + MARGIN + progressSquare.getBounds().x + progressSquare + .getWidth() + MARGIN, MARGIN, 80); + + window.add(progressCircle); + + Battery dayBattery = new DayBattery(progressCircle.getBounds().x, + progressCircle.getY() + MARGIN + progressCircle.getHeight(), 140); + window.add(dayBattery); + + + Battery weekBattery = new WeekBattery( + dayBattery.getBounds().x + dayBattery.getWidth() + MARGIN * 2, + dayBattery.getY(), 140); + window.add(weekBattery); + + Calendar calNow = Calendar.getInstance(); + calNow.setTime(new Date()); + + int currentDayOfMonth = calNow.get(Calendar.DAY_OF_MONTH); + + int workDaysDone = 0; + int workDaysTodo = 0; + int workDaysTotal; + for (int dayOfMonth = 1; + dayOfMonth <= calNow.getActualMaximum(Calendar.DAY_OF_MONTH); + dayOfMonth++) { + DayOfWeek dayOfWeek = LocalDate.of(calNow.get(Calendar.YEAR), + calNow.get(Calendar.MONTH) + 1, dayOfMonth).getDayOfWeek(); + boolean weekend = + dayOfWeek.toString().equals("SATURDAY") || dayOfWeek + .toString().equals("SUNDAY"); + if (dayOfMonth < currentDayOfMonth && !weekend) { + ++workDaysDone; + } + if (dayOfMonth > currentDayOfMonth && !weekend) { + ++workDaysTodo; + } + } + String currentDayOfWeekAsString = LocalDate + .of(calNow.get(Calendar.YEAR), calNow.get(Calendar.MONTH) + 1, + currentDayOfMonth).getDayOfWeek().toString(); + boolean nowIsWeekend = currentDayOfWeekAsString.equals("SATURDAY") + || currentDayOfWeekAsString.equals("SUNDAY"); + workDaysTotal = workDaysDone + (nowIsWeekend ? 0 : 1) + workDaysTodo; + + Battery monthBattery = new MonthBattery( + dayBattery.getBounds().x + dayBattery.getWidth(), + dayBattery.getY() + weekBattery.getHeight() + MARGIN, 140); + window.add(monthBattery); + + Battery hourBattery = new HourBattery(monthBattery.getBounds().x, + monthBattery.getY() + monthBattery.getHeight() + MARGIN, 140); + window.add(hourBattery); + + Rectangle dayRectangle = dayBattery.getBounds(); + hourBattery.setBounds(dayRectangle); + hourBattery.setBounds(hourBattery.getX() + 2 * MARGIN, hourBattery.getY(), hourBattery.getWidth(), hourBattery.getHeight()); + dayBattery.setBounds(hourBattery.getX() + hourBattery.getWidth() + MARGIN, hourBattery.getY(), hourBattery.getWidth(), hourBattery.getHeight()); + weekBattery.setBounds(hourBattery.getX(), hourBattery.getY() + hourBattery.getHeight() + MARGIN, hourBattery.getWidth(), hourBattery.getHeight()); + monthBattery.setBounds(hourBattery.getX() + hourBattery.getWidth() + MARGIN, hourBattery.getY() + hourBattery.getHeight() + MARGIN, hourBattery.getWidth(), hourBattery.getHeight()); + + hourBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); + dayBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); + weekBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); + monthBattery.wavesProperty.bindTo(timeCalcApp.wavesProperty.asReadOnlyProperty()); + + ComponentRegistry componentRegistry = new ComponentRegistry(); + componentRegistry.addAll( + walkingHumanProgressAsciiArt, + progressSquare, + progressCircle, + analogClock, + dayBattery, + weekBattery, + monthBattery, + hourBattery, + jokeButton, + commandButton, + restartButton, + exitButton + ); + walkingHumanProgressAsciiArt.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + progressSquare.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + progressCircle.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + analogClock.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + dayBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + weekBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + monthBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + hourBattery.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + jokeButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + commandButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + restartButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + exitButton.visibilityProperty.bindTo(timeCalcApp.visibilityProperty); + + jokeButton.setVisible(!Visibility.valueOf(jokeButton.visibilityProperty.getValue()).isNone()); + commandButton.setVisible(!Visibility.valueOf(commandButton.visibilityProperty.getValue()).isNone()); + restartButton.setVisible(!Visibility.valueOf(restartButton.visibilityProperty.getValue()).isNone()); + exitButton.setVisible(!Visibility.valueOf(exitButton.visibilityProperty.getValue()).isNone()); + +// timeCalcApp.visibilityProperty.addListener((Property p, String oldValue, String newValue)-> { +// System.out.println("Visibility of timeCalcApp was changed FROM " + oldValue + " TO " + newValue); +// } ); +// analogClock.visibilityProperty.addListener((Property p, String oldValue, String newValue)-> { +// System.out.println("Visibility of analogClock was changed FROM " + oldValue + " TO " + newValue); +// } ); + window.setSize(520 + 20 + 100, exitButton.getY() + 3 * exitButton.getHeight() + MARGIN); + while (true) { + //time.writeString(); + if(Math.random() > 0.95) { + window.requestFocus(); + } + if (stopBeforeEnd) { + window.setVisible(false); + window.dispose(); + break; + } + + Visibility visibility = Visibility.valueOf(timeCalcApp.visibilityProperty.getValue()); + componentRegistry.setVisible(visibility.isNotNone()); + if (!visibility.isStronglyColored() || visibility.isGray()) { + jokeButton.setBackground(BG); + commandButton.setBackground(BG); + restartButton.setBackground(BG); + exitButton.setBackground(BG); + + jokeButton.setForeground(FG); + commandButton.setForeground(FG); + restartButton.setForeground(FG); + exitButton.setForeground(FG); + } else { + jokeButton.setOriginalBackground(); + commandButton.setOriginalBackground(); + restartButton.setOriginalBackground(); + exitButton.setOriginalBackground(); + // + jokeButton.setOriginalForeground(); + commandButton.setOriginalForeground(); + restartButton.setOriginalForeground(); + exitButton.setOriginalForeground(); + } + jokeButton.setVisible( + TimeCalcConf.getInstance().isJokeVisible() + && !visibility.isNone()); + + window.setTitle(visibility.isNone() ? "" : windowTitle); + + LocalDateTime now = LocalDateTime.now(); + String nowString = + DateFormats.DATE_TIME_FORMATTER_HHmmssSSS.format(now); + + int hourNow = Integer.parseInt(nowString.split(":")[0]); + int minuteNow = Integer.parseInt(nowString.split(":")[1]); + + int secondNow = Integer.parseInt(nowString.split(":")[2]); + int millisecondNow = Integer.parseInt(nowString.split(":")[3]); + TimeHM timeRemains = new TimeHM(endTime.getHour() - hourNow, endTime.getMinute() - minuteNow); + + int secondsRemains = 60 - secondNow; + int millisecondsRemains = 1000 - millisecondNow; + + int hourDone = Constants.WORKING_HOURS_LENGTH + overtime.getHour() - timeRemains.getHour(); + int minutesDone = Constants.WORKING_MINUTES_LENGTH + overtime.getMinute() - timeRemains.getMinute(); + int secondsDone = secondNow; + int millisecondsDone = millisecondNow; + + int totalMinutesDone = hourDone * 60 + minutesDone; + int totalSecondsDone = totalMinutesDone * 60 + secondsDone; + int totalMillisecondsDone = + totalSecondsDone * 1000 + millisecondsDone; + + double done = ((double) totalMillisecondsDone) + / ((double) totalMilliseconds); + progressSquare.setDonePercent(done); + progressCircle.setDonePercent(done); + dayBattery.setDonePercent(done); + + int weekDayWhenMondayIsOne = calNow.get(Calendar.DAY_OF_WEEK) - 1; + weekBattery.setDonePercent(WeekBattery.getWeekProgress(weekDayWhenMondayIsOne, done)); + weekBattery.setLabel( + nowIsWeekend ? "5/5" : (weekDayWhenMondayIsOne + "/5")); + + monthBattery.setDonePercent(MonthBattery.getMonthProgress(weekDayWhenMondayIsOne, workDaysDone, workDaysTotal, done)); + monthBattery.setLabel( + (nowIsWeekend ? workDaysDone : workDaysDone + 1) + "/" + + (workDaysTotal)); + + hourBattery.setDonePercent(HourBattery.getHourProgress(timeRemains, secondsRemains, + millisecondsRemains)); + if (!nowIsWeekend) { + hourBattery.setLabel( + hourDone + "/" + ( + totalMinutes / 60)); + } + + int totalSecondsRemains = + (timeRemains.getHour() * 60 * 60 + timeRemains.getMinute() * 60 + + secondsRemains); + int totalMillisecondsRemains = + totalSecondsRemains * 1000 + millisecondsRemains; + double totalSecondsRemainsDouble = + ((double) totalMillisecondsRemains) / 1000; + +// if (timeRemains.getHour() == 0 && timeRemains.getMinute() <= 3) { +// Utils.highlighted.set(true); +// walkingHumanProgressAsciiArt.setForeground(Color.BLUE); +// } + + if (timeRemains.getHour() <= 0 && timeRemains.getMinute() <= 0) { + Toaster toasterManager = new Toaster(); + toasterManager.setDisplayTime(30000); + toasterManager.showToaster( + "Congratulation :-) It is the time to go home."); + walkingHumanProgressAsciiArt.printPercentToAscii(done, timeRemains.getHour(), timeRemains.getMinute(), done,totalSecondsRemainsDouble, endTime); + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + + } + while (!stopBeforeEnd) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + + } + } + } else { + walkingHumanProgressAsciiArt.printPercentToAscii(done, timeRemains.getHour(), timeRemains.getMinute(), done,totalSecondsRemainsDouble, endTime); + } + + try { + Thread.sleep(100); + } catch (InterruptedException e) { + + } + + walkingHumanProgressAsciiArt.setForeground( + visibility.isStronglyColored() || walkingHumanProgressAsciiArt + .getClientProperty("mouseEntered").equals("true") ? + Color.BLACK : Color.LIGHT_GRAY); + } + window.setVisible(false); + window.dispose(); + } + + private String createWindowTitle() { + return "Time Calc " + Utils.getVersion(); + } + +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Activity.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Activity.java index 17b39d4..26636e9 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Activity.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Activity.java @@ -1,26 +1,26 @@ -package org.nanoboot.utils.timecalc.entity; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * @author Robert - * @since 23.02.2024 - */ -@Getter -@Setter -@ToString -public class Activity { - private int year; - private int month; - private int day; - private int name; - private int comment; - private int ticket; - private int spentHours; - private int spentMinutes; - private boolean jira; - private boolean bugzilla; - -} +package org.nanoboot.utils.timecalc.entity; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * @author Robert Vokac + * @since 23.02.2024 + */ +@Getter +@Setter +@ToString +public class Activity { + private int year; + private int month; + private int day; + private int name; + private int comment; + private int ticket; + private int spentHours; + private int spentMinutes; + private boolean jira; + private boolean bugzilla; + +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Visibility.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Visibility.java index e477b0b..f7f64c9 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Visibility.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/Visibility.java @@ -1,29 +1,29 @@ -package org.nanoboot.utils.timecalc.entity; - -import org.nanoboot.utils.timecalc.utils.property.StringProperty; - -/** - * @author Robert - * @since 23.02.2024 - */ -public enum Visibility { - STRONGLY_COLORED, WEAKLY_COLORED, GRAY, NONE; - public boolean isStronglyColored() { - return this == STRONGLY_COLORED; - } - public boolean isWeaklyColored() { - return this == WEAKLY_COLORED; - } - public boolean isGray() { - return this == GRAY; - } - public boolean isNone() { - return this == NONE; - } - public boolean isNotNone() { - return !isNone(); - } - public static Visibility ofProperty(StringProperty stringProperty) { - return Visibility.valueOf(stringProperty.getValue()); - } -} +package org.nanoboot.utils.timecalc.entity; + +import org.nanoboot.utils.timecalc.utils.property.StringProperty; + +/** + * @author Robert Vokac + * @since 23.02.2024 + */ +public enum Visibility { + STRONGLY_COLORED, WEAKLY_COLORED, GRAY, NONE; + public boolean isStronglyColored() { + return this == STRONGLY_COLORED; + } + public boolean isWeaklyColored() { + return this == WEAKLY_COLORED; + } + public boolean isGray() { + return this == GRAY; + } + public boolean isNone() { + return this == NONE; + } + public boolean isNotNone() { + return !isNone(); + } + public static Visibility ofProperty(StringProperty stringProperty) { + return Visibility.valueOf(stringProperty.getValue()); + } +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/WorkingDay.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/WorkingDay.java index 37f3088..6a6f2b5 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/WorkingDay.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/entity/WorkingDay.java @@ -1,31 +1,31 @@ -package org.nanoboot.utils.timecalc.entity; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * @author Robert - * @since 23.02.2024 - */ -@Getter -@Setter -@ToString -public class WorkingDay { - private int year; - private int month; - private int day; - private int arrivalHour; - private int arrivalMinute; - private int departureHour; - private int departureMinute; - private String note; - private int overtimeHoursThisDay; - private int overtimeMinutesThisDay; - private int compensatoryTimeOffHoursThisDay; - private int compensatoryTimeOffMinutesThisDay; - private int overtimeHoursToBeCompensatedUntilThisDay; - private int overtimeMinutesToBeCompensatedUntilThisDay; - - -} +package org.nanoboot.utils.timecalc.entity; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * @author Robert Vokac + * @since 23.02.2024 + */ +@Getter +@Setter +@ToString +public class WorkingDay { + private int year; + private int month; + private int day; + private int arrivalHour; + private int arrivalMinute; + private int departureHour; + private int departureMinute; + private String note; + private int overtimeHoursThisDay; + private int overtimeMinutesThisDay; + private int compensatoryTimeOffHoursThisDay; + private int compensatoryTimeOffMinutesThisDay; + private int overtimeHoursToBeCompensatedUntilThisDay; + private int overtimeMinutesToBeCompensatedUntilThisDay; + + +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java index 422b299..e9f41a0 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java @@ -1,8 +1,8 @@ -package org.nanoboot.utils.timecalc.persistence.api; - -/** - * @author Robert - * @since 23.02.2024 - */ -public interface WorkingDayRepositoryApi { -} +package org.nanoboot.utils.timecalc.persistence.api; + +/** + * @author Robert Vokac + * @since 23.02.2024 + */ +public interface WorkingDayRepositoryApi { +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java index ccc6312..02ef7a6 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java @@ -1,10 +1,10 @@ -package org.nanoboot.utils.timecalc.persistence.impl.sqlite; - -import org.nanoboot.utils.timecalc.persistence.api.WorkingDayRepositoryApi; - -/** - * @author Robert - * @since 23.02.2024 - */ -public class WorkingDayRepositorySQLiteImpl implements WorkingDayRepositoryApi { -} +package org.nanoboot.utils.timecalc.persistence.impl.sqlite; + +import org.nanoboot.utils.timecalc.persistence.api.WorkingDayRepositoryApi; + +/** + * @author Robert Vokac + * @since 23.02.2024 + */ +public class WorkingDayRepositorySQLiteImpl implements WorkingDayRepositoryApi { +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/AboutButton.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/AboutButton.java index 3ed979d..3eb28cc 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/AboutButton.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/AboutButton.java @@ -1,30 +1,30 @@ -package org.nanoboot.utils.timecalc.swing.common; - -import org.nanoboot.utils.timecalc.utils.common.Utils; - -import javax.swing.JOptionPane; - -/** - * @author Robert - * @since 21.02.2024 - */ -public class AboutButton extends TimeCalcButton { - public AboutButton() { - super("About"); - addActionListener(e -> { - String version = Utils.getVersion(); - String buildDate = Utils.getBuildDate(); - if (version == null) { - version = "unknown"; - } - - if (buildDate == null) { - buildDate = "unknown"; - } - JOptionPane.showMessageDialog(null, - "Version: " + version + "\n" + "Built on (universal time): " - + buildDate, "About \"Pdf DME Downloader\"", - JOptionPane.INFORMATION_MESSAGE); - }); - } -} +package org.nanoboot.utils.timecalc.swing.common; + +import org.nanoboot.utils.timecalc.utils.common.Utils; + +import javax.swing.JOptionPane; + +/** + * @author Robert Vokac + * @since 21.02.2024 + */ +public class AboutButton extends TimeCalcButton { + public AboutButton() { + super("About"); + addActionListener(e -> { + String version = Utils.getVersion(); + String buildDate = Utils.getBuildDate(); + if (version == null) { + version = "unknown"; + } + + if (buildDate == null) { + buildDate = "unknown"; + } + JOptionPane.showMessageDialog(null, + "Version: " + version + "\n" + "Built on (universal time): " + + buildDate, "About \"Pdf DME Downloader\"", + JOptionPane.INFORMATION_MESSAGE); + }); + } +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ComponentRegistry.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ComponentRegistry.java index 9df46bf..4bae0ad 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ComponentRegistry.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ComponentRegistry.java @@ -1,31 +1,31 @@ -package org.nanoboot.utils.timecalc.swing.common; - -import javax.swing.JComponent; -import java.awt.Component; -import java.util.HashSet; -import java.util.Set; - -/** - * @author Robert - * @since 21.02.2024 - */ -public class ComponentRegistry { - private final Set set = new HashSet<>(); - public ComponentRegistry() { - - } - public void add(JComponent component) { - this.set.add(component); - } - public void addAll(JComponent... component) { - for(JComponent c:component) { - add(c); - } - } - - public void setVisible(boolean b) { - for(Component c:set) { - c.setVisible(b); - } - } -} +package org.nanoboot.utils.timecalc.swing.common; + +import javax.swing.JComponent; +import java.awt.Component; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Robert Vokac + * @since 21.02.2024 + */ +public class ComponentRegistry { + private final Set set = new HashSet<>(); + public ComponentRegistry() { + + } + public void add(JComponent component) { + this.set.add(component); + } + public void addAll(JComponent... component) { + for(JComponent c:component) { + add(c); + } + } + + public void setVisible(boolean b) { + for(Component c:set) { + c.setVisible(b); + } + } +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcButton.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcButton.java index af53ef3..4ef1ef3 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcButton.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcButton.java @@ -1,39 +1,39 @@ -package org.nanoboot.utils.timecalc.swing.common; - -import org.nanoboot.utils.timecalc.entity.Visibility; -import org.nanoboot.utils.timecalc.utils.property.StringProperty; - -import javax.swing.JButton; -import javax.swing.Timer; -import java.awt.Color; - -/** - * @author Robert - * @since 21.02.2024 - */ -public class TimeCalcButton extends JButton { - private static final int BUTTON_WIDTH = 100; - private static final int BUTTON_HEIGHT = 30; - private Color originalBackground; - private Color originalForeground; - - public StringProperty visibilityProperty = new StringProperty("visibilityProperty", Visibility.STRONGLY_COLORED.name()); - - public TimeCalcButton(String label) { - super(label); - } - - public void setBounds(int x, int y) { - setBounds(x, y, BUTTON_WIDTH, BUTTON_HEIGHT); - this.originalBackground = getBackground(); - this.originalForeground = getForeground(); - new Timer(100, e -> repaint()).start(); - } - public void setOriginalBackground() { - this.setBackground(originalBackground);; - } - - public void setOriginalForeground() { - this.setForeground(originalForeground);; - } -} +package org.nanoboot.utils.timecalc.swing.common; + +import org.nanoboot.utils.timecalc.entity.Visibility; +import org.nanoboot.utils.timecalc.utils.property.StringProperty; + +import javax.swing.JButton; +import javax.swing.Timer; +import java.awt.Color; + +/** + * @author Robert Vokac + * @since 21.02.2024 + */ +public class TimeCalcButton extends JButton { + private static final int BUTTON_WIDTH = 100; + private static final int BUTTON_HEIGHT = 30; + private Color originalBackground; + private Color originalForeground; + + public StringProperty visibilityProperty = new StringProperty("visibilityProperty", Visibility.STRONGLY_COLORED.name()); + + public TimeCalcButton(String label) { + super(label); + } + + public void setBounds(int x, int y) { + setBounds(x, y, BUTTON_WIDTH, BUTTON_HEIGHT); + this.originalBackground = getBackground(); + this.originalForeground = getForeground(); + new Timer(100, e -> repaint()).start(); + } + public void setOriginalBackground() { + this.setBackground(originalBackground);; + } + + public void setOriginalForeground() { + this.setForeground(originalForeground);; + } +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcWindow.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcWindow.java index e67fb7a..91caf2e 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcWindow.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/TimeCalcWindow.java @@ -1,30 +1,30 @@ -package org.nanoboot.utils.timecalc.swing.common; - -import javax.swing.JFrame; -import java.awt.Component; -import java.awt.HeadlessException; - -/** - * @author Robert - * @since 21.02.2024 - */ -public class TimeCalcWindow extends JFrame { - public TimeCalcWindow() throws HeadlessException { - setFocusable(true); - setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); - addWindowListener(new java.awt.event.WindowAdapter() { - @Override - public void windowClosing(java.awt.event.WindowEvent e) { - System.exit(0); - } - }); - } - - public Component[] addAll(Component... comp) { - for(Component c:comp) { - add(c); - } - return comp; - } - -} +package org.nanoboot.utils.timecalc.swing.common; + +import javax.swing.JFrame; +import java.awt.Component; +import java.awt.HeadlessException; + +/** + * @author Robert Vokac + * @since 21.02.2024 + */ +public class TimeCalcWindow extends JFrame { + public TimeCalcWindow() throws HeadlessException { + setFocusable(true); + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + } + + public Component[] addAll(Component... comp) { + for(Component c:comp) { + add(c); + } + return comp; + } + +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/Toaster.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/Toaster.java index 6bbf952..1caf034 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/Toaster.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/Toaster.java @@ -1,468 +1,468 @@ -/** - * This Java class named Toaster is licence under this licence: Apache License V2.0 - */ -package org.nanoboot.utils.timecalc.swing.common; -/** - * Java Toaster is a java utility class for your swing applications - * that show an animate box coming from the bottom of your screen - * with a notification message and/or an associated image - * (like msn online/offline notifications). - *

- * Toaster panel in windows system follow the taskbar; So if - * the taskbar is into the bottom the panel coming from the bottom - * and if the taskbar is on the top then the panel coming from the top. - *

- * This is a simple example of utilization: - *

- * import com.nitido.utils.toaster.*; - * import javax.swing.*; - *

- * public class ToasterTest - * { - *

- * public static void main(String[] args) - * { - * // Initialize toaster manager... - * Toaster toasterManager = new Toaster(); - *

- * // Show a simple toaster - * toasterManager.showToaster( new ImageIcon( "mylogo.gif" ), "A simple toaster with an image" ); - * } - * } - */ - -import org.nanoboot.utils.timecalc.utils.common.Utils; - -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextArea; -import javax.swing.JWindow; -import javax.swing.border.EtchedBorder; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.GraphicsEnvironment; -import java.awt.Image; -import java.awt.Insets; -import java.awt.Rectangle; - -/** - * Class to show tosters in multiplatform - * - * @author daniele piras - */ -public class Toaster { - private static final long serialVersionUID = 1L; - // Set the margin - int margin; - // Flag that indicate if use alwaysOnTop or not. - // method always on top start only SINCE JDK 5 ! - boolean useAlwaysOnTop = true; - // Width of the toster - private int toasterWidth = 300; - // Height of the toster - private int toasterHeight = 80; - // Step for the toaster - private int step = 20; - // Step time - private int stepTime = 20; - // Show time - private int displayTime = 3000; - // Current number of toaster... - private int currentNumberOfToaster = 0; - // Last opened toaster - private int maxToaster = 0; - // Max number of toasters for the sceen - private int maxToasterInSceen; - // Background image - private Image backgroundImage; - // Font used to display message - private Font font; - // Color for border - private Color borderColor; - // Color for toaster - private Color toasterColor; - // Set message color - private Color messageColor; - - /** - * Constructor to initialized toaster component... - * - * @author daniele piras - */ - public Toaster() { - // Set default font... - font = new Font("Arial", Font.BOLD, 12); - // Border color - borderColor = new Color(245, 153, 15); - toasterColor = Color.WHITE; - messageColor = Color.BLACK; - useAlwaysOnTop = true; - // Verify AlwaysOnTop Flag... - try { - JWindow.class - .getMethod("setAlwaysOnTop", Boolean.class); - } catch (Exception e) { - useAlwaysOnTop = false; - } - - } - - /** - * Show a toaster with the specified message and the associated icon. - */ - public void showToaster(Icon icon, String msg) { - if (!Utils.toastsAreEnabled.getValue()) { - //nothing to do - return; - } - SingleToaster singleToaster = new SingleToaster(); - if (icon != null) { - singleToaster.iconLabel.setIcon(icon); - } - singleToaster.message.setText(msg); - - singleToaster.toFront(); - singleToaster.setAlwaysOnTop(true); - singleToaster.animate(); - } - - /** - * Show a toaster with the specified message. - */ - public void showToaster(String msg) { - showToaster(null, msg); - } - - /** - * @return Returns the font - */ - public Font getToasterMessageFont() { - // TODO Auto-generated method stub - return font; - } - - /** - * Set the font for the message - */ - public void setToasterMessageFont(Font f) { - font = f; - } - - /** - * @return Returns the borderColor. - */ - public Color getBorderColor() { - return borderColor; - } - - /** - * @param borderColor The borderColor to set. - */ - public void setBorderColor(Color borderColor) { - this.borderColor = borderColor; - } - - /** - * @return Returns the displayTime. - */ - public int getDisplayTime() { - return displayTime; - } - - /** - * @param displayTime The displayTime to set. - */ - public void setDisplayTime(int displayTime) { - this.displayTime = displayTime; - } - - /** - * @return Returns the margin. - */ - public int getMargin() { - return margin; - } - - /** - * @param margin The margin to set. - */ - public void setMargin(int margin) { - this.margin = margin; - } - - /** - * @return Returns the messageColor. - */ - public Color getMessageColor() { - return messageColor; - } - - /** - * @param messageColor The messageColor to set. - */ - public void setMessageColor(Color messageColor) { - this.messageColor = messageColor; - } - - /** - * @return Returns the step. - */ - public int getStep() { - return step; - } - - /** - * @param step The step to set. - */ - public void setStep(int step) { - this.step = step; - } - - /** - * @return Returns the stepTime. - */ - public int getStepTime() { - return stepTime; - } - - /** - * @param stepTime The stepTime to set. - */ - public void setStepTime(int stepTime) { - this.stepTime = stepTime; - } - - /** - * @return Returns the toasterColor. - */ - public Color getToasterColor() { - return toasterColor; - } - - /** - * @param toasterColor The toasterColor to set. - */ - public void setToasterColor(Color toasterColor) { - this.toasterColor = toasterColor; - } - - /** - * @return Returns the toasterHeight. - */ - public int getToasterHeight() { - return toasterHeight; - } - - /** - * @param toasterHeight The toasterHeight to set. - */ - public void setToasterHeight(int toasterHeight) { - this.toasterHeight = toasterHeight; - } - - /** - * @return Returns the toasterWidth. - */ - public int getToasterWidth() { - return toasterWidth; - } - - /** - * @param toasterWidth The toasterWidth to set. - */ - public void setToasterWidth(int toasterWidth) { - this.toasterWidth = toasterWidth; - } - - public Image getBackgroundImage() { - return backgroundImage; - } - - public void setBackgroundImage(Image backgroundImage) { - this.backgroundImage = backgroundImage; - } - - /** - * Class that rappresent a single toaster - * - * @author daniele piras - */ - class SingleToaster extends JWindow { - private static final long serialVersionUID = 1L; - - // Label to store Icon - private final JLabel iconLabel = new JLabel(); - - // Text area for the message - private final JTextArea message = new JTextArea(); - - /*** - * Simple costructor that initialized components... - */ - public SingleToaster() { - initComponents(); - } - - /*** - * Function to initialized components - */ - private void initComponents() { - - setSize(toasterWidth, toasterHeight); - message.setFont(getToasterMessageFont()); - JPanel externalPanel = new JPanel(new BorderLayout(1, 1)); - externalPanel.setBackground(getBorderColor()); - JPanel innerPanel = - new JPanel(new BorderLayout(getMargin(), getMargin())) { - @Override - public void paint(Graphics g) { - if (getBackgroundImage() != null) { - g.drawImage(getBackgroundImage(), 0, 0, null); - } - super.paint(g); - } - }; - if (getBackgroundImage() != null) { - innerPanel.setOpaque(false); - message.setOpaque(false); - iconLabel.setOpaque(false); - } - innerPanel.setBackground(getToasterColor()); - message.setBackground(getToasterColor()); - message.setMargin(new Insets(2, 2, 2, 2)); - message.setLineWrap(true); - message.setWrapStyleWord(true); - EtchedBorder etchedBorder = (EtchedBorder) BorderFactory - .createEtchedBorder(); - externalPanel.setBorder(etchedBorder); - externalPanel.add(innerPanel); - message.setForeground(getMessageColor()); - innerPanel.add(iconLabel, BorderLayout.WEST); - innerPanel.add(message, BorderLayout.CENTER); - getContentPane().add(externalPanel); - JButton closeButton = new JButton("Close"); - closeButton.setBounds(480, 10, 100, 40); - innerPanel.add(closeButton, BorderLayout.BEFORE_FIRST_LINE); - closeButton.addActionListener(e -> { - setVisible(false); - dispose(); - }); - } - - /*** - * Start toaster animation... - */ - public void animate() { - (new Animation(this)).start(); - } - - } - - /*** - * Class that manage the animation - */ - class Animation extends Thread { - SingleToaster toaster; - - public Animation(SingleToaster toaster) { - this.toaster = toaster; - } - - /** - * Animate vertically the toaster. The toaster could be moved from bottom - * to upper or to upper to bottom - * - * @param posx - * @param fromY - * @param toY - * @throws InterruptedException - */ - protected void animateVertically(int posx, int fromY, int toY) - throws InterruptedException { - - toaster.setLocation(posx, fromY); - if (toY < fromY) { - for (int i = fromY; i > toY; i -= step) { - toaster.setLocation(posx, i); - Thread.sleep(stepTime); - } - } else { - for (int i = fromY; i < toY; i += step) { - toaster.setLocation(posx, i); - Thread.sleep(stepTime); - } - } - toaster.setLocation(posx, toY); - } - - public void run() { - try { - boolean animateFromBottom = true; - GraphicsEnvironment ge = GraphicsEnvironment - .getLocalGraphicsEnvironment(); - Rectangle screenRect = ge.getMaximumWindowBounds(); - - int screenHeight = screenRect.height; - - int startYPosition; - int stopYPosition; - - if (screenRect.y > 0) { - animateFromBottom = false; // Animate from top! - } - - maxToasterInSceen = screenHeight / toasterHeight; - - int posx = screenRect.width - toasterWidth - 1; - - toaster.setLocation(posx, screenHeight); - toaster.setVisible(true); - if (useAlwaysOnTop) { - toaster.setAlwaysOnTop(true); - } - - if (animateFromBottom) { - startYPosition = screenHeight; - stopYPosition = startYPosition - toasterHeight - 1; - if (currentNumberOfToaster > 0) { - stopYPosition = - stopYPosition - (maxToaster % maxToasterInSceen - * toasterHeight); - } else { - maxToaster = 0; - } - } else { - startYPosition = screenRect.y - toasterHeight; - stopYPosition = screenRect.y; - - if (currentNumberOfToaster > 0) { - stopYPosition = - stopYPosition + (maxToaster % maxToasterInSceen - * toasterHeight); - } else { - maxToaster = 0; - } - } - - currentNumberOfToaster++; - maxToaster++; - - animateVertically(posx, startYPosition, stopYPosition); - Thread.sleep(displayTime); - animateVertically(posx, stopYPosition, startYPosition); - - currentNumberOfToaster--; - toaster.setVisible(false); - toaster.dispose(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - -} +/** + * This Java class named Toaster is licence under this licence: Apache License V2.0 + */ +package org.nanoboot.utils.timecalc.swing.common; +/** + * Java Toaster is a java utility class for your swing applications + * that show an animate box coming from the bottom of your screen + * with a notification message and/or an associated image + * (like msn online/offline notifications). + *

+ * Toaster panel in windows system follow the taskbar; So if + * the taskbar is into the bottom the panel coming from the bottom + * and if the taskbar is on the top then the panel coming from the top. + *

+ * This is a simple example of utilization: + *

+ * import com.nitido.utils.toaster.*; + * import javax.swing.*; + *

+ * public class ToasterTest + * { + *

+ * public static void main(String[] args) + * { + * // Initialize toaster manager... + * Toaster toasterManager = new Toaster(); + *

+ * // Show a simple toaster + * toasterManager.showToaster( new ImageIcon( "mylogo.gif" ), "A simple toaster with an image" ); + * } + * } + */ + +import org.nanoboot.utils.timecalc.utils.common.Utils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JWindow; +import javax.swing.border.EtchedBorder; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Rectangle; + +/** + * Class to show tosters in multiplatform + * + * @author daniele piras + */ +public class Toaster { + private static final long serialVersionUID = 1L; + // Set the margin + int margin; + // Flag that indicate if use alwaysOnTop or not. + // method always on top start only SINCE JDK 5 ! + boolean useAlwaysOnTop = true; + // Width of the toster + private int toasterWidth = 300; + // Height of the toster + private int toasterHeight = 80; + // Step for the toaster + private int step = 20; + // Step time + private int stepTime = 20; + // Show time + private int displayTime = 3000; + // Current number of toaster... + private int currentNumberOfToaster = 0; + // Last opened toaster + private int maxToaster = 0; + // Max number of toasters for the sceen + private int maxToasterInSceen; + // Background image + private Image backgroundImage; + // Font used to display message + private Font font; + // Color for border + private Color borderColor; + // Color for toaster + private Color toasterColor; + // Set message color + private Color messageColor; + + /** + * Constructor to initialized toaster component... + * + * @author daniele piras + */ + public Toaster() { + // Set default font... + font = new Font("Arial", Font.BOLD, 12); + // Border color + borderColor = new Color(245, 153, 15); + toasterColor = Color.WHITE; + messageColor = Color.BLACK; + useAlwaysOnTop = true; + // Verify AlwaysOnTop Flag... + try { + JWindow.class + .getMethod("setAlwaysOnTop", Boolean.class); + } catch (Exception e) { + useAlwaysOnTop = false; + } + + } + + /** + * Show a toaster with the specified message and the associated icon. + */ + public void showToaster(Icon icon, String msg) { + if (!Utils.toastsAreEnabled.getValue()) { + //nothing to do + return; + } + SingleToaster singleToaster = new SingleToaster(); + if (icon != null) { + singleToaster.iconLabel.setIcon(icon); + } + singleToaster.message.setText(msg); + + singleToaster.toFront(); + singleToaster.setAlwaysOnTop(true); + singleToaster.animate(); + } + + /** + * Show a toaster with the specified message. + */ + public void showToaster(String msg) { + showToaster(null, msg); + } + + /** + * @return Returns the font + */ + public Font getToasterMessageFont() { + // TODO Auto-generated method stub + return font; + } + + /** + * Set the font for the message + */ + public void setToasterMessageFont(Font f) { + font = f; + } + + /** + * @return Returns the borderColor. + */ + public Color getBorderColor() { + return borderColor; + } + + /** + * @param borderColor The borderColor to set. + */ + public void setBorderColor(Color borderColor) { + this.borderColor = borderColor; + } + + /** + * @return Returns the displayTime. + */ + public int getDisplayTime() { + return displayTime; + } + + /** + * @param displayTime The displayTime to set. + */ + public void setDisplayTime(int displayTime) { + this.displayTime = displayTime; + } + + /** + * @return Returns the margin. + */ + public int getMargin() { + return margin; + } + + /** + * @param margin The margin to set. + */ + public void setMargin(int margin) { + this.margin = margin; + } + + /** + * @return Returns the messageColor. + */ + public Color getMessageColor() { + return messageColor; + } + + /** + * @param messageColor The messageColor to set. + */ + public void setMessageColor(Color messageColor) { + this.messageColor = messageColor; + } + + /** + * @return Returns the step. + */ + public int getStep() { + return step; + } + + /** + * @param step The step to set. + */ + public void setStep(int step) { + this.step = step; + } + + /** + * @return Returns the stepTime. + */ + public int getStepTime() { + return stepTime; + } + + /** + * @param stepTime The stepTime to set. + */ + public void setStepTime(int stepTime) { + this.stepTime = stepTime; + } + + /** + * @return Returns the toasterColor. + */ + public Color getToasterColor() { + return toasterColor; + } + + /** + * @param toasterColor The toasterColor to set. + */ + public void setToasterColor(Color toasterColor) { + this.toasterColor = toasterColor; + } + + /** + * @return Returns the toasterHeight. + */ + public int getToasterHeight() { + return toasterHeight; + } + + /** + * @param toasterHeight The toasterHeight to set. + */ + public void setToasterHeight(int toasterHeight) { + this.toasterHeight = toasterHeight; + } + + /** + * @return Returns the toasterWidth. + */ + public int getToasterWidth() { + return toasterWidth; + } + + /** + * @param toasterWidth The toasterWidth to set. + */ + public void setToasterWidth(int toasterWidth) { + this.toasterWidth = toasterWidth; + } + + public Image getBackgroundImage() { + return backgroundImage; + } + + public void setBackgroundImage(Image backgroundImage) { + this.backgroundImage = backgroundImage; + } + + /** + * Class that rappresent a single toaster + * + * @author daniele piras + */ + class SingleToaster extends JWindow { + private static final long serialVersionUID = 1L; + + // Label to store Icon + private final JLabel iconLabel = new JLabel(); + + // Text area for the message + private final JTextArea message = new JTextArea(); + + /*** + * Simple costructor that initialized components... + */ + public SingleToaster() { + initComponents(); + } + + /*** + * Function to initialized components + */ + private void initComponents() { + + setSize(toasterWidth, toasterHeight); + message.setFont(getToasterMessageFont()); + JPanel externalPanel = new JPanel(new BorderLayout(1, 1)); + externalPanel.setBackground(getBorderColor()); + JPanel innerPanel = + new JPanel(new BorderLayout(getMargin(), getMargin())) { + @Override + public void paint(Graphics g) { + if (getBackgroundImage() != null) { + g.drawImage(getBackgroundImage(), 0, 0, null); + } + super.paint(g); + } + }; + if (getBackgroundImage() != null) { + innerPanel.setOpaque(false); + message.setOpaque(false); + iconLabel.setOpaque(false); + } + innerPanel.setBackground(getToasterColor()); + message.setBackground(getToasterColor()); + message.setMargin(new Insets(2, 2, 2, 2)); + message.setLineWrap(true); + message.setWrapStyleWord(true); + EtchedBorder etchedBorder = (EtchedBorder) BorderFactory + .createEtchedBorder(); + externalPanel.setBorder(etchedBorder); + externalPanel.add(innerPanel); + message.setForeground(getMessageColor()); + innerPanel.add(iconLabel, BorderLayout.WEST); + innerPanel.add(message, BorderLayout.CENTER); + getContentPane().add(externalPanel); + JButton closeButton = new JButton("Close"); + closeButton.setBounds(480, 10, 100, 40); + innerPanel.add(closeButton, BorderLayout.BEFORE_FIRST_LINE); + closeButton.addActionListener(e -> { + setVisible(false); + dispose(); + }); + } + + /*** + * Start toaster animation... + */ + public void animate() { + (new Animation(this)).start(); + } + + } + + /*** + * Class that manage the animation + */ + class Animation extends Thread { + SingleToaster toaster; + + public Animation(SingleToaster toaster) { + this.toaster = toaster; + } + + /** + * Animate vertically the toaster. The toaster could be moved from bottom + * to upper or to upper to bottom + * + * @param posx + * @param fromY + * @param toY + * @throws InterruptedException + */ + protected void animateVertically(int posx, int fromY, int toY) + throws InterruptedException { + + toaster.setLocation(posx, fromY); + if (toY < fromY) { + for (int i = fromY; i > toY; i -= step) { + toaster.setLocation(posx, i); + Thread.sleep(stepTime); + } + } else { + for (int i = fromY; i < toY; i += step) { + toaster.setLocation(posx, i); + Thread.sleep(stepTime); + } + } + toaster.setLocation(posx, toY); + } + + public void run() { + try { + boolean animateFromBottom = true; + GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + Rectangle screenRect = ge.getMaximumWindowBounds(); + + int screenHeight = screenRect.height; + + int startYPosition; + int stopYPosition; + + if (screenRect.y > 0) { + animateFromBottom = false; // Animate from top! + } + + maxToasterInSceen = screenHeight / toasterHeight; + + int posx = screenRect.width - toasterWidth - 1; + + toaster.setLocation(posx, screenHeight); + toaster.setVisible(true); + if (useAlwaysOnTop) { + toaster.setAlwaysOnTop(true); + } + + if (animateFromBottom) { + startYPosition = screenHeight; + stopYPosition = startYPosition - toasterHeight - 1; + if (currentNumberOfToaster > 0) { + stopYPosition = + stopYPosition - (maxToaster % maxToasterInSceen + * toasterHeight); + } else { + maxToaster = 0; + } + } else { + startYPosition = screenRect.y - toasterHeight; + stopYPosition = screenRect.y; + + if (currentNumberOfToaster > 0) { + stopYPosition = + stopYPosition + (maxToaster % maxToasterInSceen + * toasterHeight); + } else { + maxToaster = 0; + } + } + + currentNumberOfToaster++; + maxToaster++; + + animateVertically(posx, startYPosition, stopYPosition); + Thread.sleep(displayTime); + animateVertically(posx, stopYPosition, startYPosition); + + currentNumberOfToaster--; + toaster.setVisible(false); + toaster.dispose(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WeatherWindow.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WeatherWindow.java index 752c6c7..58b8072 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WeatherWindow.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WeatherWindow.java @@ -1,160 +1,160 @@ -package org.nanoboot.utils.timecalc.swing.common; - -import org.nanoboot.utils.timecalc.utils.common.Utils; - -import javax.swing.JEditorPane; -import javax.swing.JFrame; -import javax.swing.JScrollPane; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.io.StringWriter; -import java.net.HttpURLConnection; -import java.net.URL; - -/** - * @author Robert - * @since 16.02.2024 - */ -public class WeatherWindow extends JFrame { - public WeatherWindow() { - this.setSize(400, 300); - - JEditorPane jep = new JEditorPane(); - jep.setEditable(false); - JScrollPane scrollPane = new JScrollPane(jep); - scrollPane.setBounds(10, 10, 750, 550); - getContentPane().add(scrollPane); - - // File proxyTxt = new File("proxy.txt"); - // if (!proxyTxt.exists()) { - // jep.setText("Sorry, file proxy.txt was not found."); - // return; - // } - // final HttpProxy httpProxy; - // try { - // httpProxy = new HttpProxy(proxyTxt); - // } catch (RuntimeException e) { - // jep.setContentType("text/html"); - // jep.setText(e.getMessage()); - // return; - // } - - try { - String pocasiHtml = null; - File pocasiHtmlFile = new File("pocasi.html"); - try { - pocasiHtml = downloadFile("https://pocasi.seznam.cz/praha"); - pocasiHtml = prettyFormatXml(pocasiHtml, 4); - Utils.writeTextToFile(pocasiHtmlFile, pocasiHtml); - } catch (Exception e) { - e.printStackTrace(); - pocasiHtml = pocasiHtmlFile.exists() ? - Utils.readTextFromFile(pocasiHtmlFile) : - "Sorry, pocasi.html was not found."; - } - - { - StringBuilder sb = new StringBuilder(); - boolean ogm_detailed_forecast_Started = false; - for (String line : pocasiHtml.split("\\r?\\n|\\r")) { - - if (line.contains("ogm-detailed-forecast")) { - ogm_detailed_forecast_Started = true; - } - if (ogm_detailed_forecast_Started && line - .contains("