#include "databasewindow.hpp" #include "../filesystem.hpp" #include "../functions.hpp" #include "gui_functions.hpp" #include "progresswindow.hpp" #include "searchwindow.hpp" #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_COLUMN 4 #define LANG_ID_COLUMN 5 #define TVID_COLUMN 6 #define database_width( width ) width - 25 #define database_height( height ) height - 90 #define cancel_x( width ) width - 100 #define cancel_y( height ) height - 73 #define ok_x( width ) width - 185 #define ok_y( height ) height - 73 #define save_x( width ) 5 #define save_y( height ) height - 73 DatabaseWindow *DatabaseWindow::dw = nullptr; void toggleDVD( LPNMITEMACTIVATE temp, HWND list_hwnd ) { auto dvd = getItemText( list_hwnd, temp->iItem, temp->iSubItem ) != L"No"; if ( dvd ) { setListViewItemText( list_hwnd, temp->iItem, temp->iSubItem, L"No" ); } else { setListViewItemText( list_hwnd, temp->iItem, temp->iSubItem, L"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", L"Progress", 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 ); INITCOMMONCONTROLSEX icex; // Structure for control initialization. icex.dwICC = ICC_LISTVIEW_CLASSES; InitCommonControlsEx( &icex ); list_hwnd = createListView( 5, 5, database_width( window_width ), database_height( window_height ), ID_LISTVIEW, window, hFont ); addColumnToListView( list_hwnd, L"Show", 90, SHOW_COLUMN ); addColumnToListView( list_hwnd, L"Path", 180, PATH_COLUMN ); addColumnToListView( list_hwnd, L"Language", 70, LANG_COLUMN ); addColumnToListView( list_hwnd, L"DVD", 40, DVD_COLUMN ); // create hidden columns addColumnToListView( list_hwnd, L"ID", 0, ID_COLUMN ); addColumnToListView( list_hwnd, L"LangID", 0, LANG_ID_COLUMN ); addColumnToListView( list_hwnd, L"TVID", 0, TVID_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" ? L"Yes" : L"No" ); addItemToListView( list_hwnd, row, ID_COLUMN, x[L"ID"].c_str() ); addItemToListView( list_hwnd, row, TVID_COLUMN, x[L"TVID"].c_str() ); // lang_id[0] will be index of the language wchar_t lang_id[2]; lang_id[1] = '\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[0] = i; addItemToListView( list_hwnd, row, LANG_ID_COLUMN, lang_id ); } } row++; } cancel_button = createButton( L"Cancel", cancel_x( window_width ), cancel_y( window_height ), 80, 25, ID_CANCEL_BUTTON, window, hFont ); ok_button = createButton( L"OK", ok_x( window_width ), ok_y( window_height ), 80, 25, ID_OK_BUTTON, window, hFont ); save_button = createButton( L"Save", save_x( window_width ), save_y( window_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: { wchar_t lang_id[2]; lang_id[1] = '\0'; lang_id[0] = getComboCurSel( dw->lang_combo ); setListViewItemText( dw->list_hwnd, dw->cur_row, LANG_COLUMN, dw->langs[lang_id[0]].second.c_str() ); setListViewItemText( dw->list_hwnd, dw->cur_row, LANG_ID_COLUMN, lang_id ); } break; } break; } break; case WM_SIZE: { 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, ( L"Directory '" + path + L"' doesn't exist" ).c_str(), L"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::stoi( getItemText( list_hwnd, row, ID_COLUMN ) ); auto show = getItemText( list_hwnd, row, SHOW_COLUMN ); auto path = getItemText( list_hwnd, row, PATH_COLUMN ); auto lang = langs[getItemText( list_hwnd, row, LANG_ID_COLUMN )[0]].first; auto show_id = getItemText( list_hwnd, row, TVID_COLUMN ); bool dvd = getItemText( list_hwnd, row, DVD_COLUMN ) == L"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 = getItemText( list_hwnd, temp->iItem, LANG_ID_COLUMN ); auto show = getItemText( list_hwnd, temp->iItem, SHOW_COLUMN ); SearchWindow sw( hInst, langs, lang_id[0], 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() ); setListViewItemText( list_hwnd, temp->iItem, TVID_COLUMN, sw.getShowID().c_str() ); setListViewItemText( list_hwnd, temp->iItem, LANG_COLUMN, langs[sw.getLangID()].second.c_str() ); wchar_t langid[2]; langid[1] = '\0'; langid[0] = sw.getLangID(); setListViewItemText( list_hwnd, temp->iItem, LANG_ID_COLUMN, langid ); } } 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, item_rect.top, item_rect.right - item_rect.left, window_height, NULL ); ShowWindow( lang_combo, SW_SHOW ); SetFocus( lang_combo ); auto id = getItemText( list_hwnd, temp->iItem, LANG_ID_COLUMN ); SendMessage( lang_combo, CB_SETCURSEL, id[0], NULL ); } break; case DVD_COLUMN: toggleDVD( temp, list_hwnd ); break; } changed( temp->iItem ); } break; } }