Bump for 3.6-28
[LibreOffice.git] / autodoc / source / display / toolkit / out_position.cxx
blob75e51b0ce5a8e9a4eee630a881d21ff2caa968c9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <precomp.h>
30 #include <toolkit/out_position.hxx>
33 // NOT FULLY DEFINED SERVICES
37 namespace output
42 namespace
45 const int C_nAssumedMaxLinkLength = 500;
47 void move_ToParent(
48 Node * & io_node,
49 intt i_levels = 1 );
51 void
52 move_ToParent( Node * & io_node,
53 intt i_levels )
55 for ( intt n = 0; n < i_levels; ++n )
57 csv_assert(io_node != 0);
58 io_node = io_node->Parent();
64 } // namepace anonymous
68 Position::Position()
69 : sFile(),
70 pDirectory(&Node::Null_())
75 Position::Position( Node & i_directory,
76 const String & i_file )
77 : sFile(i_file),
78 pDirectory(&i_directory)
82 Position::Position( const Position & i_directory,
83 const String & i_sDifferentFile )
84 : sFile(i_sDifferentFile),
85 pDirectory(i_directory.pDirectory)
90 Position::~Position()
95 Position &
96 Position::operator=( Node & i_node )
98 pDirectory = &i_node;
99 sFile.clear();
100 return *this;
103 Position &
104 Position::operator+=( const String & i_nodeName )
106 csv_assert(pDirectory != 0);
108 pDirectory = &pDirectory->Provide_Child(i_nodeName);
109 sFile.clear();
111 return *this;
114 Position &
115 Position::operator-=( intt i_levels )
117 csv_assert(pDirectory != 0);
119 for ( intt i = i_levels; i > 0; --i )
121 pDirectory = pDirectory->Parent();
122 if (pDirectory == 0)
124 pDirectory = &Node::Null_();
125 i = 0;
128 sFile.clear();
130 return *this;
133 String
134 Position::LinkToRoot() const
136 StreamLock sl(C_nAssumedMaxLinkLength);
137 return sl() << get_UpLink(Depth()) << c_str;
140 void
141 Position::Get_LinkTo( StreamStr & o_result,
142 const Position & i_destination,
143 const String & i_localLabel ) const
145 Node * p1 = pDirectory;
146 Node * p2 = i_destination.pDirectory;
148 intt diff = Depth() - i_destination.Depth();
149 intt pathLength1 = 0;
150 intt pathLength2 = 0;
152 if ( diff > 0 )
154 pathLength1 = diff;
155 move_ToParent(p1,pathLength1);
157 else if ( diff < 0 )
159 pathLength2 = -diff;
160 move_ToParent(p2,pathLength2);
163 while ( p1 != p2 )
165 move_ToParent(p1);
166 move_ToParent(p2);
167 ++pathLength1;
168 ++pathLength2;
171 o_result << get_UpLink(pathLength1);
172 i_destination.pDirectory->Get_Path(o_result, pathLength2);
173 o_result << i_destination.sFile;
174 if (i_localLabel.length())
175 o_result << "#" << i_localLabel;
178 void
179 Position::Get_LinkToRoot( StreamStr & o_result ) const
181 o_result << get_UpLink(Depth());
184 void
185 Position::Set( Node & i_node,
186 const String & i_file )
188 sFile = i_file;
189 pDirectory = &i_node;
195 const char *
196 get_UpLink(uintt i_depth)
198 static const uintt
199 C_nMaxDepth = 30;
200 static const char
201 C_sUpLinkArray[3*C_nMaxDepth+1] =
202 "../../../../../../../../../../"
203 "../../../../../../../../../../"
204 "../../../../../../../../../../";
205 static const char *
206 C_sUpLink = &C_sUpLinkArray[0];
208 if ( i_depth <= C_nMaxDepth )
210 return C_sUpLink + 3*(C_nMaxDepth - i_depth);
212 else
213 { // not THREAD fast
214 static std::vector<char>
215 aRet;
216 uintt nNeededSize = i_depth * 3 + 1;
218 if (aRet.size() < nNeededSize)
220 aRet.resize(nNeededSize);
221 char * pEnd = &aRet[nNeededSize-1];
222 *pEnd = '\0';
224 for ( char * pFill = &(*aRet.begin());
225 pFill != pEnd;
226 pFill += 3 )
228 memcpy(pFill, C_sUpLink, 3);
230 } // end if
232 return &aRet[aRet.size() - 1 - 3*i_depth];
239 } // namespace output
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */