void CGUIEditControl::RecalcLabelPosition() { // ensure that our cursor is within our width ValidateCursor(); CStdStringW text = GetDisplayedText(); m_textWidth = m_label.CalcTextWidth(text + L'|'); float beforeCursorWidth = m_label.CalcTextWidth(text.substr(0, m_cursorPos)); float afterCursorWidth = m_label.CalcTextWidth(text.substr(0, m_cursorPos) + L'|'); float leftTextWidth = m_label.GetRenderRect().Width(); float maxTextWidth = m_label.GetMaxWidth(); if (leftTextWidth > 0) maxTextWidth -= leftTextWidth + spaceWidth; // if skinner forgot to set height :p if (m_height == 0 && m_label.GetLabelInfo().font) m_height = m_label.GetLabelInfo().font->GetTextHeight(1); if (m_textWidth > maxTextWidth) { // we render taking up the full width, so make sure our cursor position is // within the render window if (m_textOffset + afterCursorWidth > maxTextWidth) { // move the position to the left (outside of the viewport) m_textOffset = maxTextWidth - afterCursorWidth; } else if (m_textOffset + beforeCursorWidth < 0) // offscreen to the left { // otherwise use original position m_textOffset = -beforeCursorWidth; } else if (m_textOffset + m_textWidth < maxTextWidth) { // we have more text than we're allowed, but we aren't filling all the space m_textOffset = maxTextWidth - m_textWidth; } } else m_textOffset = 0; }
bool CWIN32Util::IsUsbDevice(const CStdStringW &strWdrive) { if (strWdrive.size() < 2) return false; CStdStringW strWDevicePath = StringUtils::Format(L"\\\\.\\%s",strWdrive.substr(0, 2).c_str()); HANDLE deviceHandle = CreateFileW( strWDevicePath.c_str(), 0, // no access to the drive FILE_SHARE_READ | // share mode FILE_SHARE_WRITE, NULL, // default security attributes OPEN_EXISTING, // disposition 0, // file attributes NULL); // do not copy file attributes if(deviceHandle == INVALID_HANDLE_VALUE) return false; // setup query STORAGE_PROPERTY_QUERY query; memset(&query, 0, sizeof(query)); query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; // issue query DWORD bytes; STORAGE_DEVICE_DESCRIPTOR devd; STORAGE_BUS_TYPE busType = BusTypeUnknown; if (DeviceIoControl(deviceHandle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &devd, sizeof(devd), &bytes, NULL)) { busType = devd.BusType; } CloseHandle(deviceHandle); return BusTypeUsb == busType; }
void TestDocReader::TestCommentsWithTrackChanges() { DocReader dr; dr.OpenFile(TEST_COMMENTS_TC_DOC); CStdStringW sExp = L"Lots of the - the only actual change from this story is that the w3 file appear next to the revolving document,"; sExp += " not in a dms folder, plus it create dms \05folders where there isn't one already.\r"; sExp += "QA IanX> 2X integration sheets received 03/10/03\05. No visable change\05, change \05is to development tests only.\r"; CStdStringW sGot = dr.GetMainDocumentText(); for (unsigned int i=0; i<(x64_int_cast)sExp.size(); i++) { OutputDebugString(CStdString(sGot.substr(i,1))); assertTest(sGot[i] == sExp[i]); } assertTest(dr.GetMainDocumentText() == sExp); }
void TestDocReader::TestTabChanges() { DocReader dr; dr.OpenFile(TEST_TABS_TC_DOC); CStdStringW sExp = L"\t\t\t\t\t\t\t\t\t\tABC\t1.23\tDEF\tGHI\tFFF\r"; sExp += "Abc\t222.23\t\t\t\t\tdef\tghi\tddd\r"; sExp += "Aaa\t10.87 b\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcb\tccc\txxx\r"; sExp += "Ddd\t1.44994\t\t\t\t\t\t\r"; sExp += "ABC\t1.23 DEF GHI aaa\t\t\t\r"; sExp += "Abc\t222.\t\t\txxx\r"; sExp += "Aaa\t10.87\tbcb\tccc\tzzz\r"; sExp += "Ddd\t1.44994\teEEee\tfffLeft\tright\r"; sExp += "Left\tRIGHT\r"; CStdStringW sGot = dr.GetMainDocumentText(); for (unsigned int i=0; i<(x64_int_cast)sExp.size(); i++) { OutputDebugString(CStdString(sGot.substr(i,1))); assertTest(sGot[i] == sExp[i]); } assertTest(dr.GetMainDocumentText() == sExp); }
void CWIN32Util::GetDrivesByType(VECSOURCES &localDrives, Drive_Types eDriveType, bool bonlywithmedia) { WCHAR* pcBuffer= NULL; DWORD dwStrLength= GetLogicalDriveStringsW( 0, pcBuffer ); if( dwStrLength != 0 ) { CMediaSource share; dwStrLength+= 1; pcBuffer= new WCHAR [dwStrLength]; GetLogicalDriveStringsW( dwStrLength, pcBuffer ); int iPos= 0; WCHAR cVolumeName[100]; do{ int nResult = 0; cVolumeName[0]= L'\0'; CStdStringW strWdrive = pcBuffer + iPos; UINT uDriveType= GetDriveTypeW( strWdrive.c_str() ); // don't use GetVolumeInformation on fdd's as the floppy controller may be enabled in Bios but // no floppy HW is attached which causes huge delays. if(strWdrive.size() >= 2 && strWdrive.substr(0,2) != L"A:" && strWdrive.substr(0,2) != L"B:") nResult= GetVolumeInformationW( strWdrive.c_str() , cVolumeName, 100, 0, 0, 0, NULL, 25); if(nResult == 0 && bonlywithmedia) { iPos += (wcslen( pcBuffer + iPos) + 1 ); continue; } // usb hard drives are reported as DRIVE_FIXED and won't be returned by queries with REMOVABLE_DRIVES set // so test for usb hard drives /*if(uDriveType == DRIVE_FIXED) { if(IsUsbDevice(strWdrive)) uDriveType = DRIVE_REMOVABLE; }*/ share.strPath= share.strName= ""; bool bUseDCD= false; if( uDriveType > DRIVE_UNKNOWN && (( eDriveType == ALL_DRIVES && (uDriveType == DRIVE_FIXED || uDriveType == DRIVE_REMOTE || uDriveType == DRIVE_CDROM || uDriveType == DRIVE_REMOVABLE )) || ( eDriveType == LOCAL_DRIVES && (uDriveType == DRIVE_FIXED || uDriveType == DRIVE_REMOTE)) || ( eDriveType == REMOVABLE_DRIVES && ( uDriveType == DRIVE_REMOVABLE )) || ( eDriveType == DVD_DRIVES && ( uDriveType == DRIVE_CDROM )))) { //share.strPath = strWdrive; g_charsetConverter.wToUTF8(strWdrive, share.strPath); if( cVolumeName[0] != L'\0' ) g_charsetConverter.wToUTF8(cVolumeName, share.strName); if( uDriveType == DRIVE_CDROM && nResult) { // Has to be the same as auto mounted devices share.strStatus = share.strName; share.strName = share.strPath; share.m_iDriveType= CMediaSource::SOURCE_TYPE_LOCAL; bUseDCD= true; } else { // Lets show it, like Windows explorer do... TODO: sorting should depend on driver letter switch(uDriveType) { case DRIVE_CDROM: share.strName = StringUtils::Format( "%s (%s)", share.strPath.c_str(), g_localizeStrings.Get(218).c_str()); break; case DRIVE_REMOVABLE: if(share.strName.empty()) share.strName = StringUtils::Format( "%s (%s)", g_localizeStrings.Get(437).c_str(), share.strPath.c_str()); break; case DRIVE_UNKNOWN: share.strName = StringUtils::Format( "%s (%s)", share.strPath.c_str(), g_localizeStrings.Get(13205).c_str()); break; default: if(share.strName.empty()) share.strName = share.strPath; else share.strName = StringUtils::Format( "%s (%s)", share.strPath.c_str(), share.strName.c_str()); break; } } StringUtils::Replace(share.strName, ":\\", ":"); StringUtils::Replace(share.strPath, ":\\", ":"); share.m_ignore= true; if( !bUseDCD ) { share.m_iDriveType= ( ( uDriveType == DRIVE_FIXED ) ? CMediaSource::SOURCE_TYPE_LOCAL : ( uDriveType == DRIVE_REMOTE ) ? CMediaSource::SOURCE_TYPE_REMOTE : ( uDriveType == DRIVE_CDROM ) ? CMediaSource::SOURCE_TYPE_DVD : ( uDriveType == DRIVE_REMOVABLE ) ? CMediaSource::SOURCE_TYPE_REMOVABLE : CMediaSource::SOURCE_TYPE_UNKNOWN ); } AddOrReplace(localDrives, share); } iPos += (wcslen( pcBuffer + iPos) + 1 ); } while( wcslen( pcBuffer + iPos ) > 0 ); delete[] pcBuffer; } }
void CGUITextLayout::ParseText(const CStdStringW &text, uint32_t defaultStyle, color_t defaultColor, vecColors &colors, vecText &parsedText) { // run through the string, searching for: // [B] or [/B] -> toggle bold on and off // [I] or [/I] -> toggle italics on and off // [COLOR ffab007f] or [/COLOR] -> toggle color on and off // [CAPS <option>] or [/CAPS] -> toggle capatilization on and off uint32_t currentStyle = defaultStyle; // start with the default font's style color_t currentColor = 0; colors.push_back(defaultColor); stack<color_t> colorStack; colorStack.push(0); // these aren't independent, but that's probably not too much of an issue // eg [UPPERCASE]Glah[LOWERCASE]FReD[/LOWERCASE]Georeg[/UPPERCASE] will work (lower case >> upper case) // but [LOWERCASE]Glah[UPPERCASE]FReD[/UPPERCASE]Georeg[/LOWERCASE] won't int startPos = 0; size_t pos = text.find(L'['); while (pos != std::string::npos && pos + 1 < text.size()) { uint32_t newStyle = 0; color_t newColor = currentColor; bool colorTagChange = false; bool newLine = false; // have a [ - check if it's an ON or OFF switch bool on(true); size_t endPos = pos++; // finish of string if (text[pos] == L'/') { on = false; pos++; } // check for each type if (text.compare(pos, 2, L"B]") == 0) { // bold - finish the current text block and assign the bold state pos += 2; if ((on && text.find(L"[/B]",pos) != std::string::npos) || // check for a matching end point (!on && (currentStyle & FONT_STYLE_BOLD))) // or matching start point newStyle = FONT_STYLE_BOLD; } else if (text.compare(pos, 2, L"I]") == 0) { // italics pos += 2; if ((on && text.find(L"[/I]", pos) != std::string::npos) || // check for a matching end point (!on && (currentStyle & FONT_STYLE_ITALICS))) // or matching start point newStyle = FONT_STYLE_ITALICS; } else if (text.compare(pos, 10, L"UPPERCASE]") == 0) { pos += 10; if ((on && text.find(L"[/UPPERCASE]", pos) != std::string::npos) || // check for a matching end point (!on && (currentStyle & FONT_STYLE_UPPERCASE))) // or matching start point newStyle = FONT_STYLE_UPPERCASE; } else if (text.compare(pos, 10, L"LOWERCASE]") == 0) { pos += 10; if ((on && text.find(L"[/LOWERCASE]", pos) != std::string::npos) || // check for a matching end point (!on && (currentStyle & FONT_STYLE_LOWERCASE))) // or matching start point newStyle = FONT_STYLE_LOWERCASE; } else if (text.compare(pos, 3, L"CR]") == 0 && on) { newLine = true; pos += 3; } else if (text.compare(pos,5, L"COLOR") == 0) { // color size_t finish = text.find(L']', pos + 5); if (on && finish != std::string::npos && text.find(L"[/COLOR]",finish) != std::string::npos) { color_t color = g_colorManager.GetColor(text.substr(pos + 5, finish - pos - 5)); vecColors::const_iterator it = std::find(colors.begin(), colors.end(), color); if (it == colors.end()) { // create new color if (colors.size() <= 0xFF) { newColor = colors.size(); colors.push_back(color); } else // we have only 8 bits for color index, fallback to first color if reach max. newColor = 0; } else // reuse existing color newColor = it - colors.begin(); colorStack.push(newColor); colorTagChange = true; } else if (!on && finish == pos + 5 && colorStack.size() > 1) { // revert to previous color colorStack.pop(); newColor = colorStack.top(); colorTagChange = true; } if (finish != CStdString::npos) pos = finish + 1; } if (newStyle || colorTagChange || newLine) { // we have a new style or a new color, so format up the previous segment CStdStringW subText = text.substr(startPos, endPos - startPos); if (currentStyle & FONT_STYLE_UPPERCASE) StringUtils::ToUpper(subText); if (currentStyle & FONT_STYLE_LOWERCASE) StringUtils::ToLower(subText); AppendToUTF32(subText, ((currentStyle & 3) << 24) | (currentColor << 16), parsedText); if (newLine) parsedText.push_back(L'\n'); // and switch to the new style startPos = pos; currentColor = newColor; if (on) currentStyle |= newStyle; else currentStyle &= ~newStyle; } pos = text.find(L'[', pos); } // now grab the remainder of the string CStdStringW subText = text.substr(startPos); if (currentStyle & FONT_STYLE_UPPERCASE) StringUtils::ToUpper(subText); if (currentStyle & FONT_STYLE_LOWERCASE) StringUtils::ToLower(subText); AppendToUTF32(subText, ((currentStyle & 3) << 24) | (currentColor << 16), parsedText); }