It is currently April 25th, 2024, 10:07 am

Timer reminder

Get help with creating, editing & fixing problems with skins
jadiazrod
Posts: 46
Joined: February 1st, 2022, 7:07 pm

Re: Timer reminder

Post by jadiazrod »

Never Mind... I figured it out by process of elimination...
if I may ask for some more questions it will be really appreciated...
As I mentioned before I was experimenting with this W10Stab skin... in particular with the To Do section...
I've managed to add more lines to achieve 14 notes which are separated in 2's... my idea is to have 2 daily groups, Morning events and afternoon events for each day of the week... ( I think we'll have 4 daily events at the most so basically 2 lines at front of each blue square will be enough...)
I've managed to put "labels" ( pardon my terminology ) for the first group as shown in the picture...
But when trying to add " Labels " for the second pair of blue squares ( Lets say "Tuesday" centered, then "Morning" & "Afternoon" ...) in the same way the first 2 ones got "labeled", the text gets placed in between the first 2 blue squares instead being placed above the Third one...
I know this W10Stab skin uses very old coding which you guys mentioned before should be updated for newer more efficient one... but for now is just an experiment .... if it works for event reminders as I hope it will, then I'll take the time to polish it...
Here it goes the questions...
How to achieve labeling the 2nd group of blue squares so I can do the same for each pair remaining...?
Double clicking on a blue square gives me either a "!" mark or a "Check" mark... but when an event has been completed, ( Lets say payment was done to the phone company on Monday morning...) that reminder is not longer needed... is there a way to reset that to get ready for the next event... ( Clean blue Square, no marks & grayed out " Click here to add a note" text....?
Is there a way to make the "Monday" Text string to show the actual date...? ( for instance showing "Monday February 21")
Thanks again
Side bar todo list.png
You do not have the required permissions to view the files attached to this post.
jadiazrod
Posts: 46
Joined: February 1st, 2022, 7:07 pm

Re: Timer reminder

Post by jadiazrod »

Hello guys....
I've time to work on the skin and accomplished some of the issues mentioned before...
I think is a Brute Force based but it works... so the experiment keeps going forward...
Now just 2 more issues remain:
Double clicking on a blue square gives me either a "!" mark or a "Check" mark... but when an event has been completed, ( Lets say payment was done to the phone company on Monday morning...) that reminder is not longer needed... is there a way to reset that to get ready for the next event... ( Clean blue Square, no marks & grayed out " Click here to add a note" text....?
Is there a way to make the day of the week Text string to show the actual date...? ( for instance instead of "Monday" to show "Monday February 21"
Instead of just "Tuesday" to show " Tuesday February 22 and so on...)
Cheers
Side bar todo list.png
You do not have the required permissions to view the files attached to this post.
User avatar
Yincognito
Rainmeter Sage
Posts: 7157
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Timer reminder

Post by Yincognito »

jadiazrod wrote: February 22nd, 2022, 9:01 pm Hello guys....
I've time to work on the skin and accomplished some of the issues mentioned before...
I think is a Brute Force based but it works... so the experiment keeps going forward...
Now just 2 more issues remain:
Double clicking on a blue square gives me either a "!" mark or a "Check" mark... but when an event has been completed, ( Lets say payment was done to the phone company on Monday morning...) that reminder is not longer needed... is there a way to reset that to get ready for the next event... ( Clean blue Square, no marks & grayed out " Click here to add a note" text....?
Is there a way to make the day of the week Text string to show the actual date...? ( for instance instead of "Monday" to show "Monday February 21"
Instead of just "Tuesday" to show " Tuesday February 22 and so on...)
Cheers
Side bar todo list.png
You try to transform a skin with lots of other features - and in my opinion difficult to work with since it hides on mouse hover, but then maybe I'm not aware how its author thought it "should" work - into your otherwise simpler objective, which is a reminders skin (and not a notes one). What W10Tab has there are notes, meaning it has no "event X has been completed" or a "timer", unless you simulate that manually by simply deleting the desired note and make your task harder by trying to understand the skin and add things that it hasn't been designed for to it.

Now, I'm not saying you shouldn't use it or try to transform it into what you want, I'm just saying that this will be harder than just starting from scratch and write only the code that you need for the desired functionality. The latter is the thing you should be first be focused on, since all kinds of colors, effects and nice visuals can easily be added later, once you know that what you did works.

For example, the (unfinished) skin below, which I wrote as I promised earlier, is simply showing the reminders for which the current time is greater than their "end time" (i.e. the time that should trigger a potential future reminder popup containing these) and that have not been cancelled. Here, a reminder has 3 states: initiated, postponed or cancelled; the postponed state similar to the initiated one except it's made in anticipation of a button that will do that later on; the cancelled state is basically the equivalent of being deleted and thus not shown in a future popup, except that the reminder still exists in the source file for recording purposes if you like. The reminders are stored in a simple Reminders.txt "source file" that ATM can be edited from Notepad (editing from the skin can be added later on, since postponing an "end time" would do just that), and has the following format, based on your posts so far and my judgment (in case of states):

Code: Select all

startyear-startmonth-startday, endyear-endmonth-endday, state, text
The skin:
Reminders_1.0.0.rmskin
The files...
Entropy.wav, aka the sound from Zapps Reality Check skin (to be added later in the code, on hiding a potential future popup)
Reminders.txt, aka the source file where all reminders are stored:

Code: Select all

2022-02-21,2022-02-23,Initiated,Customer John Smith coming
2022-02-21,2022-02-23,Postponed,Warranty repair for item 0367
2022-02-21,2022-02-23,Initiated,Part 0026 ordered by David Mitchell
2022-02-21,2022-02-23,Postponed,Repair approved for case 0928 (Susan Campbell)
2022-02-21,2022-02-23,Cancelled,Repair rejected for case 0051 (George Beckett)
2022-02-21,2022-02-23,Initiated,Piece 1926 ready to pick up by John Smith
Reminders.lua, aka the Lua code that pretty much does all the work (can load and save reminders from and to the source file and shows those meeting the time condition I mentioned above on update):

Code: Select all

function Initialize()
  states, reminders, reminderslist, reminderslistcount, currenttime = {'Initiated','Postponed','Cancelled'}, {}, {}, 0, os.time()
  LoadReminders('Reminders.txt')
end

function Update()
  currenttime, reminderslist, reminderslistcount = os.time(), {}, 0
  for i = 1, #reminders do
    local secondsdifference = os.difftime(currenttime, os.time({year=tonumber(reminders[i][4]), month=tonumber(reminders[i][5]), day=tonumber(reminders[i][6]), hour = 0, min = 0, sec = 0}))
    if reminders[i][7] ~= states[3] and secondsdifference>=0 then
      reminderslist[#reminderslist + 1] = reminders[i][1] .. '-' .. reminders[i][2] .. '-' .. reminders[i][3] .. ',' .. reminders[i][4] .. '-' .. reminders[i][5] .. '-' .. reminders[i][6] .. ',' .. reminders[i][7] .. ',' .. reminders[i][8]
    end
  end
  reminderslistcount = #reminderslist
  return table.concat(reminderslist, '\n')
end

function LoadReminders(remindersname)
  local reminderspath = SKIN:MakePathAbsolute(remindersname)
  local remindersfile = assert(io.open(reminderspath, 'r'), 'Unable to load ' .. reminderspath)
  reminders = {}
  for remindersline in remindersfile:lines() do
    startyear, startmonth, startday, endyear, endmonth, endday, state, text = remindersline:match('^(.+)%-(.+)%-(.+),(.+)%-(.+)%-(.+),(.+),(.+)$')
    reminders[#reminders + 1] = {startyear, startmonth, startday, endyear, endmonth, endday, state, text}
  end
  remindersfile:close()
  print('Loaded ' .. #reminders .. ' reminders from ' .. reminderspath)
  return true
end

function SaveReminders(remindersname)
  local reminderspath = SKIN:MakePathAbsolute(remindersname)
  local remindersfile = assert(io.open(reminderspath, 'w'), 'Unable to save ' .. reminderspath)
  local reminderslines = {}
  for i = 1, #reminders do
    reminderslines[#reminderslines + 1] = reminders[i][1] .. '-' .. reminders[i][2] .. '-' .. reminders[i][3] .. ',' .. reminders[i][4] .. '-' .. reminders[i][5] .. '-' .. reminders[i][6] .. ',' .. reminders[i][7] .. ',' .. reminders[i][8]
  end
  remindersfile:write(table.concat(reminderslines, '\n'))
  remindersfile:close()
  print('Saved ' .. #reminders .. ' reminders to ' .. reminderspath)
  return true
end
EventPopup.ini, aka the potential future "popup skin" like the Quotes skin from Zapps Reality Check earlier, currently empty, see below why: Reminders.ini, aka the main skin, which currently shows more or less what a potential future popup skin should show, i.e. the "active" reminders, if you like:

Code: Select all

[Variables]

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=47,47,47,255

---Measures---

[RemindersList]
Measure=Script
ScriptFile=#@#Reminders.lua

---Meters---

[RemindersText]
Meter=String
FontFace=Consolas
FontColor=255,255,255,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text="Reminders List ([&RemindersList:reminderslistcount])#CRLF##CRLF#[RemindersList]"
LeftMouseUpAction=[&Script:SaveReminders('Reminders.txt')]
DynamicVariables=1
The reason why I didn't finish it is because I want to know what you think of it, regarding the "fields" in the source file (like what should a start or end event should mean, in your view, cause right now the start event doesn't mean much) and how the "system" is built from your point of view, so that I know if I should continue with it. I don't like to do pointless things that would be of no use, so if you think you'll choose another path, please say so, no problem whatsoever.

What this skin doesn't have or do at this moment, given its unfinished status:
- it doesn't separate data between the main skin and the "popup" one (that's easy to do)
- it doesn't have OK, Cancel or Postpone buttons in such a popup skin that would trigger nothing, cancelling the reminder, or setting a new end time followed by saving the updated source file (also easy to do, since the saving function already exists)
- the potential popup doesn't yet show on the time condition, or hide if no un-cancelled reminders exist in the source file (easy as well)
- scrolling over the popup skin to iterate through the popup reminders list (slightly harder, but I've done it before on other occasions)

The main advantages of this approach is that:
- the code will be simple (it would have been more complicated without Lua in this case)
- allows any number of reminders in the source file, 10 or 10000 it doesn't matter
- reminders will still exist when cancelled, though they won't be shown in the popup (this can be useful if you want to have a "history" of them, for, say, accounting purposes or something)
- besides the source file, it will only require 2 skins, the main one and the popup, similar to Zapps Reality Check, since the popup will contain all reminders that are not cancelled and meet the time condition mentioned earlier, and scrolling in that list will be possible

Now, the choice is yours - let me know so I know what to do next. :D
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
jadiazrod
Posts: 46
Joined: February 1st, 2022, 7:07 pm

Re: Timer reminder

Post by jadiazrod »

I appreciate very much the assistance you re providing me Yincognito...
You must pardon my ignorance... I guess every newbie tries to modify what is already done accordingly to our needs... tweaking a little bit this and then another tweak over there...
I don't fully understand how to incorporate the unfinished skin sample to another skin to experiment the features built on it....neither how the Event Popup ini gets populated. :confused:
What is very simple for you guys is daunting for us newbies...
Thanks to you guys I've learned a lot of things about coding to get some things working... is like learning another Language... you start getting around and then... Lua script comes... and its like Chinese Mandarin... :uhuh:
Probably like in " The Matrix " you guys don't even see the code anymore... you see all those formulas and variables and already a picture of what that represent starts forming in your heads...
May I ask how to put all those things together...?
User avatar
Yincognito
Rainmeter Sage
Posts: 7157
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Timer reminder

Post by Yincognito »

jadiazrod wrote: February 23rd, 2022, 3:15 am I appreciate very much the assistance you re providing me Yincognito...
You must pardon my ignorance... I guess every newbie tries to modify what is already done accordingly to our needs... tweaking a little bit this and then another tweak over there...
I don't fully understand how to incorporate the unfinished skin sample to another skin to experiment the features built on it....neither how the Event Popup ini gets populated. :confused:
What is very simple for you guys is daunting for us newbies...
Thanks to you guys I've learned a lot of things about coding to get some things working... is like learning another Language... you start getting around and then... Lua script comes... and its like Chinese Mandarin... :uhuh:
Probably like in " The Matrix " you guys don't even see the code anymore... you see all those formulas and variables and already a picture of what that represent starts forming in your heads...
May I ask how to put all those things together...?
Nah, that's ok, we were all newbies once, in pretty much everything. ;-)
You don't have to incorporate this sample into anything, just let me know if you're ok with how it works and what it does (disregarding the things that are not yet done), so that I know if I need to change anything in my approach - that's all.

For example, the main skin takes its data from Reminders.txt, aka the "source file", which you can edit with Notepad for the moment, taking care to respect the format of StartDate,EndDate,ReminderState,ReminderText that you can see below (in your first post you said "ordering parts on Monday and being reminded if parts have not arrived yet a week later", so "Monday" is the StartDate and "a week later" is the EndDate in that case, with the ReminderState being Initiated if "active", Postponed if the timer has been reset to start over like you mentioned in your previous replies, and Cancelled if that reminder is to be "deleted" or not bothering you anymore):

Code: Select all

2022-02-21,2022-02-23,Initiated,Customer John Smith coming
2022-02-21,2022-02-23,Postponed,Warranty repair for item 0367
2022-02-21,2022-02-23,Initiated,Part 0026 ordered by David Mitchell
2022-02-21,2022-02-23,Postponed,Repair approved for case 0928 (Susan Campbell)
2022-02-21,2022-02-23,Cancelled,Repair rejected for case 0051 (George Beckett)
2022-02-21,2022-02-23,Initiated,Piece 1926 ready to pick up by John Smith
The main skin looks like this:
Reminders.jpg
Now, apart from being still ugly and gray, you can notice that:
- what "should be" the main skin and the popup are kind of "merged" above, i.e. you'd want the first line to be in the main skin and the last 5 lines in a popup that is either hidden or shown depending on whether the current date is past the end date for those reminders in the list (e.g. in the case of your phrase from the first post, that would happen if the current date is past "a week later" from the "Monday" when those parts were ordered)
- the popup doesn't yet exist; that is irrelevant since it's not a problem to make one, the data being already there and "filtered", i.e. if you change your computer date to say 2022-02-22 while keeping the skin loaded you'll notice that all the reminders will dissapear and their number will be 0 simply because that date is not yet past the end dates of the reminders in the Reminders.txt source file, aka 2022-02-23, so no "popup" should be triggered; also, you'll notice that those 5 last lines don't include the 2022-02-21,2022-02-23,Cancelled,Repair rejected for case 0051 (George Beckett) reminder in the source file, because that reminder has been cancelled - or "deleted" if you like
- you can of course, further edit the source file to make it more diverse, and see only some reminders when you change your computer date, others when you change it to another date, and so on; is this process starting to make sense now, apart from the fact that you need to "simulate" the passing of time to see what happens? I mean, it would be easier and faster to see this if we were talking about minutes or seconds, but since you mentioned days, I assume you won't wait a whole day to test if something like this works, right?

That's pretty much all there is to it at this moment - are you ok with it, does it do what you envision (bar the yet inexistent popup for now, of course), do you have any suggestions or things that I missed regarding the basic idea?

Yeah, Lua was Chinese Mandarin for me too before I needed some of its features and started writing for it, so I understand your view on it, LMAO. Don't worry about the coding details yet, I'll explain them when and if you give me the ok to finish it (if you're going to use it one way or another, that is). Lua is different from the native Rainmeter INI format, but it's actually just a couple of dozen functions, as it's a scripting language and not a fully fledged one, so not that hard to wrap you mind around some key concepts. For example, for the Lua 5.1 Manual, most of the functions used in the code are only from the 5.1 – Basic Functions section there, so more or less towards the end of the document. Having done the above in Lua is actually simplifying things for you, because it would have taken lengthier and more complex code to replicate some of that in native Rainmeter, in this specific case.
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
jadiazrod
Posts: 46
Joined: February 1st, 2022, 7:07 pm

Re: Timer reminder

Post by jadiazrod »

You're right again Yincognito...
Our lack of knowledge about this stuff make us to focus on the appearance and visuals instead on the functionality of a skin...
The sample you made above has all the ingredients to accomplish the scheduler project we have in mind...
Before we move forward let me share with you some facts about what we do...
We repair electronics... and when I say repair that means " repair" not replace modules & Boards... which translates in tracking Model Numbers, Serial Numbers, Purchase Order Numbers, PCB component Location Numbers, Part Numbers, Numbers printed on Components, Numbers on the Service Manual, Phone Numbers, Tracking Numbers.... Now add to that another funny fact... my memory is TERRIBLE... reason for the birth of this project...

Considering the amount of " Numbers we have to play with, it sound interesting working with Days ( Monday, Tuesday, Wednesday, etc... ) instead of Dates... yeas, its nice having the benefit to have a visible date, but more important will be the day of the week... and work in a weekly basis... less information to look at and more space to display reminders avoiding confusion and mistakes... (I don't want to see more Numbers at front my eyes... ;-) )
Tinkering with the computer date is not a good idea... it will mess up tons of things here... No need to consider that option...
I think having a reminder popping up ( blinking with music and red text for instance ) will be sufficient to take hands on that event and Order parts for instance... I don't think it needs a due date either... ( since the reminder will pop up again lets say, 3 days later if not completed )... besides, a repair is done whenever is done... if parts are stuck in Customs there is no much can be done about it... we can always call customers and let them know parts are in Back Order or so... and customers will come to pick up their stuff whenever they remember it... but keeping the reminder alive will help us keep bugging customers until they come to pick their stuff... Besides, Customers will have 30 days from the day they were called to pick their stuff up... after that pieces will be considered abandoned... ( time to reset that event and start another one...)

The idea of having one hidden skin containing populating events and popping up as events reach their end time was pretty good... but as days pass, today's event should move one day back giving space for the current day and so on.... ( some kind of scrolling agenda....) which it would be more complicated than having a little "sticky note" popping up as each event gets its end time... it would be a plus if events could be written directly to the Little "Sticky Note" and a way to assign a day for it...
Cheers
User avatar
Yincognito
Rainmeter Sage
Posts: 7157
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Timer reminder

Post by Yincognito »

jadiazrod wrote: February 23rd, 2022, 8:14 pm You're right again Yincognito...
Our lack of knowledge about this stuff make us to focus on the appearance and visuals instead on the functionality of a skin...
The sample you made above has all the ingredients to accomplish the scheduler project we have in mind...
Before we move forward let me share with you some facts about what we do...
We repair electronics... and when I say repair that means " repair" not replace modules & Boards... which translates in tracking Model Numbers, Serial Numbers, Purchase Order Numbers, PCB component Location Numbers, Part Numbers, Numbers printed on Components, Numbers on the Service Manual, Phone Numbers, Tracking Numbers.... Now add to that another funny fact... my memory is TERRIBLE... reason for the birth of this project...

Considering the amount of " Numbers we have to play with, it sound interesting working with Days ( Monday, Tuesday, Wednesday, etc... ) instead of Dates... yeas, its nice having the benefit to have a visible date, but more important will be the day of the week... and work in a weekly basis... less information to look at and more space to display reminders avoiding confusion and mistakes... (I don't want to see more Numbers at front my eyes... ;-) )
Tinkering with the computer date is not a good idea... it will mess up tons of things here... No need to consider that option...
I think having a reminder popping up ( blinking with music and red text for instance ) will be sufficient to take hands on that event and Order parts for instance... I don't think it needs a due date either... ( since the reminder will pop up again lets say, 3 days later if not completed )... besides, a repair is done whenever is done... if parts are stuck in Customs there is no much can be done about it... we can always call customers and let them know parts are in Back Order or so... and customers will come to pick up their stuff whenever they remember it... but keeping the reminder alive will help us keep bugging customers until they come to pick their stuff... Besides, Customers will have 30 days from the day they were called to pick their stuff up... after that pieces will be considered abandoned... ( time to reset that event and start another one...)

The idea of having one hidden skin containing populating events and popping up as events reach their end time was pretty good... but as days pass, today's event should move one day back giving space for the current day and so on.... ( some kind of scrolling agenda....) which it would be more complicated than having a little "sticky note" popping up as each event gets its end time... it would be a plus if events could be written directly to the Little "Sticky Note" and a way to assign a day for it...
Cheers
Alright, but just so to be clear, I'm not going to build a database, I'll only set up the reminder part, and then it'll be up to you to adjust it further, once I explain how things work. So, from that point of view, what your shop does isn't that relevant to the objective at hand, setting the reminder properly using the Text "field" in the source file will be entirely up to you or whoever will use the skin or edit the source file.

I can make it to allow actual reminder editing (apart from the popup showing when the time is up for already existing reminders), but first the popup thing needs to work properly, so one step at a time. You'll also need to test it to make sure it suits the objective, and really, without time changing it's impossible to do such testing, so if it's like that, you'll have to rely on my understanding of things (which might or might not be precisely what you envision). After all, you can easily set back the time to the right one by synchronizing with an atomic clock server on the internet, the Windows Control Panel's Date and Time already has that and it's a matter of two or three clicks, no disaster pending, LOL.

Regarding days of week, yes, they can easily be added - I actually thought about that in the beginning but skipped that part for later on. Days passing by will automatically be handled by the Time manipulation in the skin BUT it will also depend on you to click OK or Cancel to make the needed reminder "obsolete", otherwise it will keep popping up in the list until it's "solved" one way or another, there's no magic way to get around that, it's how stuff works.

In case you're curious, this is how it looks now (the little clock and the exclamation mark will flash and the popup will show and play the sound, unless you edit those reminders to have their end time further in the future):
Reminders_1.1.0.rmskin
Reminders.jpg
Not finished yet, since personally I have no deadline on this and do other things as well as you can imagine, but it's step by step getting there. The popup is "half" done, the scrolling, OK/Cancel/Postpone buttons, and potentially editing the "active" reminders are next. Then, adding the weekday is not big deal, but a more comprehensive editing, while entirely possible, will require a bit more attention and work. ;-)
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7157
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Timer reminder

Post by Yincognito »

jadiazrod wrote: February 23rd, 2022, 8:14 pmThe sample you made above has all the ingredients to accomplish the scheduler project we have in mind...
[...]
Considering the amount of " Numbers we have to play with, it sound interesting working with Days ( Monday, Tuesday, Wednesday, etc... ) instead of Dates... yeas, its nice having the benefit to have a visible date, but more important will be the day of the week... and work in a weekly basis... less information to look at and more space to display reminders avoiding confusion and mistakes... (I don't want to see more Numbers at front my eyes... ;-) )
[...]
I think having a reminder popping up ( blinking with music and red text for instance ) will be sufficient to take hands on that event and Order parts for instance...
[...]
The idea of having one hidden skin containing populating events and popping up as events reach their end time was pretty good... but as days pass, today's event should move one day back giving space for the current day and so on.... ( some kind of scrolling agenda....) which it would be more complicated than having a little "sticky note" popping up as each event gets its end time... it would be a plus if events could be written directly to the Little "Sticky Note" and a way to assign a day for it...
Ok, so this took a bit longer than expected due to various reasons, but this is very close to the final version, if you're still interested (and if not, this is a project for the community here as well, since it's basically a fully fledged CSV editor, that can be adapted easily for a variety of purposes and source data):
Reminders_1.1.8.rmskin
Reminders.txt, the test source file:

Code: Select all

2022-02-10 00:00:00, 2022-02-21 00:00:00, Customer John Smith coming
2022-02-11 00:00:00, 2022-02-18 00:00:00, Warranty repair for item 0367
2022-02-12 00:00:00, 2022-02-20 00:00:00, Part 0026 ordered by David Mitchell
2022-02-13 00:00:00, 2022-02-19 00:00:00, Repair approved for case 0928 (Susan Campbell)
2022-02-14 00:00:00, 2022-02-23 00:00:00, Repair rejected for case 0051 (George Beckett)
2022-02-15 00:00:00, 2022-02-22 00:00:00, Piece 1926 ready to pick up by John Smith
2022-02-10 00:00:00, 2022-02-21 00:00:00, Customer John Smith coming
2022-02-11 00:00:00, 2022-02-18 00:00:00, Warranty repair for item 0367
2022-02-12 00:00:00, 2022-02-20 00:00:00, Part 0026 ordered by David Mitchell
2022-02-13 00:00:00, 2022-02-19 00:00:00, Repair approved for case 0928 (Susan Campbell)
2022-02-14 00:00:00, 2022-02-23 00:00:00, Repair rejected for case 0051 (George Beckett)
2022-02-15 00:00:00, 2022-02-22 00:00:00, Piece 1926 ready to pick up by John Smith
2022-02-10 00:00:00, 2022-02-21 00:00:00, Customer John Smith coming
2022-02-11 00:00:00, 2022-02-18 00:00:00, Warranty repair for item 0367
2022-02-12 00:00:00, 2022-02-20 00:00:00, Part 0026 ordered by David Mitchell
2022-02-13 00:00:00, 2022-02-19 00:00:00, Repair approved for case 0928 (Susan Campbell)
Variables.inc, more or less the Rainmeter / Lua common variables:

Code: Select all

[Variables]
Manual=0
Setup=0
MaxPageRows=20
TimeUnit=86400
PageRows=5
Reminders.lua, most of the managing happens here, in these 100 lines:

Code: Select all

function Initialize()
  fields = {3, 6}; items, infos, now, tkeys, tform, lform = {}, {}, os.time(), {'year', 'month', 'day', 'hour', 'min', 'sec'}, '^(.-)%-(.-)%-(.-)%s+(.-):(.-):(.-)$', '^' .. ('%s*(.-),'):rep(fields[1]):gsub(',$', '') .. '$'
  LoadItems('')
  return true
end

function Update()
  now, infos, setup, tunit = os.time(), {}, tonumber(SKIN:GetVariable('Setup')), SKIN:ParseFormula(SKIN:GetVariable('TimeUnit'))
  for i = 1, #items do
    local xtras = {i, Round(os.difftime(now, TimeStamp(items[i][2])) / tunit, 0), Round(os.difftime(TimeStamp(items[i][2]), TimeStamp(items[i][1])) / tunit, 0)}
    if setup > 0 or (xtras[2] and xtras[2] > 0) then
      infos[#infos + 1] = {unpack(items[i])}
      for j = 1, #xtras do infos[#infos][#infos[#infos] + 1] = xtras[j] end
    end
  end
  return GetCount()
end

function LoadItems(path)
  if path == '' then path = SELF:GetOption('PathToFile') elseif not path:match(':') then path = SKIN:MakePathAbsolute(path) end
  local file = assert(io.open(path, 'r'), 'Unable to load file ' .. path)
  items = {}; for line in file:lines() do if line:match(lform) then items[#items + 1] = {line:match(lform)} end end
  file:close(); sort = {0, 0}; Update()
  print('Loaded ' .. #items .. ' items from file ' .. path)
  return true
end

function SaveItems(path)
  if path == '' then path = SELF:GetOption('PathToFile') elseif not path:match(':') then path = SKIN:MakePathAbsolute(path) end
  local file = assert(io.open(path, 'w'), 'Unable to save file ' .. path)
  local lines = {}; for i = 1, #items do lines[#lines + 1] = table.concat(items[i], ', ') end
  file:write(table.concat(lines, '\n')); file:close()
  print('Saved ' .. #items .. ' items to file ' .. path)
  return true
end

function Round(number, decimals)
  number = number * 10 ^ decimals
  number = (number < 0 and math.ceil(number - 0.5) or math.floor(number + 0.5))
  return (number == -0 and 0 or (decimals == 0 and number or number / decimals))
end

function TimeTable(ttext)
  local ttable, tvals, nulls = {}, {tostring(ttext):match(tform)}, 0
  for i = 1, #tkeys do if not tvals or i < 1 or i > #tvals then ttable[tkeys[i]] = '0'; nulls = nulls + 1 else ttable[tkeys[i]] = tvals[i] end end
  if nulls < #tkeys then return ttable else return nil end
end

function TimeStamp(ttext)
  local ttable = TimeTable(ttext)
  return ttable and os.time(ttable) or ttext
end

function GetCount()
  if not infos then return 0 else return #infos end
end

function GetFields(index)
  index = SKIN:ParseFormula(index)
  if not infos or index < 1 or index > #infos then return '' else return table.concat(infos[index], ', ') end
end

function GetField(index, field)
  index = SKIN:ParseFormula(index)
  if not infos or index < 1 or index > #infos or field < 1 or field > fields[2] then return '' else return infos[index][field] end
end

function GetItems()
  if not items then return 0 else return #items end
end

function SetSort(field, order)
  sort = {field, order}; order = (field == fields[1] + 1 and 1 or order)
  if not infos or not items or field < 1 or field > fields[2] then
    return true
  else
    table.sort(infos, function(a,b) return TimeStamp((order > 0 and b or a)[field]) < TimeStamp((order > 0 and a or b)[field]) end)
    for i = 1, #infos do items[#items + 1] = {unpack(items[infos[i][fields[1] + 1]])}; items[infos[i][fields[1] + 1]] = {} end
    for i = #items, 1, -1 do if items[i] and #items[i] == 0 then table.remove(items, i) end end
    Update()
    return true
  end
end

function InsFields(index, value)
  index = SKIN:ParseFormula(index)
  if not infos or not items or index < 0 or index > #infos then return true else table.insert(items, (index < 1 and #items + 1 or infos[index][fields[1] + 1]), {value:match(lform)}); Update(); return true end
end

function DupFields(index)
  index = SKIN:ParseFormula(index)
  if not infos or not items or index < 0 or index > #infos or #items < 1 then return true else table.insert(items, (index < 1 and #items + 1 or infos[index][fields[1] + 1]), {unpack(items[(index < 1 and #items + 0 or infos[index][fields[1] + 1])])}); Update(); return true end
end

function SetFields(index, value)
  index = SKIN:ParseFormula(index)
  if not infos or not items or index < 1 or index > #infos then return true else items[infos[index][fields[1] + 1]] = {value:match(lform)}; Update(); return true end
end

function SetField(index, field, value, vform)
  index = SKIN:ParseFormula(index)
  if not infos or not items or index < 1 or index > #infos or field < 1 or field > fields[1] then return true else items[infos[index][fields[1] + 1]][field] = string.format('%' .. vform, (vform == 's' and value or SKIN:ParseFormula(value))); Update(); return true end
end

function RemFields(index)
  index = SKIN:ParseFormula(index)
  if not infos or not items or index < 0 or index > #infos then return true else table.remove(items, (index < 1 and #items + 0 or infos[index][fields[1] + 1])); Update(); return true end
end
ListManager.ini, the visual side of the manager, which is only this long because of copy pasting lots of measures and meters from an otherwise simple format:

Code: Select all

[Variables]
Update=1000
SetScroll0=[!EnableMouseAction * "MouseScrollDownAction|MouseScrollUpAction"]
SetScroll1=[!DisableMouseAction * "MouseScrollDownAction|MouseScrollUpAction"]
NoScroll=0
StrokeWidth=2
StrokeColor=255,0,0,255
BackgroundColor=0,0,0,96
FontColor=255,255,255,255
InvertedFontColor=0,0,0,255
TintColor=128,128,128,255
NoTintColor=255,255,255,255
IconScale=0.75
FontFace=Times New Roman
FontSize=14
LineWidth=([#LineHeight]+[#LineIndent]+[#Field4Width[#Setup]]+[#LineIndent]+[#Field1Width[#Setup]]+[#LineIndent]+[#Field2Width[#Setup]]+[#LineIndent]+[#Field3Width[#Setup]]+[#LineIndent]+[#Field5Width[#Setup]]+[#LineIndent]+[#Field6Width[#Setup]]+[#LineIndent]+[#LineHeight])
LineIndent=5
LineSpace=5
LineHeight=21
RegularColor=0,0,0,1
HeadingColor=32,32,32,96
SelectedColor=0,255,255,255
HeadRow=0
TimeForm0=%a %d %b %Y
TimeForm1=%Y-%m-%d %H:%M:%S
TimeStamp0=Mon 01 Jan 1601
TimeStamp1=1601-01-01 00:00:00
TSPRWidth=(Min(90,([#LineWidth]-[#LineHeight]*4-[#TitleWidth]-[#LineIndent]*6)/2))
TitleWidth=130
Field4Width0=70
Field1Width0=150
Field2Width0=150
Field3Width0=300
Field5Width0=70
Field6Width0=70
Field4Width1=70
Field1Width1=170
Field2Width1=170
Field3Width1=260
Field5Width1=70
Field6Width1=70
SortField=0
SortOrder=0
SortOrderSign0=[\x200B] ▲ [\x200B]
SortOrderSign1=[\x200B] ▼ [\x200B]
@IncludeVariables=#@#Variables.inc

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
MouseLeaveAction=[!SetOptionGroup IconGroup TransformationMatrix "1;0;0;1;0;0"][!UpdateMeter *][!Redraw]
OnCloseAction=[PlayStop]

---Measures---

[Setup]
Group=InitGroup
Measure=String
String=#Setup#
UpdateDivider=-1
RegExpSubstitute=1
Substitute="^0$":"Infos","^1$":"Items"
IfCondition=(Setup=0) && (#Manual#=0)
IfTrueAction=[Play "#@#Entropy.wav"]
IfFalseAction=[PlayStop]
IfConditionMode=1
DynamicVariables=1

[Initialize]
Group=InitGroup
Measure=Calc
OnUpdateAction=[!SetVariable NoScroll 0][!SetVariable HeadRow 0][!SetVariable SortField 0][!SetVariable SortOrder 0][!SetOption TimeConverter TimeStamp [#TimeStamp[#Setup]]][!SetOption TimeStampConverter TimeStamp 0][!SetOptionGroup InputTextGroup StringAlign "Center"][!SetOptionGroup InputTextGroup ClipString 1][!SetOptionGroup InputTextGroup SolidColor "#SelectedColor#"][!SetOptionGroup InputTextGroup FontFace "#FontFace#"][!SetOptionGroup InputTextGroup FontColor "#InvertedFontColor#"][!SetOptionGroup InputTextGroup FontSize #FontSize#][!SetOptionGroup InputTextGroup AntiAlias 1]
UpdateDivider=-1
DynamicVariables=1

[List]
Group=ListGroup
Measure=Script
ScriptFile=#@#Reminders.lua
PathToFile=#@#Reminders.txt
UpdateDivider=((1-#Setup#*2)*1000/#Update#)
OnUpdateAction=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
DynamicVariables=1

[Now]
Group=TimeConverterGroup
Measure=Time
Format=#TimeForm1#

[TimeConverter]
Group=TimeConverterGroup
Measure=Time
Format=#TimeForm1#
TimeStamp=[#TimeStamp[#Setup]]
TimeStampFormat=[#TimeForm[#Setup]]
UpdateDivider=-1
DynamicVariables=1

[TimeStampConverter]
Group=TimeConverterGroup
Measure=Time
Format=#TimeForm1#
TimeStamp=0
UpdateDivider=-1
DynamicVariables=1

[TimeUnitInput]
Group=ItemFieldsGroup | InputTextGroup
Measure=Plugin
Plugin=InputText
X=[TimeUnit:X]
Y=[TimeUnit:Y]
W=[TimeUnit:W]
H=[TimeUnit:H]
DefaultValue=#TimeUnit#
InputNumber=1
UpdateDivider=-1
Command1=[!SetVariable TimeUnit "$UserInput$"][!SetVariable TimeUnit "[TimeUnitInput]" "#ROOTCONFIG#"][!WriteKeyValue Variables TimeUnit "[TimeUnitInput]" "#@#Variables.inc"]
Command2=[!UpdateMeasureGroup ListGroup]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[PageRowsInput]
Group=ItemFieldsGroup | InputTextGroup
Measure=Plugin
Plugin=InputText
X=[PageRows:X]
Y=[PageRows:Y]
W=[PageRows:W]
H=[PageRows:H]
DefaultValue=#PageRows#
InputNumber=1
UpdateDivider=-1
Command1=[!SetVariable PageRows "$UserInput$"][!SetVariable PageRows "[PageRowsInput]" "#ROOTCONFIG#"][!WriteKeyValue Variables PageRows "[PageRowsInput]" "#@#Variables.inc"]
Command2=[!UpdateMeasureGroup ListGroup]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item1Field1Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+1)',1)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item1Field2Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+1)',2)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item2Field1Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+2)',1)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item2Field2Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+2)',2)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item3Field1Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+3)',1)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item3Field2Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+3)',2)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item4Field1Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+4)',1)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item4Field2Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+4)',2)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item5Field1Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+5)',1)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item5Field2Time]
Group=ItemFieldsGroup
Disabled=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Measure=Time
Format=[#TimeForm[#Setup]]
TimeStamp=[&List:GetField('(#HeadRow#+5)',2)]
TimeStampFormat=#TimeForm1#
UpdateDivider=-1
DynamicVariables=1

[Item1Field1Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item1Field1:X]
Y=[Item1Field1:Y]
W=[Item1Field1:W]
H=[Item1Field1:H]
DefaultValue=[Item1Field1Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+1)',1,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item1Field2Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item1Field2:X]
Y=[Item1Field2:Y]
W=[Item1Field2:W]
H=[Item1Field2:H]
DefaultValue=[Item1Field2Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+1)',2,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item1Field3Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item1Field3:X]
Y=[Item1Field3:Y]
W=[Item1Field3:W]
H=[Item1Field3:H]
DefaultValue=[&List:GetField('(#HeadRow#+1)',3)]
UpdateDivider=-1
Command1=[]
Command2=[&List:SetField('(#HeadRow#+1)',3,"$UserInput$",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item2Field1Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item2Field1:X]
Y=[Item2Field1:Y]
W=[Item2Field1:W]
H=[Item2Field1:H]
DefaultValue=[Item2Field1Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+2)',1,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item2Field2Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item2Field2:X]
Y=[Item2Field2:Y]
W=[Item2Field2:W]
H=[Item2Field2:H]
DefaultValue=[Item2Field2Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+2)',2,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item2Field3Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item2Field3:X]
Y=[Item2Field3:Y]
W=[Item2Field3:W]
H=[Item2Field3:H]
DefaultValue=[&List:GetField('(#HeadRow#+2)',3)]
UpdateDivider=-1
Command1=[]
Command2=[&List:SetField('(#HeadRow#+2)',3,"$UserInput$",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item3Field1Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item3Field1:X]
Y=[Item3Field1:Y]
W=[Item3Field1:W]
H=[Item3Field1:H]
DefaultValue=[Item3Field1Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+3)',1,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item3Field2Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item3Field2:X]
Y=[Item3Field2:Y]
W=[Item3Field2:W]
H=[Item3Field2:H]
DefaultValue=[Item3Field2Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+3)',2,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item3Field3Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item3Field3:X]
Y=[Item3Field3:Y]
W=[Item3Field3:W]
H=[Item3Field3:H]
DefaultValue=[&List:GetField('(#HeadRow#+3)',3)]
UpdateDivider=-1
Command1=[]
Command2=[&List:SetField('(#HeadRow#+3)',3,"$UserInput$",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item4Field1Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item4Field1:X]
Y=[Item4Field1:Y]
W=[Item4Field1:W]
H=[Item4Field1:H]
DefaultValue=[Item4Field1Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+4)',1,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item4Field2Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item4Field2:X]
Y=[Item4Field2:Y]
W=[Item4Field2:W]
H=[Item4Field2:H]
DefaultValue=[Item4Field2Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+4)',2,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item4Field3Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item4Field3:X]
Y=[Item4Field3:Y]
W=[Item4Field3:W]
H=[Item4Field3:H]
DefaultValue=[&List:GetField('(#HeadRow#+4)',3)]
UpdateDivider=-1
Command1=[]
Command2=[&List:SetField('(#HeadRow#+4)',3,"$UserInput$",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item5Field1Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item5Field1:X]
Y=[Item5Field1:Y]
W=[Item5Field1:W]
H=[Item5Field1:H]
DefaultValue=[Item5Field1Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+5)',1,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item5Field2Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item5Field2:X]
Y=[Item5Field2:Y]
W=[Item5Field2:W]
H=[Item5Field2:H]
DefaultValue=[Item5Field2Time]
UpdateDivider=-1
Command1=[!SetOption TimeConverter TimeStamp "$UserInput$"][!UpdateMeasure TimeConverter]
Command2=[&List:SetField('(#HeadRow#+5)',2,"[&TimeConverter]",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

[Item5Field3Input]
Group=ItemFieldsGroup | InputTextGroup
Disabled=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Measure=Plugin
Plugin=InputText
X=[Item5Field3:X]
Y=[Item5Field3:Y]
W=[Item5Field3:W]
H=[Item5Field3:H]
DefaultValue=[&List:GetField('(#HeadRow#+5)',3)]
UpdateDivider=-1
Command1=[]
Command2=[&List:SetField('(#HeadRow#+5)',3,"$UserInput$",'s')]
Command3=[!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Command4=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
OnDismissAction=[!SetVariable NoScroll ([#NoScroll]-1)][#SetScroll[#NoScroll]]
DynamicVariables=1

---Styles---

[sIcons]
Group=IconGroup
X=(#LineIndent#)R
Y=(0)r
W=(#LineHeight#)
H=(#LineHeight#)
ImageTint=#TintColor#
UpdateDivider=-1
MouseOverAction=[!SetOption #CURRENTSECTION# ImageTint "#NoTintColor#"][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# ImageTint "#TintColor#"][!UpdateMeter *][!Redraw]
LeftMouseDownAction=[!SetOption #CURRENTSECTION# TransformationMatrix "(#IconScale#);0;0;(#IconScale#);((1-#IconScale#)*([#CURRENTSECTION#:X]+[#CURRENTSECTION#:W]/2));((1-#IconScale#)*([#CURRENTSECTION#:Y]+[#CURRENTSECTION#:H]/2))"][!UpdateMeter *][!Redraw]
MiddleMouseDownAction=[!SetOption #CURRENTSECTION# TransformationMatrix "(#IconScale#);0;0;(#IconScale#);((1-#IconScale#)*([#CURRENTSECTION#:X]+[#CURRENTSECTION#:W]/2));((1-#IconScale#)*([#CURRENTSECTION#:Y]+[#CURRENTSECTION#:H]/2))"][!UpdateMeter *][!Redraw]
DynamicVariables=1

[sPlace]
Group=PlaceGroup
X=(#LineIndent#)R
Y=(0)r
H=(#LineHeight#)
SolidColor=0,0,0,255
UpdateDivider=-1
DynamicVariables=1

[sTexts]
Container=#CURRENTSECTION#Place
X=([#CURRENTSECTION#Place:W]*0.5)
Y=([#CURRENTSECTION#Place:H]*0.0)
W=([#CURRENTSECTION#Place:W])
H=([#CURRENTSECTION#Place:H])
StringAlign=Center
FontFace=#FontFace#
FontColor=#FontColor#
FontSize=#FontSize#
ClipString=1
AntiAlias=1
InlineSetting=Size | (#FontSize#-1)
InlinePattern=(^#SortOrderSign0#|^#SortOrderSign1#|#SortOrderSign0#$|#SortOrderSign1#$)
UpdateDivider=-1
DynamicVariables=1

[sValue]
Group=ValueGroup
SolidColor=#RegularColor#
MouseOverAction=[!SetOptionGroup ValueGroup SolidColor "#RegularColor#"][!SetOption #CURRENTSECTION# SolidColor "#SelectedColor#"][!SetOption #CURRENTSECTION# FontColor "#InvertedFontColor#"][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# SolidColor "#RegularColor#"][!SetOption #CURRENTSECTION# FontColor "#FontColor#"][!UpdateMeter *][!Redraw]

---Meters---

[Background]
Meter=Shape
Shape=Rectangle (#StrokeWidth#/2),(#StrokeWidth#/2),(#LineWidth#+#LineIndent#*2+#StrokeWidth#),((#LineHeight#+#LineSpace#)*(2+#PageRows#)+#LineSpace#+#StrokeWidth#),(Max(#LineIndent#,#LineSpace#)*2) | Fill Color #BackgroundColor# | StrokeWidth #StrokeWidth# | Stroke Color #StrokeColor#
UpdateDivider=-1
MouseScrollUpAction=[!SetVariable HeadRow (Clamp(#HeadRow#-1,0,Max(0,[&List:GetCount()]-1)))][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetVariable HeadRow (Clamp(#HeadRow#+1,0,Max(0,[&List:GetCount()]-#PageRows#)))][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
DynamicVariables=1

[TitleBar]
Meter=Image
MeterStyle=sPlace
X=(#StrokeWidth#+#LineIndent#)
Y=(#StrokeWidth#+#LineSpace#)
W=(#LineWidth#)
SolidColor=#BackgroundColor#

[Load]
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#)
ImageName=#@#Load.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:LoadItems('')][!SetOptionGroup HeadingGroup Prefix ""][!SetOptionGroup HeadingGroup Postfix ""][!UpdateMeasureGroup InitGroup][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[TimeUnitPlace]
Meter=Image
MeterStyle=sPlace
W=(#TSPRWidth#)

[TimeUnit]
Meter=String
MeterStyle=sTexts | sValue
Text=#TimeUnit#
MouseScrollUpAction=[!SetVariable TimeUnit (Clamp(#TimeUnit#+1,1,31622400))][!SetVariable TimeUnit [#TimeUnit] "#ROOTCONFIG#"][!WriteKeyValue Variables TimeUnit [#TimeUnit] "#@#Variables.inc"][!UpdateMeasureGroup ListGroup][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetVariable TimeUnit (Clamp(#TimeUnit#-1,1,31622400))][!SetVariable TimeUnit [#TimeUnit] "#ROOTCONFIG#"][!WriteKeyValue Variables TimeUnit [#TimeUnit] "#@#Variables.inc"][!UpdateMeasureGroup ListGroup][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure TimeUnitInput "ExecuteBatch All"]

[TimeUnitIcon]
Meter=Image
MeterStyle=sIcons
ImageName=#@#TimeUnit.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[TitlePlace]
Meter=Image
MeterStyle=sPlace
X=(#StrokeWidth#+#LineIndent#+(#LineWidth#-#TitleWidth#)/2)
W=(#TitleWidth#)

[Title]
Meter=String
MeterStyle=sTexts
FontWeight=700
Text=[Setup] ([&List:GetCount()]/[&List:GetItems()])

[Save]
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#+#LineWidth#-#LineHeight#)
ImageName=#@#Save.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:SaveItems('')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[PageRowsPlace]
Meter=Image
MeterStyle=sPlace
X=(-#TSPRWidth#-#LineIndent#)r
W=(#TSPRWidth#)

[PageRows]
Meter=String
MeterStyle=sTexts | sValue
Text=#PageRows#
MouseScrollUpAction=[!SetVariable PageRows (Clamp(#PageRows#+1,1,#MaxPageRows#))][!SetVariable PageRows [#PageRows] "#ROOTCONFIG#"][!WriteKeyValue Variables PageRows [#PageRows] "#@#Variables.inc"][!UpdateMeasureGroup ListGroup][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetVariable PageRows (Clamp(#PageRows#-1,1,#MaxPageRows#))][!SetVariable PageRows [#PageRows] "#ROOTCONFIG#"][!WriteKeyValue Variables PageRows [#PageRows] "#@#Variables.inc"][!UpdateMeasureGroup ListGroup][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure PageRowsInput "ExecuteBatch All"]

[PageRowsIcon]
Meter=Image
MeterStyle=sIcons
X=(-#LineIndent#-#LineHeight#)r
ImageName=#@#PageRows.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[RemoveItemEnd]
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#)
Y=(#LineSpace#)R
Greyscale=1
ImageTint=0,128,128,255
ImageName=#@#Remove.png
MouseOverAction=[!SetOption #CURRENTSECTION# ImageTint "0,255,255,255"][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# ImageTint "0,128,128,255"][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:RemFields('0')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Heading4Place]
Meter=Image
MeterStyle=sPlace
W=([#Field4Width[#Setup]])

[Heading4]
Group=HeadingGroup
Meter=String
MeterStyle=sTexts
SolidColor=#HeadingColor#
FontWeight=700
Text=N
LeftMouseUpAction=[!SetVariable SortField 4][!SetVariable SortOrder ([#SortField]=#SortField#?1-#SortOrder#:1)][&List:SetSort([#SortField],[#SortOrder])][!SetOptionGroup HeadingGroup Prefix ""][!SetOptionGroup HeadingGroup Postfix ""][!SetOption #CURRENTSECTION# Prefix "[#SortOrderSign[#SortOrder]]"][!SetOption #CURRENTSECTION# Postfix "[#SortOrderSign[#SortOrder]]"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Heading1Place]
Meter=Image
MeterStyle=sPlace
W=([#Field1Width[#Setup]])

[Heading1]
Group=HeadingGroup
Meter=String
MeterStyle=sTexts
SolidColor=#HeadingColor#
FontWeight=700
Text=Start Time
LeftMouseUpAction=[!SetVariable SortField 1][!SetVariable SortOrder ([#SortField]=#SortField#?1-#SortOrder#:0)][&List:SetSort([#SortField],[#SortOrder])][!SetOptionGroup HeadingGroup Prefix ""][!SetOptionGroup HeadingGroup Postfix ""][!SetOption #CURRENTSECTION# Prefix "[#SortOrderSign[#SortOrder]]"][!SetOption #CURRENTSECTION# Postfix "[#SortOrderSign[#SortOrder]]"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Heading2Place]
Meter=Image
MeterStyle=sPlace
W=([#Field2Width[#Setup]])

[Heading2]
Group=HeadingGroup
Meter=String
MeterStyle=sTexts
SolidColor=#HeadingColor#
FontWeight=700
Text=End Time
LeftMouseUpAction=[!SetVariable SortField 2][!SetVariable SortOrder ([#SortField]=#SortField#?1-#SortOrder#:0)][&List:SetSort([#SortField],[#SortOrder])][!SetOptionGroup HeadingGroup Prefix ""][!SetOptionGroup HeadingGroup Postfix ""][!SetOption #CURRENTSECTION# Prefix "[#SortOrderSign[#SortOrder]]"][!SetOption #CURRENTSECTION# Postfix "[#SortOrderSign[#SortOrder]]"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Heading3Place]
Meter=Image
MeterStyle=sPlace
W=([#Field3Width[#Setup]])

[Heading3]
Group=HeadingGroup
Meter=String
MeterStyle=sTexts
SolidColor=#HeadingColor#
FontWeight=700
Text=Reminder Text
LeftMouseUpAction=[!SetVariable SortField 3][!SetVariable SortOrder ([#SortField]=#SortField#?1-#SortOrder#:0)][&List:SetSort([#SortField],[#SortOrder])][!SetOptionGroup HeadingGroup Prefix ""][!SetOptionGroup HeadingGroup Postfix ""][!SetOption #CURRENTSECTION# Prefix "[#SortOrderSign[#SortOrder]]"][!SetOption #CURRENTSECTION# Postfix "[#SortOrderSign[#SortOrder]]"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Heading5Place]
Meter=Image
MeterStyle=sPlace
W=([#Field5Width[#Setup]])

[Heading5]
Group=HeadingGroup
Meter=String
MeterStyle=sTexts
SolidColor=#HeadingColor#
FontWeight=700
Text=T
LeftMouseUpAction=[!SetVariable SortField 5][!SetVariable SortOrder ([#SortField]=#SortField#?1-#SortOrder#:0)][&List:SetSort([#SortField],[#SortOrder])][!SetOptionGroup HeadingGroup Prefix ""][!SetOptionGroup HeadingGroup Postfix ""][!SetOption #CURRENTSECTION# Prefix "[#SortOrderSign[#SortOrder]]"][!SetOption #CURRENTSECTION# Postfix "[#SortOrderSign[#SortOrder]]"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Heading6Place]
Meter=Image
MeterStyle=sPlace
W=([#Field6Width[#Setup]])

[Heading6]
Group=HeadingGroup
Meter=String
MeterStyle=sTexts
SolidColor=#HeadingColor#
FontWeight=700
Text=P
LeftMouseUpAction=[!SetVariable SortField 6][!SetVariable SortOrder ([#SortField]=#SortField#?1-#SortOrder#:0)][&List:SetSort([#SortField],[#SortOrder])][!SetOptionGroup HeadingGroup Prefix ""][!SetOptionGroup HeadingGroup Postfix ""][!SetOption #CURRENTSECTION# Prefix "[#SortOrderSign[#SortOrder]]"][!SetOption #CURRENTSECTION# Postfix "[#SortOrderSign[#SortOrder]]"][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[InsertItemEnd]
Meter=Image
MeterStyle=sIcons
Greyscale=1
ImageTint=0,128,128,255
ImageName=#@#Insert.png
MouseOverAction=[!SetOption #CURRENTSECTION# ImageTint "0,255,255,255"][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# ImageTint "0,128,128,255"][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('0','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:DupFields('0')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[RemoveItem1]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#)
Y=(#LineSpace#)R
ImageName=#@#Remove.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:RemFields('(#HeadRow#+1)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item1Field4Place]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field4Width[#Setup]])

[Item1Field4]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+1)',4)]

[Item1Field1Place]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field1Width[#Setup]])

[Item1Field1]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item1Field1Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item1Field1Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+1)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item1Field1Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+1)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item1Field1Input "ExecuteBatch All"]

[Item1Field2Place]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field2Width[#Setup]])

[Item1Field2]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item1Field2Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item1Field2Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+1)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item1Field2Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+1)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item1Field2Input "ExecuteBatch All"]

[Item1Field3Place]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field3Width[#Setup]])

[Item1Field3]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+1)',3)]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item1Field3Input "ExecuteBatch All"]

[Item1Field5Place]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field5Width[#Setup]])

[Item1Field5]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+1)',5)]

[Item1Field6Place]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field6Width[#Setup]])

[Item1Field6]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+1)',6)]

[InsertItem1]
Hidden=((#HeadRow#+1>[&List:GetCount()])||(1>#PageRows#))
Meter=Image
MeterStyle=sIcons
ImageName=#@#Insert.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+1)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:DupFields('(#HeadRow#+1)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[RemoveItem2]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#)
Y=(#LineSpace#)R
ImageName=#@#Remove.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:RemFields('(#HeadRow#+2)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item2Field4Place]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field4Width[#Setup]])

[Item2Field4]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+2)',4)]
LeftMouseUpAction=[!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+2)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[&List:DupFields('(#HeadRow#+2)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
RightMouseUpAction=[&List:RemFields('(#HeadRow#+2)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item2Field1Place]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field1Width[#Setup]])

[Item2Field1]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item2Field1Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item2Field1Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+2)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item2Field1Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+2)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item2Field1Input "ExecuteBatch All"]

[Item2Field2Place]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field2Width[#Setup]])

[Item2Field2]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item2Field2Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item2Field2Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+2)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item2Field2Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+2)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item2Field2Input "ExecuteBatch All"]

[Item2Field3Place]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field3Width[#Setup]])

[Item2Field3]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+2)',3)]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item2Field3Input "ExecuteBatch All"]

[Item2Field5Place]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field5Width[#Setup]])

[Item2Field5]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+2)',5)]

[Item2Field6Place]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field6Width[#Setup]])

[Item2Field6]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+2)',6)]

[InsertItem2]
Hidden=((#HeadRow#+2>[&List:GetCount()])||(2>#PageRows#))
Meter=Image
MeterStyle=sIcons
ImageName=#@#Insert.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+2)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:DupFields('(#HeadRow#+2)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[RemoveItem3]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#)
Y=(#LineSpace#)R
ImageName=#@#Remove.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:RemFields('(#HeadRow#+3)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item3Field4Place]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field4Width[#Setup]])

[Item3Field4]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+3)',4)]
LeftMouseUpAction=[!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+3)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[&List:DupFields('(#HeadRow#+3)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
RightMouseUpAction=[&List:RemFields('(#HeadRow#+3)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item3Field1Place]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field1Width[#Setup]])

[Item3Field1]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item3Field1Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item3Field1Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+3)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item3Field1Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+3)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item3Field1Input "ExecuteBatch All"]

[Item3Field2Place]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field2Width[#Setup]])

[Item3Field2]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item3Field2Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item3Field2Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+3)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item3Field2Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+3)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item3Field2Input "ExecuteBatch All"]

[Item3Field3Place]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field3Width[#Setup]])

[Item3Field3]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+3)',3)]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item3Field3Input "ExecuteBatch All"]

[Item3Field5Place]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field5Width[#Setup]])

[Item3Field5]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+3)',5)]

[Item3Field6Place]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field6Width[#Setup]])

[Item3Field6]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+3)',6)]

[InsertItem3]
Hidden=((#HeadRow#+3>[&List:GetCount()])||(3>#PageRows#))
Meter=Image
MeterStyle=sIcons
ImageName=#@#Insert.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+3)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:DupFields('(#HeadRow#+3)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[RemoveItem4]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#)
Y=(#LineSpace#)R
ImageName=#@#Remove.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:RemFields('(#HeadRow#+4)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item4Field4Place]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field4Width[#Setup]])

[Item4Field4]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+4)',4)]
LeftMouseUpAction=[!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+4)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[&List:DupFields('(#HeadRow#+4)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
RightMouseUpAction=[&List:RemFields('(#HeadRow#+4)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item4Field1Place]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field1Width[#Setup]])

[Item4Field1]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item4Field1Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item4Field1Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+4)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item4Field1Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+4)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item4Field1Input "ExecuteBatch All"]

[Item4Field2Place]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field2Width[#Setup]])

[Item4Field2]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item4Field2Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item4Field2Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+4)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item4Field2Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+4)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item4Field2Input "ExecuteBatch All"]

[Item4Field3Place]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field3Width[#Setup]])

[Item4Field3]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+4)',3)]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item4Field3Input "ExecuteBatch All"]

[Item4Field5Place]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field5Width[#Setup]])

[Item4Field5]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+4)',5)]

[Item4Field6Place]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field6Width[#Setup]])

[Item4Field6]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+4)',6)]

[InsertItem4]
Hidden=((#HeadRow#+4>[&List:GetCount()])||(4>#PageRows#))
Meter=Image
MeterStyle=sIcons
ImageName=#@#Insert.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+4)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:DupFields('(#HeadRow#+4)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[RemoveItem5]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sIcons
X=(#StrokeWidth#+#LineIndent#)
Y=(#LineSpace#)R
ImageName=#@#Remove.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:RemFields('(#HeadRow#+5)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item5Field4Place]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field4Width[#Setup]])

[Item5Field4]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+5)',4)]
LeftMouseUpAction=[!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+5)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[&List:DupFields('(#HeadRow#+5)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
RightMouseUpAction=[&List:RemFields('(#HeadRow#+5)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]

[Item5Field1Place]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field1Width[#Setup]])

[Item5Field1]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item5Field1Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item5Field1Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+5)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item5Field1Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+5)',1,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item5Field1Input "ExecuteBatch All"]

[Item5Field2Place]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field2Width[#Setup]])

[Item5Field2]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[Item5Field2Time]
MouseScrollUpAction=[!SetOption TimeStampConverter TimeStamp ([Item5Field2Time:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+5)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption TimeStampConverter TimeStamp ([Item5Field2Time:TimeStamp]-#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:SetField('(#HeadRow#+5)',2,'[&TimeStampConverter]','s')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item5Field2Input "ExecuteBatch All"]

[Item5Field3Place]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field3Width[#Setup]])

[Item5Field3]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+5)',3)]
LeftMouseUpAction=[!SetVariable NoScroll ([#NoScroll]+1)][#SetScroll[#NoScroll]][!CommandMeasure Item5Field3Input "ExecuteBatch All"]

[Item5Field5Place]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field5Width[#Setup]])

[Item5Field5]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+5)',5)]

[Item5Field6Place]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sPlace
W=([#Field6Width[#Setup]])

[Item5Field6]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=String
MeterStyle=sTexts | sValue
Text=[&List:GetField('(#HeadRow#+5)',6)]

[InsertItem5]
Hidden=((#HeadRow#+5>[&List:GetCount()])||(5>#PageRows#))
Meter=Image
MeterStyle=sIcons
ImageName=#@#Insert.png
LeftMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][!SetOption TimeStampConverter TimeStamp ([&Now:TimeStamp]+#TimeUnit#)][!UpdateMeasure TimeStampConverter][&List:InsFields('(#HeadRow#+5)','[&Now], [&TimeStampConverter], <Reminder Text>')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
MiddleMouseUpAction=[!SetOption #CURRENTSECTION# TransformationMatrix "1;0;0;1;0;0"][&List:DupFields('(#HeadRow#+5)')][!UpdateMeasureGroup ItemFieldsGroup][!UpdateMeter *][!Redraw]
Reminders.ini, the main skin or the centralizer:

Code: Select all

[Variables]
Color0=255,255,255,255
Color1=255,16,160,255
ColIdx=0
Update=500
Flashy=0
CanAct=0
@IncludeVariables=#@#Variables.inc

[Rainmeter]
Update=#Update#
DynamicWindowSize=1
AccurateText=1
OnCloseAction=[!DeactivateConfig "#ROOTCONFIG#\ListManager"]
OnRefreshAction=[!SetVariable CanAct 1][!DeactivateConfig "#ROOTCONFIG#\ListManager"]

---Measures---

[List]
Measure=Script
ScriptFile=#@#Reminders.lua
PathToFile=#@#Reminders.txt
UpdateDivider=((1-#Setup#*2)*1000/#Update#)
IfCondition=(#CanAct#=1) && (#Setup#=0) && ([List:]<=0)
IfTrueAction=[!SetVariable Flashy (#Setup#)][!DeactivateConfig "#ROOTCONFIG#\ListManager"]
IfCondition2=(#CanAct#=1) && (((#Setup#=0) && ([List:]>0)) || (#Setup#=1))
IfTrueAction2=[!SetVariable Flashy (1-#Setup#)][!ActivateConfig "#ROOTCONFIG#\ListManager"]
IfConditionMode=1
DynamicVariables=1

---Meters---

[Icon]
Meter=Image
ImageName=#@#Reminders.png
ImageTint=[#Color[#ColIdx]]
LeftMouseUpAction=[!SetVariable Manual 1][!SetVariable Setup (1-#Setup#)][!UpdateMeasure *][!UpdateMeter *][!Redraw][!SetVariable Manual 1 "#ROOTCONFIG#\ListManager"][!SetVariable Setup (1-#Setup#) "#ROOTCONFIG#\ListManager"][!UpdateMeasure * "#ROOTCONFIG#\ListManager"][!UpdateMeter * "#ROOTCONFIG#\ListManager"][!Redraw "#ROOTCONFIG#\ListManager"][!SetVariable Manual 0][!SetVariable Manual 0 "#ROOTCONFIG#\ListManager"]
MiddleMouseUpAction=[PlayStop]
DynamicVariables=1

[Text]
Meter=String
X=32r
Y=16r
FontFace=Times New Roman
FontColor=[#Color[#ColIdx]]
FontSize=16
FontWeight=700
AntiAlias=1
Text=!
OnUpdateAction=[!SetVariable ColIdx (#Flashy#>0?1-#ColIdx#:0)]
DynamicVariables=1
Reminders.jpg
Briefly, the current implementation has:
- the little clock skin, aka the "centralizer", which will automatically load the "list manager" and play the sound for active reminders (called "infos" here) if any, or toggle between editing the "infos" (active reminders) and "items" (all reminders, active or not, in the Reminders.txt source file) on left click; it will also stop the playing sound if desired on middle click
- the table-like larger skin, aka the "list manager", which will do the:
a) editing (by left clicking on the "fields" in the case of all fields bar the computed ones, or scrolling over the fields in the case of times or numbers; when editing times via left click be careful to write the correct day of week or you'd get an error)
b) scrolling (on mouse scroll everywhere except the time or numerical and time fields)
c) loading and saving the CSV data from / to Reminders.txt (can be any CSV formatted file, but that's another matter) by left clicking on the associated icons at the top
d) changing via left click or scroll the "time unit" to which time differences are divided to get how much time has passed since the "end time" and "today" (the T or "timer" column) or between the "start time" and "end time" (the P or "period" column), currently set to 1 day aka 86400 seconds to get the number of days for those differences
e) changing via left click or scroll the "page rows", aka how many rows are displayed in the "list manager", with a minimum of 1 and a maximum of 20 (adjustable, if you copy paste and modify the proper indexes to create more than 5 rows / lines of "infos" / "items")
f) removing, inserting or duplicating the "info" / "item" corresponding to the clicked minus and plus icons, by left click on minus (remove), left click on plus (insert) or middle click on the plus (duplicate) for the red and green icons, as well as removing, inserting or duplicating the "last" or "after the last" "info" / "item" by left clicking on the similar minus and plus icons colored in cyan at the top
g) ascending or descending sorting of the "infos" / "items" by any field by left clicking on the headers (ascending and descending are toggled on the next left click, in most cases), as a "bonus feature" that I liked so I added it

As always in my skins, almost everything can be controlled either by editing one or two variables or lines. Columns can be hidden or shown at will just by setting their width variables to either a positive number or the equivalent of (-#LineIndent#) (which is -5 currently), or rearranged (since they are mostly relative to each other). There is highlighting on the hovered fields, tinting to dark and light and some mouse click / mouse release effects on the icons, counting "infos" / "items" in the title, and so on.

If you're still interested, go take a look at it and let me know what you think. If not, well, I'm sure others will be happy to play with it or even use it for their purposes whenever they'll need it - I surely do already. 8-)

P.S. The explanations, if needed, will come after everything is set in stone following your opinion. There might be things I forgot to mention above, but I'll probably touch them if asked about it.
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
jadiazrod
Posts: 46
Joined: February 1st, 2022, 7:07 pm

Re: Timer reminder

Post by jadiazrod »

Good Morning Yincognito

Of course I'm still interested...!
Though you have forgotten about it...
I had the chance of play with that a little bit this morning and .... definetely I got more that want I bargained for... I love it...! :great:
You really took in consideration many useful things...
The scrolling feature is great... but the ascending / descending function is better...!!!
The "Minus" will delete and the "Plus" will add, but the "Save" option is genious... :jawdrop
I guess some people will find easier to work with Day and Month names rather with Numbers...( I do...)
I didn't have the time to figure what the Yellow folder function is... but definetely I'll give it some attention this weekend and play with that a little bit more...
Thanks for all your efforts to come up with something I'm pretty sure many of us will benefit from it... :thumbup:
User avatar
Yincognito
Rainmeter Sage
Posts: 7157
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Timer reminder

Post by Yincognito »

jadiazrod wrote: March 11th, 2022, 3:06 pm Good Morning Yincognito

Of course I'm still interested...!
Though you have forgotten about it...
I had the chance of play with that a little bit this morning and .... definetely I got more that want I bargained for... I love it...! :great:
You really took in consideration many useful things...
The scrolling feature is great... but the ascending / descending function is better...!!!
The "Minus" will delete and the "Plus" will add, but the "Save" option is genious... :jawdrop
I guess some people will find easier to work with Day and Month names rather with Numbers...( I do...)
I didn't have the time to figure what the Yellow folder function is... but definetely I'll give it some attention this weekend and play with that a little bit more...
Thanks for all your efforts to come up with something I'm pretty sure many of us will benefit from it... :thumbup:
Glad you liked it. Yeah, I never forget a promise I make, because I don't promise often, LOL.

Yes, I wanted to make it complete, because as I said, it can be used as a CSV editor / viewer in all kind of situations, not limited to your case - all it takes are a couple of appropriate adjustments.

The yellow folder icon is the Load function, aka the Save's "twin". It can be used as a general purpose complete "undo", assuming you didn't Save the potential changes to the files yet, sort of like a "reset" of things to the source file status, if you want.

The time formats can be easily adjusted to suit your preferences, via changing the associated variables from [Variables], and columns can also be hidden, shown or resized pretty much any way you like - let me know exactly how you want them to look like and I'll explain what needs to be done, if you can't figure it out by yourself. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth