Files
BlitzNext/ide/mainframe.cpp
T

1097 lines
23 KiB
C++
Raw Normal View History

2019-01-19 18:31:46 +01:00
#include "mainframe.h"
#include "about.h"
#include "blitzide.h"
#include "libs.h"
#include "resource.h"
#include "stdafx.h"
#include <mmsystem.h>
#include <fstream>
#include <sstream>
IMPLEMENT_DYNAMIC(MainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(MainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_CLOSE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_ACTIVATE()
ON_COMMAND(Inew, fileNew)
ON_COMMAND(ID_OPEN, fileOpen)
ON_COMMAND(ID_SAVE, fileSave)
ON_COMMAND(ID_SAVEAS, fileSaveAs)
ON_COMMAND(ID_SAVEALL, fileSaveAll)
ON_COMMAND(ID_PRINT, filePrint)
ON_COMMAND(ID_CLOSE, fileClose)
ON_COMMAND(ID_CLOSEALL, fileCloseAll)
ON_COMMAND(ID_EXIT, fileExit)
ON_COMMAND_RANGE(333, 343, fileRecent)
ON_COMMAND(ID_CUT, editCut)
ON_COMMAND(ID_COPY, editCopy)
ON_COMMAND(ID_PASTE, editPaste)
ON_COMMAND(ID_SELECTALL, editSelectAll)
ON_COMMAND(ID_FIND, editFind)
ON_COMMAND(ID_FINDNEXT, editFindNext)
ON_COMMAND(ID_REPLACE, editReplace)
ON_COMMAND(ID_CTRLTAB, ctrlTab)
ON_COMMAND(ID_CTRLSHIFTTAB, ctrlShiftTab)
ON_COMMAND(ID_ESCAPE, escape)
ON_COMMAND(ID_QUICKHELP, quick_Help)
ON_COMMAND(ID_EXECUTE, programExecute)
ON_COMMAND(ID_REEXECUTE, programReExecute)
ON_COMMAND(ID_COMPILE, programCompile)
ON_COMMAND(ID_PUBLISH, programPublish)
ON_COMMAND(ID_COMMANDLINE, programCommandLine)
ON_COMMAND(ID_DEBUG, programDebug)
ON_COMMAND(ID_HOME, helpHome)
ON_COMMAND(ID_BACK, helpBack)
ON_COMMAND(ID_FORWARD, helpForward)
ON_COMMAND(ID_ABOUT, helpAbout)
ON_UPDATE_COMMAND_UI(Inew, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_OPEN, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_SAVE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_SAVEAS, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_SAVEALL, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_PRINT, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_CLOSE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_CLOSEALL, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_CUT, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_COPY, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_PASTE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_SELECTALL, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_FIND, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_FINDNEXT, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_REPLACE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_EXECUTE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_REEXECUTE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_COMPILE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_PUBLISH, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_COMMANDLINE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_DEBUG, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_HOME, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_BACK, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_FORWARD, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_ESCAPE, updateCmdUI)
ON_UPDATE_COMMAND_UI(ID_QUICKHELP, updateCmdUI)
ON_UPDATE_COMMAND_UI_RANGE(333, 343, updateCmdUIRange)
END_MESSAGE_MAP()
enum { TAB_INVALID, TAB_EDITOR, TAB_HTMLHELP, TAB_DEBUGLOG };
static string getFile(const string& f)
{
int n;
string t = f;
n = t.rfind('/');
if (n != string::npos)
t = t.substr(n + 1);
n = t.rfind('\\');
if (n != string::npos)
t = t.substr(n + 1);
return t;
}
static string getPath(const string& f)
{
int n;
string t = f;
n = t.rfind('/');
if (n != string::npos)
t = t.substr(0, n);
n = t.rfind('\\');
if (n != string::npos)
t = t.substr(0, n);
return t;
}
MainFrame::MainFrame() : exit_flag(false) {}
int MainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWnd::OnCreate(lpCreateStruct);
static HBITMAP toolbmp;
static SIZE imgsz, butsz;
static UINT toolbuts[] = {Inew, ID_OPEN, ID_SAVE, ID_CLOSE, ID_SEPARATOR, ID_CUT,
ID_COPY, ID_PASTE, ID_SEPARATOR, ID_FIND, ID_SEPARATOR, ID_EXECUTE,
ID_SEPARATOR, ID_HOME, ID_BACK, ID_FORWARD};
static int toolcnt = sizeof(toolbuts) / sizeof(UINT);
if (!toolbmp) {
BITMAP bm;
string t = prefs.homeDir + "/cfg/ide_toolbar.bmp";
toolbmp = (HBITMAP)LoadImage(0, t.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_LOADMAP3DCOLORS);
if (!toolbmp) {
AfxMessageBox("toolbar bitmap failed to load!");
ExitProcess(0);
}
GetObject(toolbmp, sizeof(bm), &bm);
int n = 0;
for (int k = 0; k < toolcnt; ++k)
if (toolbuts[k] != ID_SEPARATOR)
++n;
imgsz.cx = bm.bmWidth / n;
imgsz.cy = bm.bmHeight;
butsz.cx = imgsz.cx + 7;
butsz.cy = imgsz.cy + 6;
}
toolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS);
toolBar.SetBitmap(toolbmp);
toolBar.SetSizes(butsz, imgsz);
toolBar.SetButtons(toolbuts, toolcnt);
int style;
style = WS_CHILD | WS_VISIBLE | CBRS_ALIGN_BOTTOM;
statusBar.CreateEx(this, 0, style);
UINT IDS[] = {ID_STATUSTEXT, ID_COLROWTEXT};
statusBar.SetIndicators(IDS, 2);
statusBar.SetPaneInfo(0, ID_STATUSTEXT, SBPS_NOBORDERS | SBPS_STRETCH, 0);
statusBar.SetPaneInfo(1, ID_COLROWTEXT, 0, 128);
statusBar.SetPaneText(0, "");
statusBar.SetPaneText(1, "");
tabber.Create(WS_VISIBLE | WS_CHILD | TCS_HOTTRACK, CRect(0, 0, 0, 0), this, 1);
tabber.SetFont(&prefs.tabsFont);
tabber.setListener(this);
prefs.win_notoolbar = !prefs.win_notoolbar;
escape();
//create recent file list
CMenu menu;
menu.CreatePopupMenu();
for (int k = 0; k < prefs.recentFiles.size(); ++k) {
menu.InsertMenu(k, MF_BYPOSITION | MF_ENABLED, 333 + k, prefs.recentFiles[k].c_str());
}
CMenu* file = GetMenu()->GetSubMenu(0);
file->InsertMenu(12, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT)menu.m_hMenu, "&Recent Files");
menu.Detach();
helpHome();
trackmem(true);
if (blitzIDE.m_lpCmdLine[0]) {
string t = string(blitzIDE.m_lpCmdLine);
if (t[0] == '\"')
t = t.substr(1, t.size() - 2);
open(t);
} else {
SetCurrentDirectory((prefs.homeDir + "/samples").c_str());
}
return 0;
}
void MainFrame::OnDestroy()
{
trackmem(false);
WINDOWPLACEMENT wp = {sizeof(wp)};
if (GetWindowPlacement(&wp)) {
prefs.win_rect = wp.rcNormalPosition;
if (wp.showCmd == SW_SHOWMAXIMIZED) {
prefs.win_maximized = true;
} else {
prefs.win_maximized = false;
}
}
}
void MainFrame::setTitle(const string& s)
{
SetWindowText(("Blitz3D - " + s).c_str());
return;
}
void MainFrame::OnClose()
{
bool exit_flag = true;
for (int k = tabber.size() - 1; k >= 0; --k) {
exit_flag = close(k);
if (!exit_flag)
break;
}
if (exit_flag)
DestroyWindow();
}
BOOL MainFrame::OnEraseBkgnd(CDC* dc)
{
return true;
}
void MainFrame::OnSize(UINT type, int sw, int sh)
{
CFrameWnd::OnSize(type, sw, sh);
CRect r, t;
GetClientRect(&r);
int x = r.left, y = r.top, w = r.Width(), h = r.Height();
if (!prefs.win_notoolbar) {
statusBar.GetWindowRect(&t);
h -= t.Height();
toolBar.GetWindowRect(&t);
y += t.Height();
h -= t.Height();
}
tabber.MoveWindow(x, y, w, h);
}
static char* bbFilter =
"Blitz Basic files (.bb)|*.bb|"
"Image files (.bmp,.jpg,.png,.tga,.iff,.pcx)|*.bmp;*.jpg;*.png;*.tga;*.iff;*.pcx|"
"Audio files (.wav,.mid,.mod,.mp3,.s3m,.xm,.it,.rmi,.sgt)|*.wav;*.mid;*.mod;*.mp3;*.s3m;*.xm;*.it;*.rmi;*.sgt|"
"3D Mesh files (.x,.3ds,.md2)|*.x;*.3ds;*.md2|"
"All files|*.*||";
Editor* MainFrame::getEditor()
{
return getEditor(tabber.getCurrent());
}
Editor* MainFrame::getEditor(int n)
{
map<CWnd*, Editor*>::iterator it = editors.find(tabber.getTabWnd(n));
return it == editors.end() ? 0 : it->second;
}
HtmlHelp* MainFrame::getHelp(int n)
{
map<CWnd*, HtmlHelp*>::iterator it = helps.find(tabber.getTabWnd(n));
return it == helps.end() ? 0 : it->second;
}
HtmlHelp* MainFrame::getHelp()
{
return getHelp(tabber.getCurrent());
}
HtmlHelp* MainFrame::findHelp()
{
int n;
HtmlHelp* h;
for (n = 0; n < tabber.size(); ++n) {
if (h = getHelp(n))
break;
}
if (n == tabber.size()) {
h = new HtmlHelp(this);
h->Create(0, "Help", WS_CHILD | WS_BORDER, CRect(0, 0, 0, 0), &tabber, 1);
helps[h] = h;
tabber.insert(n, h, "Help");
}
tabber.setCurrent(n);
return h;
}
void MainFrame::cursorMoved(Editor* editor)
{
if (editor != getEditor())
return;
int row, col;
editor->getCursor(&row, &col);
char mod = editor->getModified() ? '*' : ' ';
char str[64];
sprintf(str, "Row:%i Col:%i %c", row, col, mod);
statusBar.SetPaneText(1, str);
}
void MainFrame::currentSet(Tabber* tabber, int index)
{
if (Editor* e = getEditor()) {
string t = e->getName();
if (!t.size())
t = "<untitled>";
setTitle(t);
cursorMoved(e);
} else if (HtmlHelp* h = getHelp()) {
setTitle(h->getTitle());
statusBar.SetPaneText(1, "");
} else {
setTitle("no file");
statusBar.SetPaneText(1, "");
}
}
void MainFrame::helpOpen(HtmlHelp* help, const string& file)
{
open(file);
}
void MainFrame::helpTitleChange(HtmlHelp* help, const string& title)
{
if (HtmlHelp* h = getHelp())
setTitle(h->getTitle());
}
void MainFrame::insertRecent(const string& file)
{
//check recent files
if (CMenu* list = GetMenu()->GetSubMenu(0)->GetSubMenu(12)) {
vector<string>::iterator it;
vector<string>& f = prefs.recentFiles;
for (it = f.begin(); it != f.end(); ++it) {
if (tolower(*it) == tolower(file))
break;
}
if (it != f.end()) {
//move to top
string t = *it;
f.erase(it);
f.insert(f.begin(), t);
} else {
//insert
if (f.size() == 10) {
f.pop_back();
list->RemoveMenu(9, MF_BYPOSITION);
}
f.insert(f.begin(), file);
list->InsertMenu(0, MF_BYPOSITION | MF_ENABLED, 333, file.c_str());
}
//renumber menu items
for (int k = 0; k < f.size(); ++k) {
list->ModifyMenu(k, MF_BYPOSITION | MF_ENABLED, 333 + k, f[k].c_str());
}
}
}
void MainFrame::newed(const string& t)
{
CRect r(0, 0, 0, 0);
Editor* e = new Editor(this);
e->Create(0, "Editor", WS_CHILD, r, &tabber, 1);
e->setName(t);
editors[e] = e;
int n = tabber.size();
string s = t.size() ? getFile(t) : "<untitled>";
tabber.insert(n, e, s.c_str());
tabber.setCurrent(n);
}
bool MainFrame::open(const string& f)
{
string file = f, filter = "*.bb";
int n = f.find("*.");
if (n != string::npos) {
file = f.substr(0, n);
filter = f.substr(n);
}
int attr = GetFileAttributes(file.c_str());
if (attr == -1)
attr = 0;
if (!file.size() || (attr & FILE_ATTRIBUTE_DIRECTORY)) {
int n = OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST;
CFileDialog fd(true, "bb", filter.c_str(), n, bbFilter);
char* i_dir = strdup(file.c_str());
fd.m_ofn.lpstrInitialDir = i_dir;
fd.m_ofn.lpstrTitle = "Open Blitz Basic File...";
int nn = fd.DoModal();
free(i_dir);
if (nn == IDCANCEL)
return false;
file = fd.GetPathName();
} else {
char buff[MAX_PATH], *p;
if (GetFullPathName(file.c_str(), MAX_PATH, buff, &p))
file = buff;
else
file = f;
}
if (isMediaFile(tolower(file))) {
string t = prefs.homeDir + "/bin/mediaview.exe";
if ((int)ShellExecute(::GetDesktopWindow(), 0, t.c_str(), file.c_str(), 0, SW_SHOW) > 32) {
}
return false;
}
//is file already open?
int k;
for (k = 0; k < tabber.size(); ++k) {
if (Editor* e = getEditor(k)) {
if (tolower(e->getName()) == tolower(file)) {
tabber.setCurrent(k);
return true;
}
}
}
//open new file
ifstream in(file.c_str());
if (!in.good()) {
string e = "Error reading file \"" + f + "\"";
AfxMessageBox(e.c_str(), MB_ICONWARNING);
return false;
}
newed(file);
tabber.UpdateWindow();
Editor* e = getEditor();
e->setText(in);
e->setName(file);
e->setModified(false);
insertRecent(file);
cursorMoved(e);
return true;
}
bool MainFrame::close(int n)
{
if (Editor* e = getEditor(n)) {
if (e->getModified()) {
tabber.setCurrent(n);
string t = "File " + e->getName() + " has been modified!\nSave changes before closing?";
int rt = AfxMessageBox(t.c_str(), MB_YESNOCANCEL | MB_ICONWARNING);
if (rt == IDYES)
return save(n);
if (rt == IDCANCEL)
return false;
}
tabber.remove(n);
e->DestroyWindow();
editors.erase(e);
delete e;
} else if (HtmlHelp* h = getHelp(n)) {
}
return true;
}
bool MainFrame::save(int n)
{
Editor* e = getEditor(n);
if (!e)
return true;
string t = e->getName();
if (!t.size()) {
tabber.setCurrent(n);
int df = OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_OVERWRITEPROMPT;
CFileDialog fd(false, "bb", "*.bb", df, bbFilter);
fd.m_ofn.lpstrTitle = "Save Blitz Basic program as...";
if (fd.DoModal() == IDCANCEL)
return false;
t = fd.GetPathName();
tabber.setTabText(n, getFile(t));
e->setName(t);
insertRecent(t);
}
//Do backups!
if (prefs.edit_backup) {
for (int k = prefs.edit_backup; k > 1; --k) {
CopyFile((t + "_bak" + itoa(k - 1)).c_str(), (t + "_bak" + itoa(k)).c_str(), false);
}
CopyFile(t.c_str(), (t + "_bak1").c_str(), false);
}
int om = ios_base::binary | ios_base::out | ios_base::trunc;
ofstream out(t.c_str(), om);
if (!out.good()) {
string e = "Error writing file \"" + t + "\"";
AfxMessageBox(e.c_str(), MB_ICONWARNING);
return false;
}
e->getText(out);
out.close();
e->setModified(false);
cursorMoved(e);
return true;
}
void MainFrame::fileNew()
{
newed("");
}
void MainFrame::fileOpen()
{
open("");
}
void MainFrame::fileSave()
{
save(tabber.getCurrent());
}
void MainFrame::fileSaveAs()
{
if (Editor* e = getEditor()) {
string t = e->getName();
e->setName("");
if (!save(tabber.getCurrent()))
e->setName(t);
currentSet(&tabber, tabber.getCurrent());
}
}
void MainFrame::fileSaveAll()
{
for (int k = tabber.size() - 1; k >= 0; --k) {
if (!save(k))
return;
}
}
void MainFrame::filePrint()
{
if (Editor* e = getEditor())
e->print();
}
void MainFrame::fileClose()
{
close(tabber.getCurrent());
}
void MainFrame::fileCloseAll()
{
for (int k = tabber.size() - 1; k >= 0; --k) {
if (!close(k))
return;
}
}
void MainFrame::fileExit()
{
PostMessage(WM_CLOSE);
}
void MainFrame::fileRecent(UINT id)
{
id -= 333;
if (id < 0 || id >= prefs.recentFiles.size())
return;
open(prefs.recentFiles[id]);
}
void MainFrame::editCut()
{
if (Editor* e = getEditor())
e->cut();
}
void MainFrame::editCopy()
{
if (Editor* e = getEditor())
e->copy();
}
void MainFrame::editPaste()
{
if (Editor* e = getEditor())
e->paste();
}
void MainFrame::editSelectAll()
{
if (Editor* e = getEditor())
e->selectAll();
}
void MainFrame::editFind()
{
if (Editor* e = getEditor())
e->find();
}
void MainFrame::editFindNext()
{
if (Editor* e = getEditor())
e->findNext(true);
}
void MainFrame::editReplace()
{
if (Editor* e = getEditor())
e->replace();
}
static HANDLE startProc(const string& proc)
{
HANDLE rd, wr;
SECURITY_ATTRIBUTES sa = {sizeof(sa), 0, true};
if (CreatePipe(&rd, &wr, &sa, 0)) {
STARTUPINFO si = {sizeof(si)};
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = si.hStdError = wr;
PROCESS_INFORMATION pi = {0};
if (CreateProcess(0, (char*)proc.c_str(), 0, 0, true, DETACHED_PROCESS, 0, 0, &si, &pi)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(wr);
return rd;
}
CloseHandle(rd);
CloseHandle(wr);
}
return 0;
}
class PDialog : public CDialog {
public:
void OnOk() {}
void OnCancel() {}
};
void MainFrame::compile(const string& cmd)
{
CDialog compiling;
compiling.Create(IDD_COMPILING);
CProgressCtrl* cp = (CProgressCtrl*)compiling.GetDlgItem(IDC_COMPILEPROGRESS);
cp->SetStep(20);
putenv("blitzide=1");
HANDLE rd = startProc(cmd);
if (!rd) {
putenv("blitzide");
compiling.DestroyWindow();
AfxMessageBox("Error launching compiler", MB_ICONWARNING | MB_OK);
return;
}
string line, err;
//OK....here we go!
for (;;) {
char buff;
unsigned long sz;
int n = ReadFile(rd, &buff, 1, &sz, 0);
if (n && !sz)
break; //EOF!
if (!n && GetLastError() == ERROR_BROKEN_PIPE)
break; //PROC END!
if (!n) {
err = "Internal Error";
break;
}
if (buff == '\r')
continue;
if (buff != '\n') {
line += buff;
continue;
}
if (!line.size())
continue;
if (line[0] == '\"') {
err = line;
int n = line.find("\"", 1);
if (n == string::npos)
break;
if (++n == line.size() || line[n] != ':')
break;
string file = line.substr(1, n - 2);
line = line.substr(n + 1);
n = line.find(':');
if (!n || n == string::npos)
break;
int row1 = atoi(line.substr(0, n));
line = line.substr(n + 1);
n = line.find(':');
if (!n || n == string::npos)
break;
int col1 = atoi(line.substr(0, n));
line = line.substr(n + 1);
n = line.find(':');
if (!n || n == string::npos)
break;
int row2 = atoi(line.substr(0, n));
line = line.substr(n + 1);
n = line.find(':');
if (!n || n == string::npos)
break;
int col2 = atoi(line.substr(0, n));
line = line.substr(n + 1);
int pos = ((row1 - 1) << 16) | (col1 - 1);
if (!open(file))
return;
if (Editor* e = getEditor())
e->setCursor(pos);
err = line;
break;
} else if (line.find("...") != line.size() - 3) {
err = line;
break;
}
if (line.find("Executing") == 0) {
//OK, we're running!
break;
}
cp->StepIt();
line = "";
}
compiling.DestroyWindow();
CloseHandle(rd);
putenv("blitzide");
if (!err.size())
return;
AfxMessageBox(err.c_str(), MB_ICONWARNING | MB_OK);
}
void MainFrame::build(bool exec, bool publish)
{
Editor* e = getEditor();
if (!e)
return;
string src_file = e->getName();
for (int k = tabber.size() - 1; k >= 0; --k) {
if (Editor* e = getEditor(k)) {
if (e->getModified() && e->getName().size()) {
if (!save(k))
return;
}
}
}
string opts = " ";
if (prefs.prg_debug)
opts += "-d ";
if (publish) {
string exe = src_file;
if (exe.size()) {
int n = exe.find('.');
if (n != string::npos)
exe = exe.substr(0, n);
} else {
exe = "untitled";
}
static char* exeFilter = "Executable files (*.exe)|*.exe||";
int t = OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
CFileDialog fd(false, "exe", exe.c_str(), t, exeFilter);
fd.m_ofn.lpstrTitle = "Select executable filename";
fd.m_ofn.lpstrInitialDir = "./";
if (fd.DoModal() == IDCANCEL)
return;
opts += "-o \"" + string(fd.GetPathName()) + "\" ";
} else if (!exec) {
opts += "-c ";
}
string src = src_file;
if (!src.size()) {
src = prefs.homeDir + "\\tmp\\tmp.bb";
int om = ios_base::binary | ios_base::out | ios_base::trunc;
ofstream out(src.c_str(), om);
if (!out.good()) {
string e = "Error writing file \"" + src + "\"";
AfxMessageBox(e.c_str(), MB_ICONWARNING);
return;
}
e->getText(out);
out.close();
e->setName(src);
} else {
prefs.prg_lastbuild = e->getName();
}
compile(prefs.homeDir + "/bin/blitzcc -q " + opts + " \"" + src + "\" " + prefs.cmd_line);
if (!src_file.size())
e->setName("");
}
void MainFrame::programExecute()
{
build(true, false);
}
void MainFrame::programReExecute()
{
if (prefs.prg_lastbuild.size() && open(prefs.prg_lastbuild)) {
build(true, false);
}
}
void MainFrame::programCompile()
{
build(false, false);
}
void MainFrame::programPublish()
{
#ifdef DEMO
MessageBox("Create Executable unavailable in demo version", "Sorry!",
MB_TOPMOST | MB_SETFOREGROUND | MB_ICONINFORMATION);
return;
#endif
Editor* e = getEditor();
if (!e)
return;
if (prefs.prg_debug) {
string t =
"You currently have the debugging feature enabled!\n\n"
"This will result in slower executables - continue anyway?";
if (MessageBox(t.c_str(), 0, MB_OKCANCEL) == IDCANCEL)
return;
}
build(false, true);
}
struct CmdLineDialog : public CDialog {
CmdLineDialog() : CDialog(IDD_COMMANDLINE) {}
BOOL OnInitDialog()
{
CDialog::OnInitDialog();
SetDlgItemText(IDC_CMDLINE, prefs.cmd_line.c_str());
return TRUE;
}
void OnOK()
{
CString c_str;
GetDlgItemText(IDC_CMDLINE, c_str);
prefs.cmd_line = c_str;
CDialog::OnOK();
}
};
void MainFrame::programCommandLine()
{
CmdLineDialog d;
d.DoModal();
}
void MainFrame::programDebug()
{
prefs.prg_debug = !prefs.prg_debug;
}
void MainFrame::helpHome()
{
HtmlHelp* h = findHelp();
string t;
t = "index.html";
h->Navigate((prefs.homeDir + "/help/" + t).c_str());
}
void MainFrame::helpAutodoc()
{
HtmlHelp* h = findHelp();
h->Navigate((prefs.homeDir + "/help/autodoc.html").c_str());
}
void MainFrame::helpBack()
{
if (HtmlHelp* h = findHelp())
h->GoBack();
}
void MainFrame::helpForward()
{
if (HtmlHelp* h = findHelp())
h->GoForward();
}
void MainFrame::helpAbout()
{
aboutBlitz(false);
}
void MainFrame::ctrlTab()
{
int n = tabber.getCurrent() + 1;
if (n >= tabber.size())
n -= tabber.size();
tabber.setCurrent(n);
}
void MainFrame::ctrlShiftTab()
{
int n = tabber.getCurrent() - 1;
if (n < 0)
n += tabber.size();
tabber.setCurrent(n);
}
void MainFrame::escape()
{
if (!prefs.win_notoolbar) {
toolBar.ShowWindow(SW_HIDE);
statusBar.ShowWindow(SW_HIDE);
prefs.win_notoolbar = true;
} else {
toolBar.ShowWindow(SW_SHOW);
statusBar.ShowWindow(SW_SHOW);
prefs.win_notoolbar = false;
}
RECT r;
GetClientRect(&r);
int w = r.right - r.left, h = r.bottom - r.top;
int n = prefs.win_maximized ? SIZE_MAXIMIZED : SIZE_RESTORED;
PostMessage(WM_SIZE, n, (h << 16) | w);
}
void MainFrame::updateCmdUIRange(CCmdUI* ui)
{
int n = ui->m_nID - 333;
if (n >= 0 && n < prefs.recentFiles.size()) {
ui->Enable(true);
} else {
ui->Enable(false);
}
}
void MainFrame::updateCmdUI(CCmdUI* ui)
{
int k;
Editor* e = getEditor();
switch (ui->m_nID) {
case Inew:
case ID_OPEN:
case ID_HOME:
ui->Enable(true);
break;
case ID_DEBUG:
ui->SetCheck(prefs.prg_debug);
ui->Enable(true);
break;
case ID_CLOSE:
case ID_PRINT:
ui->Enable(!!e);
break;
case ID_CLOSEALL:
for (k = 0; k < tabber.size() && !getEditor(k); ++k) {
}
ui->Enable(k < tabber.size());
break;
case ID_CUT:
case ID_COPY:
if (!!e) {
ui->Enable(e->canCutCopy());
} else
ui->Enable(false);
break;
case ID_PASTE:
if (!!e) {
ui->Enable(e->canPaste());
} else
ui->Enable(false);
break;
case ID_SELECTALL:
case ID_QUICKHELP:
case ID_FIND:
case ID_FINDNEXT:
case ID_REPLACE:
case ID_EXECUTE:
case ID_COMPILE:
case ID_PUBLISH:
ui->Enable(!!e);
break;
case ID_REEXECUTE:
ui->Enable(prefs.prg_lastbuild.size());
break;
case ID_COMMANDLINE:
ui->Enable(true);
break;
case ID_SAVE:
case ID_SAVEAS:
ui->Enable(!!e);
break;
case ID_SAVEALL:
for (k = 0; k < tabber.size() && !getEditor(k); ++k) {
}
ui->Enable(k < tabber.size());
break;
case ID_BACK:
case ID_FORWARD:
ui->Enable(getHelp() != 0);
break;
case ID_ESCAPE:
ui->SetCheck(!prefs.win_notoolbar);
break;
default:
ui->Enable(false);
}
}
static string commandURL(const string& t)
{
static char* dirs[] = {"help\\commands\\2d_commands\\", "help\\commands\\3d_commands\\", 0};
char** dir_p = dirs;
while (char* dir = *dir_p++) {
WIN32_FIND_DATA fd;
string path = prefs.homeDir + "/" + dir + t + ".htm";
HANDLE h = FindFirstFile(path.c_str(), &fd);
if (h == INVALID_HANDLE_VALUE)
continue;
FindClose(h);
return path;
}
return "";
}
void MainFrame::quick_Help()
{
if (Editor* e = getEditor()) {
//look for keyword at cursor...
string t = e->getKeyword();
if (!t.size())
return;
statusBar.SetPaneText(0, quickHelp(t).c_str());
if (t != last_quick_help) {
last_quick_help = t;
return;
}
string url = commandURL(t);
if (!url.size()) {
string ex = "Unable to open help file for \"" + t + "\"";
AfxMessageBox(ex.c_str(), MB_ICONWARNING);
return;
}
if (HtmlHelp* h = findHelp()) {
h->Navigate(url.c_str(), 0, 0);
}
}
}
void MainFrame::OnActivate(UINT state, CWnd* other, BOOL min)
{
CFrameWnd::OnActivate(state, other, min);
if (Editor* e = getEditor()) {
if (state != WA_ACTIVE && state != WA_CLICKACTIVE)
return;
e->SetFocus();
}
}