#pragma comment( linker, "\"/manifestdependency:type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"" ) #include "databasewindow.hpp" #include "gui_functions.hpp" #include "progresswindow.hpp" #include "searchwindow.hpp" #include "../filesystem.hpp" #include "../functions.hpp" #include "../resources_windows.h" #include #include #include #define ID_LISTVIEW 0x0001 #define ID_OK_BUTTON 0x0002 #define ID_CANCEL_BUTTON 0x0003 #define ID_SAVE_BUTTON 0x0004 #define ID_LANG_COMBO 0x0005 #define SHOW_COLUMN 0 #define PATH_COLUMN 1 #define LANG_COLUMN 2 #define DVD_COLUMN 3 #define ID_INDEX 0 #define LANG_ID_INDEX 1 #define TVID_INDEX 2 #define database_width( width ) width - 10 #define database_height( height ) height - 50 #define cancel_x( width ) width - 85 #define cancel_y( height ) height - 30 #define ok_x( width ) width - 170 #define ok_y( height ) height - 30 #define save_x( width ) 5 #define save_y( height ) height - 30 DatabaseWindow *DatabaseWindow::dw = nullptr; void toggleDVD( LPNMITEMACTIVATE temp, HWND list_hwnd ) { auto dvd = getItemText( list_hwnd, temp->iItem, temp->iSubItem ) != _( NO ); if ( dvd ) { setListViewItemText( list_hwnd, temp->iItem, temp->iSubItem, _( NO ) ); } else { setListViewItemText( list_hwnd, temp->iItem, temp->iSubItem, _( YES ) ); } } DatabaseWindow::DatabaseWindow( HINSTANCE hInstance, std::vector< std::pair< std::wstring, std::wstring > > &languages, HWND parent_window ) : parent( parent_window ), hInst( hInstance ), langs( languages ) { // need to set this here for WM_NOTIFY to work dw = this; window = CreateWindowW( L"DatabaseWindow", _( DATABASE ), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, window_width, window_height, parent, NULL, hInstance, NULL ); ShowWindow( window, SW_SHOW ); auto hFont = ( HFONT )GetStockObject( DEFAULT_GUI_FONT ); EnableWindow( parent, false ); setIcons( hInstance, window ); INITCOMMONCONTROLSEX icex; // Structure for control initialization. icex.dwICC = ICC_LISTVIEW_CLASSES; InitCommonControlsEx( &icex ); RECT client_rect{}; GetClientRect( window, &client_rect ); auto client_width = client_rect.right - client_rect.left; auto client_height = client_rect.bottom - client_rect.top; list_hwnd = createListView( 5, 5, database_width( client_width ), database_height( client_height ), ID_LISTVIEW, window, hFont ); addColumnToListView( list_hwnd, _( SHOW ), 90, SHOW_COLUMN ); addColumnToListView( list_hwnd, _( PATH ), 180, PATH_COLUMN ); addColumnToListView( list_hwnd, _( ID_LANGUAGE ), 70, LANG_COLUMN ); addColumnToListView( list_hwnd, _( DVD ), 40, DVD_COLUMN ); int row{ 0 }; for ( auto &x : dbGetShows() ) { if ( x[L"SHOW"] == L"pattern" ) continue; addItemToListView( list_hwnd, row, SHOW_COLUMN, x[L"SHOW"].c_str() ); addItemToListView( list_hwnd, row, PATH_COLUMN, x[L"PATH"].c_str() ); addItemToListView( list_hwnd, row, DVD_COLUMN, x[L"DVD"] == L"1" ? _( YES ) : _( NO ) ); int lang_id = 0; for ( wchar_t i = 0; i < ( wchar_t )languages.size(); i++ ) { if ( x[L"LANGUAGE"] == languages[i].first ) { addItemToListView( list_hwnd, row, LANG_COLUMN, languages[i].second.c_str() ); lang_id = i; } } show_ids.emplace_back( std::stoi( x[L"ID"].c_str() ), lang_id, x[L"TVID"] ); row++; } cancel_button = createButton( _( CANCEL ), cancel_x( client_width ), cancel_y( client_height ), 80, 25, ID_CANCEL_BUTTON, window, hFont ); ok_button = createButton( _( OK ), ok_x( client_width ), ok_y( client_height ), 80, 25, ID_OK_BUTTON, window, hFont ); save_button = createButton( _( SAVE ), save_x( client_width ), save_y( client_height ), 80, 25, ID_SAVE_BUTTON, window, hFont ); lang_combo = createCombo( 0, 0, 120, 110, ID_LANG_COMBO, window, hFont ); ShowWindow( lang_combo, SW_HIDE ); for ( auto &x : languages ) { addItemToCombo( lang_combo, x.second.c_str() ); } UpdateWindow( window ); } LRESULT CALLBACK DatabaseWindow::messageHandler( HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam ) { switch ( umsg ) { case WM_CREATE: centerWindow( hwnd ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; case WM_COMMAND: switch ( LOWORD( wParam ) ) { case ID_OK_BUTTON: dw->save(); SendMessage( hwnd, WM_CLOSE, 0, 0 ); break; case ID_CANCEL_BUTTON: SendMessage( hwnd, WM_CLOSE, 0, 0 ); break; case ID_SAVE_BUTTON: dw->save(); break; case ID_LANG_COMBO: switch ( HIWORD( wParam ) ) { case CBN_KILLFOCUS: ShowWindow( dw->lang_combo, SW_HIDE ); break; case CBN_SELCHANGE: { ShowWindow( dw->lang_combo, SW_HIDE ); int lang_id = getComboCurSel( dw->lang_combo ); setListViewItemText( dw->list_hwnd, dw->cur_row, LANG_COLUMN, dw->langs[lang_id].second.c_str() ); std::get< LANG_ID_INDEX >( dw->show_ids[dw->cur_row] ) = lang_id; } break; } break; } break; case WM_SIZE: { if ( dw->list_hwnd == nullptr || dw->cancel_button == nullptr || dw->ok_button == nullptr || dw->save_button == nullptr ) break; ShowWindow( dw->lang_combo, SW_HIDE ); auto width = LOWORD( lParam ); auto height = HIWORD( lParam ); SetWindowPos( dw->list_hwnd, HWND_TOP, 5, 5, database_width( width ), database_height( height ), 0 ); SetWindowPos( dw->cancel_button, HWND_TOP, cancel_x( width ), cancel_y( height ), 80, 25, 0 ); SetWindowPos( dw->ok_button, HWND_TOP, ok_x( width ), ok_y( height ), 80, 25, 0 ); SetWindowPos( dw->save_button, HWND_TOP, save_x( width ), save_y( height ), 80, 25, 0 ); UpdateWindow( dw->window ); } break; case WM_NOTIFY: dw->listNotify( lParam ); break; } return DefWindowProcW( hwnd, umsg, wParam, lParam ); } void DatabaseWindow::mainLoop() { MSG msg; while ( GetMessage( &msg, NULL, 0, 0 ) ) { if ( !IsDialogMessage( window, &msg ) ) { TranslateMessage( &msg ); dw = this; DispatchMessage( &msg ); } } } void DatabaseWindow::changed( int index ) { auto path = getItemText( list_hwnd, index, PATH_COLUMN ); if ( !FSLib::isDirectory( path ) ) { MessageBox( window, _( DIR_NOT_EXIST ), _( ERROR ), MB_OK | MB_ICONERROR ); return; } changed_rows.push_back( index ); } void DatabaseWindow::save() { if ( changed_rows.size() == 0 ) return; std::unordered_set< size_t > row_indexes; for ( auto &row : changed_rows ) { auto index = std::get< ID_INDEX >( show_ids[row] ); auto show = getItemText( list_hwnd, row, SHOW_COLUMN ); auto path = getItemText( list_hwnd, row, PATH_COLUMN ); auto lang = langs[std::get< LANG_ID_INDEX >( show_ids[row] )].first; auto show_id = std::get< TVID_INDEX >( show_ids[row] ).c_str(); bool dvd = getItemText( list_hwnd, row, DVD_COLUMN ) == _( YES ); changeDB( index, path, lang, show_id, dvd ); row_indexes.insert( index ); } ProgressWindow pw( hInst, window ); std::thread t = std::thread( refreshSelectDB, row_indexes, false, pw.getWindow() ); t.detach(); pw.mainLoop(); changed_rows.clear(); } void DatabaseWindow::listNotify( LPARAM lParam ) { NMHDR &nmh = *( NMHDR * )lParam; if ( nmh.hwndFrom != dw->list_hwnd ) return; switch ( nmh.code ) { case NM_DBLCLK: { LPNMITEMACTIVATE temp = ( LPNMITEMACTIVATE )lParam; if ( temp->iItem == -1 ) break; switch ( temp->iSubItem ) { case SHOW_COLUMN: { auto lang_id = std::get< LANG_ID_INDEX >( show_ids[temp->iItem] ); auto show = getItemText( list_hwnd, temp->iItem, SHOW_COLUMN ); SearchWindow sw( hInst, langs, lang_id, show.c_str(), window ); sw.mainLoop(); // test if user clicke OK if ( sw.accepted() ) { setListViewItemText( list_hwnd, temp->iItem, SHOW_COLUMN, sw.getShow().c_str() ); std::get< TVID_INDEX >( show_ids[temp->iItem] ) = sw.getShowID(); setListViewItemText( list_hwnd, temp->iItem, LANG_COLUMN, langs[sw.getLangID()].second.c_str() ); std::get< LANG_ID_INDEX >( show_ids[temp->iItem] ) = sw.getLangID(); } } break; case PATH_COLUMN: { auto dir = getDir(); if ( !dir.empty() ) addItemToListView( list_hwnd, temp->iItem, temp->iSubItem, dir.c_str() ); } break; case LANG_COLUMN: { RECT item_rect; cur_row = temp->iItem; ListView_GetSubItemRect( list_hwnd, temp->iItem, temp->iSubItem, LVIR_BOUNDS, &item_rect ); SetWindowPos( lang_combo, HWND_TOP, item_rect.left + 5, item_rect.top + 5, item_rect.right - item_rect.left, window_height, NULL ); ShowWindow( lang_combo, SW_SHOW ); SetFocus( lang_combo ); auto id = std::get< LANG_ID_INDEX >( show_ids[temp->iItem] ); SendMessage( lang_combo, CB_SETCURSEL, id, NULL ); } break; case DVD_COLUMN: toggleDVD( temp, list_hwnd ); break; } changed( temp->iItem ); } break; } }