Update the changelog
[opencv] / apps / Tracker3dDemo / FilenamesDialog.cpp
1 #pragma warning(disable: 4786)
2 #include "FilenamesDialog.h"
3
4 static void AddStr(char *&p, const wchar_t *item)
5 {
6     size_t sz = (wcslen(item) + 1) * 2;
7     memcpy(p, item, sz);
8     p += sz;
9 }
10
11 void AddItem(char *&p, const DLGITEMTEMPLATE &item_tmpl, WORD item_class, const wchar_t *title)
12 {
13     // make sure the beginning of each DLGITEMTEMPLATE is DWORD aligned.
14     if ((int)p & 2)
15         p += 2;
16     *(DLGITEMTEMPLATE*)p = item_tmpl;
17     p += sizeof(DLGITEMTEMPLATE);
18     *(WORD*)p = (WORD)0xffff;
19     p += sizeof(WORD);
20     *(WORD*)p = item_class;
21     p += sizeof(WORD);
22     AddStr(p, title);
23     *(WORD*)p = (WORD)0;
24     p += sizeof(WORD);
25 }
26
27 #define ID_LABEL  20
28 #define ID_EDIT   40
29 #define ID_BROWSE 60
30
31 static BOOL CALLBACK DlgProc(HWND dlg, UINT msg, WPARAM w, LPARAM l);
32 static void LoadCameraIntrinsicsFilenames(std::vector<std::string> &filenames);
33 static void SaveCameraIntrinsicsFilenames(const std::vector<std::string> &filenames);
34
35 bool FilenamesDialog(HWND parent, int num_filenames, std::vector<std::string> &filenames)
36 {
37     int i;
38
39     if (num_filenames > 20)
40         return false;
41
42     if (filenames.size() == 0)
43         LoadCameraIntrinsicsFilenames(filenames);
44
45     filenames.resize(num_filenames);
46
47     int name_size = 0;
48     for (i = 0; i < num_filenames; i++)
49         name_size += filenames[i].length() + 1;
50
51     int num_items = num_filenames*3 + 2;
52     int width = 200;
53     int height = 35 + num_filenames * 20;
54     size_t sz = sizeof(DLGTEMPLATE)+90 + num_items * (sizeof(DLGITEMTEMPLATE)+18) + name_size*2;
55     char *dlgtmpl = (char *)malloc(sz);
56     char *p = dlgtmpl;
57     DLGTEMPLATE dlgtemplate = { WS_POPUP|WS_CAPTION|DS_MODALFRAME|DS_SETFONT|DS_SETFOREGROUND, 0, num_items, 0, 0, width, height };
58     *(DLGTEMPLATE*)p = dlgtemplate;
59     p += sizeof(DLGTEMPLATE);
60     *(DWORD*)p = 0;
61     p += sizeof(DWORD);
62     AddStr(p, L"Camera Intrinsics Filenames"); // title
63     *(WORD*)p = 8;
64     p += sizeof(WORD);
65     AddStr(p, L"MS Sans Serif"); // font
66
67 #define BUTTON 0x80
68 #define EDIT   0x81
69 #define STATIC 0x82
70     for (i = 0; i < num_filenames; i++)
71     {
72         DLGITEMTEMPLATE label = { SS_LEFT|WS_CHILD|WS_VISIBLE, 0, 10, 12+i*20, 40, 13, ID_LABEL+i };
73         DLGITEMTEMPLATE edit = { ES_LEFT|WS_BORDER|WS_TABSTOP|WS_CHILD|WS_VISIBLE, 0, 50, 10+i*20, width-75, 13, ID_EDIT+i };
74         DLGITEMTEMPLATE browse = { BS_PUSHBUTTON|WS_TABSTOP|WS_CHILD|WS_VISIBLE, 0, width-25, 10+i*20, 13, 13, ID_BROWSE+i };
75         wchar_t text[MAX_PATH];
76         swprintf(text, L"Camera %d", i+1);
77         AddItem(p, label, STATIC, text);
78         mbstowcs(text, filenames[i].c_str(), sizeof(text));
79         AddItem(p, edit, EDIT, text);
80         AddItem(p, browse, BUTTON, L"...");
81     }
82     DLGITEMTEMPLATE ok = { BS_DEFPUSHBUTTON|WS_TABSTOP|WS_CHILD|WS_VISIBLE, 0, 40, height - 20, 50, 14, IDOK };
83     DLGITEMTEMPLATE cancel = { BS_PUSHBUTTON|WS_TABSTOP|WS_CHILD|WS_VISIBLE, 0, width-90, height - 20, 50, 14, IDCANCEL };
84     AddItem(p, ok, BUTTON, L"OK");
85     AddItem(p, cancel, BUTTON, L"Cancel");
86
87     int r = DialogBoxIndirectParam(0, (DLGTEMPLATE *)dlgtmpl, parent, DlgProc, (LPARAM)&filenames);
88     free(dlgtmpl);
89
90     if (r == IDOK)
91         SaveCameraIntrinsicsFilenames(filenames);
92
93     return r == IDOK;
94 }
95
96 static BOOL CALLBACK DlgProc(HWND dlg, UINT msg, WPARAM w, LPARAM l)
97 {
98     char filename[MAX_PATH];
99     switch (msg)
100     {
101         case WM_INITDIALOG:
102             SetWindowLong(dlg, GWL_USERDATA, l);
103             return true;
104
105         case WM_COMMAND:
106             int control = LOWORD(w);
107             if (control == IDOK)
108             {
109                 std::vector<std::string> *filenames = (std::vector<std::string> *)GetWindowLong(dlg, GWL_USERDATA);
110                 for (int i = 0; i < filenames->size(); i++)
111                 {
112                     GetWindowText(GetDlgItem(dlg, ID_EDIT+i), filename, sizeof(filename));
113                     (*filenames)[i] = filename;
114                 }
115
116                 EndDialog(dlg, IDOK);
117                 return true;
118             }
119             else if (control == IDCANCEL)
120             {
121                 EndDialog(dlg, IDCANCEL);
122                 return true;
123             }
124             else if (control >= ID_BROWSE && control < ID_BROWSE+20)
125             {
126                 const char filter[] = "*.txt\0*.txt\0All files\0*.*\0";
127                 int index = control-ID_BROWSE;
128                 HWND edit = GetDlgItem(dlg, ID_EDIT+index);
129                 GetWindowText(edit, filename, sizeof(filename));
130                 OPENFILENAME ofn = { sizeof(OPENFILENAME), dlg, 0, filter, NULL, 0, 1,
131                                      filename, sizeof(filename), NULL, 0, NULL, "Camera Intrinsics File",
132                                      OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_NOCHANGEDIR|OFN_HIDEREADONLY };
133                 if (GetOpenFileName(&ofn))
134                     SetWindowText(edit, filename);
135                 return true;
136             }
137     }
138     return false;
139 }
140
141
142 class AutoCloseKey
143 {
144     HKEY *m_pkey;
145
146 public:
147     AutoCloseKey(HKEY *pkey) : m_pkey(pkey) { };
148     ~AutoCloseKey()
149     {
150         if (*m_pkey != 0)
151         {
152             RegCloseKey(*m_pkey);
153             *m_pkey = 0;
154         }
155     };
156 };
157
158 #define AUTO_CLOSE_KEY(f) AutoCloseKey AutoCloseKey##f(&f)
159
160 static const char key_name[] = "Software\\Intel\\VAI\\3d Tracker\\";
161
162
163 static void LoadCameraIntrinsicsFilenames(std::vector<std::string> &filenames)
164 {
165     LONG r;
166     
167     HKEY key = 0; AUTO_CLOSE_KEY(key);
168     r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &key);
169     if (r != ERROR_SUCCESS)
170         return;
171
172     char names[2000];
173     DWORD size = sizeof(names);
174     r = RegQueryValueEx(key, "CameraIntrinsicsFilenames", 0, NULL, (BYTE *)names, &size);
175     if (r != ERROR_SUCCESS)
176         return;
177
178     filenames.resize(0);
179     const char *p = names;
180     while (*p != '\0')
181     {
182         filenames.push_back(p);
183         p += strlen(p) + 1;
184     }
185 }
186
187 static void SaveCameraIntrinsicsFilenames(const std::vector<std::string> &filenames)
188 {
189     LONG r;
190     
191     HKEY key = 0; AUTO_CLOSE_KEY(key);
192     r = RegCreateKeyEx(HKEY_LOCAL_MACHINE, key_name, 0, NULL, 0, KEY_WRITE, NULL, &key, NULL);
193     if (r != ERROR_SUCCESS)
194         return;
195
196     char names[2000];
197     // Warning: no overflow protection
198     char *p = names;
199     for (int i = 0; i < filenames.size(); i++)
200     {
201         strcpy(p, filenames[i].c_str());
202         p += filenames[i].length() + 1;
203     }
204     *p = '\0';
205
206     DWORD size = p - names + 1;
207
208     RegSetValueEx(key, "CameraIntrinsicsFilenames", 0, REG_MULTI_SZ, (BYTE *)names, size);
209 }