Skip to content

Commit 7b5f586

Browse files
committed
Major refactor for 0.4.0: split SQLite/CEdit main file into distinct domain files for easier maintenance. Incremented internal version number.
1 parent 2154fc4 commit 7b5f586

12 files changed

Lines changed: 2508 additions & 2396 deletions

File tree

src/sqlite-ce-edit/database.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
** SQLiteCEdit - Database operations
3+
*/
4+
5+
#include "globals.h"
6+
7+
void SetStatusDb(const wchar_t *sz) {
8+
SendMessageW(g_hwndStatus, SB_SETTEXTW, 0, (LPARAM)sz);
9+
}
10+
11+
void SetStatusResult(const wchar_t *sz) {
12+
/* Save for when switching back to results view */
13+
int i;
14+
for (i = 0; i < 63 && sz[i]; i++) g_lastResultStatus[i] = sz[i];
15+
g_lastResultStatus[i] = 0;
16+
if (g_viewMode == 1)
17+
SendMessageW(g_hwndStatus, SB_SETTEXTW, 1, (LPARAM)sz);
18+
}
19+
20+
/* Helper to extract filename from path */
21+
const wchar_t *GetFilename(const wchar_t *path) {
22+
const wchar_t *p = path;
23+
const wchar_t *last = path;
24+
while (*p) {
25+
if (*p == '\\' || *p == '/') last = p + 1;
26+
p++;
27+
}
28+
return last;
29+
}
30+
31+
void UpdateDbSize(void) {
32+
wchar_t buf[64];
33+
const wchar_t *fn;
34+
wchar_t name[64];
35+
wchar_t *p;
36+
long size = 0;
37+
int canClose;
38+
39+
if (!g_db) return;
40+
41+
if (g_szDbPath[0] == ':') {
42+
lstrcpyW(name, L":memory:");
43+
} else {
44+
fn = GetFilename(g_szDbPath);
45+
p = name;
46+
while (*fn && *fn != '.' && p < name + 60) *p++ = *fn++;
47+
*p = 0;
48+
}
49+
50+
/* Get file size for file databases */
51+
if (g_szDbPath[0] != ':') {
52+
HANDLE hFile = CreateFileW(g_szDbPath, GENERIC_READ, FILE_SHARE_READ,
53+
NULL, OPEN_EXISTING, 0, NULL);
54+
if (hFile != INVALID_HANDLE_VALUE) {
55+
size = GetFileSize(hFile, NULL);
56+
CloseHandle(hFile);
57+
}
58+
}
59+
60+
if (size >= 1024 * 1024)
61+
wsprintfW(buf, L"%s (%ldM)", name, size / (1024 * 1024));
62+
else if (size >= 1024)
63+
wsprintfW(buf, L"%s (%ldk)", name, size / 1024);
64+
else if (size > 0)
65+
wsprintfW(buf, L"%s (%ldb)", name, size);
66+
else
67+
wsprintfW(buf, L"%s", name);
68+
SetStatusDb(buf);
69+
70+
/* Enable/disable Close based on whether we have a real file */
71+
canClose = (g_szDbPath[0] && g_szDbPath[0] != ':');
72+
EnableMenuItem(g_hMenu, IDM_CLOSE, canClose ? MF_ENABLED : MF_GRAYED);
73+
SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_CLOSE, canClose);
74+
}
75+
76+
/* Update title bar: "[query -] database - SQLite/CE" */
77+
void UpdateTitle(void) {
78+
wchar_t title[MAX_PATH];
79+
wchar_t *p = title;
80+
const wchar_t *fn;
81+
82+
/* Query filename (without extension) */
83+
if (g_szQueryPath[0]) {
84+
fn = GetFilename(g_szQueryPath);
85+
while (*fn && *fn != '.' && p < title + MAX_PATH - 40) *p++ = *fn++;
86+
*p++ = ' '; *p++ = '-'; *p++ = ' ';
87+
}
88+
89+
/* Database name (without extension) */
90+
if (g_szDbPath[0] == ':') {
91+
lstrcpyW(p, L"(memory) - SQLite/CE");
92+
} else if (g_szDbPath[0]) {
93+
fn = GetFilename(g_szDbPath);
94+
while (*fn && *fn != '.' && p < title + MAX_PATH - 15) *p++ = *fn++;
95+
lstrcpyW(p, L" - SQLite/CE");
96+
} else {
97+
lstrcpyW(p, L"SQLite/CE");
98+
}
99+
SetWindowTextW(g_hwndMain, title);
100+
}
101+
102+
void CloseDatabase(void) {
103+
if (g_db) {
104+
sqlite_close(g_db);
105+
g_db = NULL;
106+
}
107+
g_szDbPath[0] = '\0';
108+
/* Reopen in-memory database as scratchpad */
109+
g_db = sqlite_open(":memory:", 0, NULL);
110+
lstrcpyW(g_szDbPath, L":memory:");
111+
UpdateTitle();
112+
SetWindowTextW(g_hwndResult, L"");
113+
SetStatusDb(L":memory:");
114+
SetStatusResult(L"");
115+
/* Disable Close for in-memory database */
116+
EnableMenuItem(g_hMenu, IDM_CLOSE, MF_GRAYED);
117+
SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_CLOSE, FALSE);
118+
}
119+
120+
int OpenDatabase(const wchar_t *path) {
121+
char szPath[MAX_PATH * 2];
122+
char *errmsg = NULL;
123+
124+
CloseDatabase();
125+
126+
WideCharToMultiByte(CP_ACP, 0, path, -1, szPath, sizeof(szPath), NULL, NULL);
127+
g_db = sqlite_open(szPath, 0, &errmsg);
128+
129+
if (!g_db) {
130+
wchar_t msg[256];
131+
wsprintfW(msg, L"Cannot open: %s", path);
132+
MessageBoxW(g_hwndMain, msg, L"Error", MB_OK | MB_ICONERROR);
133+
if (errmsg) sqlite_freemem(errmsg);
134+
SetStatusDb(L"No database");
135+
return 0;
136+
}
137+
138+
lstrcpyW(g_szDbPath, path);
139+
UpdateTitle();
140+
UpdateDbSize();
141+
SetStatusResult(L"");
142+
143+
/* Show hint for in-memory database in query pane */
144+
if (path[0] == ':') {
145+
wchar_t hint[256];
146+
wchar_t ver[32];
147+
const char *v = sqlite_libversion();
148+
int i;
149+
for (i = 0; v[i] && i < 31; i++) ver[i] = (wchar_t)v[i];
150+
ver[i] = 0;
151+
wsprintfW(hint,
152+
L"-- SQLite/CEdit " SQLITECEDIT_VERSION L" on SQLite %s.\r\n"
153+
L"-- Using in-memory database.\r\n", ver);
154+
SetWindowTextW(g_hwndQuery, hint);
155+
g_showingHint = 1;
156+
}
157+
return 1;
158+
}

