Browse code

Added a blank button which does nothing, and set it as the default and focused button (except if there's a Pause button), to make it so pressing Space or Enter will no longer click the Quit button by default.

Apollia authored on06/27/2020 18:49:25
Showing1 changed files
... ...
@@ -676,6 +676,9 @@ class Prototype___Mr_Timer
676 676
         $vbox = $Timer_Dialog->vbox;
677 677
         
678 678
         
679
+        
680
+       # $this->Timer_Text = new GtkLabel();
681
+        
679 682
         if ( ! $dest_datetime )
680 683
         {
681 684
 			$Quit_Button=GtkButton::new_from_stock(Gtk::STOCK_QUIT);
... ...
@@ -683,6 +686,10 @@ class Prototype___Mr_Timer
683 686
 			#$Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, Gdk::CONTROL_MASK, 0 );
684 687
 			$vbox->pack_start($Quit_Button);
685 688
 			$Quit_Button->connect('clicked', array(&$this, "Quit_Timer") );
689
+			
690
+			#$Timer_Dialog->set_default($this->Timer_Text);
691
+			
692
+			#$this->Timer_Text->grab_focus();
686 693
 		}
687 694
 		
688 695
 		
... ...
@@ -782,7 +789,7 @@ class Prototype___Mr_Timer
782 789
         $vbox->pack_start($this->Countdown_or_Up_Label);
783 790
         
784 791
         
785
-        $this->Timer_Text = new GtkLabel();
792
+		$this->Timer_Text = new GtkLabel();
786 793
         $this->Timer_Text->modify_font(new PangoFontDescription("Sans 24"));
787 794
         
788 795
         if ($this->counting_down)
... ...
@@ -829,6 +836,11 @@ class Prototype___Mr_Timer
829 836
         
830 837
         $vbox->pack_start($this->Timer_Text);
831 838
         
839
+        
840
+        #$Timer_Dialog->set_default($this->Timer_Text);
841
+			
842
+		#$this->Timer_Text->grab_focus();
843
+			
832 844
         $vbox->pack_start($this->Pause_Label);
833 845
         
834 846
         
... ...
@@ -838,7 +850,10 @@ class Prototype___Mr_Timer
838 850
 			$vbox->pack_start($this->End_Label);
839 851
         }
840 852
         
841
-   
853
+		$Blank_Button=new GtkButton(" ");
854
+		$vbox->pack_start($Blank_Button);
855
+		$Timer_Dialog->set_default($Blank_Button);
856
+		$Blank_Button->grab_focus();
842 857
         
843 858
         if ( !$dest_datetime )
844 859
         {
... ...
@@ -856,6 +871,9 @@ class Prototype___Mr_Timer
856 871
 			$vbox->pack_start($Resume_Button);
857 872
         
858 873
 			$Pause_Button->connect('clicked', array(&$this, "Pause_Timer") );
874
+			$Timer_Dialog->set_default($Pause_Button);
875
+			$Pause_Button->grab_focus();
876
+			
859 877
 			$Resume_Button->connect('clicked', array(&$this, "Resume_Timer") );
860 878
         }
861 879
         else
... ...
@@ -864,19 +882,30 @@ class Prototype___Mr_Timer
864 882
 	
865 883
 			$vbox->pack_start($Quit_Button);
866 884
 			$Quit_Button->connect('clicked', array(&$this, "Quit_Timer") );
885
+			
886
+			#$Timer_Dialog->set_default($this->Timer_Text);
887
+			
888
+			#$this->Timer_Text->grab_focus();
867 889
 		}
868 890
 		
869 891
 		
892
+		
893
+		
894
+		
895
+		
870 896
 		$Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, Gdk::CONTROL_MASK, 0 );
871 897
   #      $Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, 0, 0 );
872 898
         
873 899
 		
874 900
 		$Timer_Dialog->connect('key-press-event', array (&$this, 'on_timer_window_keypress')); 
875 901
 		
876
-	
902
+		
903
+		#$Quit_Button->set_sensitive(false);
904
+		
877 905
         $Timer_Dialog->set_has_separator(false);
878 906
         $Timer_Dialog->show_all();
879 907
         
908
+        #$Quit_Button->hide();
880 909
         
881 910
         $this->Timer_Dialog = $Timer_Dialog;
882 911
 
Browse code

Now, the only keychord intended to quit the program is Ctrl-Q. Stopped "Esc" and plain "Q" from quitting the program.

Apollia authored on06/27/2020 16:53:41
Showing1 changed files
... ...
@@ -54,7 +54,7 @@
54 54
 #
55 55
 # Arg 7: "shell_command_to_exec_when_timer_done"
56 56
 # A shell command you want executed after the timer is done with its countdown (or countup).
57
-#a
57
+#
58 58
 #
59 59
 # Args 8, 9, 10: "total_hours", "total_mins", "total_secs"
60 60
 # The total amount of time you want the timer to run.
... ...
@@ -865,10 +865,14 @@ class Prototype___Mr_Timer
865 865
 			$vbox->pack_start($Quit_Button);
866 866
 			$Quit_Button->connect('clicked', array(&$this, "Quit_Timer") );
867 867
 		}
868
+		
869
+		
868 870
 		$Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, Gdk::CONTROL_MASK, 0 );
869
-        $Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, 0, 0 );
871
+  #      $Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, 0, 0 );
870 872
         
871 873
 		
874
+		$Timer_Dialog->connect('key-press-event', array (&$this, 'on_timer_window_keypress')); 
875
+		
872 876
 	
873 877
         $Timer_Dialog->set_has_separator(false);
874 878
         $Timer_Dialog->show_all();
... ...
@@ -1199,13 +1203,45 @@ class Prototype___Mr_Timer
1199 1203
     }
1200 1204
 
1201 1205
 
