diff --git a/RingConsolePanel.xaml b/RingConsolePanel.xaml index aac6a27abcaf4879e631d40cf817d18499e2a701..3538637a211875c429a1eb52bf106d20b2b40916 100644 --- a/RingConsolePanel.xaml +++ b/RingConsolePanel.xaml @@ -30,6 +30,7 @@ </Grid.RowDefinitions> <ScrollViewer x:Name="_scrollView_" Grid.Row="0" + Padding="5,5" Style="{StaticResource ConsoleScrollViewerStyle}"> <RichTextBlock x:Name="_debugWindowOutput_" Style="{StaticResource ConsoleTextStyle1}"/> @@ -42,8 +43,10 @@ </Grid.ColumnDefinitions> <TextBox x:Name="_tBoxDbg_" Grid.Column="0" + KeyDown="_sendDbgCmd__KeyDown" Style="{StaticResource ConsoleTextBoxStyle}"/> <Button x:Name="_btnSendDbgCmd_" + Click="_btnSendDbgCmd__Click" Grid.Column="1" Style="{StaticResource ButtonSendCmdStyle}"/> </Grid> diff --git a/RingConsolePanel.xaml.cpp b/RingConsolePanel.xaml.cpp index 8d2c927196a2d893595d18bcfa05b5ba780c12af..f3cb6e7441654a859358636176eba6ec5872b2c2 100644 --- a/RingConsolePanel.xaml.cpp +++ b/RingConsolePanel.xaml.cpp @@ -1,28 +1,116 @@ -/************************************************************************** -* Copyright (C) 2016 by Savoir-faire Linux * -* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 3 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program. If not, see <http://www.gnu.org/licenses/>. * -**************************************************************************/ -#include "pch.h" - -#include "RingConsolePanel.xaml.h" - -using namespace RingClientUWP; -using namespace RingClientUWP::Views; - -RingConsolePanel::RingConsolePanel() -{ - InitializeComponent(); +/************************************************************************** +* Copyright (C) 2016 by Savoir-faire Linux * +* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 3 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program. If not, see <http://www.gnu.org/licenses/>. * +**************************************************************************/ +#include "pch.h" + +#include "RingConsolePanel.xaml.h" + +using namespace RingClientUWP; +using namespace RingClientUWP::Views; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::UI::Core; +using namespace Windows::UI::Xaml::Documents; + +RingConsolePanel::RingConsolePanel() +{ + InitializeComponent(); + + RingDebug::instance->messageToScreen += ref new debugMessageToScreen([this](Platform::String^ message) { + output(message); + }); +} + +void +RingConsolePanel::output(Platform::String^ message) +{ + try { + Run^ inlineText = ref new Run(); + inlineText->Text = message; + Paragraph^ paragraph = ref new Paragraph(); + paragraph->Inlines->Append(inlineText); + _debugWindowOutput_->Blocks->Append(paragraph); + _scrollView_->UpdateLayout(); + _scrollView_->ScrollToVerticalOffset(_scrollView_->ScrollableHeight); + } + catch (Platform::Exception^ e) { + return; + } +} + +void RingConsolePanel::_btnSendDbgCmd__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + sendCommand(); +} + + +void RingConsolePanel::_sendDbgCmd__KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) +{ + if (e->Key == Windows::System::VirtualKey::Enter && _tBoxDbg_->Text != "") { + sendCommand(); + } + else if (e->Key == Windows::System::VirtualKey::PageUp) { + + if (historyLevel < 1) + return; + if (historyLevel == historyCmds.Size) + currentCmd = _tBoxDbg_->Text; + historyLevel--; + _tBoxDbg_->Text = historyCmds.GetAt(historyLevel); + + } + else if (e->Key == Windows::System::VirtualKey::PageDown) { + if (historyLevel < historyCmds.Size) { + _tBoxDbg_->Text = historyCmds.GetAt(historyLevel); + historyLevel++; + + } + else { + _tBoxDbg_->Text = currentCmd; + } + return; + } +} + +/*\ ADD EACH NEW COMMAND TO THE HELP LIST \*/ +void RingConsolePanel::sendCommand() +{ + auto cmdInput = _tBoxDbg_->Text; + addCommandToHistory(); + historyLevel++; + _tBoxDbg_->Text = ""; + currentCmd = ""; + historyLevel = historyCmds.Size; + + if (cmdInput == "") { + return; + } + else if (cmdInput == "help") { + MSG_(">> Help :"); + MSG_("use PgUp/PgDown for crawling commands history."); + return; + } + + std::wstring wStr(cmdInput->Begin()); + std::string result(wStr.begin(), wStr.end()); + + MSG_(">> error, command \'" + result + "\' not found"); +} + +void RingConsolePanel::addCommandToHistory() +{ + historyCmds.Append(_tBoxDbg_->Text); } \ No newline at end of file diff --git a/RingConsolePanel.xaml.h b/RingConsolePanel.xaml.h index 497830bc5e0dfc72d5573138b6b3aef231de0fc9..3e7ebf8116bdabf98c0e840c4f7a33ee84a68a4c 100644 --- a/RingConsolePanel.xaml.h +++ b/RingConsolePanel.xaml.h @@ -26,6 +26,19 @@ public ref class RingConsolePanel sealed { public: RingConsolePanel(); + void output(Platform::String^ message); + +private: + void sendCommand(); + void addCommandToHistory(); + void _btnSendDbgCmd__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); + void _sendDbgCmd__KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e); + + int historyLevel = 0; + /* commands already send */ + Vector<String^> historyCmds; + /* command not already send */ + String^ currentCmd; }; } } \ No newline at end of file diff --git a/RingDebug.cpp b/RingDebug.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d14f87d639c5da8f3095f66e9340ab8c8daae99 --- /dev/null +++ b/RingDebug.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** +* Copyright (C) 2016 by Savoir-faire Linux * +* Author: J�ger Nicolas <nicolas.jager@savoirfairelinux.com> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 3 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program. If not, see <http://www.gnu.org/licenses/>. * +**************************************************************************/ + +/* client */ +#include "pch.h" + +using namespace RingClientUWP; + +using namespace Platform; +using namespace Windows::UI::Core; + +void +RingDebug::print(const std::string& message, + const Type& type) +{ + /* get the current time */ + std::time_t currentTime = std::time(nullptr); + char timeBuffer[64]; + ctime_s(timeBuffer, sizeof timeBuffer, ¤tTime); + + /* timestamp */ + auto messageTimestamped = timeBuffer + message; + std::wstring wString = std::wstring(message.begin(), message.end()); + + /* set message type. */ + switch (type) { + case Type::ERR: + wString = L"(EE) " + wString; + break; + case Type::WNG: + wString = L"(WW) " + wString; + break; + /*case Type::message:*/ + } + + /* screen it into VS debug console */ + OutputDebugString(wString.c_str()); + + /* fire the event. */ + messageToScreen(ref new String(wString.c_str(), wString.length())); +} \ No newline at end of file diff --git a/RingDebug.h b/RingDebug.h new file mode 100644 index 0000000000000000000000000000000000000000..d24e9ccd8a1608fdc21f2f8b6c98802ee5462063 --- /dev/null +++ b/RingDebug.h @@ -0,0 +1,66 @@ +/*************************************************************************** +* Copyright (C) 2016 by Savoir-faire Linux * +* Author: J�ger Nicolas <nicolas.jager@savoirfairelinux.com> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 3 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program. If not, see <http://www.gnu.org/licenses/>. * +**************************************************************************/ +#pragma once + +namespace RingClientUWP +{ + +/* forward declaration */ +ref class RingDebug; + +/* delegate */ +delegate void debugMessageToScreen(Platform::String^ message); + +/* this is how to implement a singleton class*/ +public ref class RingDebug sealed +{ +public: + /* singleton */ + static property RingDebug^ instance + { + RingDebug^ get() + { + static RingDebug^ instance_ = ref new RingDebug(); + return instance_; + } + } + + /* properties */ + + /* functions */ +internal: + enum class Type { MSG, WNG, ERR }; + void print(const std::string& message, const Type& type = Type::MSG); + + /* event */ + event debugMessageToScreen^ messageToScreen; + +private: + RingDebug() {}; // singleton +}; + +#define MSG_(cstr) CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Low, \ +ref new DispatchedHandler([=]() { RingDebug::instance->print(cstr); })) + +#define WNG_(cstr) CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Low, \ +ref new DispatchedHandler([=]() { RingDebug::instance->print(std::string(cstr), RingDebug::Type::WNG); })) + +#define ERR_(cstr) CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Low, \ +ref new DispatchedHandler([=]() { RingDebug::instance->print(std::string(cstr), RingDebug::Type::ERR); })) + +} \ No newline at end of file diff --git a/Utils.h b/Utils.h new file mode 100644 index 0000000000000000000000000000000000000000..1498faa33565e007b21adf9385a1636691323571 --- /dev/null +++ b/Utils.h @@ -0,0 +1,76 @@ +#pragma once +#include <pch.h> + +using namespace Platform; +using namespace Windows::Storage; + +namespace RingClientUWP +{ +namespace Utils { + +task<bool> +fileExists(StorageFolder^ folder, String^ fileName) +{ + return create_task(folder->GetFileAsync(fileName)) + .then([](task<StorageFile^> taskResult) + { + bool exists; + try { + taskResult.get(); + exists = true; + } + catch (COMException ^e) { + if (e->HResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { + exists = false; + } + else { + throw; + } + } + return exists; + }); +} + +std::string makeString(const std::wstring& wstr) +{ + auto wideData = wstr.c_str(); + int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wideData, -1, nullptr, 0, NULL, NULL); + + std::unique_ptr<char[]> utf8; + utf8.reset(new char[bufferSize]); + + if (WideCharToMultiByte(CP_UTF8, 0, wideData, -1, utf8.get(), bufferSize, NULL, NULL) == 0) { + return std::string(); + } + + return std::string(utf8.get()); +} + +std::wstring makeWString(const std::string& str) +{ + auto utf8Data = str.c_str(); + int bufferSize = MultiByteToWideChar(CP_UTF8, 0, utf8Data, -1, nullptr, 0); + + std::unique_ptr<wchar_t[]> wide; + wide.reset(new wchar_t[bufferSize]); + + if (MultiByteToWideChar(CP_UTF8, 0, utf8Data, -1, wide.get(), bufferSize) == 0) { + return std::wstring(); + } + + return std::wstring(wide.get());; +} + +std::string toString(Platform::String ^str) +{ + std::wstring wsstr(str->Data()); + return makeString(wsstr); +} + +Platform::String^ toPlatformString(const std::string& str) +{ + std::wstring wsstr = makeWString(str); + return ref new Platform::String(wsstr.c_str(), wsstr.length()); +} +} +} \ No newline at end of file diff --git a/pch.h b/pch.h index 992f56cd6de6ccaa66212cb807a6f4be7075b8e6..cab6b561bb7ead0625d4d6e533c9ee02212a1595 100644 --- a/pch.h +++ b/pch.h @@ -19,6 +19,7 @@ /* standard system include files. */ #include <ppltasks.h> +#include <iomanip> /* required by generated headers. */ #include "App.xaml.h" @@ -26,3 +27,7 @@ #include "AccountsViewModel.h" #include "Contact.h" #include "ContactsViewModel.h" + +/* ensure to be accessed from anywhere */ +#include "RingDebug.h" +#include "Utils.h" diff --git a/ring-client-uwp.vcxproj b/ring-client-uwp.vcxproj index ec7a626a65bfa02e2129c5b4b64f870157d9e8ab..f602a9c0d9b394a8953041462b1fe7435573e5d0 100644 --- a/ring-client-uwp.vcxproj +++ b/ring-client-uwp.vcxproj @@ -175,9 +175,11 @@ <ClInclude Include="RingConsolePanel.xaml.h"> <DependentUpon>RingConsolePanel.xaml</DependentUpon> </ClInclude> + <ClInclude Include="RingDebug.h" /> <ClInclude Include="SmartPanel.xaml.h"> <DependentUpon>SmartPanel.xaml</DependentUpon> </ClInclude> + <ClInclude Include="Utils.h" /> <ClInclude Include="VideoPage.xaml.h"> <DependentUpon>VideoPage.xaml</DependentUpon> </ClInclude> @@ -263,6 +265,7 @@ <ClCompile Include="RingConsolePanel.xaml.cpp"> <DependentUpon>RingConsolePanel.xaml</DependentUpon> </ClCompile> + <ClCompile Include="RingDebug.cpp" /> <ClCompile Include="SmartPanel.xaml.cpp"> <DependentUpon>SmartPanel.xaml</DependentUpon> </ClCompile> diff --git a/ring-client-uwp.vcxproj.filters b/ring-client-uwp.vcxproj.filters index 4b8a43392b6b23ca955c1a763f97532165f209a5..bab8fc530930240bdf167721e5d7accd57a05b88 100644 --- a/ring-client-uwp.vcxproj.filters +++ b/ring-client-uwp.vcxproj.filters @@ -58,6 +58,9 @@ <ClCompile Include="ContactsViewModel.cpp"> <Filter>ModelViews</Filter> </ClCompile> + <ClCompile Include="RingDebug.cpp"> + <Filter>Common</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="pch.h" /> @@ -78,6 +81,12 @@ <ClInclude Include="ContactsViewModel.h"> <Filter>ModelViews</Filter> </ClInclude> + <ClInclude Include="RingDebug.h"> + <Filter>Common</Filter> + </ClInclude> + <ClInclude Include="Utils.h"> + <Filter>Common</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Image Include="Assets\LockScreenLogo.scale-200.png">