Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svtools/source/misc/filechangedchecker.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
10
#include <sal/config.h>
11
#include <sal/log.hxx>
12
#include <osl/file.hxx>
13
14
#include <svtools/filechangedchecker.hxx>
15
#include <utility>
16
#include <vcl/timer.hxx>
17
18
FileChangedChecker::FileChangedChecker(OUString aFilename,
19
        ::std::function<void ()> aCallback)
20
0
    : mTimer("SVTools FileChangedChecker Timer")
21
0
    , mFileName(std::move(aFilename))
22
0
    , mLastModTime()
23
0
    , mpCallback(std::move(aCallback))
24
0
{
25
    // Get the current last file modified Status
26
0
    getCurrentModTime(mLastModTime);
27
28
    // associate the callback function for the Timer
29
0
    mTimer.SetInvokeHandler(LINK(this, FileChangedChecker, TimerHandler));
30
31
    // set timer interval
32
0
    mTimer.SetTimeout(100);
33
34
    // start the timer
35
0
    resetTimer();
36
0
}
37
38
FileChangedChecker::FileChangedChecker(OUString aFilename)
39
0
    : mTimer("")
40
0
    , mFileName(std::move(aFilename))
41
0
    , mLastModTime()
42
0
    , mpCallback(nullptr)
43
0
{
44
    // Get the current last file modified Status
45
0
    getCurrentModTime(mLastModTime);
46
0
}
47
48
void FileChangedChecker::resetTimer()
49
0
{
50
0
    if (mpCallback == nullptr)
51
0
        return;
52
53
    // Start the Idle if it's not active
54
0
    if (!mTimer.IsActive())
55
0
        mTimer.Start();
56
57
    // Set lowest Priority
58
0
    mTimer.SetPriority(TaskPriority::LOWEST);
59
0
}
60
61
bool FileChangedChecker::getCurrentModTime(TimeValue& o_rValue) const
62
0
{
63
    // Need a Directory item to fetch file status
64
0
    osl::DirectoryItem aItem;
65
0
    if (osl::FileBase::E_None != osl::DirectoryItem::get(mFileName, aItem))
66
0
        return false;
67
68
    // Retrieve the status - we are only interested in last File
69
    // Modified time
70
0
    osl::FileStatus aStatus( osl_FileStatus_Mask_ModifyTime );
71
0
    if (osl::FileBase::E_None != aItem.getFileStatus(aStatus))
72
0
        return false;
73
74
0
    o_rValue = aStatus.getModifyTime();
75
0
    return true;
76
0
}
77
78
bool FileChangedChecker::hasFileChanged(bool bUpdate)
79
0
{
80
    // Get the current file Status
81
0
    TimeValue newTime={0,0};
82
0
    if( !getCurrentModTime(newTime) )
83
0
        return true; // well. hard to answer correctly here ...
84
85
    // Check if the seconds time stamp has any difference
86
    // If so, then our file has changed meanwhile
87
0
    if( newTime.Seconds != mLastModTime.Seconds ||
88
0
        newTime.Nanosec != mLastModTime.Nanosec )
89
0
    {
90
        // Since the file has changed, set the new status as the file status and
91
        // return True
92
0
        if(bUpdate)
93
0
            mLastModTime = newTime ;
94
95
0
        return true;
96
0
    }
97
0
    else
98
0
        return false;
99
0
}
100
101
IMPL_LINK_NOARG(FileChangedChecker, TimerHandler, Timer *, void)
102
0
{
103
    // If the file has changed, then update the graphic in the doc
104
0
    SAL_INFO("svtools", "Timeout Called");
105
0
    if(hasFileChanged())
106
0
    {
107
0
        SAL_INFO("svtools", "File modified");
108
0
        mpCallback();
109
0
    }
110
111
    // Reset the Timer in any case
112
0
    resetTimer();
113
0
}
114
115
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */