calendarui/views/dayview/src/calendaycontainer.cpp
changeset 55 2c54b51f39c4
parent 45 b6db4fd4947b
child 57 bb2d3e476f29
equal deleted inserted replaced
51:0b38fc5b94c6 55:2c54b51f39c4
     9 * Initial Contributors:
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10 * Nokia Corporation - initial contribution.
    11 *
    11 *
    12 * Contributors:
    12 * Contributors:
    13 *
    13 *
    14 * Description:  Day view control of calendar
    14 * Description:  Day view container - parent widget for events (CalenDayItem) and
    15 *
    15 * hours area widgets (CalenDayEventsPane)
       
    16 * Responsible for positioning and resizing events widgets.
    16 */
    17 */
    17 
    18 
    18 //System includes
    19 //System includes
    19 #include <QTime>
    20 #include <QTime>
    20 #include <QGraphicsLinearLayout>
    21 #include <QGraphicsLinearLayout>
    36 #include "calendayitem.h"
    37 #include "calendayitem.h"
    37 #include "calendaymodel.h"
    38 #include "calendaymodel.h"
    38 #include "calendayinfo.h"
    39 #include "calendayinfo.h"
    39 #include "calendayview.h"
    40 #include "calendayview.h"
    40 
    41 
    41 // -----------------------------------------------------------------------------
    42 /*!
    42 // CalenDayContainer()
    43  \brief Constructor
    43 // Constructor
    44  
    44 // -----------------------------------------------------------------------------
    45  Sets container initial geometry, creates hours area widgets.
    45 //
    46  */
    46 CalenDayContainer::CalenDayContainer(QGraphicsItem *parent) :
    47 CalenDayContainer::CalenDayContainer(QGraphicsItem *parent) :
    47     HbAbstractItemContainer(parent), mGeometryUpdated(false), mInfo(0)
    48     HbAbstractItemContainer(parent), mGeometryUpdated(false), mInfo(0)
    48 {
    49 {
    49     getTimedEventLayoutValues(mLayoutValues);
    50     getTimedEventLayoutValues(mLayoutValues);
    50     
       
    51     // Get the height of element
       
    52     qreal paneHeight = CalenDayUtils::instance()->hourElementHeight();
       
    53     
    51     
    54     QGraphicsLinearLayout* timeLinesLayout = new QGraphicsLinearLayout(
    52     QGraphicsLinearLayout* timeLinesLayout = new QGraphicsLinearLayout(
    55         Qt::Vertical, this);
    53         Qt::Vertical, this);
    56     for (int i = 0; i < 24; i++) {
    54     for (int i = 0; i < 24; i++) {
    57         CalenDayEventsPane* element = new CalenDayEventsPane(this);
    55         CalenDayEventsPane* element = new CalenDayEventsPane(this);
    58         element->setPreferredHeight(paneHeight);
       
    59         element->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
       
    60 		// Draw top line at midnight
    56 		// Draw top line at midnight
    61         if (i == 0) {
    57         if (i == 0) {
    62             element->drawTopLine(true);
    58             element->setDrawTopLine(true);
    63         }
    59         }
    64         timeLinesLayout->addItem(element);
    60         timeLinesLayout->addItem(element);
    65     }
    61     }
    66     timeLinesLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0);
    62     timeLinesLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0);
    67     timeLinesLayout->setSpacing(0.0);
    63     timeLinesLayout->setSpacing(0.0);
    68 
    64 
    69     setLayout(timeLinesLayout);
    65     setLayout(timeLinesLayout);
    70 }
    66 }
    71 
    67 
    72 // -----------------------------------------------------------------------------
    68 
    73 // ~CalenDayContainer()
    69 /*!
    74 // Destructor
    70  \brief Destructor
    75 // -----------------------------------------------------------------------------
    71  */
    76 //
       
    77 CalenDayContainer::~CalenDayContainer()
    72 CalenDayContainer::~CalenDayContainer()
    78 {
    73 {
    79 }
    74 }
    80 
    75 
    81 // -----------------------------------------------------------------------------
    76 
    82 // itemAdded()
    77 /*
    83 // 
    78     \reimp
    84 // -----------------------------------------------------------------------------
    79  */
    85 //
       
    86 void CalenDayContainer::itemAdded( int index, HbAbstractViewItem *item, 
    80 void CalenDayContainer::itemAdded( int index, HbAbstractViewItem *item, 
    87                                      bool animate )
    81                                      bool animate )
    88 {
    82 {
    89     Q_UNUSED( index )
    83     Q_UNUSED( index )
    90     Q_UNUSED( item )
    84     Q_UNUSED( item )
    91     Q_UNUSED( animate )
    85     Q_UNUSED( animate )
    92 }
    86 }
    93 
    87 
    94 // -----------------------------------------------------------------------------
    88 
    95 // reset()
    89 /*
    96 // 
    90     \reimp
    97 // -----------------------------------------------------------------------------
    91  */
    98 //
       
    99 void CalenDayContainer::reset()
    92 void CalenDayContainer::reset()
   100 {
    93 {
   101 	// remove absorbers if exist
    94 	// remove absorbers if exist
   102 	if (mAbsorbers.count())
    95 	if (mAbsorbers.count())
   103 		{
    96 		{
   112     QPointF position(pos());
   105     QPointF position(pos());
   113     HbAbstractItemContainer::reset();
   106     HbAbstractItemContainer::reset();
   114     setPos( position );
   107     setPos( position );
   115 }
   108 }
   116 
   109 
   117 // -----------------------------------------------------------------------------
   110 
   118 // itemRemoved()
   111 /*
   119 // 
   112     \reimp
   120 // -----------------------------------------------------------------------------
   113  */
   121 //
       
   122 void CalenDayContainer::itemRemoved( HbAbstractViewItem *item, bool animate )
   114 void CalenDayContainer::itemRemoved( HbAbstractViewItem *item, bool animate )
   123 {
   115 {
   124     Q_UNUSED( item )
   116     Q_UNUSED( item )
   125     Q_UNUSED( animate )
   117     Q_UNUSED( animate )
   126 }
   118 }
   127 
   119 
   128 // -----------------------------------------------------------------------------
   120 
   129 // viewResized()
   121 /*
   130 // 
   122     \reimp
   131 // -----------------------------------------------------------------------------
   123  */
   132 //
       
   133 void CalenDayContainer::viewResized (const QSizeF &size)
   124 void CalenDayContainer::viewResized (const QSizeF &size)
   134 {
   125 {
   135     resize(size);
   126     resize(size);
   136     if (!mGeometryUpdated) {
   127     if (!mGeometryUpdated) {
   137         mGeometryUpdated = true;
   128         mGeometryUpdated = true;
   138         updateGeometry();
   129         updateGeometry();
   139     }
   130     }
   140 }
   131 }
   141 
   132 
   142 // -----------------------------------------------------------------------------
   133 
   143 // createDefaultPrototype()
   134 /*
   144 // 
   135     \reimp
   145 // -----------------------------------------------------------------------------
   136  */
   146 //
       
   147 HbAbstractViewItem * CalenDayContainer::createDefaultPrototype() const
   137 HbAbstractViewItem * CalenDayContainer::createDefaultPrototype() const
   148 {
   138 {
   149     CalenDayItem *calendarViewItem = new CalenDayItem;
   139     CalenDayItem *calendarViewItem = new CalenDayItem(this);
   150     return calendarViewItem;
   140     return calendarViewItem;
   151 }
   141 }
   152 
   142 
   153 // -----------------------------------------------------------------------------
   143 
   154 // setItemModelIndex()
   144 /*
   155 // 
   145     \reimp
   156 // -----------------------------------------------------------------------------
   146  */
   157 //
       
   158 void CalenDayContainer::setItemModelIndex(HbAbstractViewItem *item, 
   147 void CalenDayContainer::setItemModelIndex(HbAbstractViewItem *item, 
   159                                             const QModelIndex &index)
   148                                             const QModelIndex &index)
   160 {
   149 {
   161     QVariant variant = index.data( CalenDayEntry );
   150     QVariant variant = index.data( CalenDayEntry );
   162     AgendaEntry entry = variant.value<AgendaEntry>();
   151     AgendaEntry entry = variant.value<AgendaEntry>();
   179     }
   168     }
   180 
   169 
   181     HbAbstractItemContainer::setItemModelIndex(item, index);
   170     HbAbstractItemContainer::setItemModelIndex(item, index);
   182 }
   171 }
   183 
   172 
   184 // -----------------------------------------------------------------------------
   173 
   185 // updateTimedEventGeometry()
   174 // TODO: updateTimedEventGeometry and updateAllDayEventGeometry
   186 // Updates geometry of a timed event.
   175 // methods are very similar and probably can be merged to avoid
   187 // -----------------------------------------------------------------------------
   176 // code duplication
   188 //
   177 /*!
       
   178 	\brief Set size and position of singe timed event widget (bubble)
       
   179 	\a item bubble widget
       
   180 	\a index pointing item data in model
       
   181  */
   189 void CalenDayContainer::updateTimedEventGeometry(HbAbstractViewItem *item, 
   182 void CalenDayContainer::updateTimedEventGeometry(HbAbstractViewItem *item, 
   190                                                    const QModelIndex &index)
   183                                                    const QModelIndex &index)
   191 {
   184 {
   192 //safety check
   185 //safety check
   193     if ( !mInfo ) {
   186     if ( !mInfo ) {
   270         eventStartX += columnIdx * eventWidth + mLayoutValues.eventMargin;
   263         eventStartX += columnIdx * eventWidth + mLayoutValues.eventMargin;
   271         eventWidth -= mLayoutValues.eventMargin;
   264         eventWidth -= mLayoutValues.eventMargin;
   272     }
   265     }
   273     
   266     
   274     QRectF eventGeometry( eventStartX, eventStartY, eventWidth, eventHeight );
   267     QRectF eventGeometry( eventStartX, eventStartY, eventWidth, eventHeight );
   275     item->setGeometry(eventGeometry);}
   268     item->setGeometry(eventGeometry);
   276 
   269 }
   277 
   270 
   278 // -----------------------------------------------------------------------------
   271 
   279 // updateAllDayEventGeometry()
   272 // TODO: updateTimedEventGeometry and updateAllDayEventGeometry
   280 // Updates geometry of a timed event.
   273 // methods are very similar and probably can be merged to avoid
   281 // -----------------------------------------------------------------------------
   274 // code duplication
   282 //
   275 /*!
       
   276 	\brief Set size and position of singe all-day event widget (bubble)
       
   277 	\a item bubble widget
       
   278 	\a index pointing item data in model
       
   279  */
   283 void CalenDayContainer::updateAllDayEventGeometry(HbAbstractViewItem *item, 
   280 void CalenDayContainer::updateAllDayEventGeometry(HbAbstractViewItem *item, 
   284                                                    const QModelIndex &index)
   281                                                    const QModelIndex &index)
   285 {
   282 {
   286 	//safety check
   283 	//safety check
   287 	if ( !mInfo ) {
   284 	if ( !mInfo ) {
   338 	item->setGeometry(eventGeometry);
   335 	item->setGeometry(eventGeometry);
   339 	    
   336 	    
   340 }
   337 }
   341 
   338 
   342 
   339 
   343 // -----------------------------------------------------------------------------
   340 /*!
   344 // movingBackwards()
   341 	\brief Gets event layout values
   345 // 
   342 	\a layoutValues structure to be filled with layout data
   346 // -----------------------------------------------------------------------------
   343  */
   347 //
       
   348 void CalenDayContainer::getTimedEventLayoutValues(LayoutValues& layoutValues)
   344 void CalenDayContainer::getTimedEventLayoutValues(LayoutValues& layoutValues)
   349 {
   345 {
   350     // get the width of content area
   346     // get the width of content area
   351     qreal contentWidth = CalenDayUtils::instance()->contentWidth();
   347     qreal contentWidth = CalenDayUtils::instance()->contentWidth();
   352 //1.time column width -> eventAreaX[out]
   348 //1.time column width -> eventAreaX[out]
   353     HbStyle style;
   349     HbStyle style;
   354     HbDeviceProfile deviceProfile;
   350     HbDeviceProfile deviceProfile;
   355     layoutValues.unitInPixels = deviceProfile.unitValue();
   351     layoutValues.unitInPixels = deviceProfile.unitValue();
   356     
   352     
   357     if ( mInfo && mInfo->AlldayCount())
   353     if ( mInfo && mInfo->AlldayCount())
   358     	{ // 9.5 -> all-day area width 
   354     	{
   359     	layoutValues.eventAreaX = 9.5 * layoutValues.unitInPixels;
   355     	// adccoriding to ui spec all-day event area should take
       
   356 		// 1/4 of content area
       
   357     	layoutValues.eventAreaX = contentWidth / 4;
   360     	}
   358     	}
   361     else
   359     else
   362     	{
   360     	{
   363     	layoutValues.eventAreaX = 0;
   361     	layoutValues.eventAreaX = 0;
   364     	}
   362     	}
   373     //curent slot height corresponds to half an hour
   371     //curent slot height corresponds to half an hour
   374     layoutValues.slotHeight = 
   372     layoutValues.slotHeight = 
   375         CalenDayUtils::instance()->hourElementHeight() / 2;
   373         CalenDayUtils::instance()->hourElementHeight() / 2;
   376     
   374     
   377     // 8.2 un (min. touchable event) from layout guide
   375     // 8.2 un (min. touchable event) from layout guide
       
   376     // used to check should we create absorber over some overlapping region
   378     layoutValues.maxColumns = layoutValues.eventAreaWidth / (8.2 * layoutValues.unitInPixels);  
   377     layoutValues.maxColumns = layoutValues.eventAreaWidth / (8.2 * layoutValues.unitInPixels);  
   379 }
   378 }
   380 
   379 
       
   380 
       
   381 /*!
       
   382 	\brief Sets day's info structer to the container.
       
   383 	\a dayInfo day's info data
       
   384  */
       
   385 void CalenDayContainer::setDayInfo( CalenDayInfo* dayInfo )
       
   386 {
       
   387     mInfo = dayInfo;
       
   388 }
       
   389 
   381 // -----------------------------------------------------------------------------
   390 // -----------------------------------------------------------------------------
   382 // setDayInfo()
   391 // setDate()
   383 // Sets day's info structer to the container.
   392 // Sets date to the container. Changes according to model which is connected to given view.
   384 // -----------------------------------------------------------------------------
   393 // -----------------------------------------------------------------------------
   385 //
   394 //
   386 void CalenDayContainer::setDayInfo( CalenDayInfo* dayInfo )
   395 void CalenDayContainer::setDate(const QDate &date)
   387 {
   396 {
   388     mInfo = dayInfo;
   397     mDate = date;
   389 }
   398 }
   390 
   399 
   391 // -----------------------------------------------------------------------------
   400 // -----------------------------------------------------------------------------
   392 // orientationChanged()
   401 // date()
   393 // Slot handles layout switch.
   402 // Returns date of the container.
   394 // -----------------------------------------------------------------------------
   403 // -----------------------------------------------------------------------------
   395 //
   404 //
       
   405 const QDate &CalenDayContainer::date() const
       
   406 {
       
   407     return mDate;
       
   408 }
       
   409 
       
   410 /*!
       
   411 	\brief Slot handles layout switch.
       
   412 	\a orientation current device orientation
       
   413  */
   396 void CalenDayContainer::orientationChanged(Qt::Orientation orientation)
   414 void CalenDayContainer::orientationChanged(Qt::Orientation orientation)
   397 {
   415 {
   398 	getTimedEventLayoutValues(mLayoutValues);
   416 	getTimedEventLayoutValues(mLayoutValues);
   399 	
   417 	
   400     Q_UNUSED( orientation )
   418     Q_UNUSED( orientation )
   412     }
   430     }
   413     
   431     
   414     createTouchEventAbsorbers();
   432     createTouchEventAbsorbers();
   415 }
   433 }
   416 
   434 
   417 // -----------------------------------------------------------------------------
   435 
   418 // createTouchEventAbsorbers()
   436 /*!
   419 // Creates absorbers which prevent touching to small items
   437 	\brief Creates absorbers which prevent touching to small items
   420 // -----------------------------------------------------------------------------
   438 	According to UI spec items smaller than 8.2 un are untouchable
   421 //
   439  */
   422 void CalenDayContainer::createTouchEventAbsorbers()
   440 void CalenDayContainer::createTouchEventAbsorbers()
   423 {
   441 {
   424 	// remove absorbers if exist
   442 	// remove absorbers if exist
   425 	if (mAbsorbers.count())
   443 	if (mAbsorbers.count())
   426 		{
   444 		{
   427 		qDeleteAll(mAbsorbers);
   445 		qDeleteAll(mAbsorbers);
   428 		mAbsorbers.clear();
   446 		mAbsorbers.clear();
   429 		}
   447 		}
   430 	
   448 	
       
   449 	//create absorber for all-day events
       
   450 	Qt::Orientation orientation = CalenDayUtils::instance()->orientation();
       
   451 	int allDayCount = mInfo->AlldayCount();
       
   452 	
       
   453 	if ((orientation == Qt::Vertical && allDayCount > 1) ||
       
   454 			(orientation == Qt::Horizontal && allDayCount > 2))
       
   455 		{
       
   456 		TouchEventAbsorber* absorber = crateAbsorberBetweenSlots(0, 0, true);
       
   457 		mAbsorbers.append(absorber);
       
   458 		}
       
   459 	
       
   460 	
       
   461 	// create absorbers for timed events
   431 	const QList<CalenTimeRegion>& regionList = mInfo->RegionList();
   462 	const QList<CalenTimeRegion>& regionList = mInfo->RegionList();
   432 	
   463 	
   433 	for(int i=0; i < regionList.count(); i++)
   464 	for(int i=0; i < regionList.count(); i++)
   434 		{
   465 		{
   435 		if(regionList[i].iColumns.count() > mLayoutValues.maxColumns )
   466 		if(regionList[i].iColumns.count() > mLayoutValues.maxColumns )
   436 			{
   467 			{
   437 			TouchEventAbsorber* absorber = 
   468 			TouchEventAbsorber* absorber = 
   438 				crateAbsorberBetweenSlots(regionList[i].iStartSlot, regionList[i].iEndSlot);
   469 				crateAbsorberBetweenSlots(regionList[i].iStartSlot, regionList[i].iEndSlot, false);
   439 			
   470 			
   440 			mAbsorbers.append(absorber);
   471 			mAbsorbers.append(absorber);
   441 			}
   472 			}
   442 		}
   473 		}
   443 	
   474 	
   444 }
   475 }
   445 
   476 
   446 // -----------------------------------------------------------------------------
   477 
   447 // crateAbsorberBetweenSlots()
   478 /*!
   448 // Creates single absorber in given location
   479 	\brief Creates single absorber in given location
   449 // -----------------------------------------------------------------------------
   480 	\a startSlot absorber area starts from there
   450 //
   481 	\a endSlot absobrber area ends here
       
   482 	\a forAllDayEvents if true absorber in all-day events area is created
       
   483  */
   451 TouchEventAbsorber *CalenDayContainer::crateAbsorberBetweenSlots
   484 TouchEventAbsorber *CalenDayContainer::crateAbsorberBetweenSlots
   452 												(int startSlot, int endSlot)
   485 												(int startSlot, int endSlot, bool forAllDayEvents)
   453 {
   486 {
   454     TouchEventAbsorber *absorber = new TouchEventAbsorber(this);
   487     TouchEventAbsorber *absorber = new TouchEventAbsorber(this);
   455     absorber->setZValue(1000);
   488     absorber->setZValue(1000);
   456     absorber->setVisible(true);
   489     absorber->setVisible(true);
   457     
   490     if (!forAllDayEvents)
   458     absorber->setGeometry( mLayoutValues.eventAreaX,			// x
   491     	{
   459 			startSlot * mLayoutValues.slotHeight,				// y
   492 		absorber->setGeometry( mLayoutValues.eventAreaX,			// x
   460 			mLayoutValues.eventAreaWidth,						// w
   493 				startSlot * mLayoutValues.slotHeight,				// y
   461 			(endSlot-startSlot) * mLayoutValues.slotHeight ); 	// h
   494 				mLayoutValues.eventAreaWidth,						// w
       
   495 				(endSlot-startSlot) * mLayoutValues.slotHeight ); 	// h
       
   496     	}
       
   497     else
       
   498     	{
       
   499     	absorber->setGeometry(0, 0, mLayoutValues.eventAreaX,
       
   500     			48 * mLayoutValues.slotHeight);
       
   501     	}
   462     
   502     
   463     return absorber;
   503     return absorber;
   464 }
   504 }
   465 
   505 
   466 
   506 
   467 // -----------------------------------------------------------------------------
   507 /*!
   468 // TouchEventAbsorber::gestureEvent()
   508 	\brief Handles tap event on overlapping area
   469 // Handles tap event on overlapping area (currently it leads to Agenda View - 
   509 	Currently it leads to Agenda View -  as described in UI spec
   470 // as described in UI spec)
   510 	\a event qt gesture event
   471 // -----------------------------------------------------------------------------
   511  */
   472 //
       
   473 void TouchEventAbsorber::gestureEvent(QGestureEvent *event)
   512 void TouchEventAbsorber::gestureEvent(QGestureEvent *event)
   474 {
   513 {
   475     QTapGesture *tapGesture = qobject_cast<QTapGesture*> (event->gesture(
   514     QTapGesture *tapGesture = qobject_cast<QTapGesture*> (event->gesture(
   476         Qt::TapGesture));
   515         Qt::TapGesture));
   477     
   516     
   482     	
   521     	
   483     	dayView->changeView(ECalenAgendaView);
   522     	dayView->changeView(ECalenAgendaView);
   484     	}
   523     	}
   485 }
   524 }
   486 
   525 
   487 // -----------------------------------------------------------------------------
   526 /*!
   488 // TouchEventAbsorber()
   527 	 \brief Constructor
   489 // default ctor
   528  */
   490 // -----------------------------------------------------------------------------
       
   491 //
       
   492 TouchEventAbsorber::TouchEventAbsorber(QGraphicsItem *parent) : HbWidget(parent)
   529 TouchEventAbsorber::TouchEventAbsorber(QGraphicsItem *parent) : HbWidget(parent)
   493 {
   530 {
   494 #ifdef _DEBUG
   531 #ifdef _DEBUG
   495     setFlag(QGraphicsItem::ItemHasNoContents, false);
   532     setFlag(QGraphicsItem::ItemHasNoContents, false);
   496 #endif	
   533 #endif	
   497     grabGesture(Qt::TapGesture);    	    
   534     grabGesture(Qt::TapGesture);    	    
   498 }
   535 }
   499 
   536 
   500 // -----------------------------------------------------------------------------
   537 
   501 // TouchEventAbsorber()
   538 /*!
   502 // default dtor
   539  \brief Destructor
   503 // -----------------------------------------------------------------------------
   540  
   504 //
   541  Sets container initial geometry, creates hours area widgets.
       
   542  */
   505 TouchEventAbsorber::~TouchEventAbsorber()
   543 TouchEventAbsorber::~TouchEventAbsorber()
   506 {
   544 {
   507 	
   545 
   508 }
   546 }
   509 
   547 
   510 // -----------------------------------------------------------------------------
   548 
   511 // TouchEventAbsorber::paint()
   549 /*!
   512 // used for debugging purposes to see absorbers areas
   550 	\brief Used for debugging purposes to see absorbers areas
   513 // -----------------------------------------------------------------------------
   551 	Not active in release builds!
   514 //
   552  
       
   553  */
   515 #ifdef _DEBUG
   554 #ifdef _DEBUG
   516 void TouchEventAbsorber::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
   555 void TouchEventAbsorber::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
   517 								QWidget *widget)
   556 								QWidget *widget)
   518 {
   557 {
   519 	Q_UNUSED(option)
   558 	Q_UNUSED(option)