Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/toolkit/source/controls/filectrl.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <controls/filectrl.hxx>
21
22
#include <com/sun/star/ui/dialogs/FilePicker.hpp>
23
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
24
#include <comphelper/processfactory.hxx>
25
#include <osl/file.h>
26
#include <svl/svlresid.hxx>
27
#include <svl/svl.hrc>
28
#include <unotools/resmgr.hxx>
29
#include <comphelper/diagnose_ex.hxx>
30
#include <tools/urlobj.hxx>
31
#include <vcl/toolkit/edit.hxx>
32
33
using namespace ::com::sun::star::uno;
34
using namespace ::com::sun::star::ui;
35
36
37
FileControl::FileControl( vcl::Window* pParent, WinBits nStyle ) :
38
0
    Window( pParent, nStyle|WB_DIALOGCONTROL ),
39
0
    maEdit( VclPtr<Edit>::Create(this, (nStyle&(~WB_BORDER))|WB_NOTABSTOP) ),
40
0
    maButton( VclPtr<PushButton>::Create( this, (nStyle&(~WB_BORDER))|WB_NOLIGHTBORDER|WB_NOPOINTERFOCUS|WB_NOTABSTOP ) ),
41
0
    maButtonText( SvlResId(STR_FILECTRL_BUTTONTEXT) ),
42
0
    mnInternalFlags( FileControlMode_Internal::ORIGINALBUTTONTEXT )