1202
-
1206
+	public function on_timer_window_keypress($widget, $event)
1207
+	{
1208
+		
1209
+		echo "\n\nA key was pressed while timer window was in focus!";
1210
+		
1211
+		echo "Key: ";
1212
+		echo $event->keyval;
1213
+		
1214
+		if ($event->keyval==Gdk::KEY_Escape) 
1215
+		{
1216
+			echo "\n\nEscape was pressed!\n\n";
1217
+		
1218
+		
1219
+			#!!!!
1220
+			return true;
1221
+				# 12:40:54 06/27/2020.  This blocks Esc from closing the timer window!
1222
+				#
1223
+				# 12:50:09 06/27/2020.  This page helped me figure out how to do this:
1224
+				#
1225
+				# https://www.kksou.com/php-gtk2/sample-codes/setup-interactive-search-in-GtkTreeView-for-PHP-GTK-v2.0-Part-1-non-OOP-version.php
1226
+				
1227
+		}
1228
+    
1229
+	}
1230
+	
1203 1231
     // Called when user closes the timer.
1204 1232
     public function Upon_Delete_Event($widget, $event)
1205 1233
     {
1206 1234
 		echo "\n\n";
1207 1235
 		echo "Timer window closed!";
1208 1236
 		
1237
+		#echo "Widget: \n\n";
1238
+		#print_r($widget);
1239
+		
1240
+		#echo "Event: \n\n";
1241
+		#print_r($event);
1242
+
1243
+    
1244
+    
1209 1245
         $this->Timer_Dialog->destroy();
1210 1246
         
1211 1247
         if ($this->timeout_ID)
Browse code

Moved files out of unnecessary folder

Apollia authored on02/13/2018 21:36:01
Showing1 changed files
1 1
new file mode 100755
... ...
@@ -0,0 +1,1325 @@
1
+#!/usr/local/bin/php
2
+<?php
3
+# Simple Countdown or Countup Timer for PHP-GTK
4
+#
5
+# Last modified Feb. 13, 2018.
6
+# 
7
+# First released March 31, 2017.
8
+#
9
+#------------------------------------------------------------------------------
10
+#
11
+#
12
+# All arguments are optional.  If no arguments are provided, the timer will
13
+# display a 5 minute countdown by default.
14
+#
15
+#
16
+# Arg 1: "title"
17
+# The title you want the timer window to have.
18
+#
19
+# Arg 2: "note"
20
+# A note you want shown near the top of the timer window.
21
+#
22
+# Arg 3: "icon_fillepath"
23
+# A fillepath (full, absolute filepath) to your desired icon for the
24
+# timer window's title bar.
25
+#
26
+#
27
+# Arg 4:  "count_up_or_down"
28
+# Possible settings: "up" or "down"
29
+#
30
+#
31
+# Arg 5: "dest_datetime"
32
+#
33
+# To make the timer count down (or up) all the seconds until a particular date/time,
34
+# set this to any date/time text that PHP's strtotime() function can understand.
35
+#
36
+# This is impressively flexible - see the below links for examples.
37
+#
38
+# http://php.net/manual/en/datetime.formats.relative.php
39
+# http://php.net/manual/en/datetime.formats.time.php
40
+# http://php.net/manual/en/datetime.formats.date.php
41
+#
42
+# If you set Arg 5, don't set Args 8 thru 13, since they'll be ignored.
43
+#
44
+# 
45
+# Arg 6: "dest_datetime_format"
46
+#
47
+# If you don't set this, dest_datetime will be displayed in the timer window
48
+# in this format by default: "Fri, 31 Mar 2017 14:56:04 -0400"
49
+#
50
+# Arg 6 lets you choose your own format.  See this link for more info:
51
+#
52
+# http://php.net/manual/en/function.date.php
53
+#
54
+#
55
+# Arg 7: "shell_command_to_exec_when_timer_done"
56
+# A shell command you want executed after the timer is done with its countdown (or countup).
57
+#a
58
+#
59
+# Args 8, 9, 10: "total_hours", "total_mins", "total_secs"
60
+# The total amount of time you want the timer to run.
61
+#
62
+# Ignored if Arg 5 ("dest_datetime") is present.
63
+#
64
+#
65
+# Args 11, 12, 13: "start_hours", "start_mins", "start_secs"
66
+# Set one or more of these if you want to make the timer skip ahead to a later time in
67
+# the countdown (or countup).
68
+#
69
+# Ignored if Arg 5 ("dest_datetime") is present.
70
+#
71
+#
72
+# Arg 14: "should_show_start_and_end_times"
73
+# Set to "y" or "yes" to make the timer definitely display the text "Timer started:"
74
+# and "Timer ended:".
75
+#
76
+# Set to anything else to hide that text.
77
+#
78
+# If not set, the value of the constant "Default_for_should_show_start_and_end_times"
79
+# is used instead.
80
+#
81
+#
82
+#------------------------------------------------------------------------------
83
+#
84
+#
85
+# Under the GNU Affero General Public License v3.0.
86
+#
87
+# Copyright (C) 2017/2018  Apollia
88
+#
89
+#    This program is free software: you can redistribute it and/or modify
90
+#    it under the terms of the GNU Affero General Public License as
91
+#    published by the Free Software Foundation, either version 3 of the
92
+#    License, or (at your option) any later version.
93
+#
94
+#    This program is distributed in the hope that it will be useful,
95
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
96
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
97
+#    GNU Affero General Public License for more details.
98
+#
99
+#    You should have received a copy of the GNU Affero General Public License
100
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
101
+#
102
+#
103
+# Contact info:     http://astroblahhh.com/contact-apollia.shtml
104
+#
105
+#-----
106
+
107
+
108
+$scripthome=dirname(__FILE__);
109
+$Fillepath____Default_Icon="$scripthome/Icons/clock-icon.png";
110
+
111
+			
112
+			
113
+$Default_Total_Hours=0;
114
+$Default_Total_Mins=5;
115
+$Default_Total_Secs=0;
116
+
117
+$orig_working_dir=getcwd();
118
+define ("Orig_Working_Dir", $orig_working_dir);
119
+
120
+define ("Default_for_should_show_start_and_end_times", true);
121
+
122
+
123
+
124
+
125
+trait Magic_Getter
126
+{
127
+	public function __get($property)
128
+	{
129
+		if (property_exists($this, $property) )
130
+		{
131
+			return $this->$property;
132
+		}
133
+		else
134
+		{
135
+			$class=get_class($this);
136
+			echo "$class doesn't have a $property property!  Aborting.";
137
+			exit;
138
+		}	
139
+	}
140
+}
141
+
142
+
143
+
144
+
145
+class Prototype___Mr_Cliargs
146
+{
147
+	protected $script_filename;
148
+	protected $args;
149
+	protected $arg_count;
150
+	
151
+
152
+
153
+	public function Get_Cliargs ()
154
+	{
155
+		global $argv;
156
+		
157
+		$args=$argv;
158
+		$script_filename=array_shift($args);
159
+		
160
+		$arg_count=count($args);
161
+
162
+		$this->arg_count=$arg_count;
163
+		$this->script_filename=$script_filename;
164
+		$this->args=$args;
165
+
166
+	}
167
+	
168
+	
169
+	
170
+	public function Maybe_Get_Arg( $num )
171
+	{
172
+		$args=$this->args;
173
+		
174
+		if (isset ($args[$num] ) )
175
+		{
176
+			return $args[$num];
177
+		}
178
+		else
179
+		{
180
+			return null;
181
+		}
182
+	}
183
+	
184
+	
185
+	
186
+	public function Get_Arg( $num )
187
+	{
188
+		$args=$this->args;
189
+		
190
+		if (isset ($args[$num] ) )
191
+		{
192
+			return $args[$num];
193
+		}
194
+		else
195
+		{
196
+			$display_num=$num+1;
197
+			echo "Aborting: No arg $display_num found!";
198
+			br();
199
+			exit;
200
+		}
201
+	}
202
+	
203
+	
204
+	
205
+	public function Get_Count()
206
+	{
207
+		return $this->$arg_count;
208
+	}
209
+}
210
+
211
+
212
+
213
+
214
+class Prototype___Mr_Raw_Input
215
+{
216
+	protected $args_to_get=array("title", "note", "icon_fillepath", "count_up_or_down", "dest_datetime", "dest_datetime_format", "shell_command_to_exec_when_timer_done", "total_hours", "total_mins", "total_secs", "start_hours", "start_mins", "start_secs", "should_show_start_and_end_times" );
217
+	
218
+	protected $raw_input=array();
219
+	
220
+
221
+	use Magic_Getter;
222
+	
223
+	
224
+	
225
+	public function Fetch_Raw_Input()
226
+	{
227
+		global $Mr_Cliargs;
228
+		
229
+		$args_to_get=$this->args_to_get;
230
+		
231
+		$argnum=0;
232
+		foreach ($args_to_get as $arg)
233
+		{
234
+			
235
+			$this->raw_input[$arg]= $Mr_Cliargs->Maybe_Get_Arg($argnum);
236
+			$argnum++;
237
+		}
238
+		print_r($this->raw_input);
239
+		
240
+	}
241
+}
242
+
243
+
244
+
245
+
246
+class Prototype___Mr_Standardized_Input
247
+{
248
+
249
+	protected $raw_input;
250
+	protected $standardized_input;
251
+	
252
+	use Magic_Getter;
253
+
254
+
255
+
256
+	public function __construct()
257
+	{
258
+		global $Mr_Raw_Input;
259
+		
260
+		$this->raw_input=$Mr_Raw_Input->raw_input;
261
+		
262
+	}
263
+
264
+	
265
+	
266
+	public function Standardize_Raw_Input()
267
+	{
268
+		$raw=$this->raw_input;
269
+		
270
+		#echo "Raw title:";
271
+		#echo $raw["title"];
272
+		
273
+		#--------------------------------------
274
+		# title
275
+		if ( ! $raw["title"] )
276
+		{	
277
+			$this->standardized_input["title"]="Timer";
278
+		}
279
+		else
280
+		{	
281
+			$this->standardized_input["title"]=$raw["title"];
282
+		}
283
+		
284
+		
285
+		#--------------------------------------
286
+		# note
287
+		
288
+		$this->standardized_input["note"]=$raw["note"];
289
+		
290
+
291
+		#--------------------------------------
292
+		# icon_fillepath
293
+		
294
+	#	$this->standardized_input["icon_fillepath"]=$raw["icon_fillepath"];
295
+		if ( ! $raw["icon_fillepath" ] )
296
+		{
297
+			global $Fillepath____Default_Icon;
298
+			$this->standardized_input["icon_fillepath"]=$Fillepath____Default_Icon;
299
+		}
300
+		else
301
+		{
302
+			$this->standardized_input["icon_fillepath"]=$raw["icon_fillepath"];
303
+		}
304
+		
305
+		#--------------------------------------
306
+		# count_up_or_down
307
+		
308
+		
309
+		if ( $raw["count_up_or_down"] == "up" || $raw["count_up_or_down"] == "down")
310
+		{
311
+			$this->standardized_input["count_up_or_down"]=$raw["count_up_or_down"];
312
+		}
313
+	
314
+		else if ( $raw["count_up_or_down"] != "up" && $raw["count_up_or_down"] != "down")
315
+		{
316
+			$this->standardized_input["count_up_or_down"]="down";
317
+		}
318
+		
319
+		
320
+		#--------------------------------------
321
+		# dest_datetime
322
+		
323
+		if ( $raw["dest_datetime"] )
324
+		{
325
+			$dest_unixtime=strtotime( $raw["dest_datetime"] );
326
+			#echo "dest_unixtime: $dest_unixtime";
327
+			if ($dest_unixtime==false)
328
+			{	
329
+				$this->standardized_input["dest_datetime"]="";
330
+			}
331
+			else
332
+			{
333
+				$this->standardized_input["dest_datetime"]=$dest_unixtime;
334
+			}
335
+		}
336
+		else
337
+		{
338
+			$this->standardized_input["dest_datetime"]="";
339
+		}
340
+		
341
+		
342
+		#--------------------------------------
343
+		# dest_datetime_format
344
+		
345
+		if ( ! $raw["dest_datetime_format"] )
346
+		{
347
+			$this->standardized_input["dest_datetime_format"] = "r";
348
+		}
349
+
350
+		
351
+		#--------------------------------------
352
+		# shell_command_to_exec_when_timer_done
353
+		
354
+		$this->standardized_input["shell_command_to_exec_when_timer_done"]=$raw["shell_command_to_exec_when_timer_done"];
355
+		
356
+		
357
+		#--------------------------------------
358
+		# total_hours
359
+		
360
+		$this->standardized_input["total_hours"]=$raw["total_hours"];
361
+		
362
+		#--------------------------------------
363
+		# total_mins
364
+		
365
+		$this->standardized_input["total_mins"]=$raw["total_mins"];
366
+		
367
+		#--------------------------------------
368
+		# total_secs
369
+		
370
+		$this->standardized_input["total_secs"]=$raw["total_secs"];
371
+		
372
+		#--------------------------------------
373
+		# start_hours
374
+		
375
+		$this->standardized_input["start_hours"]=$raw["start_hours"];
376
+		
377
+		#--------------------------------------
378
+		# start_mins
379
+		
380
+		$this->standardized_input["start_mins"]=$raw["start_mins"];
381
+		
382
+		#--------------------------------------
383
+		# start_secs
384
+		
385
+		$this->standardized_input["start_secs"]=$raw["start_secs"];
386
+		
387
+		
388
+		#--------------------------------------
389
+		# should_show_start_and_end_times
390
+		
391
+		$should_show_start_and_end_times = $raw["should_show_start_and_end_times"];
392
+		
393
+		
394
+		if ($should_show_start_and_end_times == "y" || $should_show_start_and_end_times == "yes" )
395
+		{
396
+			$this->standardized_input["should_show_start_and_end_times"] = "y";
397
+		}
398
+		else if ($should_show_start_and_end_times )
399
+		{
400
+			$this->standardized_input["should_show_start_and_end_times"]=false;
401
+		}
402
+		else if (!$should_show_start_and_end_times)
403
+		{
404
+			$this->standardized_input["should_show_start_and_end_times"]=Default_for_should_show_start_and_end_times;
405
+		}
406
+	}
407
+}
408
+
409
+
410
+
411
+
412
+class Prototype___Mr_Valichecker
413
+{
414
+
415
+		
416
+	
417
+	public function Do_Valicheck_of_Input()
418
+	{
419
+		global $Mr_Standardized_Input;
420
+		
421
+		$input = $Mr_Standardized_Input->standardized_input;
422
+		
423
+		$this->Valicheck_Arg____Must_Be_Integer_or_Empty($input["total_hours"], "total hours");
424
+		$this->Valicheck_Arg____Must_Be_Integer_or_Empty($input["total_mins"], "total mins");
425
+		$this->Valicheck_Arg____Must_Be_Integer_or_Empty($input["total_secs"], "total secs");
426
+		
427
+		$this->Valicheck_Arg____Must_Be_Integer_or_Empty($input["start_hours"], "start hours");
428
+		$this->Valicheck_Arg____Must_Be_Integer_or_Empty($input["start_mins"], "start mins");
429
+		$this->Valicheck_Arg____Must_Be_Integer_or_Empty($input["start_secs"], "start secs");
430
+		
431
+		$this->Valicheck_Arg____count_up_or_down( $input["count_up_or_down"]);
432
+		$this->Valicheck_Arg____dest_datetime( $input["dest_datetime"] );
433
+		return true;
434
+	}
435
+	
436
+	
437
+	
438
+	protected function Valicheck_Arg____dest_datetime( $arg)
439
+	{
440
+		if (! $arg)
441
+		{
442
+			return true;
443
+		}
444
+		/*
445
+		$now_unixtime=time();
446
+		
447
+		if  ( ($arg - $now_unixtime ) < 0 )
448
+		{
449
+			$abort_message="Aborting: dest_datetime must not be in the past!";
450
+			
451
+			echo "\n\n$abort_message\n";
452
+			Alert($abort_message);
453
+			exit(2);
454
+		}
455
+		* */
456
+	}
457
+	
458
+	
459
+	
460
+	protected function Valicheck_Arg____count_up_or_down( $arg )
461
+	{
462
+		if ( $arg != "down" && $arg != "up" )
463
+		{
464
+			echo "Aborting because count_up_or_down must be either up or down!";
465
+			exit;
466
+		}
467
+	}
468
+	
469
+	
470
+	
471
+	protected function Valicheck_Arg____Must_Be_Integer_or_Empty( $arg, $what_it_is )
472
+	{
473
+		if ( !$arg )
474
+		{	return true;
475
+		}
476
+		if (is_int( (int) $arg) )
477
+		{
478
+			return true;
479
+		}
480
+		echo "Aborting: $what_it_is must be an integer, but it's $arg!";
481
+		exit;
482
+	}
483
+	
484
+}
485
+
486
+
487
+
488
+function Calculate_Seconds_in_Hours_Mins_Secs($hours, $mins, $secs)
489
+{
490
+	$hoursecs=60*60*$hours;
491
+	$minsecs=60*$mins;
492
+
493
+	return $hoursecs+$minsecs+$secs; 
494
+}
495
+
496
+
497
+
498
+function Alert($msg)
499
+{
500
+    $Dialog = new GtkDialog('Alert', null, Gtk::DIALOG_MODAL);
501
+    $Dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
502
+    
503
+    $vbox = $Dialog->vbox;
504
+    $vbox->pack_start($hbox = new GtkHBox());
505
+    
506
+    $stock = GtkImage::new_from_stock(Gtk::STOCK_DIALOG_WARNING,
507
+        Gtk::ICON_SIZE_DIALOG);
508
+        
509
+    $hbox->pack_start($stock, 0, 0);
510
+    $hbox->pack_start(new GtkLabel($msg));
511
+    
512
+    $Dialog->add_button(Gtk::STOCK_OK, Gtk::RESPONSE_OK);
513
+    $Dialog->set_has_separator(false);
514
+    $Dialog->show_all();
515
+    $Dialog->run();
516
+    $Dialog->destroy();
517
+}
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+function Start_Timer( $Args_for_Timer )
526
+{
527
+	global $Total_Time;
528
+	
529
+    $Mr_Timer = new Prototype___Mr_Timer;
530
+    
531
+    $Mr_Timer->Initialize( $Args_for_Timer );
532
+    
533
+    $Mr_Timer->Start();   
534
+}
535
+
536
+
537
+
538
+class Prototype___Mr_Timer
539
+{
540
+    protected $Timer_Text;
541
+    protected $Timer_Dialog;
542
+    
543
+    protected $DateTime_At_Start;
544
+    protected $DateTime_At_End;
545
+    
546
+    protected $Start_Label;
547
+    protected $End_Label;
548
+    
549
+    protected $Pause_Button;
550
+    protected $Resume_Button;
551
+    
552
+    protected $Pause_Label;
553
+    protected $Note_Label;
554
+    
555
+    protected $total_time;
556
+    protected $total_time_text;
557
+    
558
+    protected $time_left;
559
+    
560
+    protected $timeout_ID=null;
561
+    
562
+    protected $start_time;
563
+
564
+	protected $counting_down;
565
+	protected $counting_up;
566
+	protected $count_up_or_down;
567
+
568
+	protected $timer_done=false;
569
+	protected $past_dest_datetime;
570
+	protected $Past_DateTime;
571
+	
572
+	protected $should_show_start_and_end_times;
573
+	
574
+	
575
+	
576
+	//~ public function On_Status_Icon_Click()
577
+	//~ {
578
+		//~ echo "yay";
579
+		//~ Alert("test");
580
+		//~ $Timer_Dialog=$this->Timer_Dialog;
581
+		//~ 
582
+		//~ if ($Timer_Dialog->is_visible())
583
+		//~ {	
584
+			//~ $Timer_Dialog->hide_all();
585
+		//~ }
586
+		//~ else
587
+		//~ {	$Timer_Dialog->show_all();
588
+		//~ }
589
+	//~ }
590
+	public function Start()
591
+	{
592
+		#if ($this->counting_up)
593
+		#{
594
+			$this->Update_Timer();
595
+			$this->Start_Timer();
596
+		#}
597
+		#else
598
+		#{
599
+		#	$this->Update_Timer();
600
+		#	$this->Start_Timer();
601
+		#}
602
+	}
603
+	
604
+	
605
+	
606
+    public function Initialize( $Args_for_Timer)
607
+    {   
608
+		foreach ($Args_for_Timer as $key => $value)
609
+		{
610
+			#echo "Arg: $key  $value\n";
611
+			${$key}=$value;
612
+		}
613
+		
614
+		
615
+		if ($past_dest_datetime)
616
+		{
617
+			$count_up_or_down="up";
618
+		}
619
+		
620
+		$this->count_up_or_down=$count_up_or_down;
621
+		$this->shell_command_to_exec_when_timer_done=$shell_command_to_exec_when_timer_done;
622
+		$this->past_dest_datetime=$past_dest_datetime;
623
+		$this->should_show_start_and_end_times=$should_show_start_and_end_times;
624
+		
625
+
626
+		
627
+		if ( $count_up_or_down == "up" )
628
+		{
629
+			$this->counting_down=false;
630
+			$this->counting_up=true;
631
+			$this->Set_Time_Left_to_($Total_Time-$Start_Time);
632
+		}
633
+		else
634
+		{
635
+			$this->counting_down=true;
636
+			$this->counting_up=false;
637
+			$this->Set_Time_Left_to_($Total_Time);
638
+			$this->Set_Time_Left_to_($Total_Time-$Start_Time);
639
+		}
640
+		
641
+		$this->Set_Total_Time_to_($Total_Time);
642
+		
643
+		
644
+		
645
+		
646
+		$Timer_Dialog = new GtkDialog("$Title", null, Gtk::DIALOG_MODAL);
647
+       
648
+       
649
+       # 15:46:46 02/13/20185.  Couldn't get the status icon to work at all.
650
+       # 
651
+       # http://www.devshed.com/c/a/php/building-your-own-system-tray-application-using-php-gtk/
652
+       
653
+       //~ $statusicon = new GtkStatusIcon();
654
+		//~ global $Fillepath____Default_Icon;
655
+		//~ $statusicon->set_from_stock(Gtk::STOCK_FILE);
656
+		//~ #$statusicon->set_from_file("$Fillepath____Default_Icon");
657
+		//~ $statusicon->set_visible(true);
658
+		//~ $statusicon->set_blinking(true);
659
+		//~ $statusicon->connect('activate', array(&$this, 'On_Status_Icon_Click') );
660
+
661
+		#Alert("test");
662
+		if ( $Icon_Fillepath )
663
+		{
664
+			$pixbuf=GdkPixbuf::new_from_file("$Icon_Fillepath");
665
+       
666
+			$Timer_Dialog->set_icon($pixbuf);
667
+		}
668
+       
669
+		
670
+        $Accel_Group=new GtkAccelGroup();
671
+        $Timer_Dialog->add_accel_group($Accel_Group);
672
+        
673
+        
674
+		#$Timer_Dialog->set_size_request(400, 140);
675
+       
676
+        $vbox = $Timer_Dialog->vbox;
677
+        
678
+        
679
+        if ( ! $dest_datetime )
680
+        {
681
+			$Quit_Button=GtkButton::new_from_stock(Gtk::STOCK_QUIT);
682
+		
683
+			#$Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, Gdk::CONTROL_MASK, 0 );
684
+			$vbox->pack_start($Quit_Button);
685
+			$Quit_Button->connect('clicked', array(&$this, "Quit_Timer") );
686
+		}
687
+		
688
+		
689
+        $this->Countdown_or_Up_Label = new GtkLabel();
690
+        $this->Countdown_or_Up_Label->modify_font(new PangoFontDescription("Sans 12"));
691
+        
692
+     
693
+		$this->Pause_Label = new GtkLabel();
694
+        $this->Pause_Label->modify_font(new PangoFontDescription("Sans 12"));
695
+        
696
+        
697
+        $this->Note_Label = new GtkLabel();
698
+        $this->Note_Label->modify_font(new PangoFontDescription("Sans 15"));
699
+        $this->Note_Label->set_text("$Note");
700
+        
701
+        echo "TITLE: $Title";
702
+        $total_time_seconds = $this->total_time;
703
+
704
+        $Now_DateTime=new DateTime("now");
705
+		$End_DateTime=new DateTime("now");
706
+		$End_DateTime->add(DateInterval::createFromDateString("$total_time_seconds seconds") );
707
+				
708
+		$Interval=$End_DateTime->diff($Now_DateTime, true);
709
+		
710
+		$format=$this->Get_Date_Format_But_Omit_Larger_Units_If_Possible($Interval);
711
+		$total_time_text=$Interval->format($format);
712
+			
713
+		$this->total_time_text=$total_time_text;
714
+		
715
+		
716
+		if ($this->counting_down )
717
+		{
718
+			$label = "Counting down ";
719
+		}
720
+		else
721
+		{
722
+			$label = "Counting up ";
723
+		}
724
+			
725
+		if ($dest_datetime)
726
+		{
727
+			
728
+			$formatted_dest_datetime=date( $dest_datetime_format, $dest_datetime );
729
+			
730
+			if ($past_dest_datetime)
731
+			{
732
+				$label="Time since $formatted_dest_datetime:";
733
+			}
734
+			else
735
+			{
736
+				$label .= "$total_time_text to $formatted_dest_datetime";
737
+			}
738
+		}
739
+		else
740
+		{
741
+			if ($this->counting_down )
742
+			{
743
+				$label .= "from $total_time_text";
744
+			}
745
+			else
746
+			{
747
+				$label .= "to $total_time_text";
748
+			}
749
+		}
750
+		
751
+		$countdown_or_up_label_text=$label;
752
+       
753
+		$this->countdown_or_up_label_text=$countdown_or_up_label_text;
754
+        
755
+        $this->Countdown_or_Up_Label->set_text("$countdown_or_up_label_text");
756
+        
757
+        
758
+        $vbox->pack_start($this->Note_Label);
759
+        
760
+        $this->DateTime_At_Start=new DateTime("now");
761
+	    
762
+        if ( $this->should_show_start_and_end_times )
763
+        {
764
+
765
+			$this->Start_Label = new GtkLabel();
766
+			$vbox->pack_start($this->Start_Label);
767
+			
768
+			
769
+			
770
+			$label="Timer Started: ";
771
+			$label .= $this->DateTime_At_Start->format("r");
772
+			
773
+			$this->Start_Label->set_text( $label );
774
+		}
775
+        
776
+        echo "\n\nStarted Timer: ";
777
+        echo $this->DateTime_At_Start->format("r");
778
+       # echo "\n";
779
+        
780
+        echo "\n\nTimer Note: $Note";
781
+        
782
+        $vbox->pack_start($this->Countdown_or_Up_Label);
783
+        
784
+        
785
+        $this->Timer_Text = new GtkLabel();
786
+        $this->Timer_Text->modify_font(new PangoFontDescription("Sans 24"));
787
+        
788
+        if ($this->counting_down)
789
+        {
790
+			$timer_text_label="$total_time_text";
791
+
792
+        }
793
+        else
794
+        {	
795
+			if ($past_dest_datetime)
796
+			{
797
+
798
+				$Past_DateTime=new DateTime();
799
+				$Past_DateTime->setTimestamp($dest_datetime);
800
+				
801
+				$Now_DateTime=new DateTime();
802
+				
803
+				$Time_Since=$Past_DateTime->diff($Now_DateTime);
804
+				
805
+				$format=$this->Get_Date_Format_But_Omit_Larger_Units_If_Possible($Time_Since);
806
+
807
+				$timer_text_label=$Time_Since->format("$format");
808
+				
809
+				$this->Past_DateTime=$Past_DateTime;
810
+				
811
+			}
812
+			else
813
+			{
814
+
815
+				if (strlen($total_time_text)>5 )
816
+				{
817
+					$timer_text_label="00:00:00";
818
+					
819
+				}
820
+				else
821
+				{
822
+					$timer_text_label="00:00";
823
+				}
824
+			}
825
+		}
826
+        
827
+        
828
+        $this->Timer_Text->set_text($timer_text_label);
829
+        
830
+        $vbox->pack_start($this->Timer_Text);
831
+        
832
+        $vbox->pack_start($this->Pause_Label);
833
+        
834
+        
835
+        if ( $this->should_show_start_and_end_times )
836
+        {
837
+			$this->End_Label = new GtkLabel();
838
+			$vbox->pack_start($this->End_Label);
839
+        }
840
+        
841
+   
842
+        
843
+        if ( !$dest_datetime )
844
+        {
845
+			$Pause_Button=new GtkButton("Pause");
846
+			$Resume_Button=new GtkButton("Resume");
847
+        
848
+			$Pause_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_P, Gdk::CONTROL_MASK, 0 );
849
+			$Pause_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_P, 0, 0 );
850
+			$Pause_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_S, Gdk::CONTROL_MASK, 0 );
851
+			$Pause_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_S, 0, 0 );
852
+			$Resume_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_R, Gdk::CONTROL_MASK, 0 );
853
+			$Resume_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_R, 0, 0 );
854
+			
855
+			$vbox->pack_start($Pause_Button);
856
+			$vbox->pack_start($Resume_Button);
857
+        
858
+			$Pause_Button->connect('clicked', array(&$this, "Pause_Timer") );
859
+			$Resume_Button->connect('clicked', array(&$this, "Resume_Timer") );
860
+        }
861
+        else
862
+        {
863
+			$Quit_Button=GtkButton::new_from_stock(Gtk::STOCK_QUIT);
864
+	
865
+			$vbox->pack_start($Quit_Button);
866
+			$Quit_Button->connect('clicked', array(&$this, "Quit_Timer") );
867
+		}
868
+		$Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, Gdk::CONTROL_MASK, 0 );
869
+        $Quit_Button->add_accelerator('clicked', $Accel_Group, Gdk::KEY_Q, 0, 0 );
870
+        
871
+		
872
+	
873
+        $Timer_Dialog->set_has_separator(false);
874
+        $Timer_Dialog->show_all();
875
+        
876
+        
877
+        $this->Timer_Dialog = $Timer_Dialog;
878
+
879
+        $Timer_Dialog->connect('delete-event',
880
+            array( &$this, "Upon_Delete_Event"));
881
+
882
+        $this->start_time = microtime(1);
883
+    }
884
+    
885
+    
886
+    
887
+    protected function Note_End_Time()
888
+    {
889
+		$this->DateTime_At_End=new DateTime("now");
890
+	}
891
+	
892
+	
893
+	
894
+	public function Set_End_Label()
895
+	{
896
+	
897
+		
898
+        
899
+        $label="Timer Ended: ";
900
+        $label .= $this->DateTime_At_End->format("r");
901
+        
902
+        $this->End_Label->set_text( $label );
903
+        
904
+	}
905
+	
906
+	
907
+	
908
+	public function Set_Total_Time_to_($seconds)
909
+	{
910
+		$this->total_time=$seconds;
911
+	}
912
+	
913
+	
914
+	
915
+	public function Set_Time_Left_to_($seconds)
916
+	{	$this->time_left=$seconds;
917
+	}
918
+	
919
+	
920
+	
921
+	public function Start_Timer()
922
+	{	
923
+		$count_up_or_down=$this->count_up_or_down;
924
+		
925
+		echo "\n\n\n"; echo "Starting Count$count_up_or_down Timer";
926
+		echo " - ";
927
+		echo $this->countdown_or_up_label_text;
928
+		
929
+		#$this->Show_Time_Left();
930
+		$this->Show_Time_Left_and_Time_Elapsed();
931
+		
932
+		$this->start_time = microtime(1);
933
+		$this->timeout_ID = Gtk::timeout_add(1000,
934
+			array(&$this, 'Update_Timer'));
935
+	}
936
+	
937
+	
938
+	
939
+	public function Resume_Timer()
940
+	{
941
+		if ( $this->timer_done)
942
+		{
943
+			return false;
944
+		}
945
+		if ($this->timeout_ID === null )
946
+		{
947
+			echo "\n\n"; echo "Resuming Timer"; echo "\n";
948
+			$this->Pause_Label->set_text('');
949
+
950
+			$this->Start_Timer();
951
+			
952
+		}
953
+	}
954
+	
955
+	
956
+	
957
+	protected function Perform_Pause()
958
+	{
959
+		
960
+		Gtk::timeout_remove($this->timeout_ID);
961
+		$this->timeout_ID=null;	
962
+		
963
+		echo "\n\n\n"; echo "Pausing Timer"; echo "\n";
964
+		
965
+		$this->Show_Time_Left_and_Time_Elapsed();
966
+	}
967
+	
968
+	
969
+	public function Quit_Timer()
970
+	{
971
+		exit(0);
972
+	}
973
+	public function Pause_Timer()
974
+	{
975
+		if ( $this->timer_done)
976
+		{
977
+			return false;
978
+		}
979
+		if ($this->timeout_ID === null)
980
+		{
981
+			return true;
982
+		}
983
+		$this->Pause_Label->set_text('(paused)');
984
+		$this->Perform_Pause();
985
+	}
986
+	
987
+	
988
+	
989
+	protected function Show_Time_Left()
990
+	{
991
+		$timetext=$this->Assemble_Time_Text($this->time_left);
992
+	
993
+		echo "\nTime left: $timetext";
994
+	}
995
+	
996
+	
997
+	
998
+	protected function Show_Time_Elapsed()
999
+	{
1000
+		$timetext=$this->Assemble_Time_Text( ( $this->total_time - $this->time_left ));
1001
+		echo "\nTime elapsed: $timetext";
1002
+	}
1003
+	
1004
+	
1005
+	
1006
+	protected function Show_Time_Left_and_Time_Elapsed()
1007
+	{
1008
+		$this->Show_Time_Left();
1009
+		$this->Show_Time_Elapsed();	
1010
+	}
1011
+	
1012
+	
1013
+	
1014
+	protected function Convert_to_Hours_Mins_Secs($time)
1015
+	{
1016
+		$hours= floor( $time / 60 / 60 );
1017
+		$hoursecs=$hours*60*60;
1018
+        
1019
+		$minutes=floor(($time-$hoursecs)/60);
1020
+		$minutesecs=$minutes*60; 
1021
+        
1022
+		$seconds=floor($time-$hoursecs-$minutesecs);
1023
+			
1024
+		return array($hours, $minutes, $seconds);
1025
+	}
1026
+	
1027
+	
1028
+	
1029
+	protected function Get_Date_Format_But_Omit_Larger_Units_If_Possible($interval)
1030
+	{
1031
+		$format="";
1032
+	
1033
+		if ($interval->y)
1034
+		{
1035
+			$format .="%yy ";
1036
+		}
1037
+		if ($interval->m)
1038
+		{	
1039
+			$format .= "%mm ";
1040
+		}
1041
+		if ($interval->d)
1042
+		{
1043
+			$format .= "%dd ";
1044
+		}
1045
+		
1046
+		$format.="%H:%I:%S";
1047
+		
1048
+		return $format;
1049
+	}
1050
+	protected function Assemble_Time_Text( $time )
1051
+	{
1052
+		list($hours, $minutes, $seconds) = $this->Convert_to_Hours_Mins_Secs($time);
1053
+		
1054
+		 # 04:56:13 03/30/2017.  Left-padding with zeros:
1055
+		if ($hours!=0)
1056
+		{
1057
+			$hours=sprintf("%02d:", $hours);
1058
+		}
1059
+		else
1060
+		{	$hours="";
1061
+		}
1062
+		$minutes=sprintf("%02d:", $minutes);
1063
+		$seconds=sprintf("%02d", $seconds);
1064
+
1065
+		$timetext="$hours$minutes$seconds";
1066
+		
1067
+		return $timetext;
1068
+
1069
+	}
1070
+	
1071
+	
1072
+	
1073
+    public function Update_Timer()
1074
+    {   
1075
+        $elapsed_time = microtime(1) - $this->start_time;
1076
+        $remaining_time = $this->total_time - $elapsed_time;
1077
+        
1078
+	
1079
+        	
1080
+        if ( abs($remaining_time - $this->time_left ) > 1)
1081
+        {
1082
+			$remaining_time=$this->time_left;
1083
+			$elapsed_time=$this->total_time - $this->time_left;
1084
+		}
1085
+
1086
+		
1087
+		if ( $this->counting_down )
1088
+		{	
1089
+			$remaining_time=floor($remaining_time);
1090
+
1091
+			$Now_DateTime=new DateTime("now");
1092
+			$End_DateTime=new DateTime("now");
1093
+			$End_DateTime->add(DateInterval::createFromDateString("$remaining_time seconds") );
1094
+			
1095
+			$Interval=$End_DateTime->diff($Now_DateTime);
1096
+			
1097
+			$format=$this->Get_Date_Format_But_Omit_Larger_Units_If_Possible($Interval);
1098
+			$timetext=$Interval->format($format);
1099
+			
1100
+
1101
+			#$timetext=$this->Assemble_Time_Text($remaining_time);
1102
+
1103
+		}
1104
+		else
1105
+		{	
1106
+			if ($this->past_dest_datetime)
1107
+			{
1108
+				$Past_DateTime=$this->Past_DateTime;
1109
+				
1110
+				$Time_Since=$Past_DateTime->diff( new DateTime('now') );
1111
+				
1112
+				$format=$this->Get_Date_Format_But_Omit_Larger_Units_If_Possible($Time_Since);
1113
+				
1114
+				$timetext=$Time_Since->format($format);
1115
+				
1116
+			}
1117
+			else
1118
+			{
1119
+				$Now_DateTime=new DateTime("now");
1120
+				$End_DateTime=new DateTime("now");
1121
+				$elapsed_time=floor($elapsed_time);
1122
+				$End_DateTime->add(DateInterval::createFromDateString("$elapsed_time seconds") );
1123
+				
1124
+				$Interval=$End_DateTime->diff($Now_DateTime);
1125
+				
1126
+				$format=$this->Get_Date_Format_But_Omit_Larger_Units_If_Possible($Interval);
1127
+				$timetext=$Interval->format($format);
1128
+			
1129
+				#$timetext=$this->Assemble_Time_Text($elapsed_time);
1130
+			}
1131
+		}
1132
+
1133
+
1134
+		$this->Timer_Text->set_text("$timetext");
1135
+		 
1136
+		
1137
+		--$this->time_left;
1138
+
1139
+        
1140
+        while (Gtk::events_pending()) {Gtk::main_iteration();}
1141
+
1142
+        if ($remaining_time>0)
1143
+        {
1144
+            return true;
1145
+        } 
1146
+        else 
1147
+        {   
1148
+			if ($this->past_dest_datetime)
1149
+			{
1150
+				# 22:55:48 03/30/2017.  If the dest_datetime is in the past, just keep going forever.
1151
+				
1152
+				return true;
1153
+			}
1154
+            chdir(Orig_Working_Dir);
1155
+            #Alert(Orig_Working_Dir);
1156
+            
1157
+            $shell_command_to_exec_when_timer_done=$this->shell_command_to_exec_when_timer_done;
1158
+            
1159
+            
1160
+            
1161
+            if ($shell_command_to_exec_when_timer_done)
1162
+            {
1163
+				echo "\n\n\nShell command about to be executed: $shell_command_to_exec_when_timer_done";
1164
+				
1165
+				exec("$shell_command_to_exec_when_timer_done", $output, $retcode);
1166
+				
1167
+				$output_string=implode("\n", $output);
1168
+				echo "\n\n\nOutput:";
1169
+				
1170
+				echo "\n\n";
1171
+				echo $output_string;
1172
+				echo "\n\n";
1173
+            }
1174
+            
1175
+           # $this->Timer_Dialog->destroy();
1176
+            
1177
+            if ( $this->timeout_ID)
1178
+            {
1179
+				Gtk::timeout_remove($this->timeout_ID);
1180
+			}
1181
+			
1182
+			$this->Pause_Label->set_text("Timer Done");
1183
+			
1184
+			$this->Note_End_Time();
1185
+			
1186
+			if ( $this->should_show_start_and_end_times )
1187
+			{
1188
+				$this->Set_End_Label();
1189
+			}
1190
+			echo "\n\nTimer Done: ";
1191
+			echo $this->DateTime_At_End->format("r");
1192
+			echo "\n";
1193
+			
1194
+			$this->timer_done=true;
1195
+			
1196
+			#exit;
1197
+			return false;
1198
+        }
1199
+    }
1200
+
1201
+
1202
+
1203
+    // Called when user closes the timer.
1204
+    public function Upon_Delete_Event($widget, $event)
1205
+    {
1206
+		echo "\n\n";
1207
+		echo "Timer window closed!";
1208
+		
1209
+        $this->Timer_Dialog->destroy();
1210
+        
1211
+        if ($this->timeout_ID)
1212
+        {
1213
+			Gtk::idle_remove($this->timeout_ID);
1214
+		}
1215
+		
1216
+		exit;
1217
+    }
1218
+}
1219
+
1220
+
1221
+
1222
+
1223
+$Mr_Cliargs=new Prototype___Mr_Cliargs;
1224
+$Mr_Cliargs->Get_Cliargs();
1225
+
1226
+$Mr_Raw_Input=new Prototype___Mr_Raw_Input;
1227
+$Mr_Raw_Input->Fetch_Raw_Input();
1228
+
1229
+$Mr_Standardized_Input=new Prototype___Mr_Standardized_Input;
1230
+$Mr_Standardized_Input->Standardize_Raw_Input();
1231
+
1232
+$Mr_Valichecker=new Prototype___Mr_Valichecker;
1233
+$Mr_Valichecker->Do_Valicheck_of_Input();
1234
+
1235
+
1236
+
1237
+$input=$Mr_Standardized_Input->standardized_input;
1238
+
1239
+$Icon_Fillepath=$input["icon_fillepath"];
1240
+
1241
+$count_up_or_down=$input["count_up_or_down"];
1242
+$dest_datetime=$input["dest_datetime"];
1243
+$dest_datetime_format=$input["dest_datetime_format"];
1244
+
1245
+$past_dest_datetime=false;
1246
+$should_show_start_and_end_times=$input["should_show_start_and_end_times"];
1247
+
1248
+
1249
+
1250
+if ($dest_datetime)
1251
+{
1252
+	$now_unixtime=time();
1253
+	
1254
+	if ( $dest_datetime < $now_unixtime)