Wtx ~ Wt Extension Library
WtxLib
MonthView.cpp
1 
2 
3 #include <Wt/WTemplate.h>
4 #include <Wt/WText.h>
5 #include <Wt/WDate.h>
6 #include <Wt/WTableView.h>
7 #include <Wt/WAbstractItemModel.h>
8 #include <Wt/WPushButton.h>
9 #include <Wt/WStandardItemModel.h>
10 #include <Wt/WTime.h>
11 
12 #include "Calendar.h"
13 #include "MonthView.h"
14 #include "Widget.h"
15 
16 #define COUT_(X) std::cout << __FILE__ << "::" << __LINE__ << " " << X << std::endl;
17 #define COUT_LINE COUT_("");
18 
19 namespace {
20 
21 class DayOfMonth
23 {
24  public:
25 
26  DayOfMonth( int index, Wtx::Web::Calendar::MonthView * widget )
27  : DayWidget( index ),
28  m_widget( widget )
29  {
30  addStyleClass( "divDayOfMonth" );
31 
32  m_tableView =
33  body()-> addNew<Wt::WTableView>();
34 
35  m_tableView-> setHeaderHeight(0);
36  m_tableView-> setSelectionMode( Wt::SelectionMode::Single );
37  m_tableView-> setHeight( "100px" );
38  m_tableView-> setOverflow( Wt::Overflow::Hidden, Wt::Orientation::Horizontal );
39 
40  m_tableView-> clicked().connect( [=]( Wt::WModelIndex index, Wt::WMouseEvent event )
41  {
42  clicked().emit( event );
43  });
44 
45  m_tableView-> doubleClicked().connect( [=]( Wt::WModelIndex index, Wt::WMouseEvent event )
46  {
47  doubleClicked().emit( event );
48  });
49 
50  }
51 
52  Wt::WTableView * tableView();
53 
54  virtual void setDate( const Wt::WDate & value );
55 
56  Wt::WTableView * m_tableView;
57 
58  Wtx::Web::Calendar::MonthView * m_widget = nullptr;
59 
60 };
61 
62 Wt::WTableView * DayOfMonth::tableView()
63 {
64  return m_tableView;
65 }
66 
67 void DayOfMonth::setDate( const Wt::WDate & value )
68 {
69  Wtx::Web::Calendar::DayWidget::setDate( value );
70 
71  // 2 3 4 5 6
72  auto datamodel = m_widget-> getModel( date(), {"keyField","cfyField","timeStart","timeStop","note"} );
73 
74  auto model = std::make_shared<Wt::WStandardItemModel>( datamodel-> rowCount(), 3 );
75 
76  /*
77  ** generate a table of formatted rows
78  **
79  */
80  for( int row=0; row < datamodel-> rowCount(); row++ )
81  {
82  /*
83  ** grab some data from the source model
84  **
85  */
86  auto keyField = Wt::asString( datamodel-> data( row, 2 ) );
87  auto cfyField = Wt::asString( datamodel-> data( row, 3 ) );
88  auto timeStart = Wt::WTime::fromString( Wt::asString( datamodel-> data( row, 4 ) ), "hh:mm:ss" );
89  auto timeStop = Wt::WTime::fromString( Wt::asString( datamodel-> data( row, 5 ) ), "hh:mm:ss" );
90  auto note = Wt::asString( datamodel-> data( row, 6 ) );
91 
92  /*
93  ** if this appointment has a time associated with it
94  ** generate some formatting for that
95  **
96  */
97  Wt::WString timepart;
98  if( timeStart.isValid() )
99  {
100  Wt::WString format = "hA";
101  if( timeStart.minute() != 0 )
102  format = "h:mmA";
103 
104  timepart = timeStart.toString(format) + " ";
105  }
106 
107  /*
108  ** set the data in to the model
109  **
110  */
111  model-> setData( row, 0, datamodel-> data( row, 0 ) );
112  model-> setData( row, 1, datamodel-> data( row, 1 ) );
113  model-> setData( row, 2, timepart + keyField );
114 
115  /*
116  ** set the tool-tip for this item as well
117  **
118  */
119  auto toolTip =
120  Wt::WString("{1}\n{2}\n{3}\n{4}\n{5}")
121  .arg( value.toString() )
122  .arg( timeStart.toString() + " " + timeStop.toString() )
123  .arg( keyField )
124  .arg( cfyField )
125  .arg( note.toUTF8().substr(0,150) )
126  ;
127 
128  model-> setData( row, 2, toolTip, Wt::ItemDataRole::ToolTip );
129 
130  } // endfor( int row=0; row < datamodel-> rowCount(); row++ )
131 
132  m_tableView-> setModel( model );
133 
134  m_tableView-> setColumnHidden(0,true);
135  m_tableView-> setColumnHidden(1,true);
136 
137 } // endvoid DayOfMonth::setDate( const Wt::WDate & value )
138 
139 } // endnamespace {
140 
142 : Wtx::Web::Calendar::BaseView( firstDayOfWeek, widget )
143 {
144  addStyleClass( "divTable" );
145  addStyleClass( "blueTable" );
146 
147  {
148  auto cwHeader = addNew<Wt::WContainerWidget>();
149  cwHeader-> addStyleClass( "divTableHeading" );
150 
151  auto cwRow = cwHeader-> addNew<Wt::WContainerWidget>();
152  cwRow-> addStyleClass( "divTableRow" );
153 
154  for( int weekday = 0; weekday < 7; weekday++ )
155  {
156  auto cwDay = cwRow-> addNew<Wt::WContainerWidget>();
157  cwDay-> addStyleClass( "divTableHead" );
158 
159  cwDay-> addNew<Wt::WText>( daynames().at(weekday) );
160  }
161  }
162 
163  /*
164  ** loop through five weeks of calendar
165  **
166  */
167  for( int week = 0; week < 6; week++ )
168  {
169  auto cwWeek = addNew<Wt::WContainerWidget>();
170  cwWeek-> addStyleClass( "divTableRow" );
171 
172  /*
173  ** loop through 7 days in a week
174  **
175  */
176  for( int day = 0; day < 7; day++ )
177  {
178  /*
179  ** create the container for this day
180  **
181  */
182  auto cwDay = cwWeek-> addNew<DayOfMonth>( (week*7)+day, this );
183 
184  cwDay-> clicked().connect( [=]()
185  {
186  if( cwDay-> tableView()-> selectedIndexes().size() == 1 )
187  {
188  m_itemClicked.emit( *cwDay-> tableView()-> selectedIndexes().begin() );
189  }
190 
191  m_clicked.emit( cwDay-> date() );
192 
193  });
194 
195  cwDay-> doubleClicked().connect( [=]()
196  {
197  if( cwDay-> tableView()-> selectedIndexes().size() == 1 )
198  {
199  m_itemDoubleClicked.emit( *cwDay-> tableView()-> selectedIndexes().begin() );
200  }
201 
202  m_doubleClicked.emit( cwDay-> date() );
203 
204  });
205 
206  /*
207  ** remember
208  **
209  */
210  m_dayWidgets.push_back( cwDay );
211 
212  } // endfor( int day = 0; day < 7; day++ )
213 
214  } // endfor( int week = 0; week < 5; week++ )
215 
227 // updateView();
228 
229 } // endWtx::Web::Calendar::MonthView::MonthView( const Wt::WDate & selectedDate )
230 
231 Wt::Signal<Wt::WDate> & Wtx::Web::Calendar::MonthView::clicked()
232 {
233  return m_clicked;
234 }
235 
236 Wt::Signal<Wt::WDate> & Wtx::Web::Calendar::MonthView::doubleClicked()
237 {
238  return m_doubleClicked;
239 }
240 
241 Wt::Signal<Wt::WModelIndex> & Wtx::Web::Calendar::MonthView::itemClicked()
242 {
243  return m_itemClicked;
244 }
245 
246 Wt::Signal<Wt::WModelIndex> & Wtx::Web::Calendar::MonthView::itemDoubleClicked()
247 {
248  return m_itemDoubleClicked;
249 }
250 
251 void Wtx::Web::Calendar::MonthView::updateView()
252 {
253  Wt::WDate first( selectedDate().year(), selectedDate().month(), 1 );
254  Wt::WDate start = first.addDays( first.dayOfWeek() * -1 );
255 
256  int cellDate = first.dayOfWeek() * -1;
257 
258  for( auto cwDay : dayWidgets() )
259  {
260  cwDay-> removeStyleClass( "divPreviousMonth" );
261  cwDay-> removeStyleClass( "divNextMonth" );
262  cwDay-> removeStyleClass( "divToday" );
263  cwDay-> day()-> removeStyleClass( "divSelectedDate" );
264 
265  cwDay-> setDate( start.addDays( cwDay-> index() ) );
266 
267  /*
268  ** if this day is in the previous month, then change
269  ** the background-color
270  **
271  */
272  if( cwDay-> date().month() < selectedDate().month() )
273  {
274  cwDay-> addStyleClass( "divPreviousMonth", true );
275  }
276 
277  /*
278  ** if this day is in the next month, then change
279  ** the background-color
280  **
281  */
282  if( cwDay-> date().month() > selectedDate().month() )
283  {
284  cwDay-> addStyleClass( "divNextMonth", true );
285  }
286 
287  /*
288  ** if this day is actually 'today' then change the
289  ** background color.
290  **
291  */
292  if( cwDay-> date() == today() )
293  {
294  cwDay-> addStyleClass( "divToday", true );
295  }
296 
297  /*
298  ** if this day is the date that is selected
299  ** background color.
300  **
301  */
302  if( cwDay-> date() == selectedDate() )
303  {
304  cwDay-> day()-> addStyleClass( "divSelectedDate", true );
305  }
306 
307  } // endfor( auto cwDay : days() )
308 
309 } // endvoid Wtx::Web::Calendar::MonthView::updateView()
310 
311 void Wtx::Web::Calendar::MonthView::setSelectedDate( const Wt::WDate & date )
312 {
313  Wtx::Web::Calendar::BaseView::setSelectedDate( date );
314  updateView();
315 }
316 
317 const Wt::WDate Wtx::Web::Calendar::MonthView::today() const
318 {
319  return Wt::WDate::currentDate();
320 }
321 
322 Wtx::Web::Calendar::DayWidget * Wtx::Web::Calendar::MonthView::dayWidget( const Wt::WDate & date ) const
323 {
324  for( auto dw : m_dayWidgets )
325  {
326  if( date == dw-> date() )
327  return dw;
328  }
329 
330  return nullptr;
331 }
332 
333 const std::vector< Wtx::Web::Calendar::DayWidget * > & Wtx::Web::Calendar::MonthView::dayWidgets() const
334 {
335  return m_dayWidgets;
336 }
337 
338 
Calendar Widget.
Definition: Widget.h:66
const std::vector< std::string > & daynames()
Long Day Names.
Definition: Calendar.cpp:11
Calendar Day Widget.
Definition: DayWidget.h:66
MonthView(int firstDayOfWeek, Wtx::Web::Calendar::Widget *widget)
Definition: MonthView.cpp:141
witty extension library
Definition: Activity.h:51