1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // dlgSchedule.cpp - PostgreSQL Schedule Property
9 //
10 //////////////////////////////////////////////////////////////////////////
11 
12 #include "pgAdmin3.h"
13 
14 // App headers
15 #include "utils/misc.h"
16 #include "agent/dlgSchedule.h"
17 #include "agent/pgaSchedule.h"
18 
19 // image for de/-select all
20 #include "images/check.pngc"
21 #include "images/uncheck.pngc"
22 
23 // pointer to controls
24 #define	txtID				CTRL_TEXT("txtID")
25 #define chkEnabled          CTRL_CHECKBOX("chkEnabled")
26 #define calStart            CTRL_CALENDAR("calStart")
27 #define timStart            CTRL_TIME("timStart")
28 #define calEnd              CTRL_CALENDAR("calEnd")
29 #define timEnd              CTRL_TIME("timEnd")
30 #define chkWeekdays			CTRL_CHECKLISTBOX("chkWeekdays")
31 #define chkMonthdays		CTRL_CHECKLISTBOX("chkMonthdays")
32 #define chkMonths			CTRL_CHECKLISTBOX("chkMonths")
33 #define chkHours			CTRL_CHECKLISTBOX("chkHours")
34 #define chkMinutes			CTRL_CHECKLISTBOX("chkMinutes")
35 #define lstExceptions       CTRL_LISTVIEW("lstExceptions")
36 #define timException     	CTRL_TIME("timException")
37 #define calException    	CTRL_CALENDAR("calException")
38 #define btnAddException     CTRL_BUTTON("btnAddException")
39 #define btnChangeException  CTRL_BUTTON("btnChangeException")
40 #define btnRemoveException  CTRL_BUTTON("btnRemoveException")
41 #define btnWeekdays  		CTRL_BUTTON("btnWeekdays")
42 #define btnMonthdays  		CTRL_BUTTON("btnMonthdays")
43 #define btnMonths  		CTRL_BUTTON("btnMonths")
44 #define btnHours  			CTRL_BUTTON("btnHours")
45 #define btnMinutes  		CTRL_BUTTON("btnMinutes")
46 
47 BEGIN_EVENT_TABLE(dlgSchedule, dlgAgentProperty)
48 	EVT_CHECKBOX(XRCID("chkEnabled"),                dlgSchedule::OnChangeCom)
49 	EVT_CALENDAR_SEL_CHANGED(XRCID("calStart"),      dlgSchedule::OnChangeCal)
50 	EVT_TEXT(XRCID("timStart"),                      dlgSchedule::OnChangeCom)
51 	EVT_CALENDAR_SEL_CHANGED(XRCID("calEnd"),        dlgSchedule::OnChangeCal)
52 	EVT_TEXT(XRCID("timEnd"),                        dlgSchedule::OnChangeCom)
53 	EVT_LIST_ITEM_SELECTED(XRCID("lstExceptions"),   dlgSchedule::OnSelChangeException)
54 	EVT_BUTTON(XRCID("btnAddException"),             dlgSchedule::OnAddException)
55 	EVT_BUTTON(XRCID("btnChangeException"),          dlgSchedule::OnChangeException)
56 	EVT_BUTTON(XRCID("btnRemoveException"),          dlgSchedule::OnRemoveException)
57 	EVT_BUTTON(XRCID("btnWeekdays"),        	     dlgSchedule::OnSelectAllWeekdays)
58 	EVT_BUTTON(XRCID("btnMonthdays"),		         dlgSchedule::OnSelectAllMonthdays)
59 	EVT_BUTTON(XRCID("btnMonths"), 				     dlgSchedule::OnSelectAllMonths)
60 	EVT_BUTTON(XRCID("btnHours"),  			         dlgSchedule::OnSelectAllHours)
61 	EVT_BUTTON(XRCID("btnMinutes"),			         dlgSchedule::OnSelectAllMinutes)
62 	EVT_CHECKLISTBOX(XRCID("chkWeekdays"),           dlgSchedule::OnChangeCom)
63 	EVT_CHECKLISTBOX(XRCID("chkMonthdays"),          dlgSchedule::OnChangeCom)
64 	EVT_CHECKLISTBOX(XRCID("chkMonths"),             dlgSchedule::OnChangeCom)
65 	EVT_CHECKLISTBOX(XRCID("chkHours"),              dlgSchedule::OnChangeCom)
66 	EVT_CHECKLISTBOX(XRCID("chkMinutes"),            dlgSchedule::OnChangeCom)
67 #ifdef __WXMAC__
68 	EVT_SIZE(                                        dlgSchedule::OnChangeSize)
69 #endif
70 END_EVENT_TABLE();
71 
72 
CreateDialog(frmMain * frame,pgObject * node,pgObject * parent)73 dlgProperty *pgaScheduleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
74 {
75 	return new dlgSchedule(this, frame, (pgaSchedule *)node, (pgaJob *)parent);
76 }
77 
78 
dlgSchedule(pgaFactory * f,frmMain * frame,pgaSchedule * node,pgaJob * j)79 dlgSchedule::dlgSchedule(pgaFactory *f, frmMain *frame, pgaSchedule *node, pgaJob *j)
80 	: dlgAgentProperty(f, frame, wxT("dlgSchedule"))
81 {
82 	schedule = node;
83 	job = j;
84 	if (job)
85 		jobId = job->GetRecId();
86 	else
87 		jobId = 0;
88 
89 	lstExceptions->CreateColumns(0, _("Date"), _("Time"), 90);
90 	lstExceptions->AddColumn(wxT("dirty"), 0);
91 	lstExceptions->AddColumn(wxT("id"), 0);
92 
93 	txtID->Disable();
94 
95 	btnChangeException->Disable();
96 	btnRemoveException->Disable();
97 
98 	int i;
99 
100 	for (i = 0 ; i < 24 ; i++)
101 		chkHours->Append(wxString::Format(wxT("%02d"), i));
102 
103 	for (i = 0 ; i < 60 ; i++)
104 		chkMinutes->Append(wxString::Format(wxT("%02d"), i));
105 }
106 
107 
GetObject()108 pgObject *dlgSchedule::GetObject()
109 {
110 	return schedule;
111 }
112 
113 
114 #ifdef __WXMAC__
OnChangeSize(wxSizeEvent & ev)115 void dlgSchedule::OnChangeSize(wxSizeEvent &ev)
116 {
117 	lstExceptions->SetSize(wxDefaultCoord, wxDefaultCoord,
118 	                       ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
119 	if (GetAutoLayout())
120 	{
121 		Layout();
122 	}
123 }
124 #endif
125 
126 
Go(bool modal)127 int dlgSchedule::Go(bool modal)
128 {
129 	int returncode;
130 
131 	if (schedule)
132 	{
133 		// edit mode
134 		recId = schedule->GetRecId();
135 		txtID->SetValue(NumToStr(recId));
136 		chkEnabled->SetValue(schedule->GetEnabled());
137 		calStart->SetValue(schedule->GetStart().GetDateOnly());
138 		timStart->SetTime(schedule->GetStart());
139 		if (schedule->GetEnd().IsValid())
140 		{
141 			calEnd->SetValue(schedule->GetEnd().GetDateOnly());
142 			timEnd->SetTime(schedule->GetEnd());
143 		}
144 		else
145 		{
146 			calEnd->SetValue(wxInvalidDateTime);
147 			timEnd->SetTime(wxInvalidDateTime);
148 			timEnd->Disable();
149 		}
150 
151 		unsigned int x;
152 		for (x = 0; x < schedule->GetMonths().Length(); x++ )
153 			if (schedule->GetMonths()[x] == 't') chkMonths->Check(x, true);
154 
155 		for (x = 0; x < schedule->GetMonthdays().Length(); x++ )
156 			if (schedule->GetMonthdays()[x] == 't') chkMonthdays->Check(x, true);
157 
158 		for (x = 0; x < schedule->GetWeekdays().Length(); x++ )
159 			if (schedule->GetWeekdays()[x] == 't') chkWeekdays->Check(x, true);
160 
161 		for (x = 0; x < schedule->GetHours().Length(); x++ )
162 			if (schedule->GetHours()[x] == 't') chkHours->Check(x, true);
163 
164 		for (x = 0; x < schedule->GetMinutes().Length(); x++ )
165 			if (schedule->GetMinutes()[x] == 't') chkMinutes->Check(x, true);
166 
167 		wxString id, dateToken, timeToken;
168 		wxDateTime val;
169 		long pos = 0;
170 		wxStringTokenizer tkz(schedule->GetExceptions(), wxT("|"));
171 
172 		while (tkz.HasMoreTokens() )
173 		{
174 			dateToken.Empty();
175 			timeToken.Empty();
176 
177 			// First is the ID
178 			id = tkz.GetNextToken();
179 
180 			// Look for a date
181 			if (tkz.HasMoreTokens())
182 				dateToken = tkz.GetNextToken();
183 
184 			// Look for a time
185 			if (tkz.HasMoreTokens())
186 				timeToken = tkz.GetNextToken();
187 
188 			if (!dateToken.IsEmpty() && !timeToken.IsEmpty())
189 			{
190 				val.ParseDate(dateToken);
191 				val.ParseTime(timeToken);
192 				pos = lstExceptions->AppendItem(0, val.FormatDate(), val.FormatTime());
193 			}
194 			else if (!dateToken.IsEmpty() && timeToken.IsEmpty())
195 			{
196 				val.ParseDate(dateToken);
197 				pos = lstExceptions->AppendItem(0, val.FormatDate(), _("<any>"));
198 			}
199 			else if (dateToken.IsEmpty() && !timeToken.IsEmpty())
200 			{
201 				val.ParseTime(timeToken);
202 				pos = lstExceptions->AppendItem(0, _("<any>"), val.FormatTime());
203 			}
204 
205 			lstExceptions->SetItem(pos, 2, BoolToStr(false));
206 			lstExceptions->SetItem(pos, 3, id);
207 
208 		}
209 
210 		wxNotifyEvent ev;
211 	}
212 	else
213 	{
214 		// create mode
215 	}
216 
217 	// setup de-/select buttons
218 	InitSelectAll();
219 
220 	returncode = dlgProperty::Go(modal);
221 
222 	SetSqlReadOnly(true);
223 
224 	return returncode;
225 }
226 
227 
CreateObject(pgCollection * collection)228 pgObject *dlgSchedule::CreateObject(pgCollection *collection)
229 {
230 	pgObject *obj = scheduleFactory.CreateObjects(collection, 0, wxT("   AND jscid=") + NumToStr(recId) + wxT("\n"));
231 	return obj;
232 }
233 
234 
OnChangeCal(wxCalendarEvent & ev)235 void dlgSchedule::OnChangeCal(wxCalendarEvent &ev)
236 {
237 	CheckChange();
238 }
239 
240 
OnChangeCom(wxCommandEvent & ev)241 void dlgSchedule::OnChangeCom(wxCommandEvent &ev)
242 {
243 	CheckChange();
244 }
245 
246 
CheckChange()247 void dlgSchedule::CheckChange()
248 {
249 	timEnd->Enable(calEnd->GetValue().IsValid());
250 
251 	wxString name = GetName();
252 	bool enable = true;
253 
254 	if (statusBar)
255 		statusBar->SetStatusText(wxEmptyString);
256 
257 	InitSelectAll();
258 
259 	CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
260 	CheckValid(enable, calStart->GetValue().IsValid(), _("Please specify start date."));
261 
262 	if (enable)
263 	{
264 		EnableOK(!GetSql().IsEmpty());
265 	}
266 	else
267 		EnableOK(false);
268 }
269 
270 
OnSelChangeException(wxListEvent & ev)271 void dlgSchedule::OnSelChangeException(wxListEvent &ev)
272 {
273 	int sel = lstExceptions->GetSelection();
274 	if (sel >= 0)
275 	{
276 		wxString exDate = lstExceptions->GetText(sel, 0);
277 		wxString exTime = lstExceptions->GetText(sel, 1);
278 		wxDateTime val, null;
279 
280 		if (exDate == _("<any>"))
281 			calException->SetValue(null);
282 		else
283 		{
284 			val.ParseDate(exDate);
285 			calException->SetValue(val);
286 		}
287 		if (exTime == _("<any>"))
288 			timException->SetTime(null);
289 		else
290 		{
291 			val.ParseTime(exTime);
292 			timException->SetTime(val);
293 		}
294 
295 		btnChangeException->Enable();
296 		btnRemoveException->Enable();
297 	}
298 }
299 
300 
OnAddException(wxCommandEvent & ev)301 void dlgSchedule::OnAddException(wxCommandEvent &ev)
302 {
303 	if (!calException->GetValue().IsValid() && timException->GetValue().IsNull())
304 	{
305 		wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
306 		return;
307 	}
308 
309 	wxString exDate, exTime;
310 
311 	if (calException->GetValue().IsValid())
312 		exDate = calException->GetValue().FormatDate();
313 	else
314 		exDate = _("<any>");
315 
316 	if (!timException->GetValue().IsNull())
317 		exTime = timException->GetValue().Format();
318 	else
319 		exTime = _("<any>");
320 
321 	for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++)
322 	{
323 
324 		if (lstExceptions->GetText(pos, 0) == exDate &&
325 		        lstExceptions->GetText(pos, 1) == exTime)
326 		{
327 			wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
328 			return;
329 		}
330 
331 		if (lstExceptions->GetText(pos, 0) == exDate &&
332 		        lstExceptions->GetText(pos, 1) == _("<any>"))
333 		{
334 			wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
335 			return;
336 		}
337 
338 		if (lstExceptions->GetText(pos, 1) == exTime &&
339 		        lstExceptions->GetText(pos, 0) == _("<any>"))
340 		{
341 			wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
342 			return;
343 		}
344 	}
345 
346 	lstExceptions->AppendItem(0, exDate, exTime);
347 	CheckChange();
348 }
349 
350 
OnChangeException(wxCommandEvent & ev)351 void dlgSchedule::OnChangeException(wxCommandEvent &ev)
352 {
353 	if (!calException->GetValue().IsValid() && timException->GetValue().IsNull())
354 	{
355 		wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
356 		return;
357 	}
358 
359 	wxString exDate, exTime;
360 
361 	if (calException->GetValue().IsValid())
362 		exDate = calException->GetValue().FormatDate();
363 	else
364 		exDate = _("<any>");
365 
366 	if (!timException->GetValue().IsNull())
367 		exTime = timException->GetValue().Format();
368 	else
369 		exTime = _("<any>");
370 
371 	long item = lstExceptions->GetFocusedItem();
372 
373 	for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++)
374 	{
375 		if (item != pos)
376 		{
377 			if (lstExceptions->GetText(pos, 0) == exDate &&
378 			        lstExceptions->GetText(pos, 1) == exTime)
379 			{
380 				wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
381 				return;
382 			}
383 
384 			if (lstExceptions->GetText(pos, 0) == exDate &&
385 			        lstExceptions->GetText(pos, 1) == _("<any>"))
386 			{
387 				wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
388 				return;
389 			}
390 
391 			if (lstExceptions->GetText(pos, 1) == exTime &&
392 			        lstExceptions->GetText(pos, 0) == _("<any>"))
393 			{
394 				wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
395 				return;
396 			}
397 		}
398 	}
399 
400 	lstExceptions->SetItem(item, 0, exDate);
401 	lstExceptions->SetItem(item, 1, exTime);
402 	lstExceptions->SetItem(item, 2, BoolToStr(true));
403 	CheckChange();
404 }
405 
406 
OnRemoveException(wxCommandEvent & ev)407 void dlgSchedule::OnRemoveException(wxCommandEvent &ev)
408 {
409 	if (lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3) != wxEmptyString)
410 	{
411 		deleteExceptions.Add(lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3));
412 	}
413 	lstExceptions->DeleteCurrentItem();
414 
415 	btnChangeException->Disable();
416 	btnRemoveException->Disable();
417 
418 	CheckChange();
419 }
420 
421 
GetComment()422 wxString dlgSchedule::GetComment()
423 {
424 	return txtComment->GetValue();
425 }
426 
427 
GetInsertSql()428 wxString dlgSchedule::GetInsertSql()
429 {
430 	wxString sql;
431 	if (!schedule)
432 	{
433 		wxString name = GetName();
434 		wxString jscjobid, list = wxT("NULL");
435 		if (jobId)
436 			jscjobid = NumToStr(jobId);
437 		else
438 			jscjobid = wxT("<JobId>");
439 
440 		// Build the various arrays of values
441 		sql = wxT("INSERT INTO pgagent.pga_schedule (jscid, jscjobid, jscname, jscdesc, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths, jscenabled, jscstart, jscend)\n")
442 		      wxT("VALUES(<SchId>, ") + jscjobid + wxT(", ") + qtDbString(name) + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ")
443 		      + wxT("'") + ChkListBox2PgArray(chkMinutes) + wxT("', ")
444 		      + wxT("'") + ChkListBox2PgArray(chkHours) + wxT("', ")
445 		      + wxT("'") + ChkListBox2PgArray(chkWeekdays) + wxT("', ")
446 		      + wxT("'") + ChkListBox2PgArray(chkMonthdays) + wxT("', ")
447 		      + wxT("'") + ChkListBox2PgArray(chkMonths) + wxT("', ")
448 		      + BoolToStr(chkEnabled->GetValue()) + wxT(", ")
449 		      + wxT("'") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'");
450 
451 		if (calEnd->GetValue().IsValid())
452 			sql += wxT(", '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'");
453 		else
454 			sql += wxT(", NULL");
455 
456 		sql += wxT(");\n");
457 	}
458 
459 	return sql;
460 }
461 
462 
GetUpdateSql()463 wxString dlgSchedule::GetUpdateSql()
464 {
465 	wxString sql, name;
466 	name = GetName();
467 
468 	if (schedule)
469 	{
470 		// edit mode
471 		wxString vars;
472 
473 		if (name != schedule->GetName())
474 		{
475 			if (!vars.IsEmpty())
476 				vars.Append(wxT(", "));
477 			vars.Append(wxT("jscname = ") + qtDbString(name));
478 		}
479 		if (txtComment->GetValue() != schedule->GetComment())
480 		{
481 			if (!vars.IsEmpty())
482 				vars.Append(wxT(", "));
483 			vars.Append(wxT("jscdesc = ") + qtDbString(txtComment->GetValue()));
484 		}
485 
486 		if ((!chkEnabled->IsChecked() && schedule->GetEnabled()) || (chkEnabled->IsChecked() && !schedule->GetEnabled()))
487 		{
488 			if (!vars.IsEmpty())
489 				vars.Append(wxT(", "));
490 			vars.Append(wxT("jscenabled = ") + BoolToStr(chkEnabled->IsChecked()));
491 		}
492 
493 		if (calStart->GetValue() + timStart->GetValue() != schedule->GetStart())
494 		{
495 			if (!vars.IsEmpty())
496 				vars.Append(wxT(", "));
497 			vars.Append(wxT("jscstart = '") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'"));
498 		}
499 
500 		if (calEnd->GetValue().IsValid())
501 		{
502 			if (schedule->GetEnd().IsValid())
503 			{
504 				if (calEnd->GetValue() + timEnd->GetValue() != schedule->GetEnd())
505 				{
506 					if (!vars.IsEmpty())
507 						vars.Append(wxT(", "));
508 					vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'"));
509 				}
510 			}
511 			else
512 			{
513 				if (!vars.IsEmpty())
514 					vars.Append(wxT(", "));
515 				vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + wxTimeSpan()) + wxT("'"));
516 			}
517 		}
518 		else
519 		{
520 			if (schedule->GetEnd().IsValid())
521 			{
522 				if (!vars.IsEmpty())
523 					vars.Append(wxT(", "));
524 				vars.Append(wxT("jscend = NULL"));
525 			}
526 		}
527 
528 		if (ChkListBox2StrArray(chkMinutes) != schedule->GetMinutes())
529 		{
530 			if (!vars.IsEmpty())
531 				vars.Append(wxT(", "));
532 			vars.Append(wxT("jscminutes = '") + ChkListBox2PgArray(chkMinutes) + wxT("'"));
533 		}
534 
535 		if (ChkListBox2StrArray(chkHours) != schedule->GetHours())
536 		{
537 			if (!vars.IsEmpty())
538 				vars.Append(wxT(", "));
539 			vars.Append(wxT("jschours = '") + ChkListBox2PgArray(chkHours) + wxT("'"));
540 		}
541 
542 		if (ChkListBox2StrArray(chkWeekdays) != schedule->GetWeekdays())
543 		{
544 			if (!vars.IsEmpty())
545 				vars.Append(wxT(", "));
546 			vars.Append(wxT("jscweekdays = '") + ChkListBox2PgArray(chkWeekdays) + wxT("'"));
547 		}
548 
549 		if (ChkListBox2StrArray(chkMonthdays) != schedule->GetMonthdays())
550 		{
551 			if (!vars.IsEmpty())
552 				vars.Append(wxT(", "));
553 			vars.Append(wxT("jscmonthdays = '") + ChkListBox2PgArray(chkMonthdays) + wxT("'"));
554 		}
555 
556 		if (ChkListBox2StrArray(chkMonths) != schedule->GetMonths())
557 		{
558 			if (!vars.IsEmpty())
559 				vars.Append(wxT(", "));
560 			vars.Append(wxT("jscmonths = '") + ChkListBox2PgArray(chkMonths) + wxT("'"));
561 		}
562 
563 		if (!vars.IsEmpty())
564 			sql = wxT("UPDATE pgagent.pga_schedule SET ") + vars + wxT("\n")
565 			      wxT(" WHERE jscid=") + NumToStr(recId) + wxT(";\n");
566 	}
567 	else
568 	{
569 		// create mode
570 		// Handled by GetInsertSQL
571 	}
572 
573 	unsigned int x = 0;
574 	int y = 0;
575 	wxDateTime tmpDateTime;
576 	wxString newDate, newTime;
577 
578 	// Remove old exceptions
579 	for (x = 0; x < deleteExceptions.Count(); x++)
580 	{
581 		sql += wxT("DELETE FROM pgagent.pga_exception\n  WHERE jexid = ") + deleteExceptions[x] + wxT(";\n");
582 	}
583 
584 	// Update dirty exceptions
585 	for (y = 0; y < lstExceptions->GetItemCount(); y++)
586 	{
587 		if (lstExceptions->GetText(y, 2) == BoolToStr(true) &&
588 		        lstExceptions->GetText(y, 3) != wxEmptyString)
589 		{
590 			if (lstExceptions->GetText(y, 0) == _("<any>"))
591 				newDate = wxT("null");
592 			else
593 			{
594 				tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x"));
595 				newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'");
596 			}
597 
598 			if (lstExceptions->GetText(y, 1) == _("<any>"))
599 				newTime = wxT("null");
600 			else
601 			{
602 				tmpDateTime.ParseTime(lstExceptions->GetText(y, 1));
603 				newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'");
604 			}
605 
606 			sql += wxT("UPDATE pgagent.pga_exception SET jexdate = ") + newDate +
607 			       wxT(", jextime = ") + newTime + wxT("\n  WHERE jexid = ") +
608 			       lstExceptions->GetText(y, 3) + wxT(";\n");
609 		}
610 	}
611 
612 	// Insert new exceptions
613 	for (y = 0; y < lstExceptions->GetItemCount(); y++)
614 	{
615 		if (lstExceptions->GetText(y, 2) == wxEmptyString &&
616 		        lstExceptions->GetText(y, 3) == wxEmptyString)
617 		{
618 			if (lstExceptions->GetText(y, 0) == _("<any>"))
619 				newDate = wxT("null");
620 			else
621 			{
622 				tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x"));
623 				newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'");
624 			}
625 
626 			if (lstExceptions->GetText(y, 1) == _("<any>"))
627 				newTime = wxT("null");
628 			else
629 			{
630 				tmpDateTime.ParseTime(lstExceptions->GetText(y, 1));
631 				newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'");
632 			}
633 
634 			sql += wxT("INSERT INTO pgagent.pga_exception (jexscid, jexdate, jextime)\n  VALUES (")
635 			       + NumToStr(recId) + wxT(", ") + newDate + wxT(", ") + newTime + wxT(");\n");
636 
637 		}
638 	}
639 
640 
641 
642 	return sql;
643 }
644 
645 
ChkListBox2PgArray(wxCheckListBox * lb)646 const wxString dlgSchedule::ChkListBox2PgArray(wxCheckListBox *lb)
647 {
648 	wxString res = wxT("{");
649 
650 	for (unsigned int x = 0; x < lb->GetCount(); x++)
651 	{
652 		if (lb->IsChecked(x))
653 			res += wxT("t,");
654 		else
655 			res += wxT("f,");
656 	}
657 	if (res.Length() > 1)
658 		res.RemoveLast();
659 
660 	res += wxT("}");
661 
662 	return res;
663 }
664 
665 
ChkListBox2StrArray(wxCheckListBox * lb)666 const wxString dlgSchedule::ChkListBox2StrArray(wxCheckListBox *lb)
667 {
668 	wxString res;
669 
670 	for (unsigned int x = 0; x < lb->GetCount(); x++)
671 	{
672 		if (lb->IsChecked(x))
673 			res += wxT("t");
674 		else
675 			res += wxT("f");
676 	}
677 
678 	return res;
679 }
680 
681 
OnSelectAll(wxCommandEvent & ev,int origin)682 void dlgSchedule::OnSelectAll(wxCommandEvent &ev, int origin)
683 {
684 	bool check = false;
685 	wxBitmapButton *btn;
686 	wxCheckListBox *lb;
687 	wxString tooltip;
688 
689 	switch (origin)
690 	{
691 		case 1:
692 			btn = ((wxBitmapButton *)btnWeekdays);
693 			lb = chkWeekdays;
694 			break;
695 		case 2:
696 			btn = ((wxBitmapButton *)btnMonthdays);
697 			lb = chkMonthdays;
698 			break;
699 		case 3:
700 			btn = ((wxBitmapButton *)btnMonths);
701 			lb = chkMonths;
702 			break;
703 		case 4:
704 			btn = ((wxBitmapButton *)btnHours);
705 			lb = chkHours;
706 			break;
707 		case 5:
708 			btn = ((wxBitmapButton *)btnMinutes);
709 			lb = chkMinutes;
710 			break;
711 		default:
712 			return;
713 			break;
714 	}
715 
716 	for (unsigned int x = 0; x < lb->GetCount(); x++)
717 	{
718 		if (!lb->IsChecked(x))
719 		{
720 			check = true;
721 			break;
722 		}
723 	}
724 	for (unsigned int x = 0; x < lb->GetCount(); x++)
725 	{
726 		lb->Check(x, check);
727 	}
728 
729 	CheckChange();
730 }
731 
732 
InitSelectAll()733 void dlgSchedule::InitSelectAll()
734 {
735 	bool check = false;
736 	wxBitmapButton *btn;
737 	wxCheckListBox *lb;
738 	wxString tooltip;
739 
740 	btn = ((wxBitmapButton *)btnWeekdays);
741 	lb = chkWeekdays;
742 	for (unsigned int x = 0; x < lb->GetCount(); x++)
743 	{
744 		if (!lb->IsChecked(x))
745 		{
746 			check = true;
747 			break;
748 		}
749 	}
750 
751 	if (check)
752 	{
753 		btn->SetBitmapLabel(*check_png_bmp);
754 		tooltip = _("Select all week days");
755 	}
756 	else
757 	{
758 		btn->SetBitmapLabel(*uncheck_png_bmp);
759 		tooltip = _("Deselect all week days");
760 	}
761 	btn->SetToolTip(tooltip);
762 
763 	check = false;
764 	btn = ((wxBitmapButton *)btnMonthdays);
765 	lb = chkMonthdays;
766 	for (unsigned int x = 0; x < lb->GetCount(); x++)
767 	{
768 		if (!lb->IsChecked(x))
769 		{
770 			check = true;
771 			break;
772 		}
773 	}
774 
775 	if (check)
776 	{
777 		btn->SetBitmapLabel(*check_png_bmp);
778 		tooltip = _("Select all month days");
779 	}
780 	else
781 	{
782 		btn->SetBitmapLabel(*uncheck_png_bmp);
783 		tooltip = _("Deselect all month days");
784 	}
785 	btn->SetToolTip(tooltip);
786 
787 	check = false;
788 	btn = ((wxBitmapButton *)btnMonths);
789 	lb = chkMonths;
790 	for (unsigned int x = 0; x < lb->GetCount(); x++)
791 	{
792 		if (!lb->IsChecked(x))
793 		{
794 			check = true;
795 			break;
796 		}
797 	}
798 
799 	if (check)
800 	{
801 		btn->SetBitmapLabel(*check_png_bmp);
802 		tooltip = _("Select all months");
803 	}
804 	else
805 	{
806 		btn->SetBitmapLabel(*uncheck_png_bmp);
807 		tooltip = _("Deselect all months");
808 	}
809 	btn->SetToolTip(tooltip);
810 
811 	check = false;
812 	btn = ((wxBitmapButton *)btnHours);
813 	lb = chkHours;
814 	for (unsigned int x = 0; x < lb->GetCount(); x++)
815 	{
816 		if (!lb->IsChecked(x))
817 		{
818 			check = true;
819 			break;
820 		}
821 	}
822 
823 	if (check)
824 	{
825 		btn->SetBitmapLabel(*check_png_bmp);
826 		tooltip = _("Select all hours");
827 	}
828 	else
829 	{
830 		btn->SetBitmapLabel(*uncheck_png_bmp);
831 		tooltip = _("Deselect all hours");
832 	}
833 	btn->SetToolTip(tooltip);
834 
835 
836 	check = false;
837 	btn = ((wxBitmapButton *)btnMinutes);
838 	lb = chkMinutes;
839 	for (unsigned int x = 0; x < lb->GetCount(); x++)
840 	{
841 		if (!lb->IsChecked(x))
842 		{
843 			check = true;
844 			break;
845 		}
846 	}
847 
848 	if (check)
849 	{
850 		btn->SetBitmapLabel(*check_png_bmp);
851 		tooltip = _("Select all minutes");
852 	}
853 	else
854 	{
855 		btn->SetBitmapLabel(*uncheck_png_bmp);
856 		tooltip = _("Deselect all minutes");
857 	}
858 	btn->SetToolTip(tooltip);
859 }
860