• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

kstars

  • sources
  • kde-4.12
  • kdeedu
  • kstars
  • kstars
  • tools
calendarwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  calendarwidget.cpp - description
3  -------------------
4  begin : Wed Jul 16 2008
5  copyright : (C) 2008 by Jason Harris
6  email : kstars@30doradus.org
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "calendarwidget.h"
19 
20 #include <QPainter>
21 #include <KPlotObject>
22 #include <kdebug.h>
23 
24 #include "kstarsdata.h"
25 #include "skyobjects/kssun.h"
26 #include "skycalendar.h"
27 #include "ksalmanac.h"
28 
29 #define BIGTICKSIZE 10
30 #define SMALLTICKSIZE 4
31 #define TICKOFFSET 0
32 
33 
34 CalendarWidget::CalendarWidget( QWidget *parent )
35  : KPlotWidget( parent )
36 {
37  setAntialiasing( true );
38 
39  setTopPadding( 40 );
40  setLeftPadding( 60 );
41  setRightPadding( 100 );
42 
43  maxRTime = 12.0;
44  minSTime = -12.0;
45 }
46 
47 void CalendarWidget::paintEvent( QPaintEvent *e ) {
48  Q_UNUSED( e )
49 
50  QPainter p;
51 
52  p.begin( this );
53  p.setRenderHint( QPainter::Antialiasing, antialiasing() );
54  p.fillRect( rect(), backgroundColor() );
55  p.translate( leftPadding(), topPadding() );
56 
57  setPixRect();
58  p.setClipRect( pixRect() );
59  p.setClipping( true );
60 
61  drawHorizon( &p );
62 
63  foreach ( KPlotObject *po, plotObjects() ) {
64  po->draw( &p, this );
65  }
66 
67  p.setClipping( false );
68  drawAxes( &p );
69 
70 }
71 
72 void CalendarWidget::setHorizon() {
73  KSSun thesun;
74  SkyCalendar *skycal = (SkyCalendar*)topLevelWidget();
75  KStarsDateTime kdt( QDate( skycal->year(), 1, 1 ), QTime( 12, 0, 0 ) );
76 
77  maxRTime = 0.0;
78  minSTime = 0.0;
79 
80  // Clear date, rise and set time lists
81  dateList.clear();
82  riseTimeList.clear();
83  setTimeList.clear();
84 
85  float rTime, sTime;
86 
87  // Get rise and set time every 7 days for 1 year
88  while ( skycal->year() == kdt.date().year() ) {
89  QTime tmp_rTime = thesun.riseSetTime( kdt.djd() + 1.0, skycal->get_geo(), true, true );
90  QTime tmp_sTime = thesun.riseSetTime( kdt.djd(), skycal->get_geo(), false, true );
91 
92  /* riseSetTime seems buggy since it sometimes returns the same time for rise and set (01:00:00).
93  * In this case, we just reset tmp_rTime and tmp_sTime so they will be considered invalid
94  * in the following lines.
95  * NOTE: riseSetTime should be fix now, this test is no longer necessary*/
96  if ( tmp_rTime == tmp_sTime ) {
97  tmp_rTime = QTime();
98  tmp_sTime = QTime();
99  }
100 
101  // If rise and set times are valid, the sun rise and set...
102  if ( tmp_rTime.isValid() && tmp_sTime.isValid() ) {
103  // Compute X-coordinate value for rise and set time
104  QTime midday( 12, 0, 0 );
105  rTime = tmp_rTime.secsTo( midday ) * 24.0 / 86400.0;
106  sTime = tmp_sTime.secsTo( midday ) * 24.0 / 86400.0;
107 
108  if ( tmp_rTime <= midday )
109  rTime = 12.0 - rTime;
110  else
111  rTime = -12.0 - rTime;
112 
113  if ( tmp_sTime <= midday )
114  sTime = 12.0 - sTime;
115  else
116  sTime = -12.0 - sTime;
117  }
118  /* else, the sun don't rise and/or don't set.
119  * we look at the altitude of the sun at transit time, if it is above the horizon,
120  * there is no night, else there is no day. */
121  else {
122  if ( thesun.transitAltitude( kdt.djd(), skycal->get_geo() ).degree() > 0 ) {
123  rTime = -4.0;
124  sTime = 4.0;
125  } else {
126  rTime = 12.0;
127  sTime = -12.0;
128  }
129  }
130 
131  // Get max rise time and min set time
132  if ( rTime > maxRTime )
133  maxRTime = rTime;
134  if ( sTime < minSTime )
135  minSTime = sTime;
136 
137  // Keep the day, rise time and set time in lists
138  dateList.append( kdt.date() );
139  riseTimeList.append( rTime );
140  setTimeList.append( sTime );
141 
142  // Next week
143  kdt = kdt.addDays( skycal->scUI->spinBox_Interval->value() );
144  }
145 
146  // Set widget limits
147  maxRTime = ceil( maxRTime ) + 1.0;
148  if ( (int) maxRTime % 2 != 0 )
149  maxRTime++;
150  if ( maxRTime > 12.0 )
151  maxRTime = 12.0;
152  minSTime = floor( minSTime ) - 1.0;
153  if ( (int) minSTime % 2 != 0 )
154  minSTime--;
155  if ( minSTime < -12.0 )
156  minSTime = -12.0;
157  setLimits( minSTime, maxRTime, 0.0, 366.0 );
158  setPixRect();
159 }
160 
161 void CalendarWidget::drawHorizon( QPainter *p ) {
162  polySunRise.clear();
163  polySunSet.clear();
164 
165  for ( int date=0; date<dateList.size(); date++ ) {
166  int day = dateList.at( date ).daysInYear() - dateList.at( date ).dayOfYear();
167  polySunRise << mapToWidget( QPointF( riseTimeList.at( date ), day ) );
168  polySunSet << mapToWidget( QPointF( setTimeList.at( date ), day ) );
169  }
170 
171  //Finish polygons by adding pixRect corners
172  polySunRise << mapToWidget( QPointF( riseTimeList.last(), dataRect().top() ) )
173  << mapToWidget( QPointF( dataRect().right(), dataRect().top() ) )
174  << mapToWidget( QPointF( dataRect().right(), dataRect().bottom() ) )
175  << mapToWidget( QPointF( riseTimeList.first(), dataRect().bottom() ) );
176  polySunSet << mapToWidget( QPointF( setTimeList.last(), dataRect().top() ) )
177  << mapToWidget( QPointF( dataRect().left(), pixRect().top() ) )
178  << mapToWidget( QPointF( dataRect().left(), pixRect().bottom() ) )
179  << mapToWidget( QPointF( setTimeList.first(), dataRect().bottom() ) );
180 
181  p->setPen( Qt::darkGreen );
182  p->setBrush( Qt::darkGreen );
183  p->drawPolygon( polySunRise );
184  p->drawPolygon( polySunSet );
185 }
186 
187 void CalendarWidget::drawAxes( QPainter *p ) {
188  SkyCalendar *skycal = (SkyCalendar*)topLevelWidget();
189 
190  p->setPen( foregroundColor() );
191  p->setBrush( Qt::NoBrush );
192 
193  //Draw bounding box for the plot
194  p->drawRect( pixRect() );
195 
196  //set small font for axis labels
197  QFont f = p->font();
198  int s = f.pointSize();
199  f.setPointSize( s - 2 );
200  p->setFont( f );
201 
202  // Top axis label
203  p->drawText(
204  0, -38,
205  pixRect().width(), pixRect().height(),
206  Qt::AlignHCenter | Qt::AlignTop | Qt::TextDontClip,
207  i18n( "Local time" ) );
208  // Bottom axis label
209  p->drawText(
210  0, 0,
211  pixRect().width(), pixRect().height() + 35,
212  Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip,
213  i18n( "Universal time" ) );
214  // Left axis label
215  p->save();
216  p->rotate( 90.0 );
217  p->drawText(
218  0, 0,
219  pixRect().height(), leftPadding() -5,
220  Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip,
221  i18n( "Month" ) );
222  // Right axis label
223  p->translate( 0.0, -1 * frameRect().width() + 30 );
224  p->drawText(
225  0, 0,
226  pixRect().height(), leftPadding() -5,
227  Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip,
228  i18n( "Julian date" ) );
229  p->restore();
230 
231  //Top/Bottom axis tickmarks and time labels
232  for ( float xx = minSTime; xx <= maxRTime; xx += 1.0 ) {
233  int h = int(xx);
234  if ( h < 0 ) h += 24;
235  QTime time( h, 0, 0 );
236  QString sTime = KGlobal::locale()->formatLocaleTime( time, KLocale::TimeWithoutSeconds );
237  QString sUtTime = KGlobal::locale()->formatLocaleTime( time.addSecs( skycal->get_geo()->TZ() * -3600 ), KLocale::TimeWithoutSeconds );
238 
239  // Draw a small tick every hours and a big tick every two hours.
240  QPointF pBottomTick = mapToWidget( QPointF( xx, dataRect().y() ) );
241  QPointF pTopTick = QPointF( pBottomTick.x(), 0.0 );
242  if ( h % 2 ) {
243  // Draw small bottom tick
244  p->drawLine( pBottomTick, QPointF( pBottomTick.x(), pBottomTick.y() - SMALLTICKSIZE ) );
245  // Draw small top tick
246  p->drawLine( pTopTick, QPointF( pTopTick.x(), pTopTick.y() + SMALLTICKSIZE ) );
247  } else {
248  // Draw big bottom tick
249  p->drawLine( pBottomTick, QPointF( pBottomTick.x(), pBottomTick.y() - BIGTICKSIZE ) );
250  QRectF r( pBottomTick.x() - BIGTICKSIZE, pBottomTick.y() + 0.5*BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
251  p->drawText( r, Qt::AlignCenter | Qt::TextDontClip, sUtTime );
252  // Draw big top tick
253  p->drawLine( pTopTick, QPointF( pTopTick.x(), pTopTick.y() + BIGTICKSIZE ) );
254  r.moveTop( -2.0*BIGTICKSIZE );
255  p->drawText( r, Qt::AlignCenter | Qt::TextDontClip, sTime );
256  }
257 
258  // Vertical grid
259  if ( skycal->scUI->checkBox_GridVertical->isChecked() ) {
260  QColor c = p->pen().color();
261  c.setAlpha( 100 );
262  p->setPen( c );
263  p->drawLine( pTopTick, pBottomTick );
264  c.setAlpha( 255 );
265  p->setPen( c );
266  }
267  }
268 
269  // Month dividers
270  int y = skycal->year();
271  for ( int imonth=2; imonth <= 12; ++imonth ) {
272  QDate dt( y, imonth, 1 );
273  float doy = float( dt.daysInYear() - dt.dayOfYear() );
274 
275  // Draw a tick every months on left axis
276  QPointF pMonthTick = mapToWidget( QPointF( dataRect().x(), doy ) );
277  p->drawLine( pMonthTick, QPointF( pMonthTick.x() + BIGTICKSIZE, pMonthTick.y() ) );
278 
279  // Draw month labels
280  QRectF rMonth(
281  mapToWidget( QPointF( 0.0, float( dt.daysInYear() - dt.addMonths( -1 ).dayOfYear() ) ) ),
282  mapToWidget( QPointF( dataRect().left() - 0.1, doy ) ) );
283  p->drawText( rMonth, Qt::AlignRight|Qt::AlignVCenter|Qt::TextDontClip, QDate::shortMonthName( imonth - 1 ) );
284  if ( imonth == 12 ) { // December
285  rMonth = QRectF(
286  mapToWidget( QPointF( 0.0, doy ) ),
287  mapToWidget( QPointF( dataRect().left() - 0.1, 0.0 ) ) );
288  p->drawText( rMonth, Qt::AlignRight|Qt::AlignVCenter|Qt::TextDontClip, QDate::shortMonthName( imonth ) );
289  }
290 
291  // Draw dividers
292  if ( skycal->scUI->checkBox_GridMonths->isChecked() ) {
293  QColor c = p->pen().color();
294  c.setAlpha( 100 );
295  p->setPen( c );
296  p->drawLine( pMonthTick, QPointF( pixRect().right(), pMonthTick.y() ) );
297  c.setAlpha( 255 );
298  p->setPen( c );
299  }
300  }
301 
302  // Interval dividers
303  QFont origFont = p->font();
304  p->setFont( QFont( "Monospace", origFont.pointSize() - 1 ) );
305  for( KStarsDateTime kdt( QDate( y, 1, 1 ), QTime( 12, 0, 0 ) );
306  kdt.date().year() == y;
307  kdt = kdt.addDays( skycal->scUI->spinBox_Interval->value() > 7 ? skycal->scUI->spinBox_Interval->value() : 7 ) )
308  {
309  // Draw ticks
310  float doy = float( kdt.date().daysInYear() - kdt.date().dayOfYear() );
311  QPointF pWeekTick = mapToWidget( QPointF( dataRect().right(), doy ) );
312  p->drawLine( pWeekTick, QPointF( pWeekTick.x() - BIGTICKSIZE, pWeekTick.y() ) );
313 
314  // Draw julian date
315  QRectF rJd(
316  mapToWidget( QPointF( dataRect().right() + 0.1, doy + 2 ) ),
317  mapToWidget( QPointF( dataRect().right(), doy ) ) );
318  p->drawText(
319  rJd,
320  Qt::AlignLeft|Qt::AlignVCenter|Qt::TextDontClip,
321  QString().setNum( double( kdt.djd() ), 'f', 1 ) );
322 
323  // Draw dividers
324  if ( skycal->scUI->checkBox_GridWeeks->isChecked() ) {
325  QColor c = p->pen().color();
326  c.setAlpha( 50 );
327  p->setPen( c );
328  p->drawLine( pWeekTick, QPointF( pixRect().left(), pWeekTick.y() ) );
329  c.setAlpha( 255 );
330  p->setPen( c );
331  }
332  }
333 
334  // Current day
335  if ( skycal->scUI->checkBox_GridToday->isChecked() ) {
336  p->setPen( QColor( Qt::yellow) );
337  QDate today = QDate::currentDate();
338  float doy = float( today.daysInYear() - today.dayOfYear() );
339  p->drawLine(
340  mapToWidget( QPointF( dataRect().left(), doy ) ),
341  mapToWidget( QPointF( dataRect().right(), doy ) )
342  );
343  p->drawText(
344  mapToWidget( QPointF( dataRect().left() + 0.1, doy + 2.0 ) ),
345  today.toString()
346  );
347  }
348 
349  //Draw month labels along each horizon curve
350 // if ( skycal->scUI->checkBox_LabelMonths->isChecked() ) {
351 // p->setFont( QFont( "Monospace", origFont.pointSize() + 5 ) );
352 // int textFlags = Qt::TextSingleLine | Qt::AlignCenter;
353 // QFontMetricsF fm( p->font(), p->device() );
354 //
355 // for ( int date=0; date<dateList.size(); date++ ) {
356 // if ( dateList.at( date ).day() < 12 || dateList.at( date ).day() > 18 )
357 // continue;
358 //
359 // bool noNight = false;
360 // if ( riseTimeList.at( date ) < setTimeList.at( date ) )
361 // noNight = true;
362 //
363 // int imonth = dateList.at( date ).month();
364 //
365 // QString shortMonthName = QDate::shortMonthName( dateList.at( date ).month() );
366 // QRectF riseLabelRect = fm.boundingRect( QRectF(0,0,1,1), textFlags, shortMonthName );
367 // QRectF setLabelRect = fm.boundingRect( QRectF(0,0,1,1), textFlags, shortMonthName );
368 //
369 // QDate dt( y, imonth, 15 );
370 // float doy = float( dt.daysInYear() - dt.dayOfYear() );
371 // float xRiseLabel, xSetLabel;
372 // if ( noNight ) {
373 // xRiseLabel = 0.0;
374 // xSetLabel = 0.0;
375 // } else {
376 // xRiseLabel = riseTimeList.at( date ) + 0.6;
377 // xSetLabel = setTimeList.at( date )- 0.6;
378 // }
379 // QPointF pRiseLabel = mapToWidget( QPointF( xRiseLabel, doy ) );
380 // QPointF pSetLabel = mapToWidget( QPointF( xSetLabel, doy ) );
381 //
382 // //Determine rotation angle for month labels
383 // QDate dt1( y, imonth, 1 );
384 // float doy1 = float( dt1.daysInYear() - dt1.dayOfYear() );
385 // QDate dt2( y, imonth, dt1.daysInMonth() );
386 // float doy2 = float( dt2.daysInYear() - dt2.dayOfYear() );
387 //
388 // QPointF p1, p2;
389 // float rAngle, sAngle;
390 // if ( noNight ) {
391 // rAngle = 90.0;
392 // } else {
393 // p1 = mapToWidget( QPointF( riseTimeList.at( date-2 ), doy1 ) );
394 // p2 = mapToWidget( QPointF( riseTimeList.at( date+2 ), doy2 ) );
395 // rAngle = atan2( p2.y() - p1.y(), p2.x() - p1.x() )/dms::DegToRad;
396 //
397 // p1 = mapToWidget( QPointF( setTimeList.at( date-2 ), doy1 ) );
398 // p2 = mapToWidget( QPointF( setTimeList.at( date+2 ), doy2 ) );
399 // sAngle = atan2( p2.y() - p1.y(), p2.x() - p1.x() )/dms::DegToRad;
400 // }
401 //
402 // p->save();
403 // p->translate( pRiseLabel );
404 // p->rotate( rAngle );
405 // p->drawText( riseLabelRect, textFlags, shortMonthName );
406 // p->restore();
407 //
408 // if ( ! noNight ) {
409 // p->save();
410 // p->translate( pSetLabel );
411 // p->rotate( sAngle );
412 // p->drawText( setLabelRect, textFlags, shortMonthName );
413 // p->restore();
414 // }
415 // }
416 // }
417 
418  p->setFont( origFont );
419 }
420 
421 #include "calendarwidget.moc"
SkyObject::transitAltitude
dms transitAltitude(const KStarsDateTime &dt, const GeoLocation *geo)
Definition: skyobject.cpp:245
KSSun
Child class of KSPlanetBase; encapsulates information about the Sun.
Definition: kssun.h:31
CalendarWidget::setHorizon
void setHorizon()
Definition: calendarwidget.cpp:72
KStarsDateTime::addDays
KStarsDateTime addDays(int nd) const
Modify the Date/Time by adding a number of days.
Definition: kstarsdatetime.h:117
QWidget
SkyObject::riseSetTime
QTime riseSetTime(const KStarsDateTime &dt, const GeoLocation *geo, bool rst, bool exact=true)
Determine the time at which the point will rise or set.
Definition: skyobject.cpp:105
CalendarWidget::CalendarWidget
CalendarWidget(QWidget *parent=0)
Definition: calendarwidget.cpp:34
NaN::f
const float f
Definition: nan.h:36
calendarwidget.h
SMALLTICKSIZE
#define SMALLTICKSIZE
Definition: calendarwidget.cpp:30
KPlotWidget
KStarsDateTime
Extension of KDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day...
Definition: kstarsdatetime.h:45
skycalendar.h
ksalmanac.h
kssun.h
CalendarWidget::paintEvent
void paintEvent(QPaintEvent *e)
Definition: calendarwidget.cpp:47
BIGTICKSIZE
#define BIGTICKSIZE
Definition: calendarwidget.cpp:29
kstarsdata.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:36:19 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kstars

Skip menu "kstars"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal