/***************************************************************************
* Copyright (C) 2004 by Gerhard W. Gruber *
* sparhawk@gmx.at *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/***************************************************************************
*
* PROJECT: FILOU
* $Source: /cvsroot/desktoptools/filou/src/Filou.cpp,v $
* $Revision: 1.4 $
* $Date: 2004/08/23 19:00:11 $
* $Author: lightweave $
* $Name: $
*
* $Log: Filou.cpp,v $
* Revision 1.4 2004/08/23 19:00:11 lightweave
* Added PluginList dialog
*
* Revision 1.3 2004/08/22 20:50:01 lightweave
* Added AttachPlugin Dialog
*
* Revision 1.2 2004/08/22 19:11:37 lightweave
* Added binary plugin
*
* Revision 1.1.1.1 2004/08/21 17:00:11 lightweave
* Initial release
*
*
***************************************************************************/
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#define STR_IMPORT
#define MAIN
#include "FilouGlobals.h"
#include "Filou.h"
#include "profile.h"
#include "HexPlugin.h"
#include "BinPlugin.h"
#ifdef __WXGTK__
#include "mondrian.xpm"
#endif
CGlobalSettings *g_Global;
// `Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
COptions o;
o.m_Hide = false;
if(argc > 1)
{
if(argv[1][0] == '-')
{
if(argv[1][1] == 'h')
o.m_Hide = true;
}
}
// Create the main application window
MyFrame *frame = new MyFrame(wxString(APPLICATION_NAME_STR) + " / " + wxString(APPLICATION_VERSION_STR),
wxDefaultPosition, wxDefaultSize);
// Show it and tell the application that it's our main window
// @@@ what does it do exactly, in fact? is it necessary here?
frame->Show(TRUE);
SetTopWindow(frame);
if(argc > 1)
frame->OpenFile(wxString(argv[1]));
// success: wxApp::OnRun() will be called which will enter the main message
// loop and the application will run. If we returned FALSE here, the
// application would exit immediately.
return TRUE;
}
int MyApp::OnExit()
{
return wxApp::OnExit();
}
// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(FM_FILE_OPEN, MyFrame::OnOpen)
EVT_MENU(FM_FILE_CLOSE, MyFrame::OnClose)
EVT_SIZE(MyFrame::OnSize)
END_EVENT_TABLE()
// frame constructor
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxMDIParentFrame((wxMDIParentFrame *)NULL, -1, title, pos, size, wxMINIMIZE_BOX|wxMAXIMIZE_BOX|wxSYSTEM_MENU|wxCAPTION|wxTHICK_FRAME)
{
m_Global.m_Frame = this;
m_Global.m_StatusBar = &m_StatusBar;
g_Global = &m_Global;
m_ActiveFrame = NULL;
// Now we dynamically connect the event handler for the last opened files menu.
AdjustEventHandler(FM_FILE_LIST, FM_FILE_LIST+g_Global->m_MaxFiles,
FM_FILE_LIST, FM_FILE_LIST+g_Global->m_MaxFiles,
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)&MyFrame::OnMostRecentFile);
// set the frame icon
SetIcon(wxICON(mondrian));
CreateMenu();
ScanPlugIns();
}
MyFrame::~MyFrame()
{
int i, n;
n = g_Global->m_PluginInfo.GetCount();
for(i = 0; i < n; i++)
{
delete g_Global->m_PluginInfo[i]->m_DefaultObject;
delete g_Global->m_PluginInfo[i];
}
}
void MyFrame::CreateMenu(void)
{
wxMenuBar *mb = new wxMenuBar;
wxMenu *m;
m = new wxMenu;
m->Append(FM_FILE_OPEN, FILE_OPEN_STR, FILE_OPEN_TIP_STR);
m->Append(FM_FILE_MANAGE_PLUGIN, FILE_MANAGE_PLUGIN_STR);
m->Append(FM_FILE_CLOSE, FILE_CLOSE_STR);
m->AppendSeparator();
m->Append(FM_FILE_SPLIT, FILE_SPLIT_WINDOW_STR);
m->AppendSeparator();
m->Append(FM_FILE_EXIT, FILE_EXIT_STR);
m->AppendSeparator();
mb->Append(m, FILE_MENU_STR);
SetMenuBar(mb);
UpdateMostRecentFile();
}
void MyFrame::UpdateMostRecentFile(void)
{
wxMenuBar *mb;
wxMenu *m;
wxMenuItem *mi;
int i, n;
mb = GetMenuBar();
m = mb->GetMenu(0);
// Remove all files from the most recent file list
i = 0;
while(1)
{
if((mi = m->FindItem(FM_FILE_LIST+i)) != NULL)
{
m->Remove(FM_FILE_LIST+i);
delete mi;
}
else
break;
i++;
}
n = g_Global->m_LastFile.GetCount();
for(i = 0; i < n; i++)
m->Append(FM_FILE_LIST+i, *(g_Global->m_LastFile[i]));
}
void MyFrame::OnSize(wxSizeEvent& event)
{
int w, h;
GetClientSize(&w, &h);
GetClientWindow()->SetSize(0, 0, w, h);
// FIXME: On wxX11, we need the MDI frame to process this
// event, but on other platforms this should not
// be done.
#ifdef __WXUNIVERSAL__
event.Skip();
#endif
}
void MyFrame::OnOpen(wxCommandEvent &ev)
{
wxFileDialog dlg(this, CHOOSE_FILE_STR, m_CurPathLeft);
wxString fn;
if(dlg.ShowModal() == wxID_OK)
{
fn = dlg.GetFilename();
m_CurPathLeft = dlg.GetDirectory()+g_Global->m_Slash;
fn = m_CurPathLeft+fn;
OpenFile(fn);
}
}
void MyFrame::OnClose(wxCommandEvent &event)
{
int i, n;
bool DeleteIt;
CViewerFrame *vf = NULL;
if((vf = static_cast<CViewerFrame *>(event.GetClientData())) == NULL)
{
vf = static_cast<CViewerFrame *>(GetActiveChild());
DeleteIt = true;
}
else
DeleteIt = false;
n = m_Frame.GetCount();
for(i = 0; i < n; i++)
{
if(vf == m_Frame[i])
{
m_Frame.RemoveAt(i);
if(DeleteIt == true)
delete vf;
break;
}
}
}
void MyFrame::OnMostRecentFile(wxCommandEvent &ev)
{
int id = ev.GetId()-FM_FILE_LIST;
wxString fn;
// If the file is coming from the Most Recently Opened list
// we check if the file could be successfully opened. If not
// we remove it from the list. Otherwise we add it again, to
// make sure it is at the top.
fn = *g_Global->m_LastFile[id];
OpenFile(fn);
}
void MyFrame::AdjustEventHandler(int OldId, int OldIdLast,
int NewId, int NewIdLast,
wxObjectEventFunction func)
{
Disconnect(OldId, OldIdLast, wxEVT_COMMAND_MENU_SELECTED);
Connect(NewId, NewIdLast, wxEVT_COMMAND_MENU_SELECTED, func);
}
bool MyFrame::OpenFile(wxString &fn)
{
bool rc = true;
int i, n;
CViewerFrame *vf = new CViewerFrame(this, -1, fn);
vf->Show(true);
vf->SetTitle(fn);
if((rc = vf->OpenFile(fn)) == true)
{
g_Global->AddFile(fn);
m_Frame.Add(vf);
m_ActiveFrame = vf;
}
else
{
g_Global->RemoveFile(fn);
delete vf;
vf = NULL;
}
// Now we have to update all file menus for all frames so they show the same
// MostRecentFile list.
UpdateMostRecentFile();
n = m_Frame.GetCount();
for(i = 0; i < n; i++)
{
vf = m_Frame[i];
vf->UpdateMostRecentFile();
}
return(rc);
}
void MyFrame::ScanPlugIns(void)
{
CPlugin *p;
CPlugin::SPluginInfo *pin;
// Register the hex plugin
p = new CHexPlugin;
pin = new CPlugin::SPluginInfo;
pin->m_DefaultObject = p;
p->GetPluginId(pin);
g_Global->m_PluginInfo.Add(pin);
// Register the binary plugin
p = new CBinPlugin;
pin = new CPlugin::SPluginInfo;
pin->m_DefaultObject = p;
p->GetPluginId(pin);
g_Global->m_PluginInfo.Add(pin);
}