/// \file
/// \ingroup tutorial_gui
/// This macro gives an example of how to use html widget to display tabular data.
/// To run it do either:
/// ~~~
/// .x calendar.C
/// .x calendar.C++
/// ~~~
///
/// \macro_code
///
/// \author Valeriy Onuchin 24/08/2007
#include "TDatime.h"
#include "TTimeStamp.h"
#include "TGComboBox.h"
#include "TGNumberEntry.h"
#include "TGLabel.h"
#include "TGColorSelect.h"
#include "TGHtml.h"
#include "TApplication.h"
#include "TROOT.h"
#include "TColor.h"
/////////////////////////// HTML calendar //////////////////////////////////////
TString monthNames[12] = {"January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December"};
////////////////////////////////////////////////////////////////////////////////
class HtmlDayName {
public: // make them public for shorter code
TString fDay; // day name, e.g. "Sunday"
TString fAlign; // name align inside table cell
TString fBgColor; // cell background color
TString fFontSize; // text font size
TString fFontColor; // text color
TString fHtml; // HTML output code
public:
HtmlDayName(const char *day);
virtual ~HtmlDayName() {}
TString Html() const { return fHtml; }
ClassDef(HtmlDayName, 0);
};
//______________________________________________________________________________
HtmlDayName::HtmlDayName(const char *day) : fDay(day), fAlign("middle"),
fBgColor("#000000"), fFontSize("4"), fFontColor("#FFFFFF")
{
// ctor.
fHtml += "
";
fHtml += "";
fHtml += fDay;
fHtml += " | \n";
}
////////////////////////////////////////////////////////////////////////////////
class HtmlMonthTable {
public: // make them public for shorter code
Int_t fYear; // year
Int_t fMonth; // month
TString fBorder; // border width
TString fBgColor; // background color
TString fCellpadding; // cell padding
TString fCellFontSize; // cell font size
TString fCellBgcolor; // cell background color
TString fTodayColor; // background color of cell correspondent today date
TDatime fToday; // today's date
TString fHtml; // HTML output code
void Build();
void BuildDayNames();
void BuildDays();
public:
HtmlMonthTable(Int_t year, Int_t month);
virtual ~HtmlMonthTable() {}
void SetDate(Int_t year, Int_t month);
TString Html() const { return fHtml; }
ClassDef(HtmlMonthTable, 0);
};
//______________________________________________________________________________
HtmlMonthTable::HtmlMonthTable(Int_t year, Int_t month) : fYear(year),
fMonth(month), fBorder("2"), fBgColor("#aaaaaa"), fCellpadding("5"),
fCellFontSize("3"), fCellBgcolor("#eeeeee"), fTodayColor("#ffff00")
{
// Constructor.
Build();
}
//______________________________________________________________________________
void HtmlMonthTable::SetDate(Int_t year, Int_t month)
{
// Set date.
fYear = year;
fMonth = month;
Build();
}
//______________________________________________________________________________
void HtmlMonthTable::Build()
{
// Build HTML code.
fHtml = "";
BuildDayNames();
BuildDays();
fHtml += "
\n";
}
//______________________________________________________________________________
void HtmlMonthTable::BuildDayNames()
{
// Build table header with day names.
fHtml += "";
fHtml += HtmlDayName("Sunday").Html();
fHtml += HtmlDayName("Monday").Html();
fHtml += HtmlDayName("Tuesday").Html();
fHtml += HtmlDayName("Wednesday").Html();
fHtml += HtmlDayName("Thursday").Html();
fHtml += HtmlDayName("Friday").Html();
fHtml += HtmlDayName("Saturday").Html();
fHtml += "
\n";
}
//______________________________________________________________________________
void HtmlMonthTable::BuildDays()
{
// Build part of table with day numbers.
static Int_t maxdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Int_t maxday = maxdays[fMonth-1];
if ((fMonth == 2) && TTimeStamp::IsLeapYear(fYear)) maxday = 29;
Int_t first = TTimeStamp::GetDayOfWeek(1, fMonth, fYear);
// fill html table
for (int week = 0; week < 6; week++) {
fHtml += "";
for (int weekday = 0; weekday < 7; weekday++) {//
Int_t day = week*7 + weekday - first + 1;
if ((day > maxday) && !weekday) break; //
fHtml += "";
//skip week days which are not of this month
if ((day <= 0) || (day > maxday)) {
fHtml += " | ";
continue;
}
fHtml += "";
fHtml += Form("%d", day);
fHtml += "\n";
}
fHtml += "
\n";
}
}
////////////////////////////////////////////////////////////////////////////////
class HtmlCalendar {
public: // make them public for shorter code
Int_t fYear; // year
Int_t fMonth; // month
HtmlMonthTable fMonthTable; // HTML table presenting month days
TString fHeader; // HTML header
TString fFooter; // HTML footer
TString fHtml; // output HTML string
TString fTitle; // page title
void MakeHeader();
void MakeFooter();
public:
HtmlCalendar(Int_t year, Int_t month);
virtual ~HtmlCalendar() {}
void SetDate(Int_t year, Int_t month);
TString Html() const { return fHtml; }
ClassDef(HtmlCalendar, 0);
};
//______________________________________________________________________________
HtmlCalendar::HtmlCalendar(Int_t year, Int_t month) : fMonthTable(year, month)
{
// Constructor.
fYear = year;
fMonth = month;
MakeHeader();
MakeFooter();
fHtml = fHeader;
fHtml += fMonthTable.Html();
fHtml += fFooter;
}
//______________________________________________________________________________
void HtmlCalendar::SetDate(Int_t year, Int_t month)
{
// Create calendar for month/year.
fYear = year;
fMonth = month;
fMonthTable.SetDate(year, month);
MakeHeader();
MakeFooter();
fHtml = fHeader;
fHtml += fMonthTable.Html();
fHtml += fFooter;
}
//______________________________________________________________________________
void HtmlCalendar::MakeHeader()
{
// Make HTML header.
fTitle = monthNames[fMonth-1] + Form(" %d", fYear);
fHeader = "";
fHeader += fTitle;
fHeader += "\n";
fHeader += "" + fTitle + "
";
}
//______________________________________________________________________________
void HtmlCalendar::MakeFooter()
{
// Make HTML footer.
fFooter = "
";
fFooter += "Example of using Html widget to display tabular data.";
fFooter += "";
}
//////////////////////// end of HTML calendar //////////////////////////////////
class CalendarWindow {
private:
TGMainFrame *fMain; // main frame
HtmlCalendar *fHtmlText; // calendar HTML table
TGHtml *fHtml; // html widget to display HTML calendar
TGComboBox *fMonthBox; // month selector
TGNumberEntry *fYearEntry; // year selector
TGNumberEntry *fFontEntry; // font size selector
TGColorSelect *fTableColor; // selector of background color of table
TGColorSelect *fCellColor; // selector of background color of table's cells
public:
CalendarWindow();
virtual ~CalendarWindow();
void UpdateHTML();
ClassDef(CalendarWindow, 0);
};
//______________________________________________________________________________
CalendarWindow::~CalendarWindow()
{
// Destructor.
delete fHtmlText;
delete fMain;
}
//______________________________________________________________________________
CalendarWindow::CalendarWindow()
{
// Main window.
fMain = new TGMainFrame(gClient->GetRoot(), 10, 10, kVerticalFrame);
fMain->SetCleanup(kDeepCleanup); // delete all subframes on exit
// Controls
TGHorizontalFrame *controls = new TGHorizontalFrame(fMain);
fMain->AddFrame(controls, new TGLayoutHints(kLHintsCenterX, 1, 1, 1, 1));
// generate HTML calendar table
TDatime today;
fHtmlText = new HtmlCalendar(today.GetYear(), today.GetMonth());
// create HTML widget
fHtml = new TGHtml(fMain, 1, 1);
fMain->AddFrame(fHtml, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,
5, 5, 2, 2));
// parse HTML context of HTML calendar table
fHtml->ParseText((char*)fHtmlText->Html().Data());
TGLabel *dateLabel = new TGLabel(controls, "Date:");
controls->AddFrame(dateLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,
5, 2, 2, 2));
//
fMonthBox = new TGComboBox(controls);
for (int i = 0; i < 12; i++) {
fMonthBox->AddEntry(monthNames[i].Data(), i+1);
}
fMonthBox->Select(today.GetMonth());
controls->AddFrame(fMonthBox, new TGLayoutHints(kLHintsLeft, 5, 5, 2, 2));
fYearEntry = new TGNumberEntry(controls, today.GetYear(), 5, -1,
TGNumberFormat::kNESInteger,
TGNumberFormat::kNEAPositive,
TGNumberFormat::kNELLimitMin, 1995);
controls->AddFrame(fYearEntry, new TGLayoutHints(kLHintsLeft, 5, 5, 2, 2));
fMonthBox->Resize(100, fYearEntry->GetHeight());
TGLabel *fontLabel = new TGLabel(controls, "Font Size:");
controls->AddFrame(fontLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,
30, 2, 2, 2));
Int_t fontsize = atoi(fHtmlText->fMonthTable.fCellFontSize.Data());
fFontEntry = new TGNumberEntry(controls, fontsize, 2, -1,
TGNumberFormat::kNESInteger,
TGNumberFormat::kNEAPositive,
TGNumberFormat::kNELLimitMax, 0, 7);
controls->AddFrame(fFontEntry, new TGLayoutHints(kLHintsLeft, 5, 5, 2, 2));
TGLabel *tableLabel = new TGLabel(controls, "Table:");
controls->AddFrame(tableLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,
5, 2, 2, 2));
Pixel_t color;
gClient->GetColorByName(fHtmlText->fMonthTable.fBgColor.Data(), color);
fTableColor = new TGColorSelect(controls, color);
controls->AddFrame(fTableColor, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,
5, 2, 2, 2));
TGLabel *cellLabel = new TGLabel(controls, "Cell:");
controls->AddFrame(cellLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,
5, 2, 2, 2));
gClient->GetColorByName(fHtmlText->fMonthTable.fCellBgcolor.Data(), color);
fCellColor = new TGColorSelect(controls, color);
controls->AddFrame(fCellColor, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,
5, 2, 2, 2));
// connect signals
fMonthBox->Connect("Selected(Int_t)", "CalendarWindow", this,
"UpdateHTML()");
fYearEntry->GetNumberEntry()->Connect("TextChanged(char*)", "CalendarWindow",
this, "UpdateHTML()");
fFontEntry->GetNumberEntry()->Connect("TextChanged(char*)", "CalendarWindow",
this, "UpdateHTML()");
fTableColor->Connect("ColorSelected(Pixel_t)", "CalendarWindow", this,
"UpdateHTML()");
fCellColor->Connect("ColorSelected(Pixel_t)", "CalendarWindow", this,
"UpdateHTML()");
// terminate ROOT session when window is closed
fMain->Connect("CloseWindow()", "TApplication", gApplication, "Terminate()");
fMain->DontCallClose();
fMain->MapSubwindows();
fMain->Resize(600, 333);
// set minimum size of main window
fMain->SetWMSizeHints(controls->GetDefaultWidth(), fMain->GetDefaultHeight(),
1000, 1000, 0 ,0);
TString title = "Calendar for ";
title += fHtmlText->fTitle;
fMain->SetWindowName(title.Data());
fMain->MapRaised();
}
//______________________________________________________________________________
void CalendarWindow::UpdateHTML()
{
// Update HTML table on user's input.
Int_t month = fMonthBox->GetSelected();
Int_t year = atoi(fYearEntry->GetNumberEntry()->GetText());
fHtmlText->fMonthTable.fCellFontSize = fFontEntry->GetNumberEntry()->GetText();
Pixel_t pixel = 0;
TColor *color = 0;
// table background
pixel = fTableColor->GetColor();
color = gROOT->GetColor(TColor::GetColor(pixel));
if (color) {
fHtmlText->fMonthTable.fBgColor = color->AsHexString();
}
// cell background
pixel = fCellColor->GetColor();
color = gROOT->GetColor(TColor::GetColor(pixel));
if (color) {
fHtmlText->fMonthTable.fCellBgcolor = color->AsHexString();
}
// update HTML context
fHtmlText->SetDate(year, month);
// parse new HTML context of HTML calendar table
fHtml->Clear();
fHtml->ParseText((char*)fHtmlText->Html().Data());
fHtml->Layout();
// update window title
TString title = "Calendar for ";
title += fHtmlText->fTitle;
fMain->SetWindowName(title.Data());
}
////////////////////////////////////////////////////////////////////////////////
void calendar()
{
// Main program.
new CalendarWindow();
}