Damo's Alarms 'N Timers application. Decided to start working on this after I realized there was no decent freeware/open source version of 'Alarm Clock', a package under Debian Linux, for the Windows environment.
C# 100.00%
dant's Introduction
Damo's Alarms 'N Timers
-=-=-=-=-=-=-=-=-=-=-=-
This application was first considered when I realized that there was no real
stock freeware application for Windows [that I've been able to find] that
handles a multipurpose alarms and timers function. At least not on any of the
freeware or open source sites that I've been able to google so far. I was
impressed by the capability of the stock 'Alarms' application that comes
bundled with the fresh install X11 applications for Ubuntu and Debian, so at
first I was trying to model my application after this. While not really
similar in appearance, the purpose is similar-- to make available an infinite
amount of concurrently capable specific alarm settings (with custom
notification sounds) and countdown timers (also with custom notification
sounds).
This is my first serious application in C# and as such I am learning quite a
bit about the language and proper coding technique as I go. This is a work in
progress and should not be judged on its codebase or functionality until I say
that it's complete and perfect. :)
When a timer (and presumably alarm, as well) is unchecked while running, it goes back to displaying the full amount of time for the alarm, as opposed to the amount of time remaining. Once it is reactivated it will jump back to the current point to count back from, but this is a confusing method. Perhaps something should be inserted that will show both the full time and the current counter time.
Okay, so this first issue now that I've finally got the project open is completely superfluous, but I was just learning C# when I started this, and figuring out (now that I'm back at it) how to go in and get the name of the primary folder/object to be something other than WindowsFormsApplication1 would be really great. ;)
Due to the fact that the checked status ends up handling both whether or not a timer/alarm is running, and the selection for the editing process, there is confusion. Editing selection should be made via highlighting a particular alarm or timer, and there should only be one that can be highlighted at a time. At current if more than one selection is checked, and the edit button hit, only the top item that is checked on the list will be edited. If highlighting is completely impossible, there should at least be a change made that will pop up an edit window for each of the selected/checked items, though this is far less preferable.
This seems to depend on whether or not previous alarms (maybe timers as well) have been active and/or have run prior to the one that fails to go off (simply wrapping around and counting down from 24, as far as alarms, after the messagebox is supposed to appear).
Trying to check the checkbox before an alarm or timer becomes an issue of trying to doubleclick, and to do it fast enough, when there is anything clicking. The behavior needs to be changed so that clicking on the checkbox only changes the checkbox, and the selection status only changes if you select the text of the selection, if possible.
Alternating clicks between active times and active alarms causes bugs rendering the alarms, timers, or both (inactive, even) when properly checked.
This is taken verbatim from the previous BUGS section in the comments of the code. I'm not sure what I meant by the 'inactive, even' bit in there, but I'll add more here as I get refamiliarized with the code base.
So what we need to do for this one is try to make sure that the doTick routines are preserving the selected status prior to redraw, and then are restoring them after the new entries are created. This should preserve continuity of a highlighted selection.
Due to the fact that checking and unchecking a timer results in more of a stopwatch effect, it is imperative that some sort of a reset feature/button to the timers side. Clicking should result in return of the formerly mid-countdown timer to the total time of the original countdown.
This makes selecting a timer or alarm for editing while another is active extremely hard to accomplish. When other crap is running there is only a fraction of a second to first click the alarm/timer to select it and then get down to the appropriate 'edit' button. This definitely needs to be worked around, or re-selected upon the tick when everything is being redrawn.
In-line documentation needs to adhere to an actual format; it's pretty close, so this won't take a whole lot of work, but what is in place right now should be parseable. Also, some of the functionality's inline documentation is falling out of sync with current functionality; the wiki docs are almost certainly out of sync as well in these places, as well as [potentially] others. So like fix this and stuff.
While researching issue #24, it became apparent that both timers and alarms going off require not just one interaction, but two, in order to fully dismiss the alarm/timer from going off. This is sub-optimal and should be removed as soon as better baseline functionality is achieved.
When a timer is allowed to go off, a concurrent alarm will stop counting down, though still checked, after the event fires. This may well be related to issue #4, and other like bugs, where something inhibits the counting down after events fire or the 'active' flag is changing. There should be a simple fix to this (famous last words).
When toggling one alarm from active, to inactive, and back, the alarm does not properly start the timer ticking and countdown again. This is not a problem when activating one, and then deactivating it, toggling to another one, and then coming back to the first one, though.
Need a new one of these, since the other one was disposed of when Alarms & Timers were split up. No code remaining, time to write something for here from scratch again.
Whenever times are set or edited, there is a bit of difficulty in determining exactly how the user interface wants information to be added. This needs to be clarified, and due to the lack of mentioning that things are supposed to go into 24 hour format, it's probably a good idea to add an AM/PM functionality to that interface.
Checking one timer will result in other timers' display moving to the display where they both show the original interval and the time remaining. This is bogus. At least it doesn't change the running state.
I haven't researched this issue enough to know exactly where the issues are occurring yet, but I've had a few instances of problems with timers/alarms repeatedly firing fast enough so that it's hard to get them closed and get the program back under control. I'm having troubles caffeinating this morning, so I'm not sure if I introduced this problem last night when I first started modularizing this area last night or if it's something that's been a little bit longer lasting.
Regardless, upon loading all of the Timers (and possibly Alarms: cannot remember right now) are loaded correctly by all displaying 00:00:00 for their durations/ringAt values. At one point I clicked the textbox on one of them and at 1 second intervals it began spouting new 'ring ring neo' windows all over the place, making it a pain in the butt to get under control especially in a machine very memory limited.
This may split into 2 issues soon; I'm just going to get it in here and recorded down for now.
Though the time is set correctly for the countdown, the display for it is broken. The Timers are trying to count down with an alarm style amount of time remaining, it appears. Except when doing so, they display the time to go off, and begin counting backwards from that TimeSpan, I think. This is almost certainly a repercussion of using incorrect properties when utilizing the method that fires once per second as the timer is counting down. Check it against the Alarms class, as well. I believe that, at the least, the display for these was broken as well. There are also spurious minus signs appearing in the formatting, so the formatting code needs to be revamped, as well.
After clicking OK in the timer completion dialog box the display does not reset away from the ring ring Neo message for the alarm. This needs to be changed so that after completion the total time for the next countdown is displayed.
After allowing a timer to run to completion in order to check on #28, an alarm was selected and allowed to tick down to completion. The program hung for awhile when the counter was almost down, and then finally crashed with the aforementioned error. Something is wrong with ndx in ringRingNeo().
Not sure why, but the DANT.cfg file format may be inconsistent with what different parts of the code are looking for, as it is refusing to load any timers (at least with console beep enabled). It should be known that the DANT.cfg file resides under the user's personal home directory, also.
When the application is first started, and existing alarms or timers that are loaded from the configuration file have several issues:
at least the timers, at one point, all display as all 0s; this represents internal state, because activating one will cause it to go off immediately
after going off once (but doing the notification twice), it resets all of the timers not hilighted to go off at the current time, ending up in the past after 1 second and thus invalid completely
valid timers need to be added during that session, not loaded from the files
various activities can contribute to getting the alarms or timers reset to the proper times, once in awhile, but this requires all sorts of random, unintuitive clicking; flowcharting might be useful to figure out what is awry in the first place
Wipe alarm button fails to stop the timer from ticking. Previous notes on this bug say to modularize the code to check for timer/alarm ticking activity because it needs to be used in several different places; nor does finishing the editing process for an alarm or timer.
NOTE: The last clause doesn't make a whole lot of sense; I'll translate this, again, to less terse and more readable english as I get used to the codebase again. At this point I would assume that it is just horrible grammar and that it applies to the fact that editing fails to stop an alarm or timer from ticking, perhaps.
As per advice from GD on Utopia, checkDate() should be rewritten for more efficient and legible code (ie compare entire dates, not multiple DateTime.Now property/method calls.
There needs to be an alternative for those who don't want to play an .mp3 or .wav when the alarm sounds; a console beep would be best, of course, to default to the lowest common denominator of hardware devices.
After much fiddling with the different alarms and timers in order to determine some specifics for the last reported bug, I set a 20 minute timer here that I needed. I was away from the screen for quite awhile, and after realizing that it should have been going off, I switched to the virtual machine that it was running in. The timer had stopped running, and had the display set to all 0s. There was, however, no message box awaiting my clicking, nor sign that the timer had gone off in the first place.
More testing is necessary, and this needs to be fixed.
It stays checked until the user acknowledges the messagebox dialog, and this is not the behavior that we want to use here. It should stop counting down immediately, otherwise if left for days or whatever it'll ring over the top over and over again, possibly causing an overflow or exception at some point that will stop things from working and looking nice.
As the subject says, it is going to greatly help being able to debug this code once implementation of full try/catch and throwing exception code is implemented here.
Timer now sets interval correctly; however, the code for this is kludgy as hell due to using the same object, <AlarmsTimers> for both sorts of items. This class should be separated into one for each.
Not sure why it happened, but in some update, things got seriously fucked up in the code. There are now huge stretches of code in the application that have broken method calls for things that should be working just fine. Obviously, this needs to be fixed.
Okay, so I'm copying this verbatim from the very terse comments that I'd originally put in the source code, so forgive me if it's not exactly clear (even to me at this point). After I've had some time to learn my application again, I'll clarify this in english...
Need to save the selected state of a window between redrawings when an alarm is active - then 'selection' as opposed to 'checked' status needs to be used for non-activating events as this is annoying and not very intuitive for the end user
It seems to kill the tick process in general. Going to need to do more investigation, but I believe that the culprit should be easy to spot now that I'm looking for the same basic thing in two places.
At this point the easiest thing may just to be let the ticks occur through the entire damn program, and not worry about whether or not anything is checked.
As titled, resetting a timer after checking it (it needs to be set up for selection, not checkboxed status) does properly change the variables so that when it starts up it'll look okay. However, before the timer is reactivated there is no update to show that the changes have been made via reset. So really, 2 issues here (selection, not checkbox), and then updating the display after the timer has been reset correctly in the internal variables.
This is due to my modification from using tmpTarget to interval, no doubt. It should be easy to identify and fix. Timers of any duration are going off immediately upon the first tick after activation.
This, along with an 'about' button for this program, would be great. Especially as the UI is still pretty unintuitive. Specifically, make sure to note the differences between using a checkbox to start/stop an alarm/timer and using the highlighting feature to be able to select a timer/alarm for editing/deletion.
After an alarm has gone off (to be more detailed, this was after running a timer through to completion in the same run), despite having clicked the 'Ok' on the message dialog, the alarm stays checked. Not sure if that has anything to do with it, but a few seconds later the program crashed with an unhandled ArgumentOutOfRangeException.