1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "Tickmarks_Dates.hxx"
31 #include "DateScaling.hxx"
32 #include <rtl/math.hxx>
33 #include <tools/debug.hxx>
34 #include "DateHelper.hxx"
35 
36 //.............................................................................
37 namespace chart
38 {
39 //.............................................................................
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::chart2;
42 using namespace ::rtl::math;
43 using ::basegfx::B2DVector;
44 using ::com::sun::star::chart::TimeUnit::DAY;
45 using ::com::sun::star::chart::TimeUnit::MONTH;
46 using ::com::sun::star::chart::TimeUnit::YEAR;
47 
48 DateTickFactory::DateTickFactory(
49           const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement )
50             : m_aScale( rScale )
51             , m_aIncrement( rIncrement )
52             , m_xInverseScaling(NULL)
53 {
54     //@todo: make sure that the scale is valid for the scaling
55 
56     if( m_aScale.Scaling.is() )
57     {
58         m_xInverseScaling = m_aScale.Scaling->getInverseScaling();
59         DBG_ASSERT( m_xInverseScaling.is(), "each Scaling needs to return a inverse Scaling" );
60     }
61 
62     m_fScaledVisibleMin = m_aScale.Minimum;
63     if( m_xInverseScaling.is() )
64         m_fScaledVisibleMin = m_aScale.Scaling->doScaling(m_fScaledVisibleMin);
65 
66     m_fScaledVisibleMax = m_aScale.Maximum;
67     if( m_xInverseScaling.is() )
68         m_fScaledVisibleMax = m_aScale.Scaling->doScaling(m_fScaledVisibleMax);
69 }
70 
71 DateTickFactory::~DateTickFactory()
72 {
73 }
74 
75 void DateTickFactory::getAllTicks( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos, bool bShifted ) const
76 {
77     rAllTickInfos.resize(2);
78     ::std::vector< TickInfo >& rMajorTicks = rAllTickInfos[0];
79     ::std::vector< TickInfo >& rMinorTicks = rAllTickInfos[1];
80     rMajorTicks.clear();
81     rMinorTicks.clear();
82 
83     Date aNull(m_aScale.NullDate);
84 
85     Date aDate = aNull + static_cast<long>(::rtl::math::approxFloor(m_aScale.Minimum));
86     Date aMaxDate = aNull + static_cast<long>(::rtl::math::approxFloor(m_aScale.Maximum));
87 
88     uno::Reference< chart2::XScaling > xScaling(m_aScale.Scaling);
89     uno::Reference< chart2::XScaling > xInverseScaling(m_xInverseScaling);
90     if( bShifted )
91     {
92         xScaling = new DateScaling(aNull,m_aScale.TimeResolution,true/*bShifted*/);
93         xInverseScaling = xScaling->getInverseScaling();
94     }
95 
96     //create major date tickinfos
97     while( aDate<= aMaxDate )
98     {
99         if( bShifted && aDate==aMaxDate )
100             break;
101 
102         TickInfo aNewTick(xInverseScaling); aNewTick.fScaledTickValue = aDate - aNull;
103 
104         if( xInverseScaling.is() )
105             aNewTick.fScaledTickValue = xScaling->doScaling(aNewTick.fScaledTickValue);
106         rMajorTicks.push_back( aNewTick );
107 
108         if(m_aIncrement.MajorTimeInterval.Number<=0)
109             break;
110 
111         //find next major date
112         switch( m_aIncrement.MajorTimeInterval.TimeUnit )
113         {
114         case DAY:
115             aDate += m_aIncrement.MajorTimeInterval.Number;
116             break;
117         case YEAR:
118             aDate = DateHelper::GetDateSomeYearsAway( aDate, m_aIncrement.MajorTimeInterval.Number );
119             break;
120         case MONTH:
121         default:
122             aDate = DateHelper::GetDateSomeMonthsAway( aDate, m_aIncrement.MajorTimeInterval.Number );
123             break;
124         }
125     }
126 
127     //create minor date tickinfos
128     aDate = aNull + static_cast<long>(::rtl::math::approxFloor(m_aScale.Minimum));
129     while( aDate<= aMaxDate )
130     {
131         if( bShifted && aDate==aMaxDate )
132             break;
133 
134         TickInfo aNewTick(xInverseScaling); aNewTick.fScaledTickValue = aDate - aNull;
135         if( xInverseScaling.is() )
136             aNewTick.fScaledTickValue = xScaling->doScaling(aNewTick.fScaledTickValue);
137         rMinorTicks.push_back( aNewTick );
138 
139         if(m_aIncrement.MinorTimeInterval.Number<=0)
140             break;
141 
142         //find next minor date
143         switch( m_aIncrement.MinorTimeInterval.TimeUnit )
144         {
145         case DAY:
146             aDate += m_aIncrement.MinorTimeInterval.Number;
147             break;
148         case YEAR:
149             aDate = DateHelper::GetDateSomeYearsAway( aDate, m_aIncrement.MinorTimeInterval.Number );
150             break;
151         case MONTH:
152         default:
153             aDate = DateHelper::GetDateSomeMonthsAway( aDate, m_aIncrement.MinorTimeInterval.Number );
154             break;
155         }
156     }
157 }
158 
159 void DateTickFactory::getAllTicks( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
160 {
161     getAllTicks( rAllTickInfos, false );
162 }
163 
164 void DateTickFactory::getAllTicksShifted( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
165 {
166     getAllTicks( rAllTickInfos, true );
167 }
168 
169 //.............................................................................
170 } //namespace chart
171 //.............................................................................
172