#include <commdlg.h>
#include <richedit.h>
#include <stdio.h>
+#include <sys/stat.h>
#include "qcc.h"
#include "gui.h"
-
-
/*
==============
LoadFile
==============
*/
-unsigned char *QCC_ReadFile (char *fname, void *buffer, int len)
+unsigned char *QCC_ReadFile (const char *fname, void *buffer, int len)
{
long length;
FILE *f;
return buffer;
}
-int QCC_FileSize (char *fname)
+int QCC_FileSize (const char *fname)
{
long length;
FILE *f;
return length;
}
-pbool QCC_WriteFile (char *name, void *data, int len)
+pbool QCC_WriteFile (const char *name, void *data, int len)
{
long length;
FILE *f;
char filename[MAX_PATH]; //abs
HWND window;
HWND editpane;
+ pbool modified;
+ time_t filemodifiedtime;
struct editor_s *next;
} editor_t;
editor_t *editors;
+void EditorReload(editor_t *editor);
int EditorSave(editor_t *edit);
void EditFile(char *name, int line);
pbool EditorModified(editor_t *e);
break;
case IDM_ABOUT:
- MessageBox(NULL, "FTE QuakeC Compiler\nWritten by Forethough Entertainment.\nBasically that means it was written by Spike.\n\nIt has a few cool features, like a useful IDE.\n\nSupports:\nPrecompiler (with macros)\nArrays\n+= / -= / *= / /= operations.\nSwitch statements\nfor loops\nLots of optimisations.", "About", 0);
+ MessageBox(NULL, "FTE QuakeC Compiler\nWritten by Forethough Entertainment.\n\nIt has a few cool features, like a semi-useful IDE.\n\nSupports:\nPrecompiler (with macros)\nArrays\n+= / -= / *= / /= operations.\nSwitch statements\nfor loops\nLots of optimisations.", "About", 0);
break;
case IDM_CASCADE:
{
case WM_CLOSE:
case WM_QUIT:
- if (EditorModified(editor))
+ if (editor->modified)
{
switch (MessageBox(hWnd, "Would you like to save?", editor->filename, MB_YESNOCANCEL))
{
return TRUE;
break;
case WM_COMMAND:
- if (mdibox)
- goto gdefault;
- EditorMenu(editor, wParam);
+ if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == editor->editpane)
+ {
+ if (!editor->modified)
+ {
+ char title[2048];
+ CHARRANGE chrg;
+
+ editor->modified = true;
+ if (EditorModified(editor))
+ if (MessageBox(NULL, "warning: file was modified externally. reload?", "Modified!", MB_YESNO) == IDYES)
+ EditorReload(editor);
+
+
+ SendMessage(editor->editpane, EM_EXGETSEL, 0, (LPARAM) &chrg);
+ if (editor->modified)
+ sprintf(title, "*%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, chrg.cpMin));
+ else
+ sprintf(title, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, chrg.cpMin));
+ SetWindowText(editor->window, title);
+ }
+ }
+ else
+ {
+ if (mdibox)
+ goto gdefault;
+ EditorMenu(editor, wParam);
+ }
break;
case WM_NOTIFY:
{
NMHDR *nmhdr;
SELCHANGE *sel;
- char message[2048];
+ char title[2048];
nmhdr = (NMHDR *)lParam;
switch(nmhdr->code)
{
case EN_SELCHANGE:
sel = (SELCHANGE *)nmhdr;
- sprintf(message, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin));
- SetWindowText(editor->window, message);
+ if (editor->modified)
+ sprintf(title, "*%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin));
+ else
+ sprintf(title, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin));
+ SetWindowText(editor->window, title);
break;
}
}
InvalidateRect(edit->editpane, NULL, true);
InvalidateRect(edit->window, NULL, true);
- SendMessage(edit->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
+ SendMessage(edit->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE|ENM_CHANGE);
SendMessage(edit->editpane, EM_SETSCROLLPOS, 0, (LPARAM)&scrollpos);
SendMessage(edit->editpane, EM_EXSETSEL, 0, (LPARAM) &chrg);
}
#endif
-void EditFile(char *name, int line)
+void EditorReload(editor_t *editor)
{
- char title[1024];
+ struct stat sbuf;
int flen;
char *file;
+
+ flen = QCC_FileSize(editor->filename);
+ if (flen >= 0)
+ {
+ file = malloc(flen+1);
+ QCC_ReadFile(editor->filename, file, flen);
+ file[flen] = 0;
+ }
+
+ SendMessage(editor->editpane, EM_SETEVENTMASK, 0, 0);
+
+ /*clear it out*/
+ Edit_SetSel(editor->editpane,0,Edit_GetTextLength(editor->editpane));
+ Edit_ReplaceSel(editor->editpane,"");
+
+ if (!fl_autohighlight)
+ {
+ GUIPrint(editor->editpane, file);
+ }
+ else
+ {
+ GUIFormattingPrint(editor->editpane, file);
+ }
+ free(file);
+
+ editor->modified = false;
+ stat(editor->filename, &sbuf);
+ editor->filemodifiedtime = sbuf.st_mtime;
+
+ SendMessage(editor->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE|ENM_CHANGE);
+}
+
+void EditFile(char *name, int line)
+{
+ char title[1024];
editor_t *neweditor;
WNDCLASS wndclass;
HMENU menu, menufile, menuhelp, menunavig;
}
}
- flen = QCC_FileSize(name);
- if (flen == -1)
+ if (QCC_FileSize(name) == -1)
{
MessageBox(NULL, "File not found.", "Error", 0);
return;
menufile = CreateMenu();
menuhelp = CreateMenu();
menunavig = CreateMenu();
- AppendMenu(menu, MF_POPUP, (UINT)menufile, "&File");
- AppendMenu(menu, MF_POPUP, (UINT)menunavig, "&Navigation");
- AppendMenu(menu, MF_POPUP, (UINT)menuhelp, "&Help");
+ AppendMenu(menu, MF_POPUP, (UINT_PTR)menufile, "&File");
+ AppendMenu(menu, MF_POPUP, (UINT_PTR)menunavig, "&Navigation");
+ AppendMenu(menu, MF_POPUP, (UINT_PTR)menuhelp, "&Help");
AppendMenu(menufile, 0, IDM_OPENNEW, "Open &new file ");
AppendMenu(menufile, 0, IDM_SAVE, "&Save ");
// AppendMenu(menufile, 0, IDM_FIND, "&Find");
mcs.lParam = 0;
neweditor->window = (HWND) SendMessage (mdibox, WM_MDICREATE, 0,
- (LONG) (LPMDICREATESTRUCT) &mcs);
+ (LONG_PTR) (LPMDICREATESTRUCT) &mcs);
}
else
{
return;
}
- flen = QCC_FileSize(name);
- file = malloc(flen+1);
- QCC_ReadFile(name, file, flen);
- file[flen] = 0;
-
- SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, 0);
-
- if (!fl_autohighlight)
- {
- GUIPrint(neweditor->editpane, file);
- }
- else
- {
- GUIFormattingPrint(neweditor->editpane, file);
- }
-
- SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
+ EditorReload(neweditor);
if (line >= 0)
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1));
int EditorSave(editor_t *edit)
{
+ struct stat sbuf;
int len;
char *file;
len = Edit_GetTextLength(edit->editpane);
}
free(file);
+ /*now whatever is on disk should have the current time*/
+ edit->modified = false;
+ stat(edit->filename, &sbuf);
+ edit->filemodifiedtime = sbuf.st_mtime;
+
return true;
}
void EditorsRun(void)
}
-char *GUIReadFile(char *fname, void *buffer, int blen)
+char *GUIReadFile(const char *fname, void *buffer, int blen)
{
editor_t *e;
for (e = editors; e; e = e->next)
return QCC_ReadFile(fname, buffer, blen);
}
-int GUIFileSize(char *fname)
+int GUIFileSize(const char *fname)
{
editor_t *e;
for (e = editors; e; e = e->next)
return QCC_FileSize(fname);
}
+/*checks if the file has been modified externally*/
pbool EditorModified(editor_t *e)
{
- char *buffer;
- int elen, flen;
- elen = Edit_GetTextLength(e->editpane);
- flen = QCC_FileSize(e->filename);
-
- if (elen != flen)
+ struct stat sbuf;
+ stat(e->filename, &sbuf);
+ if (e->filemodifiedtime != sbuf.st_mtime)
return true;
- buffer = malloc(elen+flen);
- Edit_GetText(e->editpane, buffer, elen);
- QCC_ReadFile(e->filename, buffer+elen, flen);
- if (memcmp(buffer, buffer+elen, elen))
- {
- free(buffer);
- return true;
- }
- free(buffer);
-
return false;
}
HMENU rootmenu, windowmenu, m;
rootmenu = CreateMenu();
- AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()), "&File");
+ AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()), "&File");
AppendMenu(m, 0, IDM_OPENNEW, "Open &new file ");
AppendMenu(m, 0, IDM_SAVE, "&Save ");
// AppendMenu(m, 0, IDM_FIND, "&Find");
AppendMenu(m, 0, IDM_UNDO, "&Undo Ctrl+Z");
AppendMenu(m, 0, IDM_REDO, "&Redo Ctrl+Y");
- AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()), "&Navigation");
+ AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()), "&Navigation");
AppendMenu(m, 0, IDM_GOTODEF, "Go to definition");
AppendMenu(m, 0, IDM_OPENDOCU, "Open selected file");
- AppendMenu(rootmenu, MF_POPUP, (UINT)(m = windowmenu = CreateMenu()), "&Window");
+ AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = windowmenu = CreateMenu()), "&Window");
AppendMenu(m, 0, IDM_CASCADE, "&Cascade");
AppendMenu(m, 0, IDM_TILE_HORIZ, "Tile &Horizontally");
AppendMenu(m, 0, IDM_TILE_VERT, "Tile &Vertically");
- AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()), "&Help");
+ AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()), "&Help");
AppendMenu(m, 0, IDM_ABOUT, "About");
SetMenu(hWnd, rootmenu);
void Sys_Error(const char *text, ...);
void RunCompiler(char *args)
{
- char *argv[64];
+ char *argv[128];
int argc;
progexterns_t ext;
progfuncs_t funcs;
+ editor_t *editor;
+ for (editor = editors; editor; editor = editor->next)
+ {
+ if (editor->modified)
+ {
+ if (EditorModified(editor))
+ {
+ char msg[1024];
+ sprintf(msg, "%s is modified in both memory and on disk. Overwrite external modification? (saying no will reload from disk)", editor->filename);
+ switch(MessageBox(NULL, msg, "Modification conflict", MB_YESNOCANCEL))
+ {
+ case IDYES:
+ EditorSave(editor);
+ break;
+ case IDNO:
+ EditorReload(editor);
+ break;
+ case IDCANCEL:
+ break; /*compiling will use whatever is in memory*/
+ }
+ }
+ else
+ {
+ /*not modified on disk, but modified in memory? try and save it, cos we might as well*/
+ EditorSave(editor);
+ }
+ }
+ else
+ {
+ /*modified on disk but not in memory? just reload it off disk*/
+ if (EditorModified(editor))
+ EditorReload(editor);
+ }
+ }
+
memset(&funcs, 0, sizeof(funcs));
funcs.parms = &ext;
memset(&ext, 0, sizeof(ext));
mcs.lParam = 0;
outputwindow = (HWND) SendMessage (mdibox, WM_MDICREATE, 0,
- (LONG) (LPMDICREATESTRUCT) &mcs);
+ (LONG_PTR) (LPMDICREATESTRUCT) &mcs);
ShowWindow(outputwindow, SW_SHOW);
}