Taupie 0.20.5
Tiny Analyser
Chargement...
Recherche...
Aucune correspondance
TaupieGUI.c
Aller à la documentation de ce fichier.
1
9
10
11
12
13#include <sys/stat.h>
14#include <stdio.h>
15#include <locale.h>
16#include <ctype.h>
17#include <time.h>
18#include <math.h>
19#include <stdint.h>
20#include <wchar.h>
21
22#include <_mingw.h>
23#include <ole2.h>
24#include <windows.h>
25#include <winreg.h>
26#include <windowsx.h>
27#include <uxtheme.h>
28#include <shlobj.h>
29#include <commctrl.h>
30
31#include "../_TkT2/Defines.h"
32
33#include "../_TkT2/EasyErrors.h"
34#include "../_TkT2/EasyWin32.h"
35#include "../_TkT2/EasyFiles.h"
36#include "../_TkT2/FormatNumber.h"
37#include "../_TkT2/ProgressBar.h"
38#include "../_TkT2/ReadArchive.h"
39#include "../_TkT2/EasyDecode.h"
40#include "../_TkT2/EasyListView.h"
41#include "../_TkT2/EasyAbout.h"
42#include "../_TkT2/EasyDPI.h"
43#include "../_TkT2/EasyCSV.h"
44#include "../_TkT2/ReadFile.h"
45#include "../_TkT2/EasyString.h"
46
47#include "../_TkT2/ManageSQLite.h"
48#include "../_TkT2/ManageSQLite_Win32.h"
49
50#include "locales.h"
51#include "TaupieGUI.h"
52
53#include "extra.h"
54
55#include "resource.h"
56
57
58
59
60static HWND hMainDataView;
61static HWND hMainProjectTree;
62static HWND hMainStatusBar;
63
64static HWND hMainQueryError;
65static HWND hMainQueryEdit;
67
68static RECT rProjectTree;
69static RECT rDataView;
70
71#define SCROLL_TIMER_ID 1
72#define SCROLL_IDLE_MS 100
73static UINT_PTR scrollingTimer;
74
75#define NBROWS_TIMER_ID 2
76#define NBROWS_IDLE_MS 1000
77//static UINT_PTR countingTimer;
78
79static wchar_t *currentCommand;
80static wchar_t *originalCommand;
81
82static sqlite3 *currentDataBase;
83static wchar_t *currentDataBaseName;
84static wchar_t *currentSelectedTable;
85
86static HTREEITEM hActualSelectedTableItem;
87static LVHITTESTINFO selectedCellInfo;
88
89static HFONT mainVariableFont;
90static HFONT mainFixedFont;
91static HFONT mainFixedBlackFont;
92
93static int xTableView;
94static int xQueryEdit;
95
96static wchar_t *sqlError;
97
98static int freezeDataView;
99
100#define DATAVIEW_MAXROWS 100000000
101static int dataViewPage;
102static int64_t dataViewNbRows;
103
104
113void SetVisibility(int project, int table, int query __attribute__((unused)))
114{
115 if (project == HIDE)
116 {
117 ShowWindow(hMainProjectTree, SW_HIDE);
118 }
119 else if (project == SHOW)
120 {
121 ShowWindow(hMainProjectTree, SW_SHOW);
122 }
123
124 if (table == HIDE)
125 {
126 ShowWindow(hMainDataView, SW_HIDE);
127 }
128 else if (table == SHOW)
129 {
130 ShowWindow(hMainDataView, SW_SHOW);
131 //AutosizeColumns(hMainDataView, 0);
132 }
133
134 if (query == HIDE)
135 {
136 ShowWindow(hMainQueryError, SW_HIDE);
137 ShowWindow(hMainQueryEdit, SW_HIDE);
138 ShowWindow(hMainQueryExecute, SW_HIDE);
139 }
140 else if (query == SHOW)
141 {
142 ShowWindow(hMainQueryError, SW_SHOW);
143 ShowWindow(hMainQueryEdit, SW_SHOW);
144 ShowWindow(hMainQueryExecute, SW_SHOW);
145 }
146}
147
148
158int ProjectTree_SelectTableByName(const wchar_t *tableName)
159{
160 int result = -1;
161
162 if (tableName && tableName[0])
163 {
164 HTREEITEM hitem = TreeView_GetRoot(hMainProjectTree);
165
166 hitem = TreeView_GetChild(hMainProjectTree, hitem);
167
168 TV_ITEM item;
169
170 if (hitem)
171 {
172 wchar_t text[0x100];
173
174 do
175 {
176 while (1)
177 {
178 item.mask = TVIF_PARAM | TVIF_TEXT;
179 item.lParam = 0;
180 item.pszText = text;
181 item.cchTextMax = _countof(text);
182 item.hItem = hitem;
183
184 if (TreeView_GetItem(hMainProjectTree, &item) == TRUE)
185 {
186 if (item.lParam == PROJECTTREE_TABLELIST)
187 {
188 hitem = TreeView_GetChild(hMainProjectTree, hitem);
189 continue;
190 }
191 }
192
193 break;
194 }
195
196 if (!wcsicmp(tableName, text))
197 {
198 TreeView_SelectItem(hMainProjectTree, hitem);
199 result = 0;
200 break;
201 }
202 }
203 while ((hitem = TreeView_GetNextSibling(hMainProjectTree, hitem)));
204 }
205 }
206
207 return result;
208}
209
210
219int64_t ProjectTree_Update(HWND hwnd)
220{
221 int64_t nbItems = -1;
222
224 {
225 int result = SQLITE_OK;
226
227 if (!currentDataBase)
228 {
229 result = OpenSQLiteDB(&currentDataBase, currentDataBaseName, FALSE);
230 }
231
232 if (result == SQLITE_OK)
233 {
234 const wchar_t *name = GetStrictFileName(currentDataBaseName);
235 nbItems = FillATreeView_Win32(hwnd, &hMainProjectTree, name, currentDataBase);
236
238 {
239 //ApplyDarkMode(hMainProjectTree, L"DarkMode_Explorer");
240
241 SetWindowRedraw(hMainProjectTree, FALSE);
242
243 SetWindowPos(hMainProjectTree,
244 HWND_TOP,
245 rProjectTree.left,
246 rProjectTree.top,
247 rProjectTree.right - rProjectTree.left,
248 rProjectTree.bottom - rProjectTree.top,
249 0);
250
252
253 SetWindowRedraw(hMainProjectTree, TRUE);
254
256 }
257 }
258 }
259
260 return nbItems;
261}
262
263
271void StatusBar_Update(const wchar_t *tableName, int64_t records)
272{
273 if (tableName)
274 {
275 wchar_t buffer[MAX_BUF] = L"";
276 swprintf(buffer, _countof(buffer), L"%ls%ls%ls",
277 tableName, tableName[0] ? L" : " : L"",
278 formater_nombre(0, records, L' ', 0, 0));
279
280 SetWindowText(hMainStatusBar, buffer);
281 }
282 else
283 {
284 SetWindowText(hMainStatusBar, L"");
285 }
286}
287
288
293void Clean(void)
294{
295 DeleteLocalFile(SOFT_NAMEW, L"temp\\" LISTE_FICHIERS);
296 DeleteLocalFile(SOFT_NAMEW, L"temp\\old" LISTE_FICHIERS);
297
298 DeleteLocalFile(SOFT_NAMEW, ARCHIVE_INFO);
299 DeleteLocalDirectory(SOFT_NAMEW, ARCHIVE_FOLDER);
300
301 DeleteLocalDirectory(SOFT_NAMEW, L"temp");
302}
303
304
313void Main_OnPaint(HWND hwnd)
314{
315 PAINTSTRUCT ps;
316 HDC hdc = BeginPaint(hwnd, &ps);
317
318 RECT rect = {0};
319
320 if (!hMainProjectTree)
321 {
322 GetClientRect(hwnd, &rect);
323 }
324 else if (!hMainDataView)
325 {
326 rect = rDataView;
327 }
328
329 RECT rPaint;
330
331 if (IntersectRect(&rPaint, &rect, &ps.rcPaint))
332 {
333 FillRect(hdc, &rPaint, GetSysColorBrush(COLOR_BTNFACE));
334 }
335
336 EndPaint(hwnd, &ps);
337}
338
339
349void Main_OnSize(HWND hwnd,
350 UINT state __attribute__((unused)),
351 UINT x,
352 UINT y)
353{
354 UINT width = 120;
355
356 RECT rectSB;
357 GetClientRect(hMainStatusBar, &rectSB);
358 SetWindowPos(hMainStatusBar, HWND_TOP, 0, 0, 0, 0, 0);
359
360 HTREEITEM hitem = TreeView_GetFirstVisible(hMainProjectTree);
361
362 if (hitem)
363 {
364 do
365 {
366 RECT rect;
367
368 if (TreeView_GetItemRect(hMainProjectTree, hitem, &rect, TRUE) == TRUE)
369 {
370 if ((UINT)rect.right > width)
371 {
372 width = rect.right;
373 }
374 }
375 }
376 while ((hitem = TreeView_GetNextVisible(hMainProjectTree, hitem)));
377 }
378
379 width += 32;
380
381 int bottom = y - rectSB.bottom;
382
383 if (width > (x / 3))
384 {
385 width = x / 3;
386 }
387
388 rProjectTree.left = 0;
389 rProjectTree.top = 0;
390 rProjectTree.right = width;
391 rProjectTree.bottom = bottom * 9 / 10;
392
393 SetWindowPos(hMainProjectTree,
394 HWND_TOP,
395 0,
396 0,
397 width,
398 bottom * 9 / 10,
399 0);
400
401 rDataView.left = width;
402 rDataView.top = 0;
403 rDataView.right = x;
404 rDataView.bottom = bottom * 9 / 10;
405
406 SetWindowPos(hMainDataView,
407 HWND_TOP,
408 width,
409 0,
410 x - width,
411 bottom * 9 / 10,
412 0);
413
414 int queryHeight = bottom * 1 / 10;
415
416 SetWindowPos(hMainQueryError,
417 HWND_TOP,
418 0,
419 bottom - queryHeight,
420 x / 3,
421 queryHeight,
422 0);
423
424 SetWindowPos(hMainQueryEdit,
425 HWND_TOP,
426 x / 3,
427 bottom - queryHeight,
428 (x * 2 / 3) - BUTTON_SIZE,
429 queryHeight,
430 0);
431
432 InvalidateRect(hwnd, NULL, TRUE);
433 UpdateWindow(hwnd);
434}
435
436
444void QueryBar_Update(const wchar_t *errorMsg, const wchar_t *request)
445{
446 if (errorMsg)
447 {
448 SetWindowText(hMainQueryError, errorMsg);
449 }
450
451 if (request)
452 {
453 SetWindowText(hMainQueryEdit, request);
454 }
455}
456
457
469LRESULT CALLBACK QueryExecute_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
470 UINT_PTR uIdSubclass, DWORD_PTR dwRefData __attribute__((unused)))
471{
472 static HFONT hFont;
473
474 switch (uMsg)
475 {
476 case WM_SHOWWINDOW :
477 {
478 RecreateDialogFont(hwnd, &hFont, VARIABLE_FONT, SIZE_OF_FONT * 2);
479 ApplyFontToChildren(hwnd, hFont);
480
481 break;
482 }
483
484 case WM_NCDESTROY :
485 {
486 if (hFont)
487 {
488 DeleteObject(hFont);
489 }
490
491 RemoveWindowSubclass(hwnd, QueryExecute_Procedure, uIdSubclass);
492
493 break;
494 }
495
496 default :
497 {
498 break;
499 }
500 }
501
502 return DefSubclassProc(hwnd, uMsg, wParam, lParam);
503}
504
505
517LRESULT CALLBACK QueryEdit_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
518 UINT_PTR uIdSubclass, DWORD_PTR dwRefData __attribute__((unused)))
519{
520 switch (uMsg)
521 {
522 case WM_WINDOWPOSCHANGING :
523 {
524 RestartScrollingTimer(GetParent(hwnd));
525
526 WINDOWPOS *wp = (LPWINDOWPOS) lParam;
527
528 if (!(wp->flags & (SWP_NOSIZE/* | SWP_NOMOVE*/)))
529 {
530 RECT r, rSB;
531 GetClientRect(GetParent(hwnd), &r);
532 GetClientRect(hMainStatusBar, &rSB);
533
534 int bottom = r.bottom - rSB.bottom;
535
536 if ((wp->x + wp->cx) != (r.right - BUTTON_SIZE))
537 {
538 wp->cx = (r.right - BUTTON_SIZE) - wp->x;
539 }
540
541 if (wp->y > (bottom - BUTTON_SIZE))
542 {
543 wp->y = bottom - BUTTON_SIZE;
544 }
545
546 wp->cy = bottom - wp->y;
547
548 xQueryEdit = wp->x;
549 SetWindowPos(hMainQueryError, 0, 0, wp->y, wp->x, wp->cy, SWP_NOSENDCHANGING);
550 SetWindowPos(hMainQueryExecute, 0, (r.right - BUTTON_SIZE), wp->y, BUTTON_SIZE, wp->cy, SWP_NOSENDCHANGING);
551
552 SetWindowPos(hMainDataView, 0, xTableView, 0, r.right - xTableView, bottom - wp->cy, SWP_NOSENDCHANGING);
553
554 rDataView.left = xTableView;
555 rDataView.top = 0;
556 rDataView.right = r.right;
557 rDataView.bottom = bottom - wp->cy;
558
559 SetWindowPos(hMainProjectTree, 0, 0, 0, xTableView, bottom - wp->cy, SWP_NOSENDCHANGING);
560
561 rProjectTree.left = 0;
562 rProjectTree.top = 0;
563 rProjectTree.right = xTableView;
564 rProjectTree.bottom = bottom - wp->cy;
565
566 return 0;
567 }
568
569 break;
570 }
571
572 case WM_NCDESTROY:
573 {
574 RemoveWindowSubclass(hwnd, QueryEdit_Procedure, uIdSubclass);
575 break;
576 }
577
578 default :
579 {
580 break;
581 }
582 }
583
584 return DefSubclassProc(hwnd, uMsg, wParam, lParam);
585}
586
587
599LRESULT CALLBACK QueryError_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
600 UINT_PTR uIdSubclass, DWORD_PTR dwRefData __attribute__((unused)))
601{
602 switch (uMsg)
603 {
604 case WM_WINDOWPOSCHANGING :
605 {
606 RestartScrollingTimer(GetParent(hwnd));
607
608 WINDOWPOS *wp = (LPWINDOWPOS) lParam;
609
610 if (!(wp->flags & (SWP_NOSIZE/* | SWP_NOMOVE*/)))
611 {
612 RECT r, rSB;
613 GetClientRect(GetParent(hwnd), &r);
614 GetClientRect(hMainStatusBar, &rSB);
615
616 int bottom = r.bottom - rSB.bottom;
617
618 //RECT rT;
619 //GetWindowRect(hMainDataView, &rT);
620
621 if (wp->x > 0)
622 {
623 wp->cx += wp->x;
624 wp->x = 0;
625 }
626
627 if (wp->cx > (r.right - BUTTON_SIZE))
628 {
629 wp->cx = r.right - BUTTON_SIZE;
630 }
631
632 if (wp->y > (bottom - BUTTON_SIZE))
633 {
634 wp->y = bottom - BUTTON_SIZE;
635 }
636
637 wp->cy = bottom - wp->y;
638
639 xQueryEdit = wp->cx;
640 SetWindowPos(hMainQueryEdit, 0, wp->cx, wp->y, (r.right - BUTTON_SIZE) - wp->cx, wp->cy, SWP_NOSENDCHANGING);
641 SetWindowPos(hMainQueryExecute, 0, (r.right - BUTTON_SIZE), wp->y, BUTTON_SIZE, wp->cy, SWP_NOSENDCHANGING);
642
643 SetWindowPos(hMainDataView, 0, xTableView, 0, r.right - xTableView, bottom - wp->cy, SWP_NOSENDCHANGING);
644
645 rDataView.left = xTableView;
646 rDataView.top = 0;
647 rDataView.right = r.right;
648 rDataView.bottom = bottom - wp->cy;
649
650 SetWindowPos(hMainProjectTree, 0, 0, 0, xTableView, bottom - wp->cy, SWP_NOSENDCHANGING);
651
652 rProjectTree.left = 0;
653 rProjectTree.top = 0;
654 rProjectTree.right = xTableView;
655 rProjectTree.bottom = bottom - wp->cy;
656
657 return 0;
658 }
659
660 break;
661 }
662
663 case WM_NCDESTROY:
664 {
665 RemoveWindowSubclass(hwnd, QueryError_Procedure, uIdSubclass);
666 break;
667 }
668
669 default :
670 {
671 break;
672 }
673 }
674
675 return DefSubclassProc(hwnd, uMsg, wParam, lParam);
676}
677
678
685void QueryBar_Create(HWND hwnd)
686{
687 hMainQueryEdit = CreateWindowEx(0, L"EDIT", TEXT(EMPTY_STRING),
688 WS_CHILD | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | WS_THICKFRAME,
689 0, 0, 0, 0, hwnd, 0, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
690
692
693 //ApplyDarkMode(hMainQueryEdit, L"DarkMode_Explorer");
694
695
696 hMainQueryExecute = CreateWindowEx(0, L"BUTTON", L"\u26A1",//L"\U0001F3B2",//L"\u2935",//L"\u2713",//L"\u23F5",//
697 WS_CHILD | WS_BORDER | BS_PUSHBUTTON | BS_TEXT,
698 0, 0, 0, 0, hwnd, (HMENU)IDM_SQL_QUERY, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
699
700 SetWindowSubclass(hMainQueryExecute, QueryExecute_Procedure, SUBCLASS_QUERYEXECUTE_ID, (DWORD_PTR)NULL);
701
702 ApplyDarkMode(hMainQueryExecute, L"DarkMode_Explorer");
703
704
705 hMainQueryError = CreateWindowEx(0, L"EDIT", TEXT(EMPTY_STRING),
706 WS_CHILD | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY | WS_THICKFRAME,
707 0, 0, 0, 0, hwnd, 0, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
708
710
711 //ApplyDarkMode(hMainQueryError, L"DarkMode_Explorer");
712}
713
714
726BOOL Main_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
727{
728 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT);
729
730 setlocale(LC_ALL, "French_France.1252");
731
732 //SetCursor(LoadCursor(NULL, IDC_ARROW));
733
734 srand(time(0));
735
736 // application de l'icone
737
738 SetClassLongPtr(hwnd, GCLP_HICON, (LONG_PTR)LoadIcon((HINSTANCE)GetModuleHandle(NULL), L"mainIcon"));
739 SendMessage(hwnd, WM_SETICON, (WPARAM)LoadIcon((HINSTANCE)GetModuleHandle(NULL), L"mainIcon"), MAKELPARAM(FALSE, 0));
740
741 // création de la barre de statut
742
743 hMainStatusBar = CreateWindowEx(0, STATUSCLASSNAME, TEXT(EMPTY_STRING),
744 WS_CHILD | WS_VISIBLE,
745 0, 0, 0, 0, hwnd, 0, (HINSTANCE)GetWindowInstance(hwnd), NULL);
746
747 StatusBar_Update(NULL, 0);
748
749 // création des répertoires locaux
750
751 wchar_t *appDir = GetLocalFile(SOFT_NAMEW, NULL);
752
753 if (appDir)
754 {
755 _wmkdir(appDir);
756 free(appDir);
757 }
758
759 wchar_t *tmpDir = GetLocalFile(SOFT_NAMEW, L"temp");
760
761 if (tmpDir)
762 {
763 _wmkdir(tmpDir);
764 free(tmpDir);
765 }
766
767 CreateInitFile(SOFT_NAMEW);
768
769 QueryBar_Create(hwnd);
770
771
772 HMENU hMenu = GetMenu(hwnd);
773 HMENU hSubMenu = GetSubMenuByID(hMenu, IDP_HELP);
774 SetSubMenuIcon(hSubMenu, IDM_ABOUT, L"mainIcon");
775
776 DrawMenuBar(hwnd);
777
778
779 ExtraInit(hwnd, lpCreateStruct);
780
781
782 RecreateDialogFont(hwnd, &mainVariableFont, VARIABLE_FONT, SIZE_OF_FONT);
783
784 // affiche le projet courant éventuel (s'il n'a pas été fermé lors de la précédente fermeture de l'application).
785 PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_INIT, 0), (LPARAM) NULL);
786
787 return TRUE;
788}
789
790
797void Main_OnClose(HWND hwnd)
798{
799 //if (MessageBoxA(hwnd, "\n Voulez-vous quitter ? \n", "Arrêt", MB_YESNO | MB_ICONQUESTION) == IDYES)
800 {
801 ShowWindow(hwnd, SW_HIDE);
802
803 CloseSQLiteDB(&currentDataBase);
804
805 Clean();
806 PostQuitMessage(0);
807
809 {
810 DeleteObject(mainVariableFont);
811 mainVariableFont = NULL;
812 }
813
814 if (mainFixedFont)
815 {
816 DeleteObject(mainFixedFont);
817 mainFixedFont = NULL;
818 }
819
821 {
822 DeleteObject(mainFixedBlackFont);
823 mainFixedBlackFont = NULL;
824 }
825 }
826}
827
828
834{
835 int width = 120;
836
837 HTREEITEM hitem = TreeView_GetFirstVisible(hMainProjectTree);
838 if (hitem)
839 {
840 do
841 {
842 RECT rect;
843
844 if (TreeView_GetItemRect(hMainProjectTree, hitem, &rect, TRUE) == TRUE)
845 {
846 if (rect.right > width)
847 {
848 width = rect.right;
849 }
850 }
851 }
852 while ((hitem = TreeView_GetNextVisible(hMainProjectTree, hitem)));
853 }
854
855 width += 32;
856
857 RECT r;
858 GetWindowRect(hMainProjectTree, &r);
859
860 SetWindowPos(hMainProjectTree, HWND_TOP, 0, 0, width, r.bottom - r.top, SWP_DRAWFRAME);
861}
862
863
870void ProjectTree_Close(HWND hwnd)
871{
872 SaveOption(SOFT_NAMEW, SOFT_NAMEW, OPTION_CURRENTPROJECT, NULL);
873
875 StatusBar_Update(NULL, 0);
876
877 dataViewNbRows = 0;
878
879 CloseSQLiteDB(&currentDataBase);
880
881 if (hMainDataView)
882 {
883 DestroyWindow(hMainDataView);
884 hMainDataView = NULL;
885 }
886
888 {
889 DestroyWindow(hMainProjectTree);
890 hMainProjectTree = NULL;
891 }
892
893 HMENU hMenu = GetSubMenuByID(GetMenu(hwnd), IDM_PROJECT);
894 if (hMenu)
895 {
896 EnableMenuItem(hMenu, IDM_PROJECT_UPDATE, MF_GRAYED);
897 EnableMenuItem(hMenu, IDM_PROJECT_OPTIMIZE, MF_GRAYED);
898 EnableMenuItem(hMenu, IDM_PROJECT_LOG_IMPORT, MF_GRAYED);
899 EnableMenuItem(hMenu, IDM_PROJECT_LOG_COMMAND, MF_GRAYED);
900 EnableMenuItem(hMenu, IDM_PROJECT_CLOSE, MF_GRAYED);
901 }
902
903 EnableMenuItem(GetMenu(hwnd), IDM_DATA, MF_GRAYED);
904 EnableMenuItem(GetMenu(hwnd), IDM_SQL, MF_GRAYED);
905
906 DrawMenuBar(hwnd);
907
908 InvalidateRect(hwnd, NULL, TRUE);
909 UpdateWindow(hwnd);
910}
911
912
920void ProjectTree_Open(HWND hwnd, int option)
921{
922 // récupération du nom du dernier projet ouvert
923
924 wchar_t *projectName = calloc(FILENAMELENGTH_MAX, sizeof(wchar_t));
925
926 if (projectName)
927 {
928 LoadOption(SOFT_NAMEW, SOFT_NAMEW, OPTION_CURRENTPROJECT, projectName, FILENAMELENGTH_MAX);
929
930 // sauf initialisation, demande à l'utilisateur la base à utiliser
931
932 BOOL testOK = FALSE;
933
934 if ((option == IDM_INIT) || (option == IDM_PROJECT_CONVERT))
935 {
936 testOK = TRUE;
937 }
938 else
939 {
940 wchar_t *newProjectName = (option == IDM_PROJECT_NEW)
941 ? FileOutChooserWithInit(TEXT(NEW_PROJECT), hwnd, TEXT(FILETYPE_PROJECT), projectName, FALSE)
942 : FileInChooserWithInit(TEXT(OPEN_PROJECT), hwnd, TEXT(FILETYPE_ANY) TEXT(FILETYPE_PROJECT), projectName);
943
944 // OK, si un nom de base valide est choisi, il est enregistré comme base courante.
945
946 if (newProjectName)
947 {
948 testOK = TRUE;
949
950 DataView_Close(hwnd);
951 QueryBar_Update(L"", L"");
952 ProjectTree_Close(hwnd);
953
954 SaveOption(SOFT_NAMEW, SOFT_NAMEW, OPTION_CURRENTPROJECT, newProjectName);
955 swprintf(projectName, FILENAMELENGTH_MAX, L"%ls", newProjectName);
956 free(newProjectName);
957 }
958 }
959
960 // si le projet courant est nouveau ou accessible en lecture/écriture, alors ouvre / crée le projet.
961
962 if (testOK)
963 {
964 dataViewNbRows = 0;
965
966 if ((option == IDM_PROJECT_NEW) || (!_waccess(projectName, R_OK | W_OK)))
967 {
968 int result = SQLITE_OK;
969
970 CloseSQLiteDB(&currentDataBase);
971 NullFree(currentDataBaseName);
972
973 result = OpenSQLiteDB(&currentDataBase, projectName, FALSE);
974
975 if (result == SQLITE_OK)
976 {
977 currentDataBaseName = projectName;
978 projectName = NULL;
979
980 if ((option == IDM_PROJECT_NEW) || (option == IDM_PROJECT_CONVERT))
981 {
982 CreateTableInDB(currentDataBase, APP_FILES,
983 TEXT(FIELD_TABLENAME) L" TEXT, "
984 TEXT(FIELD_IMPORTDATE) L" DATE, " TEXT(FIELD_IMPORTTIME) L" TIME, "
985 TEXT(FIELD_FILEPATH) L" TEXT, " TEXT(FIELD_FILENAME) L" TEXT, "
986 TEXT(FIELD_FILESIZE) L" INT, "
987 TEXT(FIELD_FILEDATE) L" DATE, " TEXT(FIELD_FILETIME) L" TIME"
988 );
989
990 CreateTableInDB(currentDataBase, APP_HISTORY,
991 TEXT(FIELD_RUNDATE) L" DATE, " TEXT(FIELD_RUNTIME) L" TIME, "
992 TEXT(FIELD_ACTION) L" TEXT, "
993 TEXT(FIELD_DOTCOMMAND) L" TEXT, "
994 TEXT(FIELD_SQL) L" TEXT, "
995 TEXT(FIELD_ERROR) L" TEXT"
996 );
997
998 if (option == IDM_PROJECT_NEW)
999 {
1000 int sizeDotCommand = wcslen(L".open --new ''") + wcslen(GetStrictFileName(currentDataBaseName)) + 1;
1001 wchar_t *dotCommand = calloc(sizeDotCommand, sizeof(wchar_t));
1002 if (dotCommand)
1003 {
1004 swprintf(dotCommand, sizeDotCommand, L".open --new \"%ls\"", GetStrictFileName(currentDataBaseName));
1005 RecordExecutedAction(TEXT(LOG_TEXTCREATEPROJECT), dotCommand, NULL, NULL);
1006 }
1007 }
1008 }
1009
1010 ProjectTree_Update(hwnd);
1012
1013 HMENU hMenu = GetSubMenuByID(GetMenu(hwnd), IDM_PROJECT);
1014 if (hMenu)
1015 {
1016 EnableMenuItem(hMenu, IDM_PROJECT_UPDATE, MF_ENABLED);
1017 EnableMenuItem(hMenu, IDM_PROJECT_OPTIMIZE, MF_ENABLED);
1018 EnableMenuItem(hMenu, IDM_PROJECT_LOG_IMPORT, MF_ENABLED);
1019 EnableMenuItem(hMenu, IDM_PROJECT_LOG_COMMAND, MF_ENABLED);
1020 EnableMenuItem(hMenu, IDM_PROJECT_CLOSE, MF_ENABLED);
1021 }
1022
1023 EnableMenuItem(GetMenu(hwnd), IDM_DATA, MF_ENABLED);
1024 EnableMenuItem(GetMenu(hwnd), IDM_SQL, MF_ENABLED);
1025
1026 DrawMenuBar(hwnd);
1027 }
1028 }
1029 else
1030 {
1031 ProjectTree_Close(hwnd);
1032 }
1033 }
1034
1035 if (projectName)
1036 {
1037 free(projectName);
1038 }
1039 }
1040}
1041
1042
1049void DataView_Close(HWND hwnd __attribute__((unused)))
1050{
1051 SetVisibility(0, HIDE, 0);
1052 StatusBar_Update(NULL, 0);
1053
1054 if (hMainDataView)
1055 {
1056 DestroyWindow(hMainDataView);
1057 hMainDataView = NULL;
1058 }
1059}
1060
1061
1071int64_t ExecuteSQLScript(HWND hwnd, const wchar_t *fileName)
1072{
1073 int64_t nbRows = -1;
1074
1075 wchar_t *command = NULL;
1076
1077 NullFree(originalCommand);
1078 NullFree(currentCommand);
1079
1080 HANDLE hProgressBar = StartProgressBar(L"Ex\351cution du script SQL", -1);
1081 nbRows = DataView_UpdateWithAFile(hwnd, &hMainDataView, &rDataView, &currentDataBase, &command, fileName);
1082 StopProgressBar(hProgressBar);
1083
1084 currentCommand = _wcsdup(command ? command : L"");
1085
1086 if (nbRows >= 0)
1087 {
1090
1091 SetWindowSubclass(hMainDataView, DataView_Procedure, SUBCLASS_TABLE_ID, 0);
1092
1094
1095 SetVisibility(0, SHOW, 0);
1096 StatusBar_Update((nbRows != INT32_MAX) ? L"" : NULL, nbRows);
1097 }
1098 else
1099 {
1102
1103 NullFree(currentCommand);
1104
1105 DataView_Close(hwnd);
1106 }
1107
1108 InvalidateRect(hwnd, NULL, TRUE);
1109 UpdateWindow(hwnd);
1110
1111 ShowWindow(hMainDataView, SW_SHOWNA);
1112
1113 return nbRows;
1114}
1115
1116
1125int64_t ExecuteCustomSQLQuery(HWND hwnd)
1126{
1127 int64_t nbRows = -1;
1128
1129 int length = GetWindowTextLength(hMainQueryEdit);
1130 wchar_t *command = calloc(length + 1, sizeof(wchar_t));
1131
1132 if (command)
1133 {
1134 GetWindowText(hMainQueryEdit, command, length + 1);
1135
1136 NullFree(originalCommand);
1137 NullFree(currentCommand);
1138 currentCommand = _wcsdup(command);
1139
1140 HANDLE hProgressBar = StartProgressBar(L"Ex\351cution de la requ\350te", -1);
1141 wchar_t *firstLetters = AllTrim(command, L" \t\r\n", TRUE, FALSE, FALSE);
1142 int useTmp = wcsnicmp(firstLetters, L"SELECT", 6) ? USE_NO_TEMP : USE_TEMP_TABLE;
1143 nbRows = DataView_Update(hwnd, &hMainDataView, &rDataView, &currentDataBase, command, useTmp);
1144
1145 StopProgressBar(hProgressBar);
1146
1147 if (nbRows >= 0)
1148 {
1151
1152 SetWindowSubclass(hMainDataView, DataView_Procedure, SUBCLASS_TABLE_ID, 0);
1153
1155
1156 SetVisibility(0, SHOW, 0);
1157 StatusBar_Update((nbRows != INT32_MAX) ? L"" : NULL, nbRows);
1158 }
1159 else
1160 {
1163
1164 NullFree(currentCommand);
1165
1166 DataView_Close(hwnd);
1167 }
1168
1169 InvalidateRect(hwnd, NULL, TRUE);
1170 UpdateWindow(hwnd);
1171
1172 ShowWindow(hMainDataView, SW_SHOWNA);
1173
1174 free(command);
1175 }
1176
1177 return nbRows;
1178}
1179
1180
1189int64_t CreateCSVFromView(HWND hwnd)
1190{
1191 int64_t nbRows = -1;
1192
1193 static exportation_table_type options;
1194
1195 int okExport = DialogBoxParam((HINSTANCE)GetWindowInstance(hwnd), L"DialogExport", hwnd,
1196 (DLGPROC)(void *)ProcedureExport, (LPARAM) &options);
1197
1198 SetForegroundWindow(hwnd);
1199
1200 if (okExport)
1201 {
1202 wchar_t *fileName = FileOutChooserWithInit(L"Exporter vers un fichier CSV ...", hwnd,
1203 L"Fichier CSV (*.csv)\0*.csv\0", currentSelectedTable, TRUE);
1204
1205 if (fileName)
1206 {
1207 FILE *fileOut = _wfopen(fileName, L"wt");
1208
1209 if (fileOut)
1210 {
1211 char *separator = (char *)&options.separateur;
1212 char *quote = (char *)&options.delimiteur;
1213
1214 HANDLE hProgressBar = StartProgressBar(L"Enregistrement des donn\351es", -1);
1215 ExportDataToCSV(currentDataBase, currentCommand, separator, quote, fileOut);
1216 StopProgressBar(hProgressBar);
1217
1218 fclose(fileOut);
1219 }
1220
1221 free(fileName);
1222 }
1223 }
1224
1225 return nbRows;
1226}
1227
1228
1239int RecordImportedFile(const wchar_t *tableName, const wchar_t *fileName, int pathLevel)
1240{
1241 int result = -1;
1242
1243 if (tableName && tableName[0] && fileName && fileName[0])
1244 {
1245 // Ouvre le fichier
1246
1247 HANDLE hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
1248
1249 if (hFile != INVALID_HANDLE_VALUE)
1250 {
1251 // Obtient les caractéristiques du fichier
1252
1253 BY_HANDLE_FILE_INFORMATION fileInfo;
1254
1255 if (GetFileInformationByHandle(hFile, &fileInfo))
1256 {
1257 // récupération du chemin sur le niveau ad hoc
1258
1259 wchar_t path[MAX_BUF] = L"";
1260 wchar_t *pathPtr = path;
1261
1262 if (pathLevel)
1263 {
1264 int level = abs(pathLevel);
1265
1266 swprintf(path, sizeof(path) / sizeof(path[0]), L"%ls", fileName);
1267 pathPtr = wcsrchr(path, L'\\');
1268 while (pathPtr && level)
1269 {
1270 level --;
1271 pathPtr[0] = L'\0';
1272 pathPtr = wcsrchr(path, L'\\');
1273 }
1274 }
1275
1276 // récupération de la date et heure actuelle
1277
1278 wchar_t nowDate[sizeof("YYYY-MM-DD")] = L"";
1279 wchar_t nowTime[sizeof("HH:MM:SS")] = L"";
1280
1281 time_t dateTime = time(NULL);
1282
1283 wcsftime(nowDate, sizeof(nowDate) / sizeof(wchar_t), L"%Y-%m-%d", localtime(&dateTime));
1284 wcsftime(nowTime, sizeof(nowTime) / sizeof(wchar_t), L"%H:%M:%S", localtime(&dateTime));
1285
1286 // récupération de la date et heure du fichier
1287
1288 SYSTEMTIME systemTime;
1289 FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &systemTime);
1290
1291 wchar_t *wRecord = calloc(MAX_BUF, sizeof(wchar_t));
1292
1293 if (wRecord)
1294 {
1295 swprintf(wRecord, MAX_BUF,
1296 L"INSERT INTO " APP_FILES L" VALUES ("
1297 L"'%ls',"
1298 L"'%ls'," L"'%ls',"
1299 L"'%ls'," L"'%ls',"
1300 L"%lld,"
1301 L"'%04d-%02d-%02d',"
1302 L"'%02d:%02d:%02d'"
1303 L")",
1304 tableName,
1305 nowDate, nowTime,
1306 pathPtr ? &pathPtr[1] : L"", GetFileName(fileName),
1307 fileInfo.nFileSizeLow + ((LONGLONG)fileInfo.nFileSizeHigh << 32),
1308 systemTime.wYear, systemTime.wMonth, systemTime.wDay,
1309 systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
1310
1311 // enregistre les informations
1312
1313 result = RequestInDB(currentDataBase, wRecord);
1314
1315 free(wRecord);
1316 }
1317 }
1318
1319
1320 // Ferme le fichier
1321
1322 CloseHandle(hFile);
1323 }
1324 }
1325
1326 return result;
1327}
1328
1329
1341int RecordExecutedAction(const wchar_t *action, const wchar_t *dotCommand, const wchar_t *query, const wchar_t *error)
1342{
1343 int result = -1;
1344
1345 if (action && action[0])
1346 {
1347 // récupération de la date et heure actuelle
1348
1349 wchar_t nowDate[sizeof("YYYY-MM-DD")] = L"";
1350 wchar_t nowTime[sizeof("HH:MM:SS")] = L"";
1351
1352 time_t dateTime = time(NULL);
1353
1354 wcsftime(nowDate, sizeof(nowDate) / sizeof(wchar_t), L"%Y-%m-%d", localtime(&dateTime));
1355 wcsftime(nowTime, sizeof(nowTime) / sizeof(wchar_t), L"%H:%M:%S", localtime(&dateTime));
1356
1357 wchar_t *wRecord = calloc(MAX_BUF, sizeof(wchar_t));
1358
1359 if (wRecord)
1360 {
1361 wchar_t *mAction = (wchar_t *)action;
1362 WReplaceInStringNoFree(&mAction, L"'", L"''");
1363
1364 wchar_t *mDotCommand = (wchar_t *)dotCommand;
1365 WReplaceInStringNoFree(&mDotCommand, L"'", L"''");
1366
1367 wchar_t *mQuery = (wchar_t *)query;
1368 WReplaceInStringNoFree(&mQuery, L"'", L"''");
1369
1370 wchar_t *mError = (wchar_t *)error;
1371 WReplaceInStringNoFree(&mError, L"'", L"''");
1372
1373 swprintf(wRecord, MAX_BUF,
1374 L"INSERT INTO " APP_HISTORY L" VALUES ("
1375 L"'%ls'," L"'%ls',"
1376 L"'%ls',"
1377 L"'%ls',"
1378 L"'%ls',"
1379 L"'%ls'"
1380 L")",
1381 nowDate, nowTime,
1382 mAction ? mAction : L"",
1383 mDotCommand ? mDotCommand : L"",
1384 mQuery ? mQuery : L"",
1385 mError ? mError : L"");
1386
1387 if (mAction != action)
1388 {
1389 free(mAction);
1390 }
1391
1392 if (mDotCommand != dotCommand)
1393 {
1394 free(mDotCommand);
1395 }
1396
1397 if (mQuery != query)
1398 {
1399 free(mQuery);
1400 }
1401
1402 if (mError != error)
1403 {
1404 free(mError);
1405 }
1406
1407 // enregistre les informations
1408
1409 result = RequestInDB(currentDataBase, wRecord);
1410
1411 free(wRecord);
1412 }
1413 }
1414
1415 return result;
1416}
1417
1418
1431int64_t CreateTableFromCSV(HWND hwnd)
1432{
1433 int64_t nbRows = -1;
1434
1435 wchar_t *fileName = FileInChooser(L"Importer des donn\351es CSV ...", hwnd,
1436 L"Fichier d\351limit\351 (*.csv;*.tsv;*.del;*.txt)\0*.csv;*.tsv;*.del;*.txt\0"
1437 L"Tout fichier (*.*)\0*.*\0");
1438
1439 if (fileName)
1440 {
1441 HANDLE hPB = StartProgressBar(L"Test du fichier ...", -1);
1442 int type = typefil(fileName, FIL_TAB_DEL);
1443 StopProgressBar(hPB);
1444
1445 if (type & FIL_ERR)
1446 {
1447 MessageBox(hwnd, L"\n Probl\350me de fichier ! \n", L"Erreur !", MB_ICONINFORMATION);
1448 }
1449
1450
1451 else if (!(type & FIL_TAB))
1452 {
1453 MessageBox(hwnd,
1454 L"\n Ce fichier n'est pas reconnu comme une table par " SOFT_NAMEW L" ! \n",
1455 L"Erreur !",
1456 MB_ICONINFORMATION);
1457 }
1458
1459 else
1460 {
1461 BOOL resultat = 1;
1462
1463 if (type & FIL_NON & FIL_TAB_DEL)
1464 {
1465 if (!DialogBoxParam((HINSTANCE)GetWindowInstance(hwnd),
1466 L"DialogDELTableStructure", hwnd,
1467 (DLGPROC)(void *)ProcedureDELTableStructure,
1468 (LPARAM)fileName))
1469 {
1470 resultat = 0;
1471 }
1472
1473 SetForegroundWindow(hwnd);
1474 }
1475
1476
1477 if (resultat)
1478 {
1479 TAB *table = fileopen_TAB(fileName, type);
1480
1481 if (table)
1482 {
1483 hPB = StartProgressBar(L"Import des donn\351es CSV ...", -1);
1484 wchar_t *tableName = _wcsdup(GetStrictFileName(fileName));
1485
1486 if (tableName)
1487 {
1488 wchar_t *query = calloc(MAX_BUF, sizeof(wchar_t));
1489
1490 if (query)
1491 {
1492 // création de la table avec les champs identifiés et typés (option texte à prévoir ?)
1493
1494 for (UINT column = 0; column < table->nb_champs; ++ column)
1495 {
1496 const wchar_t *fieldType = DATA_TEXT;
1497
1498 if (table->champ[column].type == L'D')
1499 {
1500 fieldType = DATA_DATETIME;
1501 }
1502
1503 if (table->champ[column].type == L'N')
1504 {
1505 if (table->champ[column].decimales == 0)
1506 {
1507 fieldType = DATA_INTEGER;
1508 }
1509 else
1510 {
1511 fieldType = DATA_REAL;
1512 }
1513 }
1514
1515 wchar_t *fieldName = _wcsdup(table->champ[column].nom);
1516
1517 if (fieldName)
1518 {
1519 WReplaceInString(&fieldName, L"'", L"''");
1520
1521 swprintf(query, MAX_BUF, L"%ls TABLE \"%ls\" %ls \"%ls\" %ls %ls",
1522 column ? L"ALTER" : L"CREATE",
1523 tableName,
1524 column ? L"ADD" : L"(",
1525 fieldName,
1526 fieldType,
1527 column ? L"" : L")"
1528 );
1529
1530 RequestInDB(currentDataBase, query);
1531
1532 free(fieldName);
1533 }
1534 }
1535
1536 // ajoute les enregistrements
1537
1538 nbRows = 0;
1539
1540 while (fileread_TAB(1, table) == 1)
1541 {
1542 if (!(nbRows % 1000))
1543 {
1544 if (nbRows)
1545 {
1546 EndTransactionInDB(currentDataBase);
1547 }
1548
1549 StartTransactionInDB(currentDataBase);
1550 }
1551
1552 if (ProgressBarStopped())
1553 {
1554 break;
1555 }
1556
1557 nbRows ++;
1558
1559 wchar_t *ptr = table->reg;
1560
1561 AppendNewLine(currentDataBase, tableName, nbRows);
1562
1563 for (UINT column = 0; column < table->nb_champs; ++ column)
1564 {
1565 const wchar_t *fieldName = table->champ[column].nom;
1566
1567 wchar_t *value = wcsdup(&ptr[table->champ[column].pos]);
1568
1569 if (value)
1570 {
1571 if (table->champ[column].type == L'N')
1572 {
1573 Replace(value, L',', L'.');
1574 }
1575
1576 InsertValue(currentDataBase, tableName, nbRows, fieldName, value);
1577
1578 free(value);
1579 }
1580 }
1581
1582 SetProgressBarTextNum(L"Lignes import\351es", &nbRows);
1583 }
1584
1585 if (nbRows)
1586 {
1587 EndTransactionInDB(currentDataBase);
1588 }
1589
1590 free(query);
1591 }
1592
1594 {
1596 }
1597
1598 currentSelectedTable = tableName;
1599 RecordImportedFile(tableName, fileName, 0);
1600 }
1601
1602 fileclose_TAB(table);
1603
1604 SetProgressBarTextNumText(L"Lignes import\351es", &nbRows, L"Optimisation de la base");
1605 RequestInDB(currentDataBase, L"ANALYSE;");
1606
1607 StopProgressBar(hPB);
1608 }
1609 }
1610 }
1611
1612 free(fileName);
1613 }
1614
1615 SetForegroundWindow(hwnd);
1616
1617 return nbRows;
1618}
1619
1620
1630int64_t ProjectTree_ViewAppTable(HWND hwnd, int id)
1631{
1632 int64_t nbRows = -1;
1633
1634 const wchar_t *command = L"";
1635
1636 switch (id)
1637 {
1638 case APP_FILES_ID :
1639 {
1640 command = L"SELECT * FROM " APP_FILES;
1641 break;
1642 }
1643
1644 case APP_HISTORY_ID :
1645 {
1646 command = L"SELECT * FROM " APP_HISTORY;
1647 break;
1648 }
1649
1650 default :
1651 {
1652 break;
1653 }
1654 }
1655
1656
1657 NullFree(originalCommand);
1658 NullFree(currentCommand);
1659 currentCommand = _wcsdup(command);
1660
1661 HANDLE hProgressBar = StartProgressBar(L"Lecture de la table", -1);
1662 nbRows = DataView_Update(hwnd, &hMainDataView, &rDataView, &currentDataBase, command, USE_TEMP_VIEW);
1663 StopProgressBar(hProgressBar);
1664
1665 if (nbRows >= 0)
1666 {
1667 QueryBar_Update(L"", L"");
1668
1669 SetWindowSubclass(hMainDataView, DataView_Procedure, SUBCLASS_TABLE_ID, 0);
1670
1671 originalCommand = _wcsdup(command);
1672
1673 SetVisibility(0, SHOW, 0);
1674 StatusBar_Update((nbRows != INT32_MAX) ? L"" : NULL, nbRows);
1675 }
1676 else
1677 {
1679
1680 NullFree(currentCommand);
1681
1682 DataView_Close(hwnd);
1683 }
1684
1685 InvalidateRect(hwnd, NULL, TRUE);
1686 UpdateWindow(hwnd);
1687
1688 ShowWindow(hMainDataView, SW_SHOWNA);
1689
1690 return nbRows;
1691}
1692
1693
1703const wchar_t *GetCellValue(LVHITTESTINFO hti)
1704{
1705 const wchar_t *result = NULL;
1706
1707 int64_t line = (dataViewPage * DATAVIEW_MAXROWS) + hti.iItem;
1708 int column = hti.iSubItem;
1709
1710 if (column == 0)
1711 {
1712 static wchar_t number[INT_MAXSIZE + 1];
1713 swprintf(number, _countof(number), L"%lld", line + 1);
1714 result = number;
1715 }
1716 else if (column > 0)
1717 {
1718 result = ReadInTableFromSQLiteDB(currentDataBase,
1719 L"SELECT * FROM \"" APP_VIEWTABLE L"\"",
1720 line, column - 1, 0);
1721 }
1722
1723 return result;
1724}
1725
1726
1737int ProjectTree_RenameTable(HWND hwnd, const wchar_t *oldTableName, const wchar_t *newTableName)
1738{
1739 int result = 0;
1740
1741 freezeDataView = TRUE;
1742
1743 HTREEITEM hSelectedTableItem = TreeView_GetSelection(hMainProjectTree);
1744
1745 if (hSelectedTableItem)
1746 {
1747 TV_ITEM item = {0};
1748 item.mask = TVIF_PARAM;
1749 item.hItem = hSelectedTableItem;
1750
1751 if ((TreeView_GetItem(hMainProjectTree, &item) == TRUE)
1752 && ((item.lParam == PROJECTTREE_TABLE) || (item.lParam == PROJECTTREE_APPTABLE)))
1753 {
1754 if (_wcsicmp(oldTableName, newTableName))
1755 {
1756 int renameTable = MessageBox(hwnd, TEXT(MESSAGE_QUESTION_RENAMETABLE),
1757 TEXT(MESSAGE_TITLE_WARNING), MB_YESNO | MB_ICONQUESTION);
1758
1759 if (renameTable == IDYES)
1760 {
1761 int length = MAX_BUF;
1762 wchar_t *query = calloc(length, sizeof(wchar_t));
1763
1764 if (query)
1765 {
1766 swprintf(query, length, L"ALTER TABLE \"%ls\" RENAME TO \"%ls\"", oldTableName, newTableName);
1767 int okRename = RequestInDBwithError(currentDataBase, query, &sqlError);
1768
1769 RecordExecutedAction(TEXT(LOG_TEXTRENAMETABLE), NULL, query, (okRename == SQLITE_OK) ? NULL : sqlError);
1770
1771 QueryBar_Update(L"", L"");
1772 DataView_Close(hwnd);
1773 ProjectTree_Update(hwnd);
1774
1775 free(query);
1776 }
1777 }
1778 }
1779 }
1780 }
1781
1782 freezeDataView = FALSE;
1783
1784 return result;
1785}
1786
1787
1797{
1798 int result = 0;
1799
1800 freezeDataView = TRUE;
1801
1802 HTREEITEM hSelectedTableItem = TreeView_GetSelection(hMainProjectTree);
1803
1804 if (hSelectedTableItem)
1805 {
1806 wchar_t *tableName = calloc(MIN_BUF, sizeof(wchar_t));
1807
1808 if (tableName)
1809 {
1810 TV_ITEM item = {0};
1811
1812 item.mask = TVIF_TEXT | TVIF_PARAM;
1813 item.pszText = tableName;
1814 item.cchTextMax = MIN_BUF;
1815 item.hItem = hSelectedTableItem;
1816
1817 if ((TreeView_GetItem(hMainProjectTree, &item) == TRUE)
1818 && ((item.lParam == PROJECTTREE_TABLE) || (item.lParam == PROJECTTREE_APPTABLE)))
1819 {
1820 int deleteTable = MessageBox(hwnd, TEXT(MESSAGE_QUESTION_DROPTABLE),
1821 TEXT(MESSAGE_TITLE_WARNING), MB_YESNO | MB_ICONQUESTION);
1822
1823 if (deleteTable == IDYES)
1824 {
1825 int length = MAX_BUF;
1826 wchar_t *query = calloc(length, sizeof(wchar_t));
1827
1828 if (query)
1829 {
1830 swprintf(query, length, L"DROP TABLE \"%ls\"", tableName);
1831 int okDelete = RequestInDBwithError(currentDataBase, query, &sqlError);
1832
1833 RecordExecutedAction(TEXT(LOG_TEXTDELETETABLE), NULL, query,
1834 (okDelete == SQLITE_OK) ? NULL : sqlError);
1835
1836 if (okDelete != SQLITE_OK)
1837 {
1838 swprintf(query, length, L"DROP VIEW \"%ls\"", tableName);
1839 okDelete = RequestInDBwithError(currentDataBase, query, &sqlError);
1840
1841 RecordExecutedAction(TEXT(LOG_TEXTDELETETABLE), NULL, query,
1842 (okDelete == SQLITE_OK) ? NULL : sqlError);
1843 }
1844
1845 QueryBar_Update(L"", L"");
1846 DataView_Close(hwnd);
1847 ProjectTree_Update(hwnd);
1848
1849 free(query);
1850 }
1851 }
1852 }
1853
1854 free(tableName);
1855 }
1856 }
1857
1858 freezeDataView = FALSE;
1859
1860 return result;
1861}
1862
1863
1873void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
1874{
1875 switch (id)
1876 {
1877 case IDM_HELP :
1878 {
1879 RunHelp(hwnd);
1880 break;
1881 }
1882
1883 case IDM_ABOUT :
1884 {
1885 ShowAboutBox(hwnd);
1886 break;
1887 }
1888
1889 case IDM_OPTIONS :
1890 {
1891 DialogBox((HINSTANCE)GetWindowInstance(hwnd), L"DialogOptions", hwnd, (DLGPROC)(void *)Options_Procedure);
1892 break;
1893 }
1894
1895 case IDM_PAGE_PREVIOUS :
1896 {
1897 if (dataViewPage > 0)
1898 {
1899 -- dataViewPage;
1900
1901 int64_t remainingRows = dataViewNbRows - (dataViewPage * DATAVIEW_MAXROWS);
1902 ListView_SetItemCountEx(hMainDataView, (remainingRows > DATAVIEW_MAXROWS) ? DATAVIEW_MAXROWS : remainingRows,
1903 LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
1904 }
1905 break;
1906 }
1907
1908 case IDM_PAGE_NEXT :
1909 {
1910 if (dataViewPage < 40)
1911 {
1912 ++ dataViewPage;
1913
1914 int64_t remainingRows = dataViewNbRows - (dataViewPage * DATAVIEW_MAXROWS);
1915
1916 if (remainingRows < 0)
1917 {
1918 -- dataViewPage;
1919 }
1920 else
1921 {
1922 ListView_SetItemCountEx(hMainDataView, (remainingRows > DATAVIEW_MAXROWS) ? DATAVIEW_MAXROWS : remainingRows,
1923 LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
1924 }
1925 }
1926 break;
1927 }
1928
1929 case IDM_DATA_COPYVALUE:
1930 {
1931 const wchar_t *text = GetCellValue(selectedCellInfo);
1932
1933 if (text)
1934 {
1935 CopyInClipBoard(hwnd, text);
1936 }
1937
1938 break;
1939 }
1940
1941 case IDM_PROJECT_CONVERT :
1942 {
1943 if (MessageBox(hwnd, TEXT(CONVERT_PROJECT), L"", MB_OKCANCEL) == IDOK)
1944 {
1945 ProjectTree_Open(hwnd, id);
1946 }
1947
1948 PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_PROJECT_OPTIMIZE, 0), 0);
1949 break;
1950 }
1951
1952 case IDM_INIT :
1953 case IDM_PROJECT_NEW :
1954 case IDM_PROJECT_OPEN :
1955 {
1956 ProjectTree_Open(hwnd, id);
1957 break;
1958 }
1959
1960 case IDM_DATA_IMPORT :
1961 {
1962 CreateTableFromCSV(hwnd);
1963 ProjectTree_Update(hwnd);
1965 break;
1966 }
1967
1968 case IDM_DATA_EXPORT :
1969 {
1970 CreateCSVFromView(hwnd);
1971 break;
1972 }
1973
1974 case IDM_TABLE_EXPORT :
1975 case IDM_TABLE_RENAME :
1976 {
1977 HTREEITEM hSelectedTableItem = TreeView_GetSelection(hMainProjectTree);
1978
1979 if (hSelectedTableItem)
1980 {
1981 TV_ITEM item = {0};
1982 item.mask = TVIF_PARAM;
1983 item.hItem = hSelectedTableItem;
1984
1985 if ((TreeView_GetItem(hMainProjectTree, &item) == TRUE)
1986 && ((item.lParam == PROJECTTREE_TABLE) || (item.lParam == PROJECTTREE_APPTABLE)))
1987 {
1988 if (id == IDM_TABLE_RENAME)
1989 {
1990 SetFocus(hMainProjectTree);
1991 TreeView_EditLabel(hMainProjectTree, hSelectedTableItem);
1992 }
1993 else if (id == IDM_TABLE_EXPORT)
1994 {
1995 ProjectTree_ViewSelectedTable(hwnd, hSelectedTableItem);
1996 CreateCSVFromView(hwnd);
1997 }
1998 }
1999 }
2000
2001 break;
2002 }
2003
2004 case IDM_TABLE_DELETE :
2005 {
2007 break;
2008 }
2009
2010 case IDM_DATA_CLOSE :
2011 {
2012 DataView_Close(hwnd);
2013 ProjectTree_Update(hwnd);
2014 break;
2015 }
2016
2017 case IDM_PROJECT_UPDATE :
2018 {
2019 ProjectTree_Update(hwnd);
2020 break;
2021 }
2022
2024 {
2025 HANDLE hPb = StartProgressBar(L"Optimisation en cours ...", -2);
2026 RequestInDB(currentDataBase, L"ANALYSE;");
2027 StopProgressBar(hPb);
2028 break;
2029 }
2030
2032 {
2034 break;
2035 }
2036
2038 {
2040 break;
2041 }
2042
2043 case IDM_SQL_FILE :
2044 {
2045 ExecuteSQLScript(hwnd, NULL);
2046 ProjectTree_Update(hwnd);
2047 break;
2048 }
2049
2050 case IDM_SQL_QUERY :
2051 {
2053 ProjectTree_Update(hwnd);
2054 break;
2055 }
2056
2057 case IDM_PROJECT_CLOSE :
2058 {
2059 ProjectTree_Close(hwnd);
2060 break;
2061 }
2062
2063 default :
2064 {
2065 Main_OnExtraCommand(hwnd, id, hwndCtl, codeNotify);
2066 break;
2067 }
2068 }
2069}
2070
2071
2081void Main_OnContextMenu(HWND hwnd, HWND hwndContext, short int xPos, short int yPos)
2082{
2083 HMENU hMenu = NULL;
2084
2085 freezeDataView = TRUE;
2086
2087 POINT pt = {xPos, yPos};
2088 ScreenToClient(hwndContext, &pt);
2089
2090 if (hwndContext == hMainDataView)
2091 {
2092 ZeroMemory(&selectedCellInfo, sizeof(selectedCellInfo));
2093 selectedCellInfo.pt = pt;
2094
2095 ListView_SubItemHitTest(hwndContext, &selectedCellInfo);
2096
2097 hMenu = LoadMenu((HINSTANCE)GetWindowInstance(hwnd), L"ViewMenu");
2098 }
2099 else if (hwndContext == hMainProjectTree)
2100 {
2101 TVHITTESTINFO tvhti = {0};
2102 tvhti.pt = pt;
2103
2104 TreeView_HitTest(hwndContext, &tvhti);
2105
2106 if (tvhti.flags & TVHT_ONITEM)
2107 {
2108 TV_ITEM item = {0};
2109
2110 item.mask = TVIF_PARAM;
2111 item.hItem = tvhti.hItem;
2112
2113 if ((TreeView_GetItem(hMainProjectTree, &item) == TRUE)
2114 && ((item.lParam == PROJECTTREE_TABLE) || (item.lParam == PROJECTTREE_APPTABLE)))
2115 {
2116 // avant d'éditer, récupère la sélection courante
2117 hActualSelectedTableItem = TreeView_GetSelection(hMainProjectTree);
2118
2119 TreeView_SelectItem(hwndContext, tvhti.hItem);
2120 hMenu = LoadMenu((HINSTANCE)GetWindowInstance(hwnd), L"TreeMenu");
2121 }
2122 }
2123 }
2124
2125 if (hMenu)
2126 {
2127 static HMENU hPopMenu = NULL;
2128 hPopMenu = GetSubMenu(hMenu, 0);
2129
2130 TrackPopupMenuEx(hPopMenu, 0, xPos, yPos, hwnd, NULL);
2131 DestroyMenu(hMenu);
2132 }
2133
2134 freezeDataView = FALSE;
2135}
2136
2137
2145void ProjectTree_ViewSelectedTable(HWND hwnd, HTREEITEM hItem)
2146{
2147 QueryBar_Update(L"", L"");
2148 DataView_Close(hwnd);
2149
2150 if (hItem)
2151 {
2152 TV_ITEM item;
2153
2154 wchar_t *tableName = calloc(MIN_BUF, sizeof(wchar_t));
2155
2156 if (tableName)
2157 {
2159 {
2161 }
2162
2163 currentSelectedTable = tableName;
2164
2165 item.mask = TVIF_TEXT | TVIF_PARAM;
2166 item.lParam = 0;
2167 item.pszText = tableName;
2168 item.cchTextMax = MIN_BUF;
2169 item.hItem = hItem;
2170
2171 if ((TreeView_GetItem(hMainProjectTree, &item) == TRUE)
2172 && ((item.lParam == PROJECTTREE_TABLE) || (item.lParam == PROJECTTREE_APPTABLE)))
2173 {
2174 size_t length = wcslen(tableName) + sizeof("SELECT * FROM \"\"");
2175 wchar_t *command = calloc(length, sizeof(wchar_t));
2176
2177 if (command)
2178 {
2179 swprintf(command, length, L"SELECT * FROM \"%ls\"", tableName);
2180
2181 NullFree(originalCommand);
2182 NullFree(currentCommand);
2183 currentCommand = command;
2184
2185 int nbRows = DataView_Update(hwnd, &hMainDataView, &rDataView, &currentDataBase, command, USE_TEMP_VIEW | ACTUAL_TABLE);
2186
2188
2189 if (nbRows >= 0)
2190 {
2191 SetWindowSubclass(hMainDataView, DataView_Procedure, SUBCLASS_TABLE_ID, 0);
2192
2193 originalCommand = _wcsdup(command);
2194
2195 SetVisibility(0, SHOW, 0);
2196 StatusBar_Update((nbRows != INT32_MAX) ? tableName : NULL, nbRows);
2197 }
2198 else
2199 {
2200 currentCommand = NULL;
2201 free(command);
2202 }
2203 }
2204 }
2205 }
2206 }
2207}
2208
2209
2219int Main_OnNotify_DrawDataView(HWND hwnd, LPNMLVCUSTOMDRAW lplvcd)
2220{
2221 static int clrText;
2222 static int clrTextBk;
2223
2224 switch (lplvcd->nmcd.dwDrawStage)
2225 {
2226 case CDDS_PREPAINT :
2227 {
2228 return CDRF_NOTIFYITEMDRAW;
2229 }
2230
2231 case CDDS_ITEMPREPAINT :
2232 {
2233 clrText = lplvcd->clrText;
2234 clrTextBk = lplvcd->clrTextBk;
2235
2236 return CDRF_NOTIFYSUBITEMDRAW;
2237 }
2238
2239 case CDDS_SUBITEM | CDDS_ITEMPREPAINT :
2240 {
2241 /*(lplvcd->iSubItem == 3)*/ // cible le numéro de colonne
2242 /*(lplvcd->nmcd.dwItemSpec == 2)*/ // cible le numéro de ligne
2243 /*(lplvcd->nmcd.lItemlParam == <valeur perso>)*/ // cible le paramètre optionnel de l'item (ligne)
2244
2245 switch (lplvcd->iSubItem)
2246 {
2247 case 0 :
2248 {
2249 if (!mainFixedBlackFont)
2250 {
2251 UINT dpi = GetWindowDpi(hwnd);
2252 mainFixedBlackFont = CreateFontForDPI(FIXED_FONT, FW_BLACK, SIZE_OF_FONT, dpi);
2253 }
2254
2256 {
2257 SelectObject(lplvcd->nmcd.hdc, mainFixedBlackFont);
2258 }
2259
2260 lplvcd->clrText = clrText;
2261 lplvcd->clrTextBk = GetSysColor(COLOR_BTNFACE);
2262
2263 break;
2264 }
2265
2266 default :
2267 {
2268 if (!mainFixedFont)
2269 {
2270 UINT dpi = GetWindowDpi(hwnd);
2271 mainFixedFont = CreateFontForDPI(FIXED_FONT, FW_THIN, SIZE_OF_FONT, dpi);
2272 }
2273
2274 if (mainFixedFont)
2275 {
2276 SelectObject(lplvcd->nmcd.hdc, mainFixedFont);
2277 }
2278
2279 lplvcd->clrText = clrText;
2280 lplvcd->clrTextBk = clrTextBk;
2281
2282 break;
2283 }
2284 }
2285
2286 return CDRF_NEWFONT;
2287 }
2288
2289 default :
2290 {
2291 return CDRF_DODEFAULT;
2292 }
2293 }
2294}
2295
2296
2304{
2305 if (hHeader && currentCommand)
2306 {
2307 int length = wcslen(originalCommand) + MAX_BUF;
2308 wchar_t *query = calloc(length, sizeof(wchar_t));
2309
2310 if (query)
2311 {
2312 dataViewPage = 0;
2313 dataViewNbRows = 0;
2314
2315 swprintf(query, length, L"SELECT * FROM (%ls)", originalCommand);
2316
2317 int nbColumns = Header_GetItemCount(hHeader);
2318
2319 int testColumn = 0;
2320
2321 for (int column = 1; column < nbColumns; ++ column)
2322 {
2323 wchar_t columnFilter[MIN_BUF] = {0};
2324 wchar_t columnName[MIN_BUF] = {0};
2325
2326 HD_ITEM hdi = {0};
2327 HD_TEXTFILTER htf = {0};
2328
2329 hdi.mask = HDI_FILTER | HDI_TEXT;
2330
2331 hdi.pszText = columnName;
2332 hdi.cchTextMax = _countof(columnName) - 1;
2333
2334 hdi.type = HDFT_ISSTRING;
2335 //hdi.type = HDFT_ISNUMBER;
2336 //hdi.type = HDFT_ISDATE;
2337 hdi.pvFilter = &htf;
2338
2339 htf.pszText = columnFilter;
2340 htf.cchTextMax = _countof(columnFilter) - 1;
2341
2342 Header_GetItem(hHeader, column, &hdi);
2343
2344 if (columnFilter[0])
2345 {
2346 swprintf(&query[wcslen(query)], length - wcslen(query),
2347 L" %ls \"%ls\" LIKE '%ls'",
2348 (!testColumn) ? L"WHERE" : L"AND", columnName, columnFilter);
2349
2350 ++ testColumn;
2351 }
2352 }
2353
2354 SetWindowRedraw(hMainDataView, FALSE);
2355 ListView_DeleteAllItems(hMainDataView);
2356
2357 currentCommand = query;
2358
2359 int nbRows = FillAListView_Win32(hMainDataView, currentDataBase, currentDataBaseName, query, &sqlError, USE_TEMP_TABLE, NULL);
2360
2362
2363 if (nbRows >= 0)
2364 {
2365 StatusBar_Update((nbRows != INT32_MAX) ? L"" : NULL, nbRows);
2366 dataViewNbRows = nbRows;
2367 }
2368 else
2369 {
2370 NullFree(currentCommand);
2372 }
2373
2374 SetVisibility(0, SHOW, 0);
2375
2376 SetWindowRedraw(hMainDataView, TRUE);
2377 }
2378 }
2379}
2380
2381
2389{
2390 if (scrollingTimer)
2391 {
2392 KillTimer(hwnd, scrollingTimer);
2393 }
2394
2395 scrollingTimer = SetTimer(hwnd, SCROLL_TIMER_ID, SCROLL_IDLE_MS, NULL);
2396}
2397
2398
2405int Main_OnNotify_FillDataView(LPNMLVDISPINFOW lplvdi)
2406{
2407 int result = FALSE;
2408
2409 if (lplvdi->item.mask & LVIF_TEXT)
2410 {
2411 int64_t line = (dataViewPage * DATAVIEW_MAXROWS) + lplvdi->item.iItem;
2412 int column = lplvdi->item.iSubItem;
2413
2414 result = TRUE;
2415
2416 if ((!scrollingTimer || !column) && (line >= 0))
2417 {
2418 static wchar_t *text;
2419
2420 if (column == 0)
2421 {
2422 static wchar_t number[INT_MAXSIZE + 1];
2423 swprintf(number, _countof(number), L"%lld", line + 1);
2424 text = number;
2425 }
2426 else if (column > 0)
2427 {
2428 text = ReadInTableFromSQLiteDB(currentDataBase, L"SELECT * FROM \"" APP_VIEWTABLE L"\"", line, column - 1, 0);
2429 }
2430 else
2431 {
2432 text = NULL;
2433 }
2434
2435 // la chaîne copiée ne doit pas dépasser la longueur maximale acceptable (NUL final inclus)
2436
2437 if (lplvdi->item.cchTextMax && text && (wcslen(text) >= (size_t)lplvdi->item.cchTextMax))
2438 {
2439 text[lplvdi->item.cchTextMax - 1] = L'\0';
2440 }
2441
2442 lplvdi->item.pszText = text ? text : L"";
2443
2444 // redimensionnement de la colonne
2445 if (1)
2446 {
2447 int textWidth = EstimateTextWidthWithFont(hMainDataView, text, mainFixedFont);
2448 int columnWidth = ListView_GetColumnWidth(hMainDataView, column);
2449
2450 const int padding = 16;
2451 if (textWidth + padding > columnWidth)
2452 {
2453 ListView_SetColumnWidth(hMainDataView, column, textWidth + padding);
2454 InvalidateRect(hMainDataView, NULL, TRUE);
2455 }
2456 }
2457 }
2458 else
2459 {
2460 lplvdi->item.pszText = L"\267\267\267";
2461 }
2462 }
2463
2464 return result;
2465}
2466
2467
2476BOOL Main_OnNotify(HWND hwnd,
2477 int idCtrl __attribute__((unused)),
2478 LPNMHDR pnmh)
2479{
2480 int result = FALSE;
2481
2482 static wchar_t oldItemText[MIN_BUF];
2483
2484 switch (pnmh->code)
2485 {
2486 // message de sélection d'un item du ProjectView
2487
2488 case TVN_SELCHANGED :
2489 {
2490 if (pnmh->hwndFrom == hMainProjectTree)
2491 {
2492 if (!freezeDataView)
2493 {
2494 HTREEITEM hItem = TreeView_GetSelection(hMainProjectTree);
2495 ProjectTree_ViewSelectedTable(hwnd, hItem);
2496 }
2497 }
2498
2499 break;
2500 }
2501
2502
2503 case TVN_BEGINLABELEDIT :
2504 {
2505 if (pnmh->hwndFrom == hMainProjectTree)
2506 {
2507 LPNMTVDISPINFO pdi = (LPNMTVDISPINFO)pnmh;
2508 swprintf(oldItemText, MIN_BUF, L"%ls", (pdi->item.pszText) ? pdi->item.pszText : L"");
2509 }
2510
2511 break;
2512 }
2513
2514 case TVN_ENDLABELEDIT :
2515 {
2516 if (pnmh->hwndFrom == hMainProjectTree)
2517 {
2518 LPNMTVDISPINFO pdi = (LPNMTVDISPINFO)pnmh;
2519
2520 if (pdi->item.pszText)
2521 {
2522 TV_ITEM tvi = {0};
2523
2524 tvi.mask = TVIF_TEXT;
2525 tvi.hItem = pdi->item.hItem;
2526 tvi.pszText = pdi->item.pszText;
2527
2528 TreeView_SetItem(hMainProjectTree, &tvi);
2529
2530 ProjectTree_RenameTable(hwnd, oldItemText, pdi->item.pszText);
2531 }
2532 }
2533
2534 break;
2535 }
2536
2537
2538 // gère l'aspect et la mise en forme du ListView (polices, couleurs, ...)
2539
2540 case NM_CUSTOMDRAW :
2541 {
2542 if (pnmh->hwndFrom == hMainDataView)
2543 {
2544 LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pnmh;
2545 result = Main_OnNotify_DrawDataView(hwnd, lplvcd);
2546 }
2547
2548 break;
2549 }
2550
2551
2552 case LVN_BEGINSCROLL:
2553 case LVN_ENDSCROLL:
2554 {
2555 if (pnmh->hwndFrom == hMainDataView)
2556 {
2558 }
2559
2560 break;
2561 }
2562
2563
2564 // message indiquant la partie de la table à placer en cache
2565
2566 case LVN_ODCACHEHINT :
2567 {
2568 if ((pnmh->hwndFrom == hMainDataView) && !scrollingTimer)
2569 {
2570 LPNMLVCACHEHINT lplvch = (LPNMLVCACHEHINT)pnmh;
2571
2572 int64_t line = (dataViewPage * DATAVIEW_MAXROWS) + lplvch->iFrom;
2573 int number = (lplvch->iTo - lplvch->iFrom) + 1;
2574
2575 ReadInTableFromSQLiteDB(currentDataBase, L"SELECT * FROM \"" APP_VIEWTABLE L"\"", line, 0, number);
2576 }
2577
2578 break;
2579 }
2580
2581
2582 // alimente le DataView en données à la demande
2583
2584 case LVN_GETDISPINFO :
2585 {
2586 if (pnmh->hwndFrom == hMainDataView)
2587 {
2588 LPNMLVDISPINFOW lplvdi = (LPNMLVDISPINFOW)pnmh;
2589 result = Main_OnNotify_FillDataView(lplvdi);
2590 }
2591
2592 break;
2593 }
2594
2595
2596 // gère la recherche d'un item particulier
2597
2598 case LVN_ODFINDITEM :
2599 {
2600 return -1;
2601 }
2602
2603
2604 // gère une demande de filtrage sur clic du bouton de filtre
2605
2606 case HDN_FILTERBTNCLICK :
2607 {
2608 LPNMHDFILTERBTNCLICK lphdfi = (LPNMHDFILTERBTNCLICK)pnmh;
2609
2610 HWND hHeader = lphdfi->hdr.hwndFrom;
2612
2613 break;
2614 }
2615
2616
2617 // gère une demande de filtrage automatique
2618
2619 case HDN_FILTERCHANGE :
2620 {
2621 /*LPNMHEADER lphead = (LPNMHEADER)pnmh;
2622
2623 HWND hHeader = pnmh->hwndFrom;
2624 Main_OnNotify_ApplyFilter(hHeader);*/
2625
2626 break;
2627 }
2628
2629
2630 case LVN_COLUMNCLICK :
2631 {
2632 HWND hListView = pnmh->hwndFrom;
2633 LPNMLISTVIEW pnmv = (LPNMLISTVIEW)pnmh;
2634
2635 int numColumn = pnmv->iSubItem;
2636 ListView_SetSelectedColumn(hListView, numColumn);
2637
2638 break;
2639 }
2640
2641
2642 default :
2643 {
2644 break;
2645 }
2646 }
2647
2648 return result;
2649}
2650
2651
2661LRESULT CALLBACK Main_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2662{
2663 switch (uMsg)
2664 {
2665 HANDLE_MSG(hwnd, WM_CREATE, Main_OnCreate);
2666 HANDLE_MSG(hwnd, WM_CLOSE, Main_OnClose);
2667 HANDLE_MSG(hwnd, WM_DESTROY, Main_OnClose);
2668 HANDLE_MSG(hwnd, WM_PAINT, Main_OnPaint);
2669 HANDLE_MSG(hwnd, WM_SIZE, Main_OnSize);
2670 HANDLE_MSG(hwnd, WM_COMMAND, Main_OnCommand);
2671 HANDLE_MSG(hwnd, WM_CONTEXTMENU, Main_OnContextMenu);
2672 HANDLE_MSG(hwnd, WM_NOTIFY, Main_OnNotify);
2673
2674 case WM_ERASEBKGND :
2675 {
2676 HDC hdc = (HDC)wParam;
2677
2678 RECT rect;
2679
2680 if (!hMainProjectTree)
2681 {
2682 GetClientRect(hwnd, &rect);
2683 FillRect(hdc, &rect, GetSysColorBrush(COLOR_BTNFACE));
2684 }
2685 else if (!hMainDataView)
2686 {
2687 FillRect(hdc, &rDataView, GetSysColorBrush(COLOR_BTNFACE));
2688 }
2689
2690 return TRUE;
2691 }
2692
2693 case WM_TIMER :
2694 {
2695 // temporisation du relâchement de la barre de scroll
2696 // celle-ci peut être vue à tort comme relachée, un tempo permet de gérer
2697 if (wParam == SCROLL_TIMER_ID)
2698 {
2699 KillTimer(hwnd, SCROLL_TIMER_ID);
2700 scrollingTimer = 0;
2701
2702 InvalidateRect(hMainDataView, NULL, TRUE);
2703 UpdateWindow(hMainDataView);
2704 }
2705
2706 if (wParam == NBROWS_TIMER_ID)
2707 {
2708 int64_t nbRows = VerifierTermine(NULL);
2709
2710 if (nbRows != -1)
2711 {
2712 KillTimer(hwnd, NBROWS_TIMER_ID);
2713 dataViewNbRows = nbRows;
2714 ListView_SetItemCountEx(hMainDataView, (nbRows > DATAVIEW_MAXROWS) ? DATAVIEW_MAXROWS : nbRows,
2715 LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
2716 StatusBar_Update((nbRows != INT32_MAX) ? L"" : NULL, nbRows);
2717 }
2718 }
2719
2720 break;
2721 }
2722
2723 default :
2724 {
2725 return DefWindowProc(hwnd, uMsg, wParam, lParam);
2726 }
2727 }
2728
2729 return FALSE;
2730}
2731
2732
2744LRESULT CALLBACK ProjectTree_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
2745 UINT_PTR uIdSubclass, DWORD_PTR dwRefData __attribute__((unused)))
2746{
2747 switch (uMsg)
2748 {
2749 case WM_WINDOWPOSCHANGING :
2750 {
2751 RestartScrollingTimer(GetParent(hwnd));
2752
2753 WINDOWPOS *wp = (LPWINDOWPOS) lParam;
2754
2755 if (!(wp->flags & (SWP_NOSIZE/* | SWP_NOMOVE*/)))
2756 {
2757 rProjectTree.left = wp->x;
2758 rProjectTree.top = wp->y;
2759 rProjectTree.right = wp->x + wp->cx;
2760 rProjectTree.bottom = wp->y + wp->cy;
2761
2762 RECT r;
2763 GetClientRect(GetParent(hwnd), &r);
2764
2765 RECT rSB;
2766 GetClientRect(hMainStatusBar, &rSB);
2767
2768 int bottom = r.bottom - rSB.bottom;
2769
2770 if (wp->x > 0)
2771 {
2772 wp->cx += wp->x;
2773 wp->x = 0;
2774 }
2775
2776 if (wp->y > 0)
2777 {
2778 wp->cy += wp->y;
2779 wp->y = 0;
2780 }
2781
2782 if (wp->cy > (bottom - BUTTON_SIZE))
2783 {
2784 wp->cy = bottom - BUTTON_SIZE;
2785 }
2786
2787 xTableView = wp->cx;
2788 SetWindowPos(hMainDataView, 0, wp->cx, 0, r.right - wp->cx, wp->cy, SWP_NOSENDCHANGING);
2789
2790 rDataView.left = wp->cx;
2791 rDataView.top = 0;
2792 rDataView.right = r.right;
2793 rDataView.bottom = wp->cy;
2794
2795 SetWindowPos(hMainQueryError, 0, 0, wp->cy, xQueryEdit, bottom - wp->cy, SWP_NOSENDCHANGING);
2796 SetWindowPos(hMainQueryEdit, 0, xQueryEdit, wp->cy, (r.right - BUTTON_SIZE) - xQueryEdit, bottom - wp->cy, SWP_NOSENDCHANGING);
2797 SetWindowPos(hMainQueryExecute, 0, (r.right - BUTTON_SIZE), wp->cy, BUTTON_SIZE, bottom - wp->cy, SWP_NOSENDCHANGING);
2798
2799 return 0;
2800 }
2801
2802 break;
2803 }
2804
2805 case WM_NCDESTROY:
2806 {
2807 RemoveWindowSubclass(hwnd, ProjectTree_Procedure, uIdSubclass);
2808 break;
2809 }
2810
2811 default :
2812 {
2813 break;
2814 }
2815 }
2816
2817 return DefSubclassProc(hwnd, uMsg, wParam, lParam);
2818}
2819
2820
2832LRESULT CALLBACK DataView_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
2833 UINT_PTR uIdSubclass, DWORD_PTR dwRefData __attribute__((unused)))
2834{
2835 switch (uMsg)
2836 {
2837 case WM_WINDOWPOSCHANGING :
2838 {
2839 RestartScrollingTimer(GetParent(hwnd));
2840
2841 WINDOWPOS *wp = (LPWINDOWPOS) lParam;
2842
2843 if (!(wp->flags & (SWP_NOSIZE/* | SWP_NOMOVE*/)))
2844 {
2845 rDataView.left = wp->x;
2846 rDataView.top = wp->y;
2847 rDataView.right = wp->x + wp->cx;
2848 rDataView.bottom = wp->y + wp->cy;
2849
2850 RECT rParent;
2851 GetClientRect(GetParent(hwnd), &rParent);
2852
2853 RECT rSB;
2854 GetClientRect(hMainStatusBar, &rSB);
2855
2856 int bottom = rParent.bottom - rSB.bottom;
2857
2858 if ((wp->x + wp->cx) < rParent.right)
2859 {
2860 wp->cx = rParent.right - wp->x;
2861 }
2862
2863 if (wp->y > 0)
2864 {
2865 wp->cy += wp->y;
2866 wp->y = 0;
2867 }
2868
2869 if (wp->cy > (bottom - BUTTON_SIZE))
2870 {
2871 wp->cy = bottom - BUTTON_SIZE;
2872 }
2873
2874 xTableView = wp->x;
2875 SetWindowPos(hMainProjectTree, 0, 0, 0, wp->x, wp->cy, SWP_NOSENDCHANGING);
2876
2877 rProjectTree.left = 0;
2878 rProjectTree.top = 0;
2879 rProjectTree.right = wp->cx;
2880 rProjectTree.bottom = wp->cy;
2881
2882 SetWindowPos(hMainQueryEdit, 0, xQueryEdit, wp->cy, (rParent.right - BUTTON_SIZE) - xQueryEdit, bottom - wp->cy, SWP_NOSENDCHANGING);
2883 SetWindowPos(hMainQueryError, 0, 0, wp->cy, xQueryEdit, bottom - wp->cy, SWP_NOSENDCHANGING);
2884 SetWindowPos(hMainQueryExecute, 0, (rParent.right - BUTTON_SIZE), wp->cy, BUTTON_SIZE, bottom - wp->cy, SWP_NOSENDCHANGING);
2885
2886 return 0;
2887 }
2888
2889 break;
2890 }
2891
2892 case WM_NCDESTROY:
2893 {
2894 RemoveWindowSubclass(hwnd, DataView_Procedure, uIdSubclass);
2895 break;
2896 }
2897
2898 default :
2899 {
2900 break;
2901 }
2902 }
2903
2904 return DefSubclassProc(hwnd, uMsg, wParam, lParam);
2905}
2906
2907
2921int64_t DataView_Update(HWND hwnd, HWND * pListView, RECT * rListView, sqlite3 **db, const wchar_t *command, int useTmp)
2922{
2923 int64_t nbRows = -1;
2924
2925 dataViewPage = 0;
2926 dataViewNbRows = 0;
2927
2928 if (db && command && command[0])
2929 {
2930 // Ouverture ou création de la base SQLite courante si besoin
2931
2932 int result = SQLITE_OK;
2933
2934 if (!db[0])
2935 {
2936 result = OpenSQLiteDB(db, currentDataBaseName, FALSE);
2937 }
2938
2939 if (result == SQLITE_OK)
2940 {
2941 // Destruction du ListView précédent
2942
2943 if (pListView[0])
2944 {
2945 DestroyWindow(pListView[0]);
2946 }
2947
2948 // crée un nouveau ListView
2949
2950 int virtualListView = (useTmp & USE_NO_TEMP) ? 0 : LVS_OWNERDATA;
2951 int listView_styles = LVS_REPORT/* | LVS_NOSORTHEADER*/;
2952 int window_styles = WS_CHILD | WS_THICKFRAME | WS_CLIPSIBLINGS;
2953
2954 // c'est le WS_THICKFRAME qui pose le petit problème de largeur de la dernière colonne et de hauteur de la dernière ligne
2955 // mais sans cette option, le ListView n'a plus de bordure de redimensionnement
2956
2957 pListView[0] = CreateWindowEx(0, WC_LISTVIEW, L"",
2958 virtualListView | listView_styles | window_styles,
2959 0, 0, 0, 0, hwnd, 0, (HINSTANCE)GetWindowInstance(hwnd), NULL);
2960
2961 HWND hListView = pListView[0];
2962
2963 if (hListView)
2964 {
2965 ListView_SetExtendedListViewStyleEx(hListView,
2966 LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER
2967 | /*LVS_EX_HEADERDRAGDROP | */LVS_EX_LABELTIP,
2968 LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER
2969 | LVS_EX_HEADERDRAGDROP | LVS_EX_LABELTIP);
2970
2971 //ApplyDarkMode(hListView, L"DarkMode_Explorer");
2972
2973 SetWindowPos(hListView,
2974 HWND_TOP,
2975 rListView->left,
2976 rListView->top,
2977 rListView->right - rListView->left,
2978 rListView->bottom - rListView->top,
2979 0);
2980
2981 nbRows = FillAListView_Win32(hListView, db[0], currentDataBaseName, command, &sqlError, useTmp,
2982 (useTmp & USE_NO_TEMP) ? DataView_UpdateAll : DataView_UpdateHeader);
2983
2984 if (nbRows < 0)
2985 {
2986 // Destruction du ListView en cas d'échec
2987
2988 DestroyWindow(hListView);
2989 pListView[0] = NULL;
2990 }
2991 else
2992 {
2993 dataViewNbRows = nbRows;
2994 if (!(useTmp & ACTUAL_TABLE) || (nbRows == INT32_MAX))
2995 {
2996 KillTimer(hwnd, NBROWS_TIMER_ID);
2997 SetTimer(hwnd, NBROWS_TIMER_ID, NBROWS_IDLE_MS, NULL);
2998 }
2999 }
3000 }
3001 }
3002 }
3003
3004 return nbRows;
3005}
3006
3007
3020int64_t DataView_UpdateWithAFile(HWND hwnd, HWND * pListView, RECT * rListView, sqlite3 **db, wchar_t **command, const wchar_t *fileName)
3021{
3022 int64_t nbRows = -1;
3023 wchar_t *newFileName = NULL;
3024
3025 if (db)
3026 {
3027 if (!fileName)
3028 {
3029 newFileName = FileInChooser(L"Lancer un script SQL", hwnd, L"Script SQL (*.sql)\0*.sql\0");
3030 }
3031
3032 FILE *fileIn = OpenTextFileIn(SOFT_NAMEW, fileName ? fileName : newFileName);
3033
3034 if (fileIn)
3035 {
3036 _fseeki64(fileIn, 0L, SEEK_END);
3037 _off64_t fileSize = _ftelli64(fileIn);
3038 _fseeki64(fileIn, 0L, SEEK_SET);
3039
3040 wchar_t *sql = calloc(fileSize + 1, sizeof(wchar_t));
3041
3042 if (sql)
3043 {
3044 fread(sql, sizeof(wchar_t), fileSize, fileIn);
3045
3046 // Ouverture ou création de la base SQLite courante si besoin
3047
3048 int result = SQLITE_OK;
3049
3050 if (!db[0])
3051 {
3052 wchar_t *projectName = calloc(FILENAMELENGTH_MAX, sizeof(wchar_t));
3053 if (projectName)
3054 {
3055 LoadOption(SOFT_NAMEW, SOFT_NAMEW, OPTION_CURRENTPROJECT, projectName, FILENAMELENGTH_MAX);
3056 result = OpenSQLiteDB(db, projectName, FALSE);
3057 free(projectName);
3058 }
3059 }
3060
3061 if (result == SQLITE_OK)
3062 {
3063 const wchar_t *lastSql = ScriptInDBwithAnswer(db[0], sql);
3064
3065 if (command && lastSql && lastSql[0])
3066 {
3067 NullFree(command[0]);
3068 command[0] = _wcsdup(lastSql);
3069 nbRows = DataView_Update(hwnd, pListView, rListView, db, lastSql, USE_NO_TEMP);
3070 }
3071 }
3072
3073 free(sql);
3074 }
3075
3076 fclose(fileIn);
3077 }
3078 }
3079
3080 if (newFileName)
3081 {
3082 free(newFileName);
3083 }
3084
3085 return nbRows;
3086}
3087
3088
3098LRESULT CALLBACK Options_Procedure(HWND hwnd,
3099 UINT uMsg,
3100 WPARAM wParam,
3101 LPARAM lParam __attribute__((unused)))
3102{
3103 static HFONT hFont;
3104
3105 switch (uMsg)
3106 {
3107 case WM_INITDIALOG :
3108 {
3109
3110
3111 RecreateDialogFont(hwnd, &hFont, VARIABLE_FONT, SIZE_OF_FONT);
3112
3113 return TRUE;
3114 }
3115
3116 case WM_COMMAND :
3117 {
3118 switch (LOWORD(wParam))
3119 {
3120 case IDOK :
3121 {
3122 EndDialog(hwnd, 1);
3123
3124 if (hFont)
3125 {
3126 DeleteObject(hFont);
3127 hFont = NULL;
3128 }
3129
3130 return TRUE;
3131 }
3132
3133 case IDCANCEL :
3134 {
3135 EndDialog(hwnd, 0);
3136
3137 if (hFont)
3138 {
3139 DeleteObject(hFont);
3140 hFont = NULL;
3141 }
3142
3143 return TRUE;
3144 }
3145
3146 default :
3147 {
3148 return TRUE;
3149 }
3150 }
3151 break;
3152 }
3153
3154 default :
3155 {
3156 break;
3157 }
3158 }
3159
3160 return FALSE;
3161}
#define APP_FILES_ID
Definition Defines.h:37
#define APP_HISTORY_ID
Definition Defines.h:34
#define APP_FILES
Definition Defines.h:38
#define OPTION_CURRENTPROJECT
définitions relatives au fichier des options
Definition Defines.h:43
#define APP_VIEWTABLE
définitions spéciales propres à Taupie
Definition Defines.h:31
#define APP_HISTORY
Definition Defines.h:35
void Main_OnContextMenu(HWND hwnd, HWND hwndContext, short int xPos, short int yPos)
Gestion du menu contextuel.
Definition TaupieGUI.c:2081
static int dataViewPage
Definition TaupieGUI.c:101
int Main_OnNotify_DrawDataView(HWND hwnd, LPNMLVCUSTOMDRAW lplvcd)
Redessine sur demande le listview (police, couleur, fond).
Definition TaupieGUI.c:2219
static LVHITTESTINFO selectedCellInfo
Definition TaupieGUI.c:87
#define DATAVIEW_MAXROWS
Definition TaupieGUI.c:100
int64_t ProjectTree_Update(HWND hwnd)
Crée un TreeView à partir du contenu de la base courante, et l'affiche aux bonnes dimensions.
Definition TaupieGUI.c:219
int64_t DataView_Update(HWND hwnd, HWND *pListView, RECT *rListView, sqlite3 **db, const wchar_t *command, int useTmp)
Crée un ListView à partir d'une commande SQL, et l'affiche aux bonnes dimensions.
Definition TaupieGUI.c:2921
#define NBROWS_TIMER_ID
Definition TaupieGUI.c:75
static HWND hMainStatusBar
Definition TaupieGUI.c:62
static int64_t dataViewNbRows
Definition TaupieGUI.c:102
#define NBROWS_IDLE_MS
Definition TaupieGUI.c:76
void Main_OnClose(HWND hwnd)
Supprime les fichiers temporaires et ferme l'application.
Definition TaupieGUI.c:797
#define SCROLL_TIMER_ID
Definition TaupieGUI.c:71
static int xQueryEdit
Definition TaupieGUI.c:94
void Main_OnSize(HWND hwnd, UINT state, UINT x, UINT y)
Gestion d'un changement de taille de la fenêtre principale.
Definition TaupieGUI.c:349
static wchar_t * currentDataBaseName
Definition TaupieGUI.c:83
void QueryBar_Update(const wchar_t *errorMsg, const wchar_t *request)
Définit le contenu de la QueryBar.
Definition TaupieGUI.c:444
static HFONT mainFixedBlackFont
Definition TaupieGUI.c:91
#define SCROLL_IDLE_MS
Definition TaupieGUI.c:72
int RecordExecutedAction(const wchar_t *action, const wchar_t *dotCommand, const wchar_t *query, const wchar_t *error)
Enregistrement dans l'historique d'une action de l'utilisateur.
Definition TaupieGUI.c:1341
LRESULT CALLBACK QueryEdit_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
sous-procédure spécifique de la fenêtre d'écriture de requête.
Definition TaupieGUI.c:517
BOOL Main_OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh)
Gestion des notifications des composants de la fenêtre principale.
Definition TaupieGUI.c:2476
static HTREEITEM hActualSelectedTableItem
Definition TaupieGUI.c:86
static wchar_t * originalCommand
Definition TaupieGUI.c:80
void QueryBar_Create(HWND hwnd)
Création de l'espace de saisie des requêtes.
Definition TaupieGUI.c:685
void ProjectTree_Open(HWND hwnd, int option)
Ouvre/crée un projet Taupie.
Definition TaupieGUI.c:920
LRESULT CALLBACK Main_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
procédure de la fenêtre principale.
Definition TaupieGUI.c:2661
static wchar_t * sqlError
Definition TaupieGUI.c:96
void Main_OnNotify_ApplyFilter(HWND hHeader)
Application du filtre courant à la vue courante des données.
Definition TaupieGUI.c:2303
static wchar_t * currentSelectedTable
Definition TaupieGUI.c:84
void ProjectTree_Close(HWND hwnd)
Ferme le projet courant Taupie.
Definition TaupieGUI.c:870
void DataView_Close(HWND hwnd)
Ferme la table sélectionnée dans le ProjectTree.
Definition TaupieGUI.c:1049
void ProjectTree_Enlarge(void)
redimensionne en largeur le ProjectTree.
Definition TaupieGUI.c:833
int64_t ExecuteCustomSQLQuery(HWND hwnd)
Exécute une requête demandée par l'utilisateur.
Definition TaupieGUI.c:1125
int64_t ExecuteSQLScript(HWND hwnd, const wchar_t *fileName)
Exécute une requête demandée par l'utilisateur.
Definition TaupieGUI.c:1071
static HWND hMainQueryExecute
Definition TaupieGUI.c:66
void RestartScrollingTimer(HWND hwnd)
Relance la temporisation du DataView.
Definition TaupieGUI.c:2388
BOOL Main_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
Initialisation de la fenêtre principale.
Definition TaupieGUI.c:726
int64_t CreateCSVFromView(HWND hwnd)
Crée une table dans la base courante à partir d'un fichier CSV.
Definition TaupieGUI.c:1189
void Main_OnPaint(HWND hwnd)
redessine la boîte de dialogue.
Definition TaupieGUI.c:313
void Clean(void)
Supprime les fichiers temporaires de l'application.
Definition TaupieGUI.c:293
int ProjectTree_DeleteTable(HWND hwnd)
Supprime une table dans l'arbre du projet.
Definition TaupieGUI.c:1796
static HWND hMainProjectTree
Definition TaupieGUI.c:61
int ProjectTree_SelectTableByName(const wchar_t *tableName)
Recherche et sélectionne dans l'arbre du projet une table identifiée par son nom. Limite la recherche...
Definition TaupieGUI.c:158
int64_t ProjectTree_ViewAppTable(HWND hwnd, int id)
Affiche une table "système", non présente dans l'arbre du projet.
Definition TaupieGUI.c:1630
int Main_OnNotify_FillDataView(LPNMLVDISPINFOW lplvdi)
remplissage des items du DataView à la demande.
Definition TaupieGUI.c:2405
void SetVisibility(int project, int table, int query)
définit la visibilité des trois composants de l'écran.
Definition TaupieGUI.c:113
LRESULT CALLBACK Options_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
procédure du dialogue des options de ModuleTicket.
Definition TaupieGUI.c:3098
static HWND hMainQueryEdit
Definition TaupieGUI.c:65
int64_t DataView_UpdateWithAFile(HWND hwnd, HWND *pListView, RECT *rListView, sqlite3 **db, wchar_t **command, const wchar_t *fileName)
Definition TaupieGUI.c:3020
static int freezeDataView
Definition TaupieGUI.c:98
static RECT rProjectTree
Definition TaupieGUI.c:68
static int xTableView
Definition TaupieGUI.c:93
static HFONT mainFixedFont
Definition TaupieGUI.c:90
int ProjectTree_RenameTable(HWND hwnd, const wchar_t *oldTableName, const wchar_t *newTableName)
Renomme une table dans l'arbre du projet.
Definition TaupieGUI.c:1737
static wchar_t * currentCommand
Definition TaupieGUI.c:79
const wchar_t * GetCellValue(LVHITTESTINFO hti)
Fonction permettant de récupérer le texte d'une cellule sélectionnée.
Definition TaupieGUI.c:1703
void StatusBar_Update(const wchar_t *tableName, int64_t records)
Définit le contenu de la barre de statut principale.
Definition TaupieGUI.c:271
LRESULT CALLBACK QueryExecute_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
sous-procédure spécifique du bouton de lancement de la requête.
Definition TaupieGUI.c:469
static UINT_PTR scrollingTimer
Definition TaupieGUI.c:73
static HWND hMainQueryError
Definition TaupieGUI.c:64
static sqlite3 * currentDataBase
Definition TaupieGUI.c:82
LRESULT CALLBACK DataView_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
sous-procédure spécifique de la vue des données (DataView).
Definition TaupieGUI.c:2832
static RECT rDataView
Definition TaupieGUI.c:69
LRESULT CALLBACK ProjectTree_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
sous-procédure spécifique de la vue du projet (TreeView).
Definition TaupieGUI.c:2744
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
Gère les commandes de l'application.
Definition TaupieGUI.c:1873
void ProjectTree_ViewSelectedTable(HWND hwnd, HTREEITEM hItem)
Gère la sélection d'une table dans l'arbre du projet.
Definition TaupieGUI.c:2145
static HWND hMainDataView
Definition TaupieGUI.c:60
int64_t CreateTableFromCSV(HWND hwnd)
Crée une table dans la base courante à partir d'un fichier CSV.
Definition TaupieGUI.c:1431
LRESULT CALLBACK QueryError_Procedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
sous-procédure spécifique de la fenêtre d'affichage de requête.
Definition TaupieGUI.c:599
int RecordImportedFile(const wchar_t *tableName, const wchar_t *fileName, int pathLevel)
Enregistrement des caractéristiques d'un fichier importé comme table.
Definition TaupieGUI.c:1239
static HFONT mainVariableFont
Definition TaupieGUI.c:89
Déclaration des fonctions de l'interface graphique de Taupie.
#define SUBCLASS_PROJECT_ID
Definition TaupieGUI.h:22
#define SUBCLASS_QUERYEDIT_ID
Definition TaupieGUI.h:24
#define HIDE
Definition TaupieGUI.h:28
#define SUBCLASS_TABLE_ID
Definition TaupieGUI.h:23
#define SUBCLASS_QUERYERROR_ID
Definition TaupieGUI.h:25
#define SHOW
Definition TaupieGUI.h:29
#define SUBCLASS_QUERYEXECUTE_ID
Definition TaupieGUI.h:26
#define BUTTON_SIZE
Definition TaupieGUI.h:20
#define FILETYPE_PROJECT
Definition en_locale.h:95
#define FIELD_FILESIZE
Definition en_locale.h:157
#define OPEN_PROJECT
Definition en_locale.h:85
#define NEW_PROJECT
Definition en_locale.h:83
#define FIELD_RUNDATE
Definition en_locale.h:162
#define LOG_TEXTDELETETABLE
Definition en_locale.h:175
#define MESSAGE_INFO_FAILURE
Definition en_locale.h:131
#define FIELD_FILETIME
Definition en_locale.h:159
#define LOG_TEXTCREATEPROJECT
Definition en_locale.h:172
#define EMPTY_STRING
Definition en_locale.h:81
#define CONVERT_PROJECT
Definition en_locale.h:84
#define MESSAGE_QUESTION_DROPTABLE
Definition en_locale.h:134
#define FIELD_ACTION
Definition en_locale.h:161
#define FIELD_IMPORTTIME
Definition en_locale.h:154
#define FIELD_SQL
Definition en_locale.h:165
#define FIELD_RUNTIME
Definition en_locale.h:163
#define FIELD_ERROR
Definition en_locale.h:166
#define FIELD_FILEPATH
Definition en_locale.h:155
#define MESSAGE_TITLE_WARNING
Definition en_locale.h:127
#define FIELD_FILEDATE
Definition en_locale.h:158
#define LOG_TEXTRENAMETABLE
Definition en_locale.h:174
#define FIELD_DOTCOMMAND
Definition en_locale.h:164
#define MESSAGE_QUESTION_RENAMETABLE
Definition en_locale.h:133
#define FIELD_IMPORTDATE
Definition en_locale.h:153
#define FILETYPE_ANY
Definition en_locale.h:93
#define FIELD_FILENAME
Definition en_locale.h:156
#define FIELD_TABLENAME
Definition en_locale.h:152
#define LOG_TEXTRUNSQL
Definition en_locale.h:173
void ExtraInit(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
Initialisation de la fenêtre principale.
Definition extra.c:31
void Main_OnExtraCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
Gère les commandes spécifiques de l'application.
Definition extra.c:47
Déclaration de fonctions communes mais spécifiques hors Taupie. Ces fonctions peuvent être déclinées ...
Définitions et macros pour la localisation.
#define IDP_HELP
Definition resource.h:63
#define IDM_PROJECT_LOG_IMPORT
Definition resource.h:31
#define IDM_DATA_IMPORT
Definition resource.h:40
#define IDM_TABLE_EXPORT
Definition resource.h:48
#define IDM_PROJECT_LOG_COMMAND
Definition resource.h:32
#define IDM_DATA_COPYVALUE
Definition resource.h:43
#define IDM_SQL_QUERY
Definition resource.h:58
#define IDM_OPTIONS
Definition resource.h:64
#define IDM_DATA_EXPORT
Definition resource.h:41
#define IDM_DATA_CLOSE
Definition resource.h:39
#define IDM_TABLE_DELETE
Definition resource.h:47
#define IDM_PAGE_PREVIOUS
Definition resource.h:50
#define IDM_PROJECT
Definition resource.h:23
#define IDM_PROJECT_NEW
Definition resource.h:25
#define IDM_PROJECT_CLOSE
Definition resource.h:27
#define IDM_PROJECT_CONVERT
Definition resource.h:28
#define IDM_SQL_FILE
Definition resource.h:57
#define IDM_PROJECT_OPTIMIZE
Definition resource.h:30
#define IDM_PROJECT_OPEN
Definition resource.h:26
#define IDM_PROJECT_UPDATE
Definition resource.h:29
#define IDM_TABLE_RENAME
Definition resource.h:46
#define IDM_DATA
Definition resource.h:37
#define IDM_SQL
Definition resource.h:56
#define IDM_PAGE_NEXT
Definition resource.h:51
#define IDM_INIT
Definition resource.h:22
#define SOFT_NAMEW
Definition version.h:26