diff --git a/Common/System/System.h b/Common/System/System.h index 78e954b7b5..b0f83d70bd 100644 --- a/Common/System/System.h +++ b/Common/System/System.h @@ -146,6 +146,7 @@ enum SystemProperty { SYSPROP_HAS_ACCELEROMETER, // Used to enable/disable tilt input settings SYSPROP_HAS_OPEN_DIRECTORY, SYSPROP_HAS_LOGIN_DIALOG, + SYSPROP_HAS_TEXT_CLIPBOARD, SYSPROP_HAS_TEXT_INPUT_DIALOG, // Indicates that System_InputBoxGetString is available. SYSPROP_CAN_CREATE_SHORTCUT, diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 9e6e759df1..5122131e10 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -247,6 +247,8 @@ float System_GetPropertyFloat(SystemProperty prop) { bool System_GetPropertyBool(SystemProperty prop) { switch (prop) { + case SYSPROP_HAS_TEXT_CLIPBOARD: + return true; case SYSPROP_HAS_BACK_BUTTON: return true; case SYSPROP_HAS_IMAGE_BROWSER: diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 716ebde8a9..9c97bc74cd 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -543,6 +543,7 @@ float System_GetPropertyFloat(SystemProperty prop) { bool System_GetPropertyBool(SystemProperty prop) { switch (prop) { + case SYSPROP_HAS_TEXT_CLIPBOARD: case SYSPROP_CAN_SHOW_FILE: #if PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(MAC) || (PPSSPP_PLATFORM(LINUX) && !PPSSPP_PLATFORM(ANDROID)) return true; diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 2c089e5826..fd661088e6 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -81,6 +81,9 @@ void GameScreen::update() { CRC32string = int2hexstr(crcvalue); tvCRC_->SetVisibility(UI::V_VISIBLE); tvCRC_->SetText(CRC32string); + if (tvCRCCopy_) { + tvCRCCopy_->SetVisibility(UI::V_VISIBLE); + } if (btnCalcCRC_) { btnCalcCRC_->SetVisibility(UI::V_GONE); } @@ -145,9 +148,27 @@ void GameScreen::CreateViews() { tvPlayTime_ = infoLayout->Add(new TextView("", ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); tvPlayTime_->SetShadow(true); tvPlayTime_->SetVisibility(V_GONE); - tvCRC_ = infoLayout->Add(new TextView("", ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + + LinearLayout *crcHoriz = infoLayout->Add(new LinearLayout(ORIENT_HORIZONTAL)); + tvCRC_ = crcHoriz->Add(new TextView("", ALIGN_LEFT, true, new LinearLayoutParams(0.0, G_VCENTER))); tvCRC_->SetShadow(true); - tvCRC_->SetVisibility(Reporting::HasCRC(gamePath_) ? V_VISIBLE : V_GONE); + Visibility crcVisibility = Reporting::HasCRC(gamePath_) ? V_VISIBLE : V_GONE; + tvCRC_->SetVisibility(crcVisibility); + if (System_GetPropertyBool(SYSPROP_HAS_TEXT_CLIPBOARD)) { + tvCRCCopy_ = crcHoriz->Add(new Button(di->T("Copy to clipboard"), new LinearLayoutParams(0.0, G_VCENTER))); + tvCRCCopy_->OnClick.Add([this](UI::EventParams &) { + u32 crc = Reporting::RetrieveCRC(gamePath_); + char buffer[16]; + snprintf(buffer, sizeof(buffer), "%08X", crc); + System_CopyStringToClipboard(buffer); + return UI::EVENT_DONE; + }); + tvCRCCopy_->SetVisibility(crcVisibility); + tvCRCCopy_->SetScale(0.82f); + } else { + tvCRCCopy_ = nullptr; + } + tvVerified_ = infoLayout->Add(new NoticeView(NoticeLevel::INFO, ga->T("Click \"Calculate CRC\" to verify ISO"), "", new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); tvVerified_->SetVisibility(UI::V_GONE); tvVerified_->SetSquishy(true); @@ -170,6 +191,7 @@ void GameScreen::CreateViews() { tvRegion_ = nullptr; tvPlayTime_ = nullptr; tvCRC_ = nullptr; + tvCRCCopy_ = nullptr; tvVerified_ = nullptr; } @@ -360,6 +382,9 @@ ScreenRenderFlags GameScreen::render(ScreenRenderMode mode) { std::string crc = StringFromFormat("%08X", crcVal); tvCRC_->SetText(ReplaceAll(rp->T("FeedbackCRCValue", "Disc CRC: %1"), "%1", crc)); tvCRC_->SetVisibility(UI::V_VISIBLE); + if (tvCRCCopy_) { + tvCRCCopy_->SetVisibility(UI::V_VISIBLE); + } // Let's check the CRC in the game database, looking up the ID and also matching the crc. std::vector dbInfos; diff --git a/UI/GameScreen.h b/UI/GameScreen.h index b8fd92fe78..5638eb33c6 100644 --- a/UI/GameScreen.h +++ b/UI/GameScreen.h @@ -75,6 +75,7 @@ private: UI::TextView *tvPlayTime_ = nullptr; UI::TextView *tvCRC_ = nullptr; UI::TextView *tvID_ = nullptr; + UI::Button *tvCRCCopy_ = nullptr; NoticeView *tvVerified_ = nullptr; UI::Choice *btnGameSettings_ = nullptr; diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index b20678ebfb..719d342821 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -408,6 +408,7 @@ void System_Toast(std::string_view str) {} bool System_GetPropertyBool(SystemProperty prop) { switch (prop) { + case SYSPROP_HAS_TEXT_CLIPBOARD: case SYSPROP_HAS_OPEN_DIRECTORY: { return !IsXBox(); diff --git a/Windows/main.cpp b/Windows/main.cpp index f0274692f7..bd763a0908 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -355,6 +355,7 @@ float System_GetPropertyFloat(SystemProperty prop) { bool System_GetPropertyBool(SystemProperty prop) { switch (prop) { + case SYSPROP_HAS_TEXT_CLIPBOARD: case SYSPROP_HAS_DEBUGGER: case SYSPROP_HAS_FILE_BROWSER: case SYSPROP_HAS_FOLDER_BROWSER: @@ -910,7 +911,6 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin std::string controlsConfigFilename = ""; const std::wstring controlsOption = L"--controlconfig="; - for (size_t i = 1; i < wideArgs.size(); ++i) { if (wideArgs[i][0] == L'\0') continue;