src/sqlite-ce-edit/dialogs.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
** SQLiteCEdit - Dialogs (About, Path prompt)
3+
*/
4+
5+
#include "globals.h"
6+
7+
/*============================================================================
8+
** About Dialog
9+
**============================================================================*/
10+
11+
static HBITMAP g_hLogo = NULL;
12+
13+
static LRESULT CALLBACK AboutWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
14+
switch (msg) {
15+
case WM_CREATE: {
16+
wchar_t text[256];
17+
wchar_t ver[32], built[32];
18+
const char *sv = sqlite_libversion();
19+
const char *bd = __DATE__;
20+
int i, j;
21+
for (i = 0; sv[i] && i < 31; i++) ver[i] = sv[i];
22+
ver[i] = 0;
23+
for (i = 0, j = 0; bd[i] && j < 31; i++) {
24+
if (bd[i] == ' ' && bd[i+1] == ' ') continue;
25+
built[j++] = bd[i];
26+
}
27+
built[j] = 0;
28+
wsprintfW(text,
29+
L"SQLite/CEdit " SQLITECEDIT_VERSION L" (using SQLite %s)\n"
30+
L"(C) Intermountain Systems\n"
31+
L"Build date: %s", ver, built);
32+
CreateWindowW(L"STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP,
33+
61, 10, 128, 64, hwnd, (HMENU)100, g_hInst, NULL);
34+
SendDlgItemMessage(hwnd, 100, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_hLogo);
35+
CreateWindowW(L"STATIC", text, WS_CHILD | WS_VISIBLE | SS_CENTER,
36+
5, 80, 240, 50, hwnd, NULL, g_hInst, NULL);
37+
return 0;
38+
}
39+
case WM_COMMAND:
40+
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
41+
DestroyWindow(hwnd);
42+
SetFocus(g_viewMode == 0 ? g_hwndQuery : g_hwndResult);
43+
return 0;
44+
}
45+
break;
46+
case WM_KEYDOWN:
47+
if (wParam == VK_ESCAPE || wParam == VK_RETURN) {
48+
DestroyWindow(hwnd);
49+
SetFocus(g_viewMode == 0 ? g_hwndQuery : g_hwndResult);
50+
return 0;
51+
}
52+
break;
53+
case WM_CLOSE:
54+
DestroyWindow(hwnd);
55+
SetFocus(g_viewMode == 0 ? g_hwndQuery : g_hwndResult);
56+
return 0;
57+
}
58+
return DefWindowProc(hwnd, msg, wParam, lParam);
59+
}
60+
61+
void DoAbout(void) {
62+
WNDCLASSW wc = {0};
63+
RECT rc;
64+
HWND hwndAbout;
65+
66+
if (!g_hLogo)
67+
g_hLogo = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_LOGO));
68+
69+
wc.lpfnWndProc = AboutWndProc;
70+
wc.hInstance = g_hInst;
71+
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
72+
wc.lpszClassName = L"SQLiteCEAbout";
73+
RegisterClassW(&wc);
74+
75+
GetWindowRect(g_hwndMain, &rc);
76+
hwndAbout = CreateWindowW(L"SQLiteCEAbout", L"About",
77+
WS_POPUP | WS_CAPTION | WS_SYSMENU,
78+
rc.left + 30, rc.top + 30, 250, 160,
79+
g_hwndMain, NULL, g_hInst, NULL);
80+
ShowWindow(hwndAbout, SW_SHOW);
81+
}
82+
83+
/*============================================================================
84+
** Simple Path Input Dialog
85+
**============================================================================*/
86+
87+
static wchar_t g_szPathBuf[MAX_PATH];
88+
static HWND g_hwndPathEdit;
89+
90+
static LRESULT CALLBACK PathDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
91+
switch (msg) {
92+
case WM_INITDIALOG: {
93+
RECT rc;
94+
GetClientRect(hwnd, &rc);
95+
g_hwndPathEdit = CreateWindowW(L"EDIT", g_szPathBuf,
96+
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
97+
10, 10, rc.right - 20, 26,
98+
hwnd, (HMENU)101, g_hInst, NULL);
99+
CreateWindowW(L"BUTTON", L"OK",
100+
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
101+
10, 46, 60, 26, hwnd, (HMENU)IDOK, g_hInst, NULL);
102+
CreateWindowW(L"BUTTON", L"Cancel",
103+
WS_CHILD | WS_VISIBLE,
104+
80, 46, 60, 26, hwnd, (HMENU)IDCANCEL, g_hInst, NULL);
105+
SetFocus(g_hwndPathEdit);
106+
return FALSE;
107+
}
108+
case WM_COMMAND:
109+
if (LOWORD(wParam) == IDOK) {
110+
GetWindowTextW(g_hwndPathEdit, g_szPathBuf, MAX_PATH);
111+
EndDialog(hwnd, IDOK);
112+
} else if (LOWORD(wParam) == IDCANCEL) {
113+
EndDialog(hwnd, IDCANCEL);
114+
}
115+
return TRUE;
116+
case WM_CLOSE:
117+
EndDialog(hwnd, IDCANCEL);
118+
return TRUE;
119+
}
120+
return FALSE;
121+
}
122+
123+
int PromptForPath(const wchar_t *title, const wchar_t *defPath) {
124+
struct {
125+
DLGTEMPLATE tmpl;
126+
WORD menu, wndclass, title;
127+
} dlg;
128+
129+
(void)title; /* TODO: use title in dialog */
130+
lstrcpyW(g_szPathBuf, defPath);
131+
132+
memset(&dlg, 0, sizeof(dlg));
133+
dlg.tmpl.style = WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME;
134+
dlg.tmpl.cx = 160;
135+
dlg.tmpl.cy = 50;
136+
dlg.tmpl.x = 20;
137+
dlg.tmpl.y = 20;
138+
139+
return DialogBoxIndirectW(g_hInst, &dlg.tmpl, g_hwndMain, PathDlgProc) == IDOK;
140+
}

0 commit comments

Comments
 (0)