2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "PVRChannelNumberInputHandler.h"
11 #include "ServiceBroker.h"
12 #include "settings/AdvancedSettings.h"
13 #include "settings/SettingsComponent.h"
14 #include "utils/StringUtils.h"
22 using namespace std::chrono_literals
;
24 CPVRChannelNumberInputHandler::CPVRChannelNumberInputHandler()
25 : CPVRChannelNumberInputHandler(CServiceBroker::GetSettingsComponent()
26 ->GetAdvancedSettings()
27 ->m_iPVRNumericChannelSwitchTimeout
,
28 CHANNEL_NUMBER_INPUT_MAX_DIGITS
)
32 CPVRChannelNumberInputHandler::CPVRChannelNumberInputHandler(
33 int iDelay
, int iMaxDigits
/* = CHANNEL_NUMBER_INPUT_MAX_DIGITS */)
34 : m_iDelay(iDelay
), m_iMaxDigits(iMaxDigits
), m_timer(this)
38 void CPVRChannelNumberInputHandler::OnTimeout()
40 if (m_inputBuffer
.empty())
42 std::unique_lock
<CCriticalSection
> lock(m_mutex
);
47 // call the overridden worker method
50 std::unique_lock
<CCriticalSection
> lock(m_mutex
);
52 // erase input buffer immediately , but...
53 m_inputBuffer
.erase();
55 // ... display the label for another .5 secs if we stopped the timer before regular timeout.
56 if (m_timer
.IsRunning())
63 void CPVRChannelNumberInputHandler::ExecuteAction()
65 m_timer
.Stop(true /* wait until worker thread ended */);
69 bool CPVRChannelNumberInputHandler::CheckInputAndExecuteAction()
71 const CPVRChannelNumber channelNumber
= GetChannelNumber();
72 if (channelNumber
.IsValid())
74 // we have a valid channel number; execute the associated action now.
81 void CPVRChannelNumberInputHandler::AppendChannelNumberCharacter(char cCharacter
)
83 if (cCharacter
!= CPVRChannelNumber::SEPARATOR
&& (cCharacter
< '0' || cCharacter
> '9'))
86 std::unique_lock
<CCriticalSection
> lock(m_mutex
);
88 if (cCharacter
== CPVRChannelNumber::SEPARATOR
)
90 // no leading separator
91 if (m_inputBuffer
.empty())
95 if (m_inputBuffer
.find(CPVRChannelNumber::SEPARATOR
) != std::string::npos
)
99 if (m_inputBuffer
.size() == static_cast<size_t>(m_iMaxDigits
))
101 m_inputBuffer
.erase(m_inputBuffer
.begin());
102 SetLabel(m_inputBuffer
);
104 else if (m_inputBuffer
.empty())
106 m_sortedChannelNumbers
.clear();
107 GetChannelNumbers(m_sortedChannelNumbers
);
109 std::sort(m_sortedChannelNumbers
.begin(), m_sortedChannelNumbers
.end());
112 m_inputBuffer
.append(&cCharacter
, 1);
113 SetLabel(m_inputBuffer
);
115 for (auto it
= m_sortedChannelNumbers
.begin(); it
!= m_sortedChannelNumbers
.end();)
117 const std::string channel
= *it
;
120 if (StringUtils::StartsWith(channel
, m_inputBuffer
))
122 if (it
!= m_sortedChannelNumbers
.end() && StringUtils::StartsWith(*it
, m_inputBuffer
))
124 // there are alternative numbers; wait for more input
128 // no alternatives; complete the number and fire immediately
129 m_inputBuffer
= channel
;
130 SetLabel(m_inputBuffer
);
136 if (!m_timer
.IsRunning())
137 m_timer
.Start(std::chrono::milliseconds(m_iDelay
));
142 CPVRChannelNumber
CPVRChannelNumberInputHandler::GetChannelNumber() const
144 int iChannelNumber
= 0;
145 int iSubChannelNumber
= 0;
147 std::unique_lock
<CCriticalSection
> lock(m_mutex
);
149 size_t pos
= m_inputBuffer
.find(CPVRChannelNumber::SEPARATOR
);
150 if (pos
!= std::string::npos
)
155 iChannelNumber
= std::atoi(m_inputBuffer
.substr(0, pos
).c_str());
156 if (pos
!= m_inputBuffer
.size() - 1)
157 iSubChannelNumber
= std::atoi(m_inputBuffer
.substr(pos
+ 1).c_str());
163 iChannelNumber
= std::atoi(m_inputBuffer
.c_str());
166 return CPVRChannelNumber(iChannelNumber
, iSubChannelNumber
);
169 bool CPVRChannelNumberInputHandler::HasChannelNumber() const
171 return !m_inputBuffer
.empty();
174 std::string
CPVRChannelNumberInputHandler::GetChannelNumberLabel() const
176 std::unique_lock
<CCriticalSection
> lock(m_mutex
);
180 void CPVRChannelNumberInputHandler::SetLabel(const std::string
& label
)
182 std::unique_lock
<CCriticalSection
> lock(m_mutex
);
183 if (label
!= m_label
)
187 // inform subscribers
188 m_events
.Publish(PVRChannelNumberInputChangedEvent(m_label
));