00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Skin.h"
00026 #include "XML.h"
00027 #include "LiveList.h"
00028 #include "Skin.h"
00029 #include "PageSettingsSkins.h"
00030
00031 #ifdef _DEBUG
00032 #define new DEBUG_NEW
00033 #undef THIS_FILE
00034 static char THIS_FILE[] = __FILE__;
00035 #endif
00036
00037 IMPLEMENT_DYNCREATE(CSkinsSettingsPage, CSettingsPage)
00038
00039 BEGIN_MESSAGE_MAP(CSkinsSettingsPage, CSettingsPage)
00040
00041 ON_WM_LBUTTONUP()
00042 ON_WM_SETCURSOR()
00043 ON_WM_CTLCOLOR()
00044 ON_NOTIFY(LVN_ITEMCHANGED, IDC_SKINS, OnItemChangedSkins)
00045 ON_BN_CLICKED(IDC_SKINS_BROWSE, OnSkinsBrowse)
00046 ON_BN_CLICKED(IDC_SKINS_WEB, OnSkinsWeb)
00047 ON_BN_CLICKED(IDC_SKINS_DELETE, OnSkinsDelete)
00048
00049 END_MESSAGE_MAP()
00050
00051
00053
00054
00055 CSkinsSettingsPage::CSkinsSettingsPage() : CSettingsPage( CSkinsSettingsPage::IDD )
00056 {
00057
00058
00059 }
00060
00061 CSkinsSettingsPage::~CSkinsSettingsPage()
00062 {
00063 }
00064
00065 void CSkinsSettingsPage::DoDataExchange(CDataExchange* pDX)
00066 {
00067 CSettingsPage::DoDataExchange(pDX);
00068
00069 DDX_Control(pDX, IDC_SKINS_DELETE, m_wndDelete);
00070 DDX_Control(pDX, IDC_SKIN_DESC, m_wndDesc);
00071 DDX_Control(pDX, IDC_SKIN_NAME, m_wndName);
00072 DDX_Control(pDX, IDC_SKIN_AUTHOR, m_wndAuthor);
00073 DDX_Control(pDX, IDC_SKINS, m_wndList);
00074
00075 }
00076
00078
00079
00080 BOOL CSkinsSettingsPage::OnInitDialog()
00081 {
00082 CSettingsPage::OnInitDialog();
00083
00084 m_gdiImageList.Create( 16, 16, ILC_COLOR16|ILC_MASK, 1, 1 );
00085 HICON hIcon = theApp.LoadIcon( IDI_SKIN );
00086 if ( theApp.m_bRTL ) hIcon = CreateMirroredIcon( hIcon );
00087 m_gdiImageList.Add( hIcon );
00088
00089 m_wndList.SetImageList( &m_gdiImageList, LVSIL_SMALL );
00090 m_wndList.InsertColumn( 0, _T("Name"), LVCFMT_LEFT, 210, 0 );
00091 m_wndList.InsertColumn( 1, _T("Author"), LVCFMT_LEFT, 130, 1 );
00092 m_wndList.InsertColumn( 2, _T("Version"), LVCFMT_LEFT, 42, 2 );
00093 m_wndList.InsertColumn( 3, _T("Path"), LVCFMT_LEFT, 0, 3 );
00094 m_wndList.InsertColumn( 4, _T("URL"), LVCFMT_LEFT, 0, 4 );
00095 m_wndList.InsertColumn( 5, _T("Email"), LVCFMT_LEFT, 0, 5 );
00096 m_wndList.InsertColumn( 6, _T("Description"), LVCFMT_LEFT, 0, 6 );
00097
00098 m_wndList.SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE,
00099 LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES, LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES );
00100
00101 if ( theApp.m_bRTL )
00102 m_wndDesc.ModifyStyleEx( WS_EX_RTLREADING|WS_EX_RIGHT|WS_EX_LEFTSCROLLBAR,
00103 WS_EX_LTRREADING|WS_EX_LEFT|WS_EX_RIGHTSCROLLBAR, 0 );
00104
00105 m_nSelected = -1;
00106 m_wndName.SetWindowText( _T("") );
00107 m_wndAuthor.SetWindowText( _T("") );
00108 m_wndDelete.EnableWindow( FALSE );
00109
00110 CWaitCursor pCursor;
00111
00112 EnumerateSkins();
00113
00114 return TRUE;
00115 }
00116
00117 void CSkinsSettingsPage::EnumerateSkins(LPCTSTR pszPath)
00118 {
00119 WIN32_FIND_DATA pFind;
00120 CString strPath;
00121 HANDLE hSearch;
00122
00123 strPath.Format( _T("%s\\Skins\\%s*.*"),
00124 (LPCTSTR)Settings.General.Path, pszPath ? pszPath : _T("") );
00125
00126 hSearch = FindFirstFile( strPath, &pFind );
00127
00128 if ( hSearch != INVALID_HANDLE_VALUE )
00129 {
00130 do
00131 {
00132 if ( pFind.cFileName[0] == '.' ) continue;
00133
00134 if ( pFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00135 {
00136 strPath.Format( _T("%s%s\\"),
00137 pszPath ? pszPath : _T(""), pFind.cFileName );
00138
00139 EnumerateSkins( strPath );
00140 }
00141 else if ( _tcsistr( pFind.cFileName, _T(".xml") ) != NULL &&
00142 _tcsicmp( pFind.cFileName, _T("Definitions.xml") ) &&
00143 _tcsnicmp( pFind.cFileName, _T("Default-"), 8 ) )
00144 {
00145 AddSkin( pszPath, pFind.cFileName );
00146 }
00147 }
00148 while ( FindNextFile( hSearch, &pFind ) );
00149
00150 FindClose( hSearch );
00151 }
00152 }
00153
00154 BOOL CSkinsSettingsPage::AddSkin(LPCTSTR pszPath, LPCTSTR pszName)
00155 {
00156 CString strXML;
00157 CFile pFile;
00158
00159 strXML = Settings.General.Path + _T("\\Skins\\");
00160 if ( pszPath ) strXML += pszPath;
00161 strXML += pszName;
00162
00163 if ( ! pFile.Open( strXML, CFile::modeRead ) ) return FALSE;
00164
00165 DWORD nSource = (DWORD)pFile.GetLength();
00166 if ( nSource > 4096*1024 ) return FALSE;
00167
00168 CHAR* pSource = new CHAR[ nSource ];
00169 pFile.Read( pSource, nSource );
00170 pFile.Close();
00171
00172 BYTE* pByte = (BYTE*)pSource;
00173 DWORD nByte = nSource;
00174
00175 if ( nByte >= 2 && ( ( pByte[0] == 0xFE && pByte[1] == 0xFF ) || ( pByte[0] == 0xFF && pByte[1] == 0xFE ) ) )
00176 {
00177 nByte = nByte / 2 - 1;
00178
00179 if ( pByte[0] == 0xFE && pByte[1] == 0xFF )
00180 {
00181 pByte += 2;
00182
00183 for ( DWORD nSwap = 0 ; nSwap < nByte ; nSwap ++ )
00184 {
00185 register CHAR nTemp = pByte[ ( nSwap << 1 ) + 0 ];
00186 pByte[ ( nSwap << 1 ) + 0 ] = pByte[ ( nSwap << 1 ) + 1 ];
00187 pByte[ ( nSwap << 1 ) + 1 ] = nTemp;
00188 }
00189 }
00190 else
00191 {
00192 pByte += 2;
00193 }
00194
00195 CopyMemory( strXML.GetBuffer( nByte ), pByte, nByte * 2 );
00196 strXML.ReleaseBuffer( nByte );
00197 }
00198 else
00199 {
00200 if ( nByte >= 3 && pByte[0] == 0xEF && pByte[1] == 0xBB && pByte[2] == 0xBF )
00201 {
00202 pByte += 3; nByte -= 3;
00203 }
00204
00205 DWORD nWide = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, NULL, 0 );
00206
00207 MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, strXML.GetBuffer( nWide ), nWide );
00208 strXML.ReleaseBuffer( nWide );
00209 }
00210
00211 delete [] pSource;
00212
00213 CXMLElement* pXML = NULL;
00214
00215 int nManifest = strXML.Find( _T("<manifest") );
00216
00217 if ( nManifest > 0 )
00218 {
00219 CString strManifest = strXML.Mid( nManifest ).SpanExcluding( _T(">") ) + '>';
00220
00221 if ( CXMLElement* pManifest = CXMLElement::FromString( strManifest ) )
00222 {
00223 pXML = new CXMLElement( NULL, _T("skin") );
00224 pXML->AddElement( pManifest );
00225 }
00226 }
00227
00228 if ( pXML == NULL )
00229 {
00230 pXML = CXMLElement::FromString( strXML, TRUE );
00231 if ( pXML == NULL ) return FALSE;
00232 }
00233
00234 strXML.Empty();
00235
00236 CXMLElement* pManifest = pXML->GetElementByName( _T("manifest") );
00237
00238 if ( ! pXML->IsNamed( _T("skin") ) || pManifest == NULL ||
00239 ! pManifest->GetAttributeValue( _T("type") ).CompareNoCase( _T("language") ) )
00240 {
00241 delete pXML;
00242 return FALSE;
00243 }
00244
00245 CString strType = pManifest->GetAttributeValue( _T("type"), _T("Unknown") );
00246 CString strIcon = pManifest->GetAttributeValue( _T("icon") );
00247 CString strName = pManifest->GetAttributeValue( _T("name"), pszName );
00248 CString strAuthor = pManifest->GetAttributeValue( _T("author"), _T("Unknown") );
00249 CString strVersion = pManifest->GetAttributeValue( _T("Version"), _T("Unknown") );
00250 CString strURL = pManifest->GetAttributeValue( _T("link") );
00251 CString strEmail = pManifest->GetAttributeValue( _T("email") );
00252 CString strDesc = pManifest->GetAttributeValue( _T("description") );
00253
00254 if ( theApp.m_bRTL )
00255 {
00256 strName = _T("\x202A") + strName;
00257 strAuthor = _T("\x202A") + strAuthor;
00258 }
00259
00260 delete pXML;
00261
00262 if ( strIcon.GetLength() )
00263 {
00264 if ( pszPath != NULL )
00265 strIcon = Settings.General.Path + _T("\\Skins\\") + pszPath + strIcon;
00266 else
00267 strIcon = Settings.General.Path + _T("\\Skins\\") + strIcon;
00268 }
00269 else
00270 {
00271 if ( pszPath != NULL )
00272 strIcon = Settings.General.Path + _T("\\Skins\\") + pszPath + strIcon + pszName;
00273 else
00274 strIcon = Settings.General.Path + _T("\\Skins\\") + strIcon + pszName;
00275
00276 strIcon = strIcon.Left( strIcon.GetLength() - 3 ) + _T("ico");
00277 }
00278
00279 if ( strURL.Find( _T("http://") ) == 0 )
00280 {
00281 }
00282 else if ( strURL.Find( _T("www.") ) == 0 )
00283 {
00284 strURL = _T("http://") + strURL;
00285 }
00286 else
00287 {
00288 strURL.Empty();
00289 }
00290
00291 if ( strEmail.Find( '@' ) < 0 ) strEmail.Empty();
00292
00293 CLiveItem pItem( 7, 0 );
00294 HICON hIcon;
00295
00296 if ( ExtractIconEx( strIcon, 0, NULL, &hIcon, 1 ) != NULL && hIcon != NULL )
00297 {
00298 pItem.m_nImage = m_gdiImageList.Add( hIcon );
00299 DestroyIcon( hIcon );
00300 }
00301 else
00302 {
00303 pItem.m_nImage = 0;
00304 }
00305
00306 pItem.Set( 0, strName );
00307 pItem.Set( 1, strAuthor );
00308 pItem.Set( 2, strVersion );
00309 pItem.Set( 4, strURL );
00310 pItem.Set( 5, strEmail );
00311 pItem.Set( 6, strDesc );
00312
00313 strName.Format( _T("%s%s"), pszPath ? pszPath : _T(""), pszName );
00314 pItem.Set( 3, strName );
00315
00316 int nItem = pItem.Add( &m_wndList, -1, 7 );
00317
00318 if ( theApp.GetProfileInt( _T("Skins"), strName, FALSE ) )
00319 {
00320 m_wndList.SetItemState( nItem, 2 << 12, LVIS_STATEIMAGEMASK );
00321 }
00322 else
00323 {
00324 m_wndList.SetItemState( nItem, 1 << 12, LVIS_STATEIMAGEMASK );
00325 }
00326
00327 return TRUE;
00328 }
00329
00330 void CSkinsSettingsPage::OnItemChangedSkins(NMHDR* pNMHDR, LRESULT* pResult)
00331 {
00332 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
00333 *pResult = 0;
00334
00335 int nItem = m_wndList.GetNextItem( -1, LVNI_SELECTED );
00336 if ( nItem == m_nSelected ) return;
00337 m_nSelected = nItem;
00338
00339 if ( nItem >= 0 )
00340 {
00341 m_wndName.SetWindowText( m_wndList.GetItemText( nItem, 0 ) );
00342 m_wndAuthor.SetWindowText( m_wndList.GetItemText( nItem, 1 ) );
00343 m_wndDesc.SetWindowText( m_wndList.GetItemText( nItem, 6 ) );
00344 m_wndDelete.EnableWindow( TRUE );
00345 }
00346 else
00347 {
00348 m_wndName.SetWindowText( _T("") );
00349 m_wndAuthor.SetWindowText( _T("") );
00350 m_wndDesc.SetWindowText( _T("") );
00351 m_wndDelete.EnableWindow( FALSE );
00352 }
00353 }
00354
00355 HBRUSH CSkinsSettingsPage::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
00356 {
00357 HBRUSH hbr = CSettingsPage::OnCtlColor( pDC, pWnd, nCtlColor );
00358
00359 if ( m_nSelected >= 0 )
00360 {
00361 if ( pWnd == &m_wndName )
00362 {
00363 if ( m_wndList.GetItemText( m_nSelected, 4 ).GetLength() )
00364 {
00365 pDC->SetTextColor( RGB( 0, 0, 255 ) );
00366 pDC->SelectObject( &theApp.m_gdiFontLine );
00367 }
00368 }
00369 else if ( pWnd == &m_wndAuthor )
00370 {
00371 if ( m_wndList.GetItemText( m_nSelected, 5 ).GetLength() )
00372 {
00373 pDC->SetTextColor( RGB( 0, 0, 255 ) );
00374 pDC->SelectObject( &theApp.m_gdiFontLine );
00375 }
00376 }
00377 }
00378
00379 return hbr;
00380 }
00381
00382 BOOL CSkinsSettingsPage::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
00383 {
00384 if ( m_nSelected >= 0 )
00385 {
00386 CPoint point;
00387 CRect rc;
00388
00389 GetCursorPos( &point );
00390 m_wndName.GetWindowRect( &rc );
00391
00392 if ( rc.PtInRect( point ) )
00393 {
00394 if ( m_wndList.GetItemText( m_nSelected, 4 ).GetLength() )
00395 {
00396 SetCursor( theApp.LoadCursor( IDC_HAND ) );
00397 return TRUE;
00398 }
00399 }
00400
00401 m_wndAuthor.GetWindowRect( &rc );
00402
00403 if ( rc.PtInRect( point ) )
00404 {
00405 if ( m_wndList.GetItemText( m_nSelected, 5 ).GetLength() )
00406 {
00407 SetCursor( theApp.LoadCursor( IDC_HAND ) );
00408 return TRUE;
00409 }
00410 }
00411 }
00412
00413 return CSettingsPage::OnSetCursor( pWnd, nHitTest, message );
00414 }
00415
00416 void CSkinsSettingsPage::OnLButtonUp(UINT nFlags, CPoint point)
00417 {
00418 CRect rc;
00419
00420 if ( m_nSelected < 0 ) return;
00421
00422 ClientToScreen( &point );
00423 m_wndName.GetWindowRect( &rc );
00424
00425 if ( rc.PtInRect( point ) )
00426 {
00427 CString strURL = m_wndList.GetItemText( m_nSelected, 4 );
00428
00429 if ( strURL.GetLength() )
00430 {
00431 ShellExecute( GetSafeHwnd(), _T("open"), strURL,
00432 NULL, NULL, SW_SHOWNORMAL );
00433 }
00434 return;
00435 }
00436
00437 m_wndAuthor.GetWindowRect( &rc );
00438
00439 if ( rc.PtInRect( point ) )
00440 {
00441 CString strEmail = m_wndList.GetItemText( m_nSelected, 5 );
00442
00443 if ( strEmail.GetLength() )
00444 {
00445 ShellExecute( GetSafeHwnd(), _T("open"), _T("mailto:") + strEmail,
00446 NULL, NULL, SW_SHOWNORMAL );
00447 }
00448 return;
00449 }
00450 }
00451
00452 void CSkinsSettingsPage::OnSkinsBrowse()
00453 {
00454 CFileDialog dlg( TRUE, _T("sks"), _T("*.sks"), OFN_HIDEREADONLY,
00455 _T("Skin Packages|*.sks|All Files|*.*||"), this );
00456
00457 if ( dlg.DoModal() != IDOK ) return;
00458
00459 CString strFile = dlg.GetPathName();
00460
00461 ShellExecute( GetSafeHwnd(), _T("open"), strFile, NULL, NULL, SW_SHOWNORMAL );
00462 }
00463
00464 void CSkinsSettingsPage::OnSkinsWeb()
00465 {
00466 ShellExecute( GetSafeHwnd(), _T("open"),
00467 _T("http://www.shareaza.com/skins/?Version=") + theApp.m_sVersion,
00468 NULL, NULL, SW_SHOWNORMAL );
00469 }
00470
00471 void CSkinsSettingsPage::OnOK()
00472 {
00473 BOOL bChanged = FALSE;
00474
00475 for ( int nItem = 0 ; nItem < m_wndList.GetItemCount() ; nItem++ )
00476 {
00477 CString strSkin = m_wndList.GetItemText( nItem, 3 );
00478
00479 BOOL bOn = m_wndList.GetItemState( nItem, LVIS_STATEIMAGEMASK ) == ( 2 << 12 );
00480
00481 if ( theApp.GetProfileInt( _T("Skins"), strSkin, FALSE ) != (UINT)bOn )
00482 {
00483 bChanged = TRUE;
00484 }
00485
00486 theApp.WriteProfileInt( _T("Skins"), strSkin, bOn );
00487 }
00488
00489 if ( bChanged ) AfxGetMainWnd()->PostMessage( WM_SKINCHANGED );
00490
00491 CSettingsPage::OnOK();
00492 }
00493
00494 void CSkinsSettingsPage::OnSkinsDelete()
00495 {
00496 if ( m_nSelected < 0 ) return;
00497
00498 CString strName = m_wndList.GetItemText( m_nSelected, 0 );
00499 CString strBase = m_wndList.GetItemText( m_nSelected, 3 );
00500
00501 CString strFormat, strPrompt;
00502
00503 Skin.LoadString( strFormat, IDS_SKIN_DELETE );
00504 strPrompt.Format( strFormat, (LPCTSTR)strName );
00505
00506 if ( AfxMessageBox( strPrompt, MB_ICONQUESTION|MB_OKCANCEL|MB_DEFBUTTON2 ) != IDOK ) return;
00507
00508 theApp.WriteProfileString( _T("Skins"), strBase, NULL );
00509
00510 CString strPath;
00511 strPath.Format( _T("%s\\Skins\\%s"),
00512 (LPCTSTR)Settings.General.Path, (LPCTSTR)strBase );
00513
00514 DeleteFile( strPath );
00515
00516 int nSlash = strPath.ReverseFind( '\\' );
00517 strPath = strPath.Left( nSlash ) + _T("\\*.xml");
00518
00519 WIN32_FIND_DATA pFind;
00520 HANDLE hSearch = FindFirstFile( strPath, &pFind );
00521
00522 if ( hSearch != INVALID_HANDLE_VALUE )
00523 {
00524 FindClose( hSearch );
00525 }
00526 else
00527 {
00528 strPath = strPath.Left( strPath.GetLength() - 3 ) + _T("*");
00529 hSearch = FindFirstFile( strPath, &pFind );
00530
00531 if ( hSearch != INVALID_HANDLE_VALUE )
00532 {
00533 strPath = strPath.Left( strPath.GetLength() - 3 );
00534
00535 do
00536 {
00537 if ( pFind.cFileName[0] == '.' ) continue;
00538 DeleteFile( strPath + pFind.cFileName );
00539 }
00540 while ( FindNextFile( hSearch, &pFind ) );
00541
00542 FindClose( hSearch );
00543 }
00544
00545 strPath = strPath.Left( strPath.GetLength() - 1 );
00546 RemoveDirectory( strPath );
00547 }
00548
00549 m_wndList.DeleteItem( m_nSelected );
00550 m_wndName.SetWindowText( _T("") );
00551 m_wndAuthor.SetWindowText( _T("") );
00552 m_wndDesc.SetWindowText( _T("") );
00553 m_wndDelete.EnableWindow( FALSE );
00554 m_nSelected = -1;
00555 }
00556