/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: */ |