43
0
{
44
0
    maButton->SetClickHdl( LINK( this, FileControl, ButtonHdl ) );
45
46
0
    maButton->Show();
47
0
    maEdit->Show();
48
49
0
    SetCompoundControl( true );
50
51
0
    SetStyle( ImplInitStyle( GetStyle() ) );
52
0
}
Unexecuted instantiation: FileControl::FileControl(vcl::Window*, long)
Unexecuted instantiation: FileControl::FileControl(vcl::Window*, long)
53
54
55
WinBits FileControl::ImplInitStyle( WinBits nStyle )
56
0
{
57
0
    if ( !( nStyle & WB_NOTABSTOP ) )
58
0
    {
59
0
        maEdit->SetStyle( (maEdit->GetStyle()|WB_TABSTOP)&(~WB_NOTABSTOP) );
60
0
        maButton->SetStyle( (maButton->GetStyle()|WB_TABSTOP)&(~WB_NOTABSTOP) );
61
0
    }
62
0
    else
63
0
    {
64
0
        maEdit->SetStyle( (maEdit->GetStyle()|WB_NOTABSTOP)&(~WB_TABSTOP) );
65
0
        maButton->SetStyle( (maButton->GetStyle()|WB_NOTABSTOP)&(~WB_TABSTOP) );
66
0
    }
67
68
0
    const WinBits nAlignmentStyle = ( WB_TOP | WB_VCENTER | WB_BOTTOM );
69
0
    maEdit->SetStyle( ( maEdit->GetStyle() & ~nAlignmentStyle ) | ( nStyle & nAlignmentStyle ) );
70
71
0
    if ( !(nStyle & WB_NOGROUP) )
72
0
        nStyle |= WB_GROUP;
73
74
0
    if ( !(nStyle & WB_NOBORDER ) )
75
0
        nStyle |= WB_BORDER;
76
77
0
    nStyle &= ~WB_TABSTOP;
78
79
0
    return nStyle;
80
0
}
81
82
83
FileControl::~FileControl()
84
0
{
85
0
    disposeOnce();
86
0
}
87
88
void FileControl::dispose()
89
0
{
90
0
    maEdit.disposeAndClear();
91
0
    maButton.disposeAndClear();
92
0
    Window::dispose();
93
0
}
94
95
void FileControl::SetText( const OUString& rStr )
96
0
{
97
0
    maEdit->SetText( rStr );
98
0
}
99
100
101
OUString FileControl::GetText() const
102
0
{
103
0
    return maEdit->GetText();
104
0
}
105
106
107
void FileControl::StateChanged( StateChangedType nType )
108
0
{
109
0
    if ( nType == StateChangedType::Enable )
110
0
    {
111
0
        maEdit->Enable( IsEnabled() );
112
0
        maButton->Enable( IsEnabled() );
113
0
    }
114
0
    else if ( nType == StateChangedType::Zoom )
115
0
    {
116
0
        GetEdit().SetZoom( GetZoom() );
117
0
        GetButton().SetZoom( GetZoom() );
118
0
    }
119
0
    else if ( nType == StateChangedType::Style )
120
0
    {
121
0
        SetStyle( ImplInitStyle( GetStyle() ) );
122
0
    }
123
0
    else if ( nType == StateChangedType::ControlFont )
124
0
    {
125
0
        GetEdit().SetControlFont( GetControlFont() );
126
        // Only use height of the button, as in HTML
127
        // always Courier is used
128
0
        vcl::Font aFont = GetButton().GetControlFont();
129
0
        aFont.SetFontSize( GetControlFont().GetFontSize() );
130
0
        GetButton().SetControlFont( aFont );
131
0
    }
132
0
    else if ( nType == StateChangedType::ControlForeground )
133
0
    {
134
0
        GetEdit().SetControlForeground( GetControlForeground() );
135
0
        GetButton().SetControlForeground( GetControlForeground() );
136
0
    }
137
0
    else if ( nType == StateChangedType::ControlBackground )
138
0
    {
139
0
        GetEdit().SetControlBackground( GetControlBackground() );
140
0
        GetButton().SetControlBackground( GetControlBackground() );
141
0
    }
142
0
    Window::StateChanged( nType );
143
0
}
144
145
146
void FileControl::Resize()
147
0
{
148
0
    static const tools::Long ButtonBorder = 10;
149
150
0
    if( mnInternalFlags & FileControlMode_Internal::INRESIZE )
151
0
        return;
152
0
    mnInternalFlags |= FileControlMode_Internal::INRESIZE;//InResize = sal_True
153
154
0
    Size aOutSz = GetOutputSizePixel();
155
0
    tools::Long nButtonTextWidth = maButton->GetTextWidth( maButtonText );
156
0
    if ( !(mnInternalFlags & FileControlMode_Internal::ORIGINALBUTTONTEXT) ||
157
0
         ( nButtonTextWidth < aOutSz.Width()/3 ) )
158
0
    {
159
0
        maButton->SetText( maButtonText );
160
0
    }
161
0
    else
162
0
    {
163
0
        OUString aSmallText( u"..."_ustr );
164
0
        maButton->SetText( aSmallText );
165
0
        nButtonTextWidth = maButton->GetTextWidth( aSmallText );
166
0
    }
167
168
0
    tools::Long nButtonWidth = nButtonTextWidth+ButtonBorder;
169
0
    maEdit->setPosSizePixel( 0, 0, aOutSz.Width()-nButtonWidth, aOutSz.Height() );
170
0
    maButton->setPosSizePixel( aOutSz.Width()-nButtonWidth, 0, nButtonWidth, aOutSz.Height() );
171
172
0
    mnInternalFlags &= ~FileControlMode_Internal::INRESIZE; //InResize = sal_False
173
0
}
174
175
176
void FileControl::GetFocus()
177
0
{
178
0
    if (!maEdit || maEdit->isDisposed())
179
0
        return;
180
0
    maEdit->GrabFocus();
181
0
}
182
183
void FileControl::SetEditModifyHdl( const Link<Edit&,void>& rLink )
184
0
{
185
0
    if (!maEdit || maEdit->isDisposed())
186
0
        return;
187
0
    maEdit->SetModifyHdl(rLink);
188
0
}
189
190
void FileControl::Draw( OutputDevice* pDev, const Point& rPos, SystemTextColorFlags nFlags )
191
0
{
192
0
    WinBits nOldEditStyle = GetEdit().GetStyle();
193
0
    if ( GetStyle() & WB_BORDER )
194
0
        GetEdit().SetStyle( nOldEditStyle|WB_BORDER );
195
0
    Size aOrigSize(GetEdit().GetSizePixel());
196
0
    GetEdit().SetSizePixel(GetSizePixel());
197
0
    GetEdit().Draw( pDev, rPos, nFlags );
198
0
    GetEdit().SetSizePixel(aOrigSize);
199
0
    if ( GetStyle() & WB_BORDER )
200
0
        GetEdit().SetStyle( nOldEditStyle );
201
0
}
202
203
IMPL_LINK_NOARG(FileControl, ButtonHdl, Button*, void)
204
0
{
205
0
    try
206
0
    {
207
0
        const Reference< XComponentContext >& xContext = comphelper::getProcessComponentContext();
208
0
        Reference < dialogs::XFilePicker3 > xFilePicker = dialogs::FilePicker::createWithMode( xContext, dialogs::TemplateDescription::FILEOPEN_SIMPLE );
209
        // transform the system notation text into a file URL
210
0
        OUString sSystemNotation = GetText(), sFileURL;
211
0
        oslFileError nError = osl_getFileURLFromSystemPath( sSystemNotation.pData, &sFileURL.pData );
212
0
        if ( nError == osl_File_E_INVAL )
213
0
            sFileURL = GetText();   // #97709# Maybe URL is already a file URL...
214
215
        //#90430# Check if URL is really a file URL
216
0
        OUString aTmp;
217
0
        if ( osl_getSystemPathFromFileURL( sFileURL.pData, &aTmp.pData ) == osl_File_E_None )
218
0
        {
219
            // initially set this directory
220
0
            xFilePicker->setDisplayDirectory( sFileURL );
221
0
        }
222
223
0
        if ( xFilePicker->execute() )
224
0
        {
225
0
            Sequence < OUString > aPathSeq = xFilePicker->getSelectedFiles();
226
227
0
            if ( aPathSeq.hasElements() )
228
0
            {
229
0
                OUString aNewText = aPathSeq[0];
230
0
                INetURLObject aObj( aNewText );
231
0
                if ( aObj.GetProtocol() == INetProtocol::File )
232
0
                    aNewText = aObj.PathToFileName();
233
0
                SetText( aNewText );
234
0
                maEdit->GetModifyHdl().Call( *maEdit );
235
0
            }
236
0
        }
237
0
    }
238
0
    catch( const Exception& )
239
0
    {
240
0
        TOOLS_WARN_EXCEPTION( "toolkit", "FileControl::ImplBrowseFile: caught an exception while executing the file picker!" );
241
0
    }
242
0
}
243
244
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */