blitz3d/blitzide/mainframe.cpp

949 lines
22 KiB
C++

#include "stdafx.h"
#include "resource.h"
#include "mainframe.h"
#include "about.h"
#include "blitzide.h"
#include "libs.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( ID_NEW,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( ID_NEW,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[]={
ID_NEW,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 ){
#ifdef PRO
SetWindowText( ("Blitz3D - "+s ).c_str() );
return;
#else
SetWindowText( ("Blitz2D - "+s ).c_str() );
return;
#endif
}
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|"
#ifdef PRO
"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|"
#endif
"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 ID_NEW: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\\",
#ifdef PRO
"help\\commands\\3d_commands\\",
#endif
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();
}
}