android: Update app icon to new startcenter icon
[LibreOffice.git] / fpicker / source / office / breadcrumb.cxx
blob0b27367d8a8e93ac3c8270780912751a99c38188
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <tools/urlobj.hxx>
11 #include <vcl/svapp.hxx>
12 #include "breadcrumb.hxx"
14 Breadcrumb::Breadcrumb(weld::Container* pParent)
15 : m_pParent(pParent)
16 , m_nMaxWidth(m_pParent->get_preferred_size().Width())
18 m_pParent->connect_size_allocate(LINK(this, Breadcrumb, SizeAllocHdl));
19 m_eMode = SvtBreadcrumbMode::ONLY_CURRENT_PATH;
20 appendField(); // root
23 IMPL_LINK(Breadcrumb, SizeAllocHdl, const Size&, rSize, void)
25 m_nMaxWidth = rSize.Width();
28 Breadcrumb::~Breadcrumb()
30 m_pParent->connect_size_allocate(Link<const Size&, void>());
33 void Breadcrumb::EnableFields( bool bEnable )
35 if( bEnable )
37 INetURLObject aURL( m_aCurrentURL );
38 int nSegments = aURL.getSegmentCount();
39 m_aSegments[nSegments]->m_xLink->set_sensitive(false);
43 void Breadcrumb::connect_clicked( const Link<Breadcrumb*,bool>& rLink )
45 m_aClickHdl = rLink;
48 const OUString& Breadcrumb::GetHdlURL() const
50 return m_sClickedURL;
53 void Breadcrumb::SetRootName( const OUString& rURL )
55 m_sRootName = rURL;
57 // we changed root - clear all fields
58 for (size_t i = 1; i < m_aSegments.size(); ++i)
60 m_aSegments[i]->m_xLink->set_label("");
62 m_aSegments[i]->m_xLink->hide();
63 m_aSegments[i]->m_xSeparator->hide();
64 m_aSegments[i]->m_xLink->set_sensitive(true);
68 void Breadcrumb::SetURL( const OUString& rURL )
70 m_aCurrentURL = rURL;
71 INetURLObject aURL(rURL);
72 aURL.setFinalSlash();
74 bool bClear = m_eMode == SvtBreadcrumbMode::ONLY_CURRENT_PATH;
76 int nSegments = aURL.getSegmentCount();
78 size_t nVecSizeRequired = nSegments + 1;
80 while (m_aSegments.size() < nVecSizeRequired)
81 appendField();
83 // fill the fields under root
84 for (int i = nSegments; i; --i)
86 OUString sLabel = aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset);
87 OUString sLink = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
89 if (m_eMode == SvtBreadcrumbMode::ALL_VISITED)
91 if( m_aSegments[i]->m_xLink->get_label() != sLabel )
92 bClear = true;
95 m_aSegments[i]->m_xLink->hide();
96 m_aSegments[i]->m_xLink->set_label(sLabel);
97 m_aSegments[i]->m_xLink->set_sensitive(true);
98 m_aSegments[i]->m_xLink->set_uri(sLink);
99 m_aUris[m_aSegments[i]->m_xLink.get()] = sLink;
101 m_aSegments[i]->m_xSeparator->hide();
103 aURL.removeSegment();
106 OUString sRootPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::WithCharset);
108 // root field
109 m_aSegments[0]->m_xLink->set_label( m_sRootName );
110 m_aSegments[0]->m_xLink->set_sensitive(true);
111 m_aSegments[0]->m_xLink->set_uri(sRootPath);
112 m_aUris[m_aSegments[0]->m_xLink.get()] = sRootPath;
114 // clear unused fields
115 for (size_t i = nSegments + 1; i < m_aSegments.size(); i++ )
117 if( bClear )
118 m_aSegments[i]->m_xLink->set_label( "" );
120 m_aSegments[i]->m_xLink->hide();
121 m_aSegments[i]->m_xSeparator->hide();
122 m_aSegments[i]->m_xLink->set_sensitive(true);
125 // show fields
126 unsigned int nSeparatorWidth = m_aSegments[0]->m_xSeparator->get_preferred_size().Width();
127 unsigned int nCurrentWidth = 0;
128 unsigned int nLastVisible = nSegments;
130 bool bRight = ( m_eMode == SvtBreadcrumbMode::ALL_VISITED );
131 bool bLeft = true;
133 int i = 0;
135 while( bLeft || bRight )
137 if( nSegments - i == -1 )
138 bLeft = false;
140 if( bLeft )
142 unsigned int nIndex = nSegments - i;
144 if( showField( nIndex, m_nMaxWidth - nCurrentWidth ) )
146 nCurrentWidth += m_aSegments[nIndex]->m_xLink->get_preferred_size().Width()
147 + nSeparatorWidth + 2*SPACING;
149 else
151 // label is too long
152 if( nSegments != 0 )
154 m_aSegments[0]->m_xLink->set_label("...");
155 m_aSegments[0]->m_xLink->set_sensitive(false);
157 bLeft = false;
161 if( nSegments + i == static_cast<int>(m_aSegments.size()) )
162 bRight = false;
164 if( i != 0 && bRight )
166 unsigned int nIndex = nSegments + i;
168 if( m_aSegments[nIndex]->m_xLink->get_label().isEmpty() )
170 bRight = false;
172 else if( showField( nIndex, m_nMaxWidth - nCurrentWidth ) )
174 nCurrentWidth += m_aSegments[nIndex]->m_xLink->get_preferred_size().Width()
175 + nSeparatorWidth + 3*SPACING;
176 nLastVisible = nIndex;
178 else
180 bRight = false;
184 i++;
187 // current dir should be inactive
188 m_aSegments[nSegments]->m_xLink->set_sensitive(false);
190 // hide last separator
191 m_aSegments[nLastVisible]->m_xSeparator->hide();
194 void Breadcrumb::SetMode( SvtBreadcrumbMode eMode )
196 m_eMode = eMode;
199 void Breadcrumb::appendField()
201 m_aSegments.emplace_back(std::make_unique<BreadcrumbPath>(m_pParent));
202 size_t nIndex = m_aSegments.size() - 1;
203 m_aSegments[nIndex]->m_xLink->hide();
204 m_aSegments[nIndex]->m_xLink->connect_activate_link(LINK(this, Breadcrumb, ClickLinkHdl));
205 m_aSegments[nIndex]->m_xSeparator->set_label( ">" );
206 m_aSegments[nIndex]->m_xSeparator->hide();
209 bool Breadcrumb::showField( unsigned int nIndex, unsigned int nWidthMax )
211 m_aSegments[nIndex]->m_xLink->show();
212 m_aSegments[nIndex]->m_xSeparator->show();
214 unsigned int nSeparatorWidth = m_aSegments[0]->m_xSeparator->get_preferred_size().Width();
215 unsigned int nWidth = m_aSegments[nIndex]->m_xLink->get_preferred_size().Width()
216 + nSeparatorWidth + 3*SPACING;
218 if( nWidth > nWidthMax )
220 if( nIndex != 0 )
222 m_aSegments[nIndex]->m_xLink->hide();
223 m_aSegments[nIndex]->m_xSeparator->hide();
226 return false;
229 return true;
232 IMPL_LINK(Breadcrumb, ClickLinkHdl, weld::LinkButton&, rLink, bool)
234 m_sClickedURL = m_aUris[&rLink];
235 return m_aClickHdl.Call(this);
238 BreadcrumbPath::BreadcrumbPath(weld::Container* pContainer)
239 : m_xBuilder(Application::CreateBuilder(pContainer, "fps/ui/breadcrumb.ui"))
240 , m_xContainer(m_xBuilder->weld_container("container"))
241 , m_xLink(m_xBuilder->weld_link_button("link"))
242 , m_xSeparator(m_xBuilder->weld_label("label"))
246 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */