Author: derek Date: Wed Sep 6 18:04:47 2006 New Revision: 70 Added: sofaswitch/trunk/callflow/src/ sofaswitch/trunk/callflow/src/Makefile.am sofaswitch/trunk/callflow/src/callflow.cpp sofaswitch/trunk/callflow/src/callflow.h sofaswitch/trunk/callflow/src/canvas.cpp sofaswitch/trunk/callflow/src/canvas.h sofaswitch/trunk/callflow/src/dnd.cpp sofaswitch/trunk/callflow/src/dnd.h sofaswitch/trunk/callflow/src/drawshape.cpp sofaswitch/trunk/callflow/src/drawshape.h sofaswitch/trunk/callflow/src/information.cpp sofaswitch/trunk/callflow/src/information.h sofaswitch/trunk/callflow/src/shapelist.cpp sofaswitch/trunk/callflow/src/shapelist.h Log: rework the file list, split things up etc. Added: sofaswitch/trunk/callflow/src/Makefile.am ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/Makefile.am Wed Sep 6 18:04:47 2006 @@ -0,0 +1,33 @@ +SUFFIXES=.cpp .rc + +bin_PROGRAMS = callflow + + +callflow_LDADD = $(WX_LIBS) +override CXXFLAGS = @CXXFLAGS@ -I.. + + +callflow_SOURCES = \ + callflow.cpp \ + canvas.cpp \ + conditional.cpp \ + dnd.cpp \ + drawshape.cpp \ + endcall.cpp \ + endfor.cpp \ + endhere.cpp \ + eventer.cpp \ + information.cpp \ + joinblocks.cpp \ + listpoints.cpp \ + makecall.cpp \ + python.cpp \ + requestnode.cpp \ + shapelist.cpp \ + shapeselect.cpp \ + startfor.cpp \ + starthere.cpp \ + timer.cpp + + + Added: sofaswitch/trunk/callflow/src/callflow.cpp ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/callflow.cpp Wed Sep 6 18:04:47 2006 @@ -0,0 +1,482 @@ +//Default frame.cpp for wxHatch + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include <wx/image.h> +#include <wx/filename.h> +#include <wx/listctrl.h> +#include <wx/textfile.h> + +#include "bitmaps/FileE_xit.xpm" +#include "bitmaps/Controlsstart.xpm" +#include "bitmaps/ControlsEndHere.xpm" + +#include "bitmaps/ControlsIf.xpm" + +#include "bitmaps/Controlsend_for.xpm" +#include "bitmaps/Controlsfor.xpm" +#include "bitmaps/HelpManual.xpm" +#include "bitmaps/HelpAbout.xpm" + +//#include "bitmaps/newshape.xpm" +#include "bitmaps/EditCopy.xpm" +#include "bitmaps/EditCut.xpm" +#include "bitmaps/EditPaste.xpm" +#include "bitmaps/FileNew.xpm" +#include "bitmaps/FileOpen.xpm" +#include "bitmaps/FileSave.xpm" +#include "bitmaps/FileSave__As.xpm" +#include "bitmaps/JoinObjects.xpm" +#include "bitmaps/Python.xpm" +#include "bitmaps/RequestNode.xpm" +#include "bitmaps/compile.xpm" +#include "bitmaps/eventer.xpm" +#include "bitmaps/miniclock.xpm" + +class MyFrame ; + + + + +#include "dnd.h" + + +#include "drawshape.h" + + +#include "information.h" + + +#include "shapelist.h" +#include "canvas.h" +#include "callflow.h" + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU ( wxH_EDITPASTE, MyFrame::OnEditPaste) + EVT_MENU ( wxH_EDITCOPY, MyFrame::OnEditCopy) + EVT_MENU ( wxH_EDITCUT, MyFrame::OnEditCut) + EVT_MENU ( wxH_HELPABOUT, MyFrame::OnHelpAbout) + EVT_MENU ( wxH_HELPMANUAL, MyFrame::OnHelpManual) + EVT_MENU ( wxH_CONTROLSMAKE_PLAY_HRECORD, MyFrame::OnControlsmake_play_Hrecord) + EVT_MENU ( wxH_CONTROLSJOIN_PLAY_HRECORD, MyFrame::OnControlsjoin_play_Hrecord) + EVT_MENU ( wxH_CONTROLSMAKE_CONFERENCE, MyFrame::OnControlsmake_conference) + EVT_MENU ( wxH_CONTROLSJOIN_CONFERENCE, MyFrame::OnControlsjoin_conference) + EVT_MENU ( wxH_CONTROLSMAKE_CALL, MyFrame::OnControlsmake_call) + EVT_MENU ( wxH_CONTROLSREQUESTNODE, MyFrame::OnControlsrequestnode) + EVT_MENU ( wxH_CONTROLSPYTHON, MyFrame::OnControlspython) + EVT_MENU ( wxH_CONTROLSEND_FOR, MyFrame::OnControlsend_for) + EVT_MENU ( wxH_CONTROLSFOR, MyFrame::OnControlsfor) + EVT_MENU ( wxH_CONTROLSIF, MyFrame::OnControlsif) + EVT_MENU ( wxH_CONTROLSTIMER, MyFrame::OnControlsTimer) + EVT_MENU ( wxH_CONTROLSEVENTER, MyFrame::OnControlsEventer) + EVT_MENU ( wxH_CONTROLSEND, MyFrame::OnControlsend) + EVT_MENU ( wxH_CONTROLSSTARTHERE, MyFrame::OnControlsstarthere) + EVT_MENU ( wxH_CONTROLSENDHERE, MyFrame::OnControlsendhere) + EVT_MENU ( wxH_CONTROLSCONNECT_OBJECTS, MyFrame::OnControlsConnectObjects) + EVT_MENU ( wxH_CONTROLSCOMPILE, MyFrame::OnCompile) + EVT_MENU ( wxH_FILEE_XIT, MyFrame::OnFileE_xit) + EVT_MENU ( wxH_FILESAVE__AS, MyFrame::OnFileSave__As) + EVT_MENU ( wxH_FILESAVE, MyFrame::OnFileSave) + EVT_MENU ( wxH_FILEOPEN, MyFrame::OnFileOpen) + EVT_MENU ( wxH_FILENEW, MyFrame::OnFileNew) + EVT_CLOSE(MyFrame::OnClose) + END_EVENT_TABLE() + + ; + +IMPLEMENT_APP(MyApp) + + bool MyApp::OnInit() +{ + + MyFrame *frame = new MyFrame (wxT("Callflow"), + wxPoint(20,20), wxSize(600,450)); + + frame->Show (TRUE); + ::wxInitAllImageHandlers(); + wxIcon myIcon ; + wxString sFile = wxString ( argv[0] ).BeforeLast (wxFILE_SEP_PATH) + (wxFILE_SEP_PATH) + wxT("callflow.ico"); + + if ( !wxFileExists ( sFile )) { + sFile = wxGetInstallPrefix() ; + sFile = sFile + wxT( "callflow.ico" ) ; + } + if ( wxFileExists ( sFile )) { + myIcon.CopyFromBitmap(wxBitmap(wxImage(sFile))); + frame->SetIcon(myIcon); + } + return TRUE; +} + +MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) + : wxFrame((wxFrame *)NULL, -1, title, pos, size) +{ +// create a child control here + canvas = new MyCanvas(this); + +// menu setup goes here + + wxMenu * Edit_menu = new wxMenu ; + wxMenu * Help_menu = new wxMenu ; + wxMenu * Controls_menu = new wxMenu ; + wxMenu * File_menu = new wxMenu ; + File_menu -> Append ( wxH_FILENEW, wxT("&New"), wxT("")); + File_menu -> Append ( wxH_FILEOPEN, wxT("&Open"), wxT("")); + File_menu -> Append ( wxH_FILESAVE, wxT("&Save"), wxT("")); + File_menu -> Append ( wxH_FILESAVE__AS, wxT("Save &As"), wxT("")); + File_menu -> Append ( wxH_FILEE_XIT, wxT("E&xit"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSSTARTHERE, wxT("start here"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSENDHERE, wxT("end here"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSREQUESTNODE, wxT("request node"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSEND, wxT("end"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSIF, wxT("if"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSTIMER, wxT("timer"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSEVENTER, wxT("event reg/wait"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSFOR, wxT("for"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSEND_FOR, wxT("end for"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSPYTHON, wxT("python"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSMAKE_CALL, wxT("make call"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSJOIN_CONFERENCE, wxT("join conference"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSMAKE_CONFERENCE, wxT("make conference"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSJOIN_PLAY_HRECORD, wxT("join play/record"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSMAKE_PLAY_HRECORD, wxT("make play/record"), wxT("")); + Controls_menu -> Append ( wxH_CONTROLSCONNECT_OBJECTS, wxT("connect objects"), wxT("")); + Help_menu -> Append ( wxH_HELPMANUAL, wxT("Manual"), wxT("")); + Help_menu -> AppendSeparator () ; + Help_menu -> Append ( wxH_HELPABOUT, wxT("About"), wxT("")); + Edit_menu -> Append ( wxH_EDITCUT, wxT("&Cut"), wxT("")); + Edit_menu -> Append ( wxH_EDITCOPY, wxT("&Copy"), wxT("")); + Edit_menu -> Append ( wxH_EDITPASTE, wxT("&Paste"), wxT("")); + Edit_menu -> Append ( wxH_CONTROLSCOMPILE, wxT("compile to code"), wxT("")); + wxMenuBar *menuBar = new wxMenuBar; + + menuBar->Append (File_menu, wxT("&File") ); + menuBar->Append (Edit_menu, wxT("&Edit") ); + menuBar->Append (Controls_menu, wxT("&Controls") ); + menuBar->Append (Help_menu, wxT("Help") ); + SetMenuBar (menuBar); + CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL); + InitToolBar(GetToolBar()); + + CreateStatusBar(); + SetStatusText(" Hello "); +} + + + +void MyFrame::OnClose (wxCloseEvent& event) +{ + + // event.Skip(); + // or event.Veto(); +} + + +MyFrame::~MyFrame () +{ + +} +void MyFrame::OnFileNew (wxCommandEvent & WXUNUSED(event)) +{ + canvas->RemoveCurrentShapes(); + canvas->SetEditingMode(MyCanvas::WaitDownEvent); + canvas->Refresh(); +} + + +void MyFrame::OnFileOpen (wxCommandEvent & WXUNUSED(event)) +{ + wxFileDialog filedlg(this, _T("Select a file to read data from")); + if ( filedlg.ShowModal() != wxID_OK ) + return; + + wxTextFile file(filedlg.GetPath()); + + if (!file.Exists()) { + wxMessageBox(wxString::Format("The file %s must exist to read from", filedlg.GetFilename().c_str())); + return; + } + + file.Open(); + if (file.IsOpened()) { + file.Close(); + currentFileName = filedlg.GetPath(); + canvas->ReadShapeInformationFromFile(currentFileName); + } else { + wxMessageBox(wxString::Format("Unable to open the file %s to read from", filedlg.GetFilename().c_str())); + return; + } +} + + +void MyFrame::OnFileSave (wxCommandEvent & event) +{ + if (currentFileName.IsEmpty()) { + OnFileSave__As(event); + return; + } + + wxTextFile file(currentFileName); + + file.Open(); + if (file.IsOpened()) { + file.Close(); + canvas->ShapeInformationToFile(currentFileName); + } else { + wxMessageBox(wxString::Format("Unable to open the file %s for saving", currentFileName.c_str())); + return; + } +} + + + +void MyFrame::OnFileSave__As (wxCommandEvent & WXUNUSED(event)) +{ + wxFileDialog filedlg(this, _T("Select a file to save this data to")); + if (filedlg.ShowModal() != wxID_OK) + return; + + wxTextFile file(filedlg.GetPath()); + + if (!file.Exists()) + file.Create(); + file.Open(); + if (!file.IsOpened()) { + wxMessageBox(wxString::Format("Unable to open the file %s to write data to", filedlg.GetFilename().c_str())); + return; + } + + currentFileName = filedlg.GetPath(); + file.Close(); + canvas->ShapeInformationToFile(currentFileName); +} + + +void MyFrame::OnFileE_xit (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + exit(0); +} + + +void MyFrame::InitToolBar(wxToolBar* toolBar) +{ + toolBar->SetToolSeparation(2); + toolBar->AddTool(wxH_FILENEW, wxBitmap ( FileNew_xpm ), wxT("Start over - create a new diagram")); + toolBar->AddTool(wxH_FILEOPEN, wxBitmap ( FileOpen_xpm ), wxT("open a file")); + toolBar->AddTool(wxH_FILESAVE, wxBitmap ( FileSave_xpm ), wxT("Save to the current file")); + toolBar->AddTool(wxH_FILESAVE__AS, wxBitmap ( FileSave_As_xpm ), wxT("Save to the file you specify")); + toolBar->AddTool(wxH_FILEE_XIT, wxBitmap ( FileE_xit_xpm ), wxT("")); + toolBar->AddTool(wxH_CONTROLSCOMPILE, wxBitmap ( compile_xpm ), wxT("Compile to code")); + + toolBar->AddSeparator() ; + + toolBar->AddTool(wxH_EDITCUT, wxBitmap ( EditCut_xpm ), wxT("")); + toolBar->AddTool(wxH_EDITPASTE, wxBitmap ( EditPaste_xpm ), + wxT("Copy current clipboard contents to screen")); + toolBar->AddTool(wxH_EDITCOPY, wxBitmap ( EditCopy_xpm ), wxT("Copy selected shape to clipboard ")); + + toolBar->AddSeparator() ; + + toolBar->AddTool(wxH_CONTROLSSTARTHERE, wxBitmap ( Controlsstart ), wxT("Start processing")); + toolBar->AddTool(wxH_CONTROLSENDHERE, wxBitmap ( ControlsEndHere ), wxT("End processing")); + toolBar->AddTool(wxH_CONTROLSREQUESTNODE, wxBitmap (RequestNode ), wxT("Query Supervisor for worker")); + toolBar->AddTool(wxH_CONTROLSIF, wxBitmap ( ControlsIf_xpm ), wxT("Test a condition")); + toolBar->AddTool(wxH_CONTROLSTIMER, wxBitmap ( miniclock_xpm ), wxT("Start a timer")); + toolBar->AddTool(wxH_CONTROLSEVENTER, wxBitmap ( eventer_xpm ), wxT("Register for & Wait for an event")); + + toolBar->AddTool(wxH_CONTROLSFOR, wxBitmap ( Controlsfor_xpm ), wxT("Start a for loop")); + toolBar->AddTool(wxH_CONTROLSEND_FOR, wxBitmap ( Controlsend_for_xpm ), wxT("end a for loop")); + toolBar->AddTool(wxH_CONTROLSPYTHON, wxBitmap ( Python_xpm ), wxT("arbitrary python code")); + toolBar->AddTool(wxH_CONTROLSCONNECT_OBJECTS, wxBitmap ( JoinObjects ), + wxT("Join objects with multi segmented lines")); + + toolBar->AddSeparator() ; + + toolBar->AddTool(wxH_HELPMANUAL, wxBitmap ( HelpManual_xpm ), wxT("help on using this program")); + toolBar->AddTool(wxH_HELPABOUT, wxBitmap ( HelpAbout ), wxT("Author name etc")); + toolBar->Realize(); +} + + +void MyFrame::OnControlsstarthere (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::StartHere; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + +void MyFrame::OnControlsendhere (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::EndHere; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + +void MyFrame::OnControlsrequestnode (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::RequestNode; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + + +void MyFrame::OnControlsend (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::EndCall; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + + +void MyFrame::OnControlsif (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::Conditional; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + +void MyFrame::OnControlsTimer (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::Timer; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + + +void MyFrame::OnControlsEventer (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::Eventer; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + +void MyFrame::OnControlsfor (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::StartFor; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + + +void MyFrame::OnControlsend_for (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::EndFor; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + + +void MyFrame::OnControlspython (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::Python; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); +} + + +void MyFrame::OnControlsmake_call (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + SetStatusText("Make a call"); +} + + +void MyFrame::OnControlsjoin_conference (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + SetStatusText("Join a conference"); +} + + +void MyFrame::OnControlsmake_conference (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + SetStatusText("Make a conference"); +} + + +void MyFrame::OnControlsjoin_play_Hrecord (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + SetStatusText("Join play record"); +} + + +void MyFrame::OnControlsmake_play_Hrecord (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + SetStatusText("Make a play record thing"); +} + + +void MyFrame::OnHelpManual (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + SetStatusText("Get manual"); +} + + +void MyFrame::OnHelpAbout (wxCommandEvent & WXUNUSED(event)) +{ + SetStatusText("Help | About"); + wxMessageBox(_T("Call Flow 1.0.0 \n\nAuthor Derek J Smithies (derek@indranet.co.nz)\n\n Copyright 2006"), _T("About Call Flow")); +} + + +void MyFrame::OnEditCut (wxCommandEvent & WXUNUSED(event)) +{ + canvas->RemoveSelectedShapes(); + canvas->Refresh(); +} + + +void MyFrame::OnEditCopy (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + canvas->ScreenToClipboard(); +} + + +void MyFrame::OnEditPaste (wxCommandEvent & WXUNUSED(event)) +{ + //Respond to menu here + canvas->ClipboardToScreen(); + canvas->Refresh(); +} + +void MyFrame::OnControlsConnectObjects (wxCommandEvent & WXUNUSED(event)) +{ + imageTypeForPlacing = DndShape::JoinBlocks; + canvas->SetEditingMode(MyCanvas::PlaceOneShape); + canvas->SetEditingMode(MyCanvas::PlaceJoinBlocks); +} + +void MyFrame::CloseJoinBlocks() +{ + canvas->CloseJoinBlocks(); +} + + +void MyFrame::OnCompile (wxCommandEvent & WXUNUSED(event)) +{ + wxFileDialog filedlg(this, _T("Select a file to place code in")); + if (filedlg.ShowModal() != wxID_OK) + return; + + wxTextFile file(filedlg.GetPath()); + + if (!file.Exists()) + file.Create(); + file.Open(); + if (!file.IsOpened()) { + wxMessageBox(wxString::Format("Unable to open the file %s to write data to", filedlg.GetFilename().c_str())); + return; + } + + if (canvas->Compile(file)) + wxMessageBox(wxString::Format("wrote compile code to %s", filedlg.GetFilename().c_str())); + else + wxMessageBox(wxString::Format("failed - could not compile code to %s", filedlg.GetFilename().c_str())); + + file.Close(); +} Added: sofaswitch/trunk/callflow/src/callflow.h ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/callflow.h Wed Sep 6 18:04:47 2006 @@ -0,0 +1,117 @@ +//Default frame.h for wxHatch + +#ifndef _frame_h +#define _frame_h +#include "dnd.h" + +class MyCanvas; + +enum +{ + // menu IDs these two are needed by wxHatch + wxH_FILE = 1, + wxH_FILENEW, + wxH_FILEOPEN, + wxH_FILESAVE, + wxH_FILESAVE__AS, + wxH_FILEE_XIT, + wxH_CONTROLSSTARTHERE, + wxH_CONTROLSENDHERE, + wxH_CONTROLSREQUESTNODE, + wxH_CONTROLSEND, + wxH_CONTROLSIF, + wxH_CONTROLSTIMER, + wxH_CONTROLSEVENTER, + wxH_CONTROLSFOR, + wxH_CONTROLSEND_FOR, + wxH_CONTROLSPYTHON, + wxH_CONTROLSMAKE_CALL, + wxH_CONTROLSJOIN_CONFERENCE, + wxH_CONTROLSMAKE_CONFERENCE, + wxH_CONTROLSJOIN_PLAY_HRECORD, + wxH_CONTROLSMAKE_PLAY_HRECORD, + wxH_CONTROLSCONNECT_OBJECTS, + wxH_CONTROLSCOMPILE, + wxH_HELPMANUAL, + wxH_HELPABOUT, + wxH_EDITCUT, + wxH_EDITCOPY, + wxH_EDITPASTE, + wxH_QUIT +}; + +class MyApp: public wxApp +{ +public: + virtual bool OnInit(); +}; + + + +class MyFrame: public wxFrame +{ +public: + MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); + + ~MyFrame (); + + void OnClose (wxCloseEvent& event); + void OnFileNew (wxCommandEvent & event); + void OnFileOpen (wxCommandEvent & event); + void OnFileSave (wxCommandEvent & event); + void OnFileSave__As (wxCommandEvent & event); + void OnFileE_xit (wxCommandEvent & event); + + void InitToolBar(wxToolBar* toolBar); + void OnControlsstarthere (wxCommandEvent & event); + void OnControlsendhere (wxCommandEvent & event); + void OnControlsrequestnode (wxCommandEvent & event); + void OnControlsend (wxCommandEvent & event); + void OnControlsEventer (wxCommandEvent & event); + void OnControlsif (wxCommandEvent & event); + void OnControlsfor (wxCommandEvent & event); + void OnControlsend_for (wxCommandEvent & event); + void OnControlspython (wxCommandEvent & event); + void OnControlsTimer (wxCommandEvent & event); + void OnControlsmake_call (wxCommandEvent & event); + void OnControlsjoin_conference (wxCommandEvent & event); + void OnControlsmake_conference (wxCommandEvent & event); + void OnControlsjoin_play_Hrecord (wxCommandEvent & event); + void OnControlsmake_play_Hrecord (wxCommandEvent & event); + void OnControlsConnectObjects(wxCommandEvent & event); + void OnCompile(wxCommandEvent & event); + void OnHelpManual (wxCommandEvent & event); + void OnHelpAbout (wxCommandEvent & event); + void OnEditCut (wxCommandEvent & event); + void OnEditCopy (wxCommandEvent & event); + void OnEditPaste (wxCommandEvent & event); + DECLARE_EVENT_TABLE() + +public: + DndShape::Kind GetImageTypeForPlacing() const { return imageTypeForPlacing; } + + + void ClearImageTypeForPlacing() { imageTypeForPlacing = DndShape::None; } + + /**Following a click on the tool bar, we are now editing in a + particular fashion. This method provides a common way of making + the necessary changes */ + void SetImageTypeForPlacing(DndShape::Kind newType) + { imageTypeForPlacing = newType; } + + /**Stop the entering of a join blocks structure, which contains + multiple line segments */ + void CloseJoinBlocks(); + +protected: + DndShape::Kind imageTypeForPlacing; + + + /**The name of the file we are currently editing */ + wxString currentFileName; + + /**The canvas this window frame gets to write on */ + MyCanvas * canvas ; +}; + +#endif Added: sofaswitch/trunk/callflow/src/canvas.cpp ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/canvas.cpp Wed Sep 6 18:04:47 2006 @@ -0,0 +1,550 @@ +//Default canvas.cpp for wxHatch + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#if wxUSE_CLIPBOARD +#include "wx/dataobj.h" +#include "wx/clipbrd.h" +#else +#error Clipboard must be enabled for copy and paste to work. +#endif + +#include <wx/textfile.h> +#include <wx/tokenzr.h> +#include <wx/tipwin.h> +#include <wx/timer.h> +#include <wx/utils.h> + +#include "canvas.h" +#include "callflow.h" + +BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) + + EVT_LEFT_DOWN (MyCanvas::OnLeftDown) + EVT_LEFT_UP (MyCanvas::OnLeftUp) + EVT_RIGHT_DOWN (MyCanvas::OnRightDown) + EVT_MOTION (MyCanvas::OnMouseMove) + EVT_PAINT (MyCanvas::OnPaint) + EVT_ENTER_WINDOW(MyCanvas::OnMouseEnter) + EVT_LEAVE_WINDOW(MyCanvas::OnMouseLeave) + EVT_CHAR (MyCanvas::OnChar) + EVT_TIMER (TimerId, MyCanvas::OnProgressTimer) + +END_EVENT_TABLE() + +MyCanvas::MyCanvas(MyFrame* parent): + wxScrolledWindow((wxWindow*)parent, -1) +{ + pFrame = parent ; + SetVirtualSize (1000, 1000); // width, height + SetScrollRate(20,20); // scroll x and y + SetBackgroundColour (wxColour (255, 255, 240)); + editingMode = WaitDownEvent; + + timerActivity = new wxTimer(this, TimerId); + timerActivity->Start(500); +} + + +MyCanvas::~MyCanvas () +{ + delete timerActivity; +} + +// Called when window needs to be repainted. +void MyCanvas::OnPaint(wxPaintEvent& event) +{ + activeShapes.ClearConnectionPoints(); + activeShapes.MarkConnectionPoints(); + + wxPaintDC dc(this); + PrepareDC(dc); + + // Find Out where the window is scrolled to + int vbX,vbY; // Top left corner of client + GetViewStart(&vbX,&vbY); + wxRegionIterator upd(GetUpdateRegion()); // get the update rect list + + wxRect nrect; + while (upd) + { + wxRect rect(upd.GetRect()); + wxPoint tl(rect.x, rect.y); + wxPoint ntl; + CalcUnscrolledPosition(tl.x, tl.y, &ntl.x, &ntl.y); + wxSize updateSize(upd.GetWidth(), upd.GetHeight()); + nrect= wxRect(ntl, updateSize); + + MyListShapes::iterator it = activeShapes.begin(); + while (it != activeShapes.end()) { + DndShape *oneShape = it->second; + if (oneShape != NULL) { + if (oneShape->Intersects(nrect)) + oneShape->Draw(dc); + } + it++; + } + upd ++ ; + } + + if (selectingRegion.IsSelected()) { + selectingRegion.Draw(dc); + } + + if (GetEditingMode() == PlaceJoinBlocks) { + wxPoint last; + if (joinBlocks.GetLastPoint(last)) { + dc.DrawLine(last, lastMousePoint); + joinBlocks.Draw(dc); + } + } +} + +wxPoint MyCanvas::GetUnscrolledPosition(wxMouseEvent & event) +{ + wxPoint pt(event.GetX(), event.GetY()); + wxPoint disp; + CalcUnscrolledPosition(pt.x, pt.y, &disp.x, &disp.y); +// printf(" %d,%d ===> %d,%d\n", pt.x, pt.y, disp.x, disp.y); + return disp; +} + + + +void MyCanvas::OnLeftDown (wxMouseEvent & event) +{ + wxPoint pt = GetUnscrolledPosition(event); + lastMousePoint = pt; + lastMouseDownPoint = pt; + + if (GetEditingMode() == PlaceJoinBlocks) { + joinBlocks.AddNewPoint(pt); + Refresh(); + return; + } + + if (GetEditingMode() == PlaceOneShape) { + DndShape::Kind kind = pFrame->GetImageTypeForPlacing(); + DndShape *newShape = DndShape::Construct(kind); + if (newShape != NULL) { + pFrame->SetImageTypeForPlacing(DndShape::None); + newShape->CenterOnThisPosition(pt); + activeShapes.Append(newShape); + Refresh(); + SetEditingMode(WaitDownEvent); + } + return; + } + + /* Left button down, no current "Kind" selected. we are therefore going to + move an object from the cureent position, or mark additional buttons.. */ + if (!event.ShiftDown()) { + selectingRegion.SetSelected(false); + selectingRegion.SetPosition(lastMousePoint); + activeShapes.UnselectAllShapes(); + } + SetEditingMode(DownEventNew); + + MyListShapes::iterator it = activeShapes.begin(); + while (it != activeShapes.end()) { + DndShape *oneShape = it->second; + if (oneShape->Intersects(pt)) { + oneShape->SetSelected(); + Refresh(); + return; + } + it++; + } + + if (!event.ShiftDown()) + SetEditingMode(SelectRectangle); +} + +void MyCanvas::OnProgressTimer(wxTimerEvent & event) +{ + static int count = 0; + count++; + bool mouseHasStopped = (lastMouseMovePoint == oldMousePoint); + oldMousePoint = lastMouseMovePoint; + + if (mouseHasStopped) { + MyListShapes::iterator it = activeShapes.begin(); + // printf(" Found a no movment at %3d %3d for %d\n", + // oldMousePoint.x, oldMousePoint.y, count++); + + while (it != activeShapes.end()) { + DndShape *oneShape = it->second; + if (oneShape != NULL) { + if (oneShape->Intersects(oldMousePoint)) { + wxPaintDC dc(this); + PrepareDC(dc); + wxCoord w, h; + wxString toolTip = oneShape->GetToolTip(); + GetTextExtent(toolTip, &w, &h); + wxPoint thisPoint; + thisPoint.x = oldMousePoint.x - (w/2); + thisPoint.y = oldMousePoint.y - h; + dc.SetPen(*wxWHITE); + dc.SetBrush(wxBrush(*wxWHITE, wxSOLID)); + dc.DrawRoundedRectangle(thisPoint.x, thisPoint.y, w, h, 5); + dc.SetPen(*wxBLACK); + dc.DrawText(toolTip, thisPoint); + } + } + it++; + } + } else + Refresh(); +} + +void MyCanvas::OnMouseMove (wxMouseEvent & event) +{ + wxPoint currentMousePoint = GetUnscrolledPosition(event); + lastMouseMovePoint = currentMousePoint; + + EditingMode em = GetEditingMode(); + + if (em == PlaceOneShape) { + lastMousePoint = currentMousePoint; + return; + } + + if (em == DownEventNew) { + if (selectingRegion.IsSelected()) { + SetEditingMode(MovingShapesRectangle); + } else { + SetEditingMode(MovingShapes); + } + } + + if (em == PlaceJoinBlocks) { + lastMousePoint = currentMousePoint; + Refresh(); + return; + } + + if (event.LeftIsDown()) { + if ((em == MovingShapes) || (em == MovingShapesRectangle)) { + wxPoint delta; + + delta.x = currentMousePoint.x - lastMousePoint.x; + delta.y = currentMousePoint.y - lastMousePoint.y; + + MyListShapes::iterator it = activeShapes.begin(); + while (it != activeShapes.end()) { + DndShape *oneShape = it->second; + if (oneShape->IsSelected()) { + oneShape->AdjustPosition(delta); + } + it++; + } + + if (em == MovingShapesRectangle) + selectingRegion.AdjustPosition(delta); + lastMousePoint = currentMousePoint; + Refresh(); + return; + } + } + + lastMousePoint = currentMousePoint; + if (em == SelectRectangle) { + //Calculate the region that we draw a box around. + selectingRegion.SetOtherCorner(currentMousePoint); + + MyListShapes::iterator it = activeShapes.begin(); + while (it != activeShapes.end()) { + DndShape *oneShape = it->second; + bool isSelected = oneShape->Intersects(selectingRegion.GetRect()); + oneShape->SetSelected(isSelected); + it++; + } + Refresh(); + return; + } + +// printf("On mouse move at %d, %d %s\n", +// event.GetX(), event.GetY(), +// (event.LeftIsDown() ? "is down" : "is up")); +} + + +void MyCanvas::OnLeftUp (wxMouseEvent & event) +{ + if (GetEditingMode() != PlaceJoinBlocks) + SetEditingMode(WaitDownEvent); + Refresh(); + // printf("On mouse left up at %d, %d \n", + // event.GetX(), event.GetY()); +} + + +void MyCanvas::OnMouseEnter (wxMouseEvent & event) +{ + if (GetEditingMode() == PlaceOneShape) { + Refresh(); + return; + } + + // SetEditingMode(WaitDownEvent); + Refresh(); +} + +void MyCanvas::OnMouseLeave (wxMouseEvent & event) +{ + // SetEditingMode(WaitDownEvent); + Refresh(); +} + +void MyCanvas::OnRightDown (wxMouseEvent & event) +{ + wxPoint pt = GetUnscrolledPosition(event); + if (editingMode == PlaceJoinBlocks) { + joinBlocks.AddNewPoint(pt); + + DndShape *nJoin = DndShape::Construct(DndShape::JoinBlocks); + wxString points = joinBlocks.GetShapeInfoSpecial(); + joinBlocks.RemoveCurrentPoints(); + nJoin->SetShapeInfoSpecial(points); + activeShapes.Append(nJoin); + + SetEditingMode(WaitDownEvent); + Refresh(); + return; + } + + MyListShapes::iterator it = activeShapes.begin(); + while (it != activeShapes.end()) { + DndShape *oneShape = it->second; + if (oneShape->Intersects(pt)) + oneShape->ProcessRightMouseButton(pFrame); + it++; + } +} + +void MyCanvas::ScreenToClipboard() +{ + wxString toCopy; + + MyListShapes::iterator it = activeShapes.begin(); + while (it != activeShapes.end()) { + DndShape *oneShape = it->second; + if (oneShape->IsSelected()) + toCopy += oneShape->GetShapeInfo(); + it++; + } + + //printf("shape %s\n", (const char *)toCopy); + wxTheClipboard->UsePrimarySelection(); + if (wxTheClipboard->Open()) { + wxTheClipboard->SetData( new wxTextDataObject(toCopy) ); + wxTheClipboard->Close(); + } +} + +void MyCanvas::ClipboardToScreen() +{ + if (!wxTheClipboard->Open()) + return; + + activeShapes.UnselectAllShapes(); + + if (wxTheClipboard->IsSupported( wxDF_TEXT )) { + wxTextDataObject data; + wxTheClipboard->GetData(data); + activeShapes.AddNewShapes(data.GetText(), true); + Refresh(); + } + wxTheClipboard->Close(); +} + + void MyCanvas::OnChar(wxKeyEvent& event) +{ + wxString key; + bool changedScreen = false; + long keycode = event.GetKeyCode(); + + if (keycode == WXK_DELETE) { + RemoveSelectedShapes(); + changedScreen = true; + } + + // printf ("keyocde is %d\n", keycode); + if (event.ControlDown()) { + // printf("Control is down\n"); + if (keycode == 99) { /* Process Ctrl - c */ + ScreenToClipboard(); + changedScreen = true; + } + + if ((keycode == WXK_INSERT) || (keycode == 118)) { /* Process Ctrl - v */ + ClipboardToScreen(); + changedScreen = true; + } + + } + + if (changedScreen) { + Refresh(); + event.Skip(); + return; + } +} + +void MyCanvas::ShapeInformationToFile(wxString & fileName) +{ + wxString data; + + MyListShapes::iterator it = activeShapes.begin(); + while (it != activeShapes.end()) { + data += it->second->GetShapeInfo(); + it++; + } + + wxTextFile file(fileName); + + if (!file.Exists()) + file.Create(); + file.Open(); + if (!file.IsOpened()) { + return; + } + + file.Clear(); + file.AddLine(data); + file.Write(); + file.Close(); +} + +void MyCanvas::ReadShapeInformationFromFile(wxString & fileName) +{ + wxTextFile file(fileName); + file.Open(); + + if (!file.IsOpened()) { + return; + } + + wxString data; + for (data = file.GetFirstLine(); !file.Eof();) + data += wxString(file.GetEOL()) + file.GetNextLine(); + + file.Close(); + + RemoveCurrentShapes(); + activeShapes.AddNewShapes(data); + Refresh(); +} + +void MyCanvas::RemoveCurrentShapes() +{ + selectingRegion.SetSelected(false); + activeShapes.RemoveCurrentShapes(); +} + +void MyCanvas::DisplayTextPopup(const wxString& text) //, const wxPoint& WXUNUSED(pos)) +{ +#if wxUSE_TIPWINDOW + // #warning "tip windows on " + static wxString oldMessage; + if (text == oldMessage) + return; + oldMessage = text; + + static wxTipWindow* s_tipWindow = NULL; + + if (s_tipWindow){ + // Prevent s_tipWindow being nulled in OnIdle, + // thereby removing the chance for the window to be closed by ShowHelp + s_tipWindow->SetTipWindowPtr(NULL); + s_tipWindow->Close(); + } + s_tipWindow = NULL; + + if ( !text.empty() ) { + s_tipWindow = new wxTipWindow(wxTheApp->GetTopWindow(), text, 100, & s_tipWindow); + + return; + } +#else + wxUnusedVar(text); +#endif // wxUSE_TIPWINDOW + } + + + +void MyCanvas::SetEditingMode(EditingMode newMode) +{ + if (newMode == editingMode) + return; + + editingMode = newMode; + // printf("YES. set editing mode to %d\n\n", newMode); + switch (newMode) + { + case WaitDownEvent:; + { + CloseJoinBlocks(); + pFrame->SetStatusText("Waiting for a mouse click event"); + } + break; + case DownEventNew:; + { + CloseJoinBlocks(); + pFrame->SetStatusText("Waiting for a mouse click event"); + } + break; + case PlaceOneShape:; + { + CloseJoinBlocks(); + wxString kindName = DndShape::GetKindName(pFrame->GetImageTypeForPlacing()); + wxString mess= wxString("Set the mouse at desired position to place a ") + kindName; + pFrame->SetStatusText(mess); + selectingRegion.SetSelected(false); + activeShapes.UnselectAllShapes(); + } + break; + case SelectRectangle:; + { + CloseJoinBlocks(); + pFrame->SetStatusText("Mark a rectangle on screen, and select objects within"); + selectingRegion.SetOtherCorner(lastMouseDownPoint); + selectingRegion.SetSelected(true); + } + break; + case MovingShapes:; + { + CloseJoinBlocks(); + pFrame->SetStatusText("Moving one or more shapes on the screen"); + } + break; + case MovingShapesRectangle:; + { + CloseJoinBlocks(); + pFrame->SetStatusText("Moving one or more shapes, and a selecting rectangle, on the screen"); + } + break; + case PlaceJoinBlocks:; + { + pFrame->SetStatusText("Draw interconnecting logic flow between blocks on the screen"); + } + break; + default: + { + pFrame->SetStatusText("Should not be selected"); + } + break; + } +} + + + Added: sofaswitch/trunk/callflow/src/canvas.h ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/canvas.h Wed Sep 6 18:04:47 2006 @@ -0,0 +1,184 @@ +//Default canvas.h for wxHatch + +#ifndef _canvas_h +#define _canvas_h + +#include "drawshape.h" +#include "shapelist.h" + +class MyFrame; +class MyCanvas; + + +///////////////////////////////////////////////////////////////////////////// + +class MyCanvas: public wxScrolledWindow +{ +public: + + /**Construct this canvas, which is the writing area inside the + class known as MyFrame */ + MyCanvas(MyFrame * parent); + + /**Destroy this canvas, which is called by the system on close down */ + ~MyCanvas (); + + /**Process event - character read from the keyboard */ + void OnChar(wxKeyEvent& event); + + /**Process event - left mouse button has been pressed */ + void OnLeftDown (wxMouseEvent & event); + + /**Process event - right mouse button has been pressed */ + void OnRightDown (wxMouseEvent & event); + + /**Process event - left mouse button has lifted up */ + void OnLeftUp (wxMouseEvent & event); + + /**Process event - mouse has entered the window */ + void OnMouseEnter (wxMouseEvent & event); + + /**Process event - mouse has left the window */ + void OnMouseLeave (wxMouseEvent & event); + + /**Process event - mouse has moved in the window */ + void OnMouseMove (wxMouseEvent & event); + + /**Process event - need to redraw part/all of the window */ + void OnPaint(wxPaintEvent & event); + + /**Have received a timer interrupt */ + void OnProgressTimer(wxTimerEvent & event); + + /**Write the information from the activeShapes variable to the + specified file. It is assumed the file is openable */ + void ShapeInformationToFile(wxString & fileName); + + /**Read the information from the file, and copy that information + to activeShapes variable, and display the loaded shapes */ + void ReadShapeInformationFromFile(wxString & fileName); + + /**Describes the particular editing mode we are using - eg, + selecting rectangle, selecting shapes etc */ + enum EditingMode { + /* 0 */WaitDownEvent /**Don't know what to do now - wait for mouse button down event */, + /* 1 */DownEventNew /**Left Mouse button down, on canvas, no modifier, so start over */, + /* 2 */PlaceOneShape /**Put new shape on the canvas */, + /* 3 */SelectRectangle /**Marking a region on the screen */, + /* 4 */MovingShapes /**A group of shapes on the screen are being moved */, + /* 5 */MovingShapesRectangle /**Shapes and the selecting rectangle are on the move */, + /* 6 */PlaceJoinBlocks /**Placing a series of connecting lines on the screen */, + /* 7 */NumEditingModes /**Count of the available editing modes */ + }; + + /**Provide an id to use for different elements in the main canvas */ + enum VariousIds { + TimerId = 12345 /**The id associated with the activity timer */ + }; + + /**Alter the editing mode from one type to another. This will make + the relevant changes to the display (for example, remove the + selecting region on the screen). Second, it will display to the + panel the new mode we are currently in + + This routine does not ever call Refresh(). If it did, there + will be duplicate calls of Refresh() as the calling method may + want to do Refresh also. */ + void SetEditingMode(EditingMode newMode); + + /**Remove all current shapes from the display. It is up to the calling + routine to do the display updating */ + void RemoveCurrentShapes(); + + /**Remove the shapes from this list that are marked as being selected. + It is up to the calling routine to do a refresh.*/ + void RemoveSelectedShapes() { activeShapes.RemoveSelectedShapes(); } + + /**Take the selected objects on the screen, and copy them all to + the clipbard. This will not include the selecting shape. */ + void ScreenToClipboard(); + + /**Take all the objects on the clipboard, and paste them to the + screen. Thus, all curently selected objects have to be + unselected. All objects pasted to the screen have to marked as + selctted. */ + void ClipboardToScreen(); + + /**Close down a JoinBlocks structure to nothing - which removes + all entered points. This is done because the data has already + been copied to a new JoinBlocks structure that went into the + ActiveShapes list.*/ + void CloseJoinBlocks() { joinBlocks.RemoveCurrentPoints(); } + + /**Display a text popup screen which shows information on the + shape underneath the mouse */ + void DisplayTextPopup(const wxString & text); + + /**Send the curent active shapes to be compiled, and save output + to the specified file. + + Return true on success, false on failure */ + bool Compile(wxTextFile & file) + { return activeShapes.Compile(file); } + + DECLARE_EVENT_TABLE() + +protected: + /**Given a mouse event at some location, what is the correct (in + this canvas view point) location of this event? This method + returns the value sought. */ + wxPoint GetUnscrolledPosition(wxMouseEvent & event); + + /**Report the editing mode that this canvas is curently + in. Editing mode indicates how the mouse is interepreted when + there is a move, or mouse down/up event. We use this one + variable to keep track of the different modes, and avoid using + multiple booleans.*/ + EditingMode GetEditingMode() { return editingMode; } + + /**list of current active shapes that are in this canvas */ + MyListShapesExtended activeShapes; + + /**last point at which the mouse was detected at. this variable is + used to detect the relative movement of the mouse.*/ + wxPoint lastMousePoint; + + /**last point at which the mouse was detected as having the left + mouse button clicked down */ + wxPoint lastMouseDownPoint; + + /**The region on screen that this mouse has selected. It is stored + in a DndShapeSelect for convenience and simplicity. */ + DndShapeSelect selectingRegion; + + /**The multi line segmented object that we build up on the + screen. Since it is built with multiple down clicks, (and not + one), we build it here. Exactly the same reason as the + DndShapeSelect for marking arectangle is built here */ + DndShapeJoinBlocks joinBlocks; + + /** Pointer back to the manager of this writing surface */ + MyFrame *pFrame; + + /**The name of the file which we are reading /writing data to */ + wxString currentFileName; + + /**The current mode we are using to do things on the screen */ + EditingMode editingMode; + + /** the timer for generating an input, which alluws us to check + the mouse position on a regular basis. If the mouse is not + moving, post a tool tip */ + wxTimer *timerActivity; + + /**The mouse position, which is used in looking for movement, and + helps us to determine where to test the mouse position for + displaying the tool tip */ + wxPoint oldMousePoint; + + /**The mouse position at which we were told the mouse last moved */ + wxPoint lastMouseMovePoint; +}; +#endif + + Added: sofaswitch/trunk/callflow/src/dnd.cpp ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/dnd.cpp Wed Sep 6 18:04:47 2006 @@ -0,0 +1,879 @@ +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include <wx/textfile.h> + + +#include "dnd.h" +#include "drawshape.h" + +#include "callflow.h" +#include "information.h" +#include "shapelist.h" + +#include <wx/listimpl.cpp> +WX_DEFINE_LIST(AListPoints); + +///////////////////////////////////////////////////////////////////////////// +MyTokenizer::MyTokenizer(const wxString & _source, const wxString & _token) +{ + source = _source; + token = _token; + + readPosn = 0; +} + +int MyTokenizer::CountTokens() +{ + if (source.size() == 0) + return 0; + + int count = 0; + + unsigned int currentIndex = 0; + bool keepLooking = true; + + do { + wxString working = source.Mid(currentIndex); + count++; + int nextIndex = working.Find(token); + + if (nextIndex < 0) + keepLooking = false; + else + currentIndex = currentIndex + nextIndex + token.size(); + + if (currentIndex >= source.size()) + keepLooking = false; + } + while (keepLooking); + + return count; +} + +wxString MyTokenizer::GetToken() +{ + if (readPosn >= source.size()) { + return wxString(""); + } + + wxString working = source.Mid(readPosn); + + int nextIndex = working.Find(token); + + if (nextIndex < 0) { + readPosn = source.size(); + wxString answer = (working.Trim(true)).Trim(false); + return answer; + } + + wxString answer = working.Left(nextIndex); + readPosn += nextIndex + token.size(); + answer = (answer.Trim(true)).Trim(false); + + return answer; +} + +///////////////////////////////////////////////////////////////////////////// +LabelledPoint::LabelledPoint() +{ + thisPoint = wxPoint(0, 0); + otherNodeLabel = wxString(""); + otherNodeIndex = -1; + otherNodeKind = DndShape::None; +} + +LabelledPoint::LabelledPoint(int x, int y) +{ + thisPoint = wxPoint(x, y); + otherNodeLabel = wxString(""); + otherNodeIndex = -1; + otherNodeKind = DndShape::None; +} + +LabelledPoint::LabelledPoint(int x, int y, const wxString & newLabel) +{ + thisPoint = wxPoint(x, y); + otherNodeLabel = wxString(newLabel); + otherNodeIndex = -1; + otherNodeKind = DndShape::None; +} + +LabelledPoint::LabelledPoint(wxPoint &srcData) +{ + thisPoint = srcData; + otherNodeLabel = wxString(""); + otherNodeIndex = -1; + otherNodeKind = DndShape::None; +} + +LabelledPoint::LabelledPoint(wxPoint &srcData, const wxString & srcString) +{ + thisPoint = srcData; + otherNodeLabel = wxString(srcString); + otherNodeIndex = -1; + otherNodeKind = DndShape::None; +} + +LabelledPoint::~LabelledPoint() +{ +} + +void LabelledPoint::PrintMe() +{ + wxString f = GetFullLabel(); + printf(" Labelled Point %s %d %d\n", f.c_str(), thisPoint.x, thisPoint.y); +} + +wxString LabelledPoint::GetFullLabel() const +{ + wxString kindLabel = DndShape::GetKindName((DndShape::Kind)otherNodeKind); + kindLabel.Replace(" ", "_", true); //Replace all spaces with underscores. + + wxString answer = wxString::Format("(\"%s\", %d, \"%s\" )", + otherNodeLabel.c_str(), + otherNodeIndex, + kindLabel.c_str()); + + return answer; +} + +bool LabelledPoint::SetKindValue(MyListShapesExtended & activeShapes) +{ + otherNodeKind = activeShapes.GetKindFor(otherNodeLabel); + if (otherNodeKind == DndShape::None) + return false; + + return true; +} + +void LabelledPoint::ClearData() +{ + otherNodeKind = -1; + otherNodeIndex = -1; + if (otherNodeLabel.IsNull()) + printf("not null\n"); + otherNodeLabel = wxString(""); + if (otherNodeLabel.IsNull()) + printf("not null second time.\n"); + +} + +bool LabelledPoint::LinksToShape() +{ + if (otherNodeIndex < 0) + return false; + + if (otherNodeLabel == wxString("")) + return false; + + return true; +} +///////////////////////////////////////////////////////////////////////////// + +void MyListPoints::RemoveCurrentPoints() +{ + DeleteContents(true); + Clear(); +} + +bool MyListPoints::GetLastPoint(wxPoint & point) +{ + if (GetCount() == 0) + return false; + + wxNode *node = (wxNode *)GetLast(); + point = *((wxPoint *)node->GetData()); + return true; +} + +int MyListPoints::ConnectionPointIndex(const wxPoint & testPoint) +{ + wxNode *node = (wxNode *)GetFirst(); + + int thisPointIndex = -1; + while (node != NULL) { + thisPointIndex++; + const wxPoint &thisPoint = ((LabelledPoint *)node->GetData())->GetPoint(); + if ((abs(thisPoint.x - testPoint.x) < 5) && + (abs(thisPoint.y - testPoint.y) < 5) ) + return thisPointIndex; + node = node->GetNext(); + } + + return -1; +} + +bool MyListPoints::SetKindValue(MyListShapesExtended & activeShapes) +{ + wxNode *node = (wxNode *)GetFirst(); + + while (node != NULL) { + LabelledPoint *thisLabel = (LabelledPoint *)node->GetData(); + if (!thisLabel->SetKindValue(activeShapes)) + return false; + node = node->GetNext(); + } + + return true; +} + +void MyListPoints::MarkConnectionPoint(const wxPoint & testPoint, + const wxString & label, + int otherNodeIndex) +{ + wxNode *node = (wxNode *)GetFirst(); + + while (node != NULL) { + const wxPoint &thisPoint = ((LabelledPoint *)node->GetData())->GetPoint(); + if ((abs(thisPoint.x - testPoint.x) < 5) && + (abs(thisPoint.y - testPoint.y) < 5) ) { + ((LabelledPoint *)node->GetData())->SetOtherNodeLabel(label); + ((LabelledPoint *)node->GetData())->SetOtherNodeIndex(otherNodeIndex); + + return; + } + node = node->GetNext(); + } +} + +void MyListPoints::Add (int x, int y) +{ + Add(new LabelledPoint(x, y)); +} + +void MyListPoints::Add (int x, int y, const wxString & label) +{ + Add(new LabelledPoint(x, y, label)); +} + +void MyListPoints::Add(wxPoint &newPoint) +{ + Add(new LabelledPoint(newPoint)); +} + +void MyListPoints::Add(wxPoint &newPoint, wxString &newLabel) +{ + Add(new LabelledPoint(newPoint, newLabel)); +} + +void MyListPoints::Add(wxString &newLabel, wxPoint &newPoint) +{ + Add(newPoint, newLabel); +} + +void MyListPoints::Add(LabelledPoint *addMe) +{ + // printf(" Add %d %d\n", addMe->GetX(), addMe->GetY()); + Append(addMe); +} + +bool MyListPoints::AllLinked() +{ + wxNode *node = (wxNode *)GetFirst(); + + while (node != NULL) { + LabelledPoint *thisLabel = (LabelledPoint *)node->GetData(); + + if (!thisLabel->LinksToShape()) + return false; + + node = node->GetNext(); + } + + return true; +} + +bool MyListPoints::PointLinked(int index) +{ + wxNode *node = (wxNode *)GetFirst(); + int nodeIndex = 0; + + while ((index > nodeIndex) && (node != NULL)) { + node = node->GetNext(); + nodeIndex++; + } + + if (node == NULL) + return false; + + LabelledPoint *thisLabel = (LabelledPoint *)node->GetData(); + + return thisLabel->LinksToShape(); +} + +///////////////////////////////////////////////////////////////////////////// + +DndShape::DndShape(Kind shapeDrawn) +{ + isSelected = FALSE; + + kind = shapeDrawn; + + ZeroPositionSize(); + + ioPointsLinked = false; + + StoreNewKey(GetName() + wxString::Format(" %lX", (long unsigned)this)); + + displayData[displayData.size()] = InformationSection(wxT("Tool Tip"), GetName()); +} + +bool DndShape::CheckOutputPointsLinked() +{ + return outputPoints.AllLinked(); +} + +void DndShape::StoreNewKey(wxString newKey) +{ + uniqueKey = newKey; + uniqueKey.Replace(" ", "_", true); //Replace all spaces with underscores. + inputPoints.SetKey(uniqueKey); + outputPoints.SetKey(uniqueKey); +} + +wxString DndShape::GetKindName(Kind thisKind) +{ + if (thisKind == None) + return wxString("No kind"); + + if (thisKind == StartHere) + return DndShapeStartHere::GetKindName(); + + if (thisKind == EndHere) + return DndShapeEndHere::GetKindName(); + + if (thisKind == RequestNode) + return DndShapeRequestNode::GetKindName(); + + if (thisKind == StartFor) + return DndShapeStartFor::GetKindName(); + + if (thisKind == EndFor) + return DndShapeEndFor::GetKindName(); + + if (thisKind == Conditional) + return DndShapeConditional::GetKindName(); + + if (thisKind == MakeCall) + return DndShapeMakeCall::GetKindName(); + + if (thisKind == EndCall) + return DndShapeEndCall::GetKindName(); + + if (thisKind == Select) + return DndShapeSelect::GetKindName(); + + if (thisKind == JoinBlocks) + return DndShapeJoinBlocks::GetKindName(); + + if (thisKind == Python) + return DndShapePython::GetKindName(); + + if (thisKind == Timer) + return DndShapeTimer::GetKindName(); + + if (thisKind == Eventer) + return DndShapeEventer::GetKindName(); + + wxString answer = wxString::Format("node kind is %d", thisKind); + return answer; +} + +DndShape * DndShape::Construct(int shapeRequired) +{ + if ((shapeRequired < 0) || ( shapeRequired >= KnownShapes)) { + wxMessageBox(wxString::Format("Unknown DndShape of kind %d", + shapeRequired)); + return NULL; + } + return Construct((Kind)shapeRequired); +} + +DndShape * DndShape::Construct(const wxString & description) +{ + DndShape * dndShape = NULL; + + MyTokenizer bits(description, GetEndBlock()); + + if (bits.CountTokens() != 4) { + printf("String does not have the right number of tokens - %d suppl\n", + bits.CountTokens()); + printf("Break up \"%s\"\n", description.c_str()); + return NULL; + } + long kind, xpos, ypos; + + wxString ans = bits.GetNextToken(); + if (!ans.ToLong(&kind)) { + printf("kind failed\n"); + return NULL; + } + + ans = bits.GetNextToken(); + if (!ans.ToLong(&xpos)) { + printf("xpos failed\n"); + return NULL; + } + + ans = bits.GetNextToken(); + if (!ans.ToLong(&ypos)) { + printf("ypos failed\n"); + return NULL; + } + + dndShape = DndShape::Construct(kind); + if (dndShape != NULL) { + wxPoint xy(xpos, ypos); + dndShape->SetPosition(xy); + dndShape->SetShapeInfoSpecial(bits.GetNextToken()); + } + + return dndShape; +} + +bool DndShape::LinkedTo(Kind desiredKind, const wxString & searchingNode, int outputPoint) +{ + if (kind !=desiredKind) + return false; + + if (outputPoint >= (int)outputPoints.GetCount()) + return false; + + wxNode *outputNode = (wxNode *)GetOutputPoints().Item(outputPoint); + + return (searchingNode == ((LabelledPoint *)outputNode->GetData())->GetLabel()); +} + +void DndShape::ZeroPositionSize() +{ + m_rect.SetWidth(0); + m_rect.SetHeight(0); + m_rect.SetX(0); + m_rect.SetY(0); +} + +DndShape * DndShape::Construct(Kind shapeRequired) +{ + if (shapeRequired == None) { + printf("Construction failed for build shape of None.\n"); + return NULL; + } + + switch (shapeRequired) + { + case StartHere: return new DndShapeStartHere(); + case EndHere: return new DndShapeEndHere(); + case RequestNode: return new DndShapeRequestNode(); + case EndCall: return new DndShapeEndCall(); + case StartFor: return new DndShapeStartFor(); + case EndFor: return new DndShapeEndFor(); + case Conditional: return new DndShapeConditional(); + case JoinBlocks: return new DndShapeJoinBlocks(); + case Python: return new DndShapePython(); + case Timer: return new DndShapeTimer(); + case Eventer: return new DndShapeEventer(); + default: + printf("Unknown construction of shape %d\n", shapeRequired); + } + return NULL; +} + +void DndShape::DrawCompileError(wxDC & dc) +{ + if (compileError.IsEmpty()) + return; + + dc.SetFont(*wxNORMAL_FONT); + dc.SetPen(*wxRED_PEN); + + wxCoord w, h; + dc.GetTextExtent(compileError, &w, &h); + int xPos = m_rect.x + 15 + ((35 - w)/2); + int yPos = m_rect.y + 00 + ((20 - h)/2); + dc.DrawText(compileError, xPos, yPos); +} + +void DndShape::Draw(wxDC& dc) +{ + DrawCompileError(dc); + if (isSelected) + DrawSelected(dc); +} + +void DndShape::DrawSelected(wxDC & dc) +{ + dc.SetPen(*wxRED_PEN); + + wxPoint p1(m_rect.GetPosition()); + wxPoint p2(m_rect.x + m_rect.GetWidth(), p1.y ); + wxPoint p3(m_rect.x , p1.y + m_rect.GetHeight()); + wxPoint p4(m_rect.x + m_rect.GetWidth(), p1.y + m_rect.GetHeight()); + + dc.DrawLine(p1, p4); + dc.DrawLine(p2, p3); +} + +bool DndShape::Intersects(const wxPoint & testPoint) const +{ +#if 0 + printf("Intersecst %d %d with %d %d __ %d %d\n", + testPoint.x, testPoint.y, + m_rect.x, m_rect.y, m_rect.GetWidth(), m_rect.GetHeight()); + #endif + return m_rect.Inside(testPoint); +} + +void DndShape::SetSelected(bool newIsSelected) +{ + isSelected = newIsSelected; +} + +bool DndShape::Intersects(const wxRect & testR) const +{ +#if 0 + printf("Test is %d,%d by %d %d Shape is %d %d by %d %d\n", + testR.x, testR.y, testR.GetWidth(), testR.GetHeight(), + m_rect.x, m_rect.y, m_rect.GetWidth(), m_rect.GetHeight()); +#endif + if ((testR.y + testR.GetHeight() - 1) < m_rect.y) { //test region above this shape + return false; + } + + if ((testR.y - 1) > (m_rect.y + m_rect.GetHeight())) { //test region below this shape + return false; + } + + if ((testR.x - 1) > (m_rect.x + m_rect.GetWidth())) { //test region to right of this shape + return false; + } + + if ((testR.x + testR.GetWidth()+ 1) < m_rect.x) { //test region to left of this shape + return false; + } + + return true; +} + +void DndShape::CenterOnThisPosition(wxPoint & newPosition) +{ + int hrzOffset = m_rect.GetWidth() / 2; + int hgtOffset = m_rect.GetHeight() / 2; + + wxPoint newTopLeft(newPosition.x - hrzOffset, newPosition.y - hgtOffset); + SetPosition(newTopLeft); +} + +void DndShape::SetPosition(wxPoint & newPosition) +{ + m_rect.SetX(newPosition.x); + m_rect.SetY(newPosition.y); + AdjustIoPoints(); +} + +void DndShape::AdjustPosition(wxPoint &moveSize) +{ + m_rect.Offset(moveSize.x, moveSize.y); + AdjustIoPoints(); +} + +void DndShape::SetSize(wxSize & newSize) +{ + // printf("DndShape size size to %d %d\n", newSize.GetWidth(), newSize.GetHeight()); + m_rect.SetWidth(newSize.GetWidth()); + m_rect.SetHeight(newSize.GetHeight()); +} + +bool DndShape::InputPointConnected(int index) +{ + if (index > (int)inputPoints.GetCount()) + return false; + + wxNode *node = (wxNode *)inputPoints.Item(index); + + return (*(LabelledPoint *)node->GetData()).LinksToShape(); +} + +bool DndShape::OutputPointConnected(int index) +{ + if (index > (int)outputPoints.GetCount()) + return false; + + wxNode *node = (wxNode *)outputPoints.Item(index); + + return (*(LabelledPoint *)node->GetData()).LinksToShape(); +} + +void DndShape::DrawArrow(wxDC & dc, wxPoint & locn, ArrowDirection dir, ArrowStyle style) +{ + wxPoint p1(locn), p2(locn); + + switch(dir) { + case ArrowLeft : + p1 = wxPoint(locn.x + 10, locn.y + 3); + p2 = wxPoint(locn.x + 10, locn.y - 3); + break; + case ArrowRight : + p1 = wxPoint(locn.x - 10, locn.y + 3); + p2 = wxPoint(locn.x - 10, locn.y - 3); + break; + case ArrowUp : + p1 = wxPoint(locn.x + 03, locn.y + 10); + p2 = wxPoint(locn.x - 03, locn.y + 10); + break; + case ArrowDown : + p1 = wxPoint(locn.x + 03, locn.y - 10); + p2 = wxPoint(locn.x - 03, locn.y - 10); + break; + } + + dc.DrawLine(locn, p1); + dc.DrawLine(locn, p2); + + ioPointsLinked = false; + + if (style == Connected) + dc.DrawCircle(locn, 2); +} + +void DndShape::DrawBox(wxDC &dc, int xOff, int yOff, int width, int height) +{ + dc.SetBrush(wxBrush(*wxBLUE, wxTRANSPARENT)); + dc.SetPen(*wxBLACK_PEN); + dc.DrawRoundedRectangle(m_rect.x + xOff, m_rect.y + yOff, + width, height, 5); + dc.SetBrush(wxBrush(*wxBLACK, wxSOLID ) ); +} + +void DndShape::AdjustIoPoints() +{ + inputPoints.DeleteContents(true); + inputPoints.Clear(); + + wxNode *node = (wxNode *)relInputPoints.GetFirst(); + while (node != NULL) { + LabelledPoint *pos = (LabelledPoint *)node->GetData(); + if (pos != NULL) + inputPoints.Add(m_rect.x + pos->GetX(), + m_rect.y + pos->GetY()); + node = node->GetNext(); + } + + + outputPoints.DeleteContents(true); + outputPoints.Clear(); + + node = (wxNode *)relOutputPoints.GetFirst(); + while (node != NULL) { + LabelledPoint *pos = (LabelledPoint *)node->GetData(); + if (pos != NULL) + outputPoints.Add(m_rect.x + pos->GetX(), + m_rect.y + pos->GetY()); + node = node->GetNext(); + } +} + +wxString DndShape::GetShapeInfo() +{ + wxString answer = wxString::Format("%d", kind); + answer += GetEndBlock(); + answer += wxString::Format("%d", m_rect.x); + answer += GetEndBlock(); + answer += wxString::Format("%d", m_rect.y); + answer += GetEndBlock(); + + answer += GetShapeInfoSpecial() + wxString(" ") + GetEndBlock() + GetEndShape(); + + return answer; +} + +wxString DndShape::GetShapeInfoSpecial() +{ + wxString answer = GetDescendantShapeInfo() + GetEndSpecial(); + + InformationData::iterator it = displayData.begin(); + while (it != displayData.end()) { + answer = answer + + it->second.caption + GetMidSpecial() + + it->second.data + GetMidSpecial() + GetEndSpecial(); + it++; + } + return answer; +} + +void DndShape::SetShapeInfoSpecial(const wxString & newValue) +{ + InformationData::iterator it = displayData.begin(); + while (it != displayData.end()) { + InformationData::iterator it_del = it; + it++; + + displayData.erase (it_del); + } + + bool doDescendant = true; + MyTokenizer bits(newValue, GetEndSpecial()); + while (bits.HasMoreTokens()) { + wxString currentSpecial = bits.GetNextToken(); + if (doDescendant) { + SetDescendantShapeInfo(currentSpecial); + doDescendant = false; + continue; + } + + if (currentSpecial.size() < 3) + continue; //Empty special, no information. + + MyTokenizer pieces(currentSpecial, GetMidSpecial()); + wxString caption = pieces.GetNextToken(); + wxString data = pieces.GetNextToken(); + if (data.IsEmpty() && caption.IsEmpty()) + continue; + displayData[displayData.size()] = InformationSection(caption, data); + } +} + +void DndShape::PrintContents() +{ + printf("%s\n", GetKey().c_str()); + for (int i = 0; (unsigned int) i < displayData.size(); i++) + printf(" %2d %12s %s\n", i, displayData[i].data.c_str(), displayData[i].caption.c_str()); + + printf(" Keys:: input Points %s output Points %s\n\n", + inputPoints.GetKey().c_str(), outputPoints.GetKey().c_str()); + + + wxNode *inputNode = (wxNode *)inputPoints.GetFirst(); + while (inputNode != NULL) { + const wxPoint & inputPoint = ((LabelledPoint *)inputNode->GetData()) ->GetPoint(); + const wxString & label = ((LabelledPoint *)inputNode->GetData()) ->GetLabel(); + printf(" in ---- %3d %3d %s \n", inputPoint.x, inputPoint.y, label.c_str()); + inputNode = inputNode->GetNext(); + } + + wxNode *outputNode = (wxNode *)outputPoints.GetFirst(); + while (outputNode != NULL) { + const wxPoint & outputPoint = ((LabelledPoint *)outputNode->GetData()) ->GetPoint(); + printf(" out---- %3d %3d %s\n ", outputPoint.x, outputPoint.y, + ((LabelledPoint *)outputNode->GetData())->GetFullLabel().c_str()); + + outputNode = outputNode->GetNext(); + } + printf("\n\n"); +} + +void DndShape::MarkMatchingPoints(MyListPoints &setInput) +{ + if (setInput.GetCount() == 0) { + return; + } + + if (outputPoints.GetCount() == 0) { + return; + } + + int inputNodeIndex = -1; + wxNode *inputNode = (wxNode *)setInput.GetFirst(); + while (inputNode != NULL) { + inputNodeIndex ++; + const wxPoint & inputPoint = ((LabelledPoint *)inputNode->GetData()) ->GetPoint(); + // printf("in ---- %d %d\n", inputPoint.x, inputPoint.y); + + int outputNodeIndex = -1; + wxNode *outputNode = (wxNode *)outputPoints.GetFirst(); + while (outputNode != NULL) { + outputNodeIndex++; + const wxPoint & outputPoint = ((LabelledPoint *)outputNode->GetData())->GetPoint(); + // printf(" out ---- %d %d\n", outputPoint.x, outputPoint.y); + if (abs(inputPoint.x - outputPoint.x) < 5) { + if (((outputPoint.y > inputPoint.y) && ((outputPoint.y - inputPoint.y) < 20)) || + ((inputPoint.y > outputPoint.y) && ((inputPoint.y - outputPoint.y < 5))) ) { + + ((LabelledPoint *)outputNode->GetData())->SetOtherNodeLabel(setInput.GetKey()); + ((LabelledPoint *)outputNode->GetData())->SetOtherNodeIndex(inputNodeIndex); + + ((LabelledPoint *)inputNode->GetData())->SetOtherNodeLabel(outputPoints.GetKey()); + ((LabelledPoint *)inputNode->GetData())->SetOtherNodeIndex(outputNodeIndex); + } + } + outputNode = outputNode->GetNext(); + } + inputNode = inputNode->GetNext(); + } +} + + +void DndShape::MarkMatchingPoints(DndShape *otherNode, + const wxPoint &firstPoint, + const wxPoint &lastPoint) +{ + int inputIndex; + int outputIndex; + inputIndex = otherNode->GetInputPoints().ConnectionPointIndex(firstPoint); + outputIndex = outputPoints.ConnectionPointIndex(lastPoint); + + if ((inputIndex >= 0) && (outputIndex >=0)) { + otherNode->GetInputPoints().MarkConnectionPoint(firstPoint, GetKey(), outputIndex); + outputPoints.MarkConnectionPoint(lastPoint, otherNode->GetKey(), inputIndex); + return; + } + + outputIndex = otherNode->GetOutputPoints().ConnectionPointIndex(lastPoint); + inputIndex = inputPoints.ConnectionPointIndex(firstPoint); + if ((inputIndex >= 0) && (outputIndex >=0)) { + otherNode->GetOutputPoints().MarkConnectionPoint(lastPoint, GetKey(), inputIndex); + inputPoints.MarkConnectionPoint(firstPoint, otherNode->GetKey(), outputIndex); + return; + } + + inputIndex = otherNode->GetInputPoints().ConnectionPointIndex(lastPoint); + outputIndex = outputPoints.ConnectionPointIndex(firstPoint); + if ((inputIndex >= 0) && (outputIndex >=0)) { + otherNode->GetInputPoints().MarkConnectionPoint(lastPoint, GetKey(), outputIndex); + outputPoints.MarkConnectionPoint(firstPoint, otherNode->GetKey(), inputIndex); + return; + } + + outputIndex = otherNode->GetOutputPoints().ConnectionPointIndex(firstPoint); + inputIndex = inputPoints.ConnectionPointIndex(lastPoint); + if ((inputIndex >= 0) && (outputIndex >=0)) { + otherNode->GetOutputPoints().MarkConnectionPoint(firstPoint, GetKey(), inputIndex); + inputPoints.MarkConnectionPoint(lastPoint, otherNode->GetKey(), outputIndex); + return; + } +} + +void DndShape::ProcessRightMouseButton(MyFrame *frame) +{ + wxString heading = "Properties: " + GetName(); + Information dialog(frame, heading, displayData); + + dialog.ShowModal(); //We don't care what the return value was. + //If the return is good, displayData will have been updated. + //If the return was cancel, there was not change to displayData +} + +bool DndShape::WriteSystemCode(wxTextFile & file) +{ + file.AddLine("system code "); + file.AddLine(GetName()); + + return true; +} + + +bool DndShape::WriteThisShapeInfo(wxTextFile & file) +{ + file.AddLine("this shape info"); + file.AddLine(GetKey()); + + return true; +} Added: sofaswitch/trunk/callflow/src/dnd.h ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/dnd.h Wed Sep 6 18:04:47 2006 @@ -0,0 +1,609 @@ +#ifndef _my_dnd_h +#define _my_dnd_h +//insert new code here + +#ifndef WX_PRECOMP +#include <wx/wx.h> +#endif + +#include <wx/dnd.h> +#include <wx/list.h> + +class DndShape; +class MyFrame; +class wxTextFile; +class MyListShapesExtended; + +#include "information.h" +/**A class that will break up a string into multiple pieces. This + tokenizer is special in that it will use a token string of any + length. + + Generated tokens always have the leading & trailing white spaces + removed.*/ + +class MyTokenizer : public wxObject +{ + public: + /**Constructor */ + MyTokenizer(const wxString & _source, const wxString & _token); + + /**The number of tokens generated. */ + int CountTokens(); + + /**Report the next available Token */ + wxString GetToken(); + + /**Report the next available Token, which calls GetToken() */ + wxString GetNextToken() { return GetToken(); } + + /**Report true if we are not at the end of things */ + bool HasMoreTokens() { return readPosn < source.size(); } + + private: + /**The supplied string */ + wxString source; + + /**The supplied token */ + wxString token; + + /**The curent position at which we are reading from */ + unsigned int readPosn; +}; + +///////////////////////////////////////////////////////////////////////////// + +/**A class that contains a wxPoint and a label. The label describes + the id of the node that is associated with with the point. Thus, + the Io Points use this structure to build links between nodes. */ +class LabelledPoint : public wxObject +{ + public: + /**Construct this class from nothing, and set it to blank at 0,0 */ + LabelledPoint(); + + /**Construct this class from a x & y coord, assign a blank label */ + LabelledPoint(int x, int y); + + /**Construct this class from a x & y coord, assign a label */ + LabelledPoint(int x, int y, const wxString & label); + + /**Construct this class from a wxPoint, assign a blank label */ + LabelledPoint(wxPoint &srcData); + + /**Construct this class from the supplied wxPoint and wxString */ + LabelledPoint(wxPoint &srcData, const wxString & srcString); + + /**Destroy this class */ + ~LabelledPoint(); + + /**Report the contents of this class */ + void PrintMe(); + + /**Clear the current data at this point. This data holds details about the other node */ + void ClearData(); + + /**Return the wxPoint component with this operator overload */ + operator wxPoint() { printf(" return %d %d\n", thisPoint.x, thisPoint.y); return thisPoint; } + + /**Return the wxString component with this operator overload */ + operator wxString() { return otherNodeLabel; } + + /**Get the point that is in question */ + wxPoint GetPoint() { return thisPoint; } + + /**Return the X value of this point */ + int GetX() { return thisPoint.x; } + + /**Return the Y value of this point */ + int GetY() { return thisPoint.y; } + + /**Return the label associated with this point */ + wxString & GetLabel() { return otherNodeLabel; } + + /**Return the tuple describing the label, other node index, other node kind */ + wxString GetFullLabel() const; + + /**Set the label, which describes the id of the node associated with + this point */ + void SetOtherNodeLabel(const wxString & otherNode) + { otherNodeLabel = otherNode; } + + /**Set the other node index, which describes the index of the point + from the otherNodes list of points. With this information, we + know that the second input point of an object connects to the + first output point of an object */ + void SetOtherNodeIndex(int newOtherIndex) + { otherNodeIndex = newOtherIndex; } + + /**Get the index that this point matches to in the other node */ + int GetOtherNodeIndex() { return otherNodeIndex; } + + /**Set the otherNodeKind variable - do it by extracting the dndShape + from the activeShapes (which matches thisLabel) and getting the + Kind value. This is used so the "thisLabel" is extended, and we + know what generic shape is linked to. + + return false if this shape is not linked to another node. + + return true if this shape is linked to another node.*/ + bool SetKindValue(MyListShapesExtended & activeShapes); + + /**Test this labelled point to see if it links to another shape in + the list of type "MyExtendedShapes"*/ + bool LinksToShape(); + + protected: + + /** the label, describing the node who links to us, is held in this + variable */ + wxString otherNodeLabel; + + /**The point held in this class. This point specifies where this + instance of this LabelledPoint exists in space. */ + wxPoint thisPoint; + + /**The index into the array of the other node who talks to us */ + int otherNodeIndex; + + /**The DndShap::Kind enum, which describes the type of the othe rnode */ + int otherNodeKind; +}; + + +///////////////////////////////////////////////////////////////////////////// + +WX_DECLARE_LIST(LabelledPoint, AListPoints); + +/**A class that provides some additional functionality to the simple + list of points provided by the wxList class */ +class MyListPoints : public AListPoints +{ + public: + /**Constructor - could do initialisation here. */ + MyListPoints() { } + + /**Destructor - set it to clear points on destruction and delete + associated data */ + ~MyListPoints() { RemoveCurrentPoints(); } + + /**Remove all points from this list, and delete associated data */ + void RemoveCurrentPoints(); + + /**Return the last point in this list. False if no available point.. */ + bool GetLastPoint(wxPoint & point); + + /**Add a point, given the x and y coords with no label */ + void Add (int x, int y); + + /**Add a point, given the x and y coords with the specified label */ + void Add (int x, int y, const wxString & newLabel); + + /**Add an unlabelled point to this list*/ + void Add(wxPoint &newPoint); + + /**Add a point (with associated label) to this list*/ + void Add(wxPoint &newPoint, wxString &newLabel); + + /**Repeat of the above function, for the dyslexic who muddle these two */ + void Add(wxString &newLabel, wxPoint &newPoint); + + /**Actually add the LabelledPoint */ + void Add(LabelledPoint *addMe); + + /**Set key of the owner of this list */ + void SetKey(const wxString & newKey) { ownerKey = newKey; }; + + /**Get the key of the owner of this list */ + wxString & GetKey() { return ownerKey; } + + /**Report the index (into the table) if the supplied point is in + close proximity to one of the points, or -1 if there is no + connection.*/ + int ConnectionPointIndex(const wxPoint & testPoint); + + /**From a IsConnectionPoint true, now go back through and mark tha + points that were found */ + void MarkConnectionPoint(const wxPoint & testPoint, + const wxString & label, + int otherNodeIndex); + + /**Set the otherNodeKind variable - for each of the labelled points in this shape. + Do it by calling "SetKindValue for each LabelledPoint in this list + + return true if this list contains only defined links. + + return false if this list contains undefined links.*/ + bool SetKindValue(MyListShapesExtended & activeShapes); + + /**Report true if all the points in this list are linked to some + other node . This is a necessary step in verifying the structure + will compile.*/ + bool AllLinked(); + + /**Report true if the specified point in this list are linked to some other + node . This is a necessary step in verifying the structure will + compile. + + This method is used by those shapes who do not require all + output points to be linked. DndShape::Eventer, for example, only requires + one of the output points to be linked. + + @params index is the position in the list, and values are 0, 1, 2 ....*/ + bool PointLinked(int index); + + protected: + + /**the key of the owner of this list. This key is the unique Id + assigned to the DndShape that contains this list */ + wxString ownerKey; +}; + +///////////////////////////////////////////////////////////////////////////// + + +/**This class defines the base of all shapes. Descendant classes will + actually define a particular shape which is drawn on the screen */ +class DndShape : public wxObject +{ +public: + /**The currently defined shapes that we can draw */ + enum Kind + { + /* 0 */ None /**The default kind, which is a placeholder, and is no shape at all */, + /* 1 */ StartHere, /**Start processing here */ + /* 2 */ EndHere, /**Finish processing here */ + /* 3 */ StartFor, + /* 4 */ EndFor, + /* 5 */ Conditional /**An If statement. This is the beginning - the end is handled by joining wires. */, + /* 6 */ MakeCall, + /* 7 */ EndCall, + /* 8 */ Select /**Used to indicate the rectangle on the screen we are selecting */, + /* 9 */ JoinBlocks /**The multi line segment shape which joins two structures on the screen */, + /* 10*/ Python /**The user can enter arbitary python here */, + /* 11*/ RequestNode /**Query a supervisor for a node to use to talk on*/, + /**12*/ Timer /**Initiate a timer, which runs for some specified time interval */, + /**13*/ Eventer /**Mark me as registering for an event. Possibly, wait for the registered for event */, + /* 13*/ KnownShapes /**Indicates the number of known shapes we can manage */ + }; + + /**Constructor to a predefined shape */ + DndShape(Kind shapeDrawn); + + // this is for debugging - lets us see when exactly an object is freed + // (this may be later than you think if it's on the clipboard, for example) + virtual ~DndShape() { } + + /**Create a descendant of a DndShape which is fully described by + the supplied string. If there was an error in parsing the + string, a null is returned. Otherwise, all the details in the + string (position, shape, tips, special information etc) is + loaded into the new shape */ + static DndShape * Construct(const wxString & description); + + /**Create a descendant of a DndShape which is one of the shape Kinds */ + static DndShape *Construct(Kind newShape); + + /**Create a descendant of a DndShape which is one of the shape Kinds */ + static DndShape *Construct(int newShape); + + // restore from buffer + static DndShape *New(const void *buf); + + /**Get the location of the top left corner */ + wxPoint GetPosition() const { return m_rect.GetPosition(); } + + /**Get the size of the region in which this shape is drawn */ + wxSize GetSize() const { return m_rect.GetSize(); } + + /**Get the rectangle bounding the region on which this shape is drawn */ + const wxRect & GetRect() const { return m_rect; } + + /**Get the elements that make up the input points for this shape */ + MyListPoints & GetInputPoints() { return inputPoints; } + + /**Get the elements that make up the output points for this shape */ + MyListPoints & GetOutputPoints() { return outputPoints; } + + /**Report what shape is stored in */ + Kind GetKind() const { return kind; } + + static wxString GetKindName(Kind thisKind); + + /**Get the name of this shape, based on the "kind" variable that + describes which particular shape we are */ + wxString GetName() const { return GetKindName(GetKind()); } + + /** Used to report the name of this particular class. */ + static wxString GetKindName() + { return wxString("DndShape has no name"); } + + /**Draw this particular shape to the screen. This method could be + made pure, which means this particular class is never used + directly, and always descended from. However, if this class is + created for informational purposes, the pureness of this method + would be a pain.*/ + virtual void Draw(wxDC& dc); + + /**Draw the particular shape to the screen. This method dwaws the + shape when it has been selected by the mouse. */ + virtual void DrawSelected(wxDC &dc); + + /**Mark this shape as being position so that the very middle of + this shape will coincide with the the supplied newPosition */ + void CenterOnThisPosition(wxPoint & newPosition); + + /**Mark this shape as having a top left postion as determined by + the parameter */ + virtual void SetPosition(wxPoint & newPosition); + + /**Modify the location of this shape by the specified delta. This + is used when the user is dragging this (and any other) shapes + across the canvas */ + virtual void AdjustPosition(wxPoint &moveSize); + + /**Return TRUE if any part of this shape is inside the supplied + rectangle */ + virtual bool Intersects(const wxRect & testRectangle) const; + + /**Return TRUE if the specified point is inside this particular shape */ + virtual bool Intersects(const wxPoint & testPoint) const; + + /**Set the flag to indicate this shape as having been selected by + the mouse */ + void SetSelected(bool newIsSelected = true); + + /**Report if this shape is currently selected */ + bool IsSelected() const { return isSelected; } + + /**Report the core information needed to copy this shape */ + wxString GetShapeInfo(); + + /**Report the information needed by some special shapes for + internal used */ + wxString GetShapeInfoSpecial(); + + /**Set the special info which is relevant to the particular shape + being represented */ + void SetShapeInfoSpecial(const wxString & newValue); + + /**Report a piece of special information, which will be peculiar to a + particular shape. This is made virtual. A descendant shape will specify a full + function here */ + virtual wxString GetDescendantShapeInfo() { return wxString(" extra "); } + + /**Set information which is highly peculiar to a descendant + shape. For example, the multi line join blocks shape has some + extra information on its shape - the location of the dots */ + virtual void SetDescendantShapeInfo(const wxString & newValue) { } + + /**Given the supplied input points of an external object, add the id of + the other node to this list if there is match in the location */ + void MarkMatchingPoints(MyListPoints &setInput /**an input style point */ ); + + /**We have the two endpoints of a joinblocks structure, which may + coincide with the input/output points of two DndShapes. Given + the other possible DndShape, and the two points of the + JoinBlocks structure, see if there is match between this + DndShape and the supplied DndShape On finding a match Add the + id of the other node to this list of points.*/ + void MarkMatchingPoints(DndShape *otherShape, + const wxPoint & firstPoint, + const wxPoint & lastPoint); + + + /**Remove all current connection points. Required prior to compilation */ + void ClearConnectionPoints(); + + /**Check that every output point of this shape goes + somewhere. Return False if there is a dangling output point */ + virtual bool CheckOutputPointsLinked(); + + /**Report the key which labels this unique shape */ + wxString GetKey() const { return uniqueKey; } + + /**Process right mouse button down. Invariably, a menu or + something has to be generated, and it has to be genrated on the + specified MyFrame structure. + + Some shspae will present different menus, so we need to alter + how things are displayed. This method is therefore virtual, for + each shape to override. */ + virtual void ProcessRightMouseButton(MyFrame *frame); + + + /**Report the tool tip currently defined for this shape. The tool + tip is displayed on the shape when there has been no activity + for half a second */ + wxString GetToolTip() { return displayData[0].data; } + + /**Get the tokenizir string to indicate end widget */ + static wxString GetEndShape() { return "<Shape>"; } + + /**Get the tokenizer string to indicate end of a block of + information within the description of one shape */ + static wxString GetEndBlock() { return "<B>"; } + + /**Get the tokenizer string to indicate the end of one piece of + special information. One piece of special information could be + the caption and the data value */ + static wxString GetEndSpecial() { return "<special>"; } + + /**Get the tokenizer string to indicate the end of one part of one + piece of special information. This could indicate the end of + the caption, or the end of the data value */ + static wxString GetMidSpecial() { return "<ms>"; } + + /**Write the code which is specific to one type of shape. This + code will describe how (for example) an if statement is + processed. Returns true on success, false on failure. */ + virtual bool WriteSystemCode(wxTextFile & file); + + /**Write the dictionary which describes this instance of the + shape. The dictionary contains the information on how to get to + the next shape, and information on code special to this + shspae. Thus, the dictionary will describe the code (for + example) on what to do for an if statement. Returns true on + success, false on failure */ + virtual bool WriteThisShapeInfo(wxTextFile & file); + + /**Print this shape info to the launching console, for debug purposes */ + void PrintContents(); + + /**Report true if this shape matches the kind, output point number + and key. This method is used, for example, to find the end for + loop structure that is "glued" to a launching for loop. + + To illustrate, the Start_For structure needs to find the End_For structure + that is linked to the do again input of the Start_For. */ + virtual bool LinkedTo(Kind desiredKind /**looking for a node of this kind*/, + const wxString & searchingNode /**id of node searching*/, + int outputPoint /**output point that must match. (Indexed 0, 1, 2..) */ + ); + + /**As in the case of the Start_For -- End_For pairing, there are + times when a node, to compile correctly, has to search the list + of all other nodes. This method is provided as a means for one + node to search all other nodes + + return true/false depending on if it satisfied by the search.*/ + virtual bool SearchOtherNodes + (const MyListShapesExtended & allCurrentShapes) { return true; } + + /**Clear the text string associated with this shape which + describes any compile error in creating this structure */ + void ClearCompileError() { compileError = ""; } + + /**Place a compile message into this shape - this will show up + when this shape is next displayed */ + void SetCompileError(const wxString & newError) + { compileError = newError; } + + /**Draw to the screen the current compile message for this shape */ + void DrawCompileError(wxDC & dc); + + /**The object has been detected as having moved. Consequently, the + input and output points have to be adjusted, as they are the + sum of the top left corner and relative input/output + points. + + This has the side effect of removing all current labels from + each point, so it is marked as unconnected. */ + void AdjustIoPoints(); + + protected: + + /**Store the supplied key in the list of input point, and in the + list of output points. Assign the supplied key to this shape, + in an endeavour to uniquely identify this shape */ + void StoreNewKey(wxString newKey); + + /**Initialisation - zero the values for size and position and + bounding rectangle */ + void ZeroPositionSize(); + /**Adjust the size of this shape, which is usually called from the + constuctor. It will adjust the rectangle size and local size + variable */ + void SetSize(wxSize & newSize); + + /**Mark this shape as needing help to redraw the connected lines + blob on each input/output point. This shape needs to have it's + io points marked as being linked to a neightbouring object. */ + void SetIoPointsLinked(bool areLinked = true) { ioPointsLinked = true; } + + /**Test this shape - should the connected lines block on each + input/output point be redrawn. The points are in an unknown + state, or not specified. We know the direction, but do not know + if they are connected.*/ + bool IoPointsLinked() { return ioPointsLinked; } + + /**Draw a box, relative to the top left corner, of the specified + with and height*/ + void DrawBox(wxDC &dc, int xOff, int yOff, int width, int height); + + /**Indicate the direction of the arrow on the structrue */ + enum ArrowDirection + { + ArrowLeft /**Arrow points left */, + ArrowRight /**Arrow points right */, + ArrowDown /**Arrow points down */, + ArrowUp /**Arrow points up */ + }; + + /**indicates the style of the arrow to be drawn. If it is "Loose", it is not connected. */ + enum ArrowStyle + { Loose /**unattched to another node*/, + Connected /**It is connected to something */ + }; + + /**Draw an arrow that is at some point in space, with a particular + direction and style. Send this drawing to the supplied + context */ + void DrawArrow(wxDC & dc, wxPoint & locn, ArrowDirection dir, ArrowStyle style); + + /**report true if the InputPoints list at the specified index is connected */ + bool InputPointConnected(int index); + + /**report true if the OutputPoints list at the specified index is connected */ + bool OutputPointConnected(int index); + + /**The shape that this class is representing */ + Kind kind; + + /**The rectangle which describes the outermost edge of this + particular shape. This rectangle holds information about the + current object size, so we do not need to store the size in a + separate variable. This rectangle hold information about + current object location, so we do not need to store the + location in a separate variable. */ + wxRect m_rect; + + /**the points that describe where this shape receives data from the outside world. + Consequently, these points are inputtting data to this shape. These points + are all relative to the top left corner.*/ + MyListPoints relInputPoints; + + /**the points that describe where this shape sends data to the outside world. + Consequently, these points are outputting data to other entities. These points + are all relative to the top left corner*/ + MyListPoints relOutputPoints; + + /**The same as the relInputPoints field, except that these are in + the same coordinate space as the m_pos variable. Thus, in the + coordinate space of the canvas. */ + MyListPoints inputPoints; + + /**The same as the relOutputPoints field, except that these are in + the same coordinate space as the m_pos variable. Thus, in the + coordinate space of the canvas. */ + MyListPoints outputPoints; + + /**Flag to indicate this shape is currently selected */ + bool isSelected; + + /**A flag to indicate this structure has IO points which need to + be drawn as being connected or unconnected to a second object + on the screen. */ + bool ioPointsLinked; + + /**A string which uniquely identifies this shape. For example, two + for loop shape starts will have different keys. This key is + used in labelling the id of a node we are connected to via an + IO point, or in indicating where we jump to. */ + wxString uniqueKey; + + + /**The list of information which is special to this particular + shape. It is the tootip (whci is always first, and then + anything required by a descendant class */ + InformationData displayData; + + /**The compile error generated when this shape was last compiled to code. + This messages is not saved when the shape is saved to disk */ + wxString compileError; +}; + + + + +#endif //_my_dnd_h Added: sofaswitch/trunk/callflow/src/drawshape.cpp ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/drawshape.cpp Wed Sep 6 18:04:47 2006 @@ -0,0 +1,18 @@ +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif +#include <wx/textfile.h> +#include <wx/tokenzr.h> +#include "shapelist.h" + +#include "drawshape.h" + + + Added: sofaswitch/trunk/callflow/src/drawshape.h ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/drawshape.h Wed Sep 6 18:04:47 2006 @@ -0,0 +1,20 @@ +#ifndef _drawshape_h +#define _drawshape_h + +#include "conditional.h" +#include "endcall.h" +#include "endfor.h" +#include "endhere.h" +#include "eventer.h" +#include "joinblocks.h" +#include "makecall.h" +#include "python.h" +#include "requestnode.h" +#include "shapeselect.h" +#include "startfor.h" +#include "starthere.h" +#include "timer.h" + + + +#endif Added: sofaswitch/trunk/callflow/src/information.cpp ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/information.cpp Wed Sep 6 18:04:47 2006 @@ -0,0 +1,81 @@ +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + + +#include "information.h" + +// a default Dialog +BEGIN_EVENT_TABLE(Information, wxDialog) + + END_EVENT_TABLE(); + +///////////////////////////////////////////////////////////////////////////// + +InformationSection::InformationSection(const wxString & _caption, const wxString & _data) +{ + caption = _caption; + data = _data; +} + +///////////////////////////////////////////////////////////////////////////// +Information::Information(wxFrame *parent, const wxString &newTitle, + InformationData & _data) + : wxDialog(parent, -1, newTitle, wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + data(_data) +{ + enabledControls = data.size(); + mainsizer = new wxBoxSizer( wxVERTICAL ); + + if (enabledControls > MaxMembers) + enabledControls = MaxMembers; + + for (int i = 0; i < enabledControls; i++) { + + wxString label = wxString::Format("Control %d", i+1); + staticText[i] = new wxStaticText(this, wxID_ANY, label); + staticText[i]->SetLabel(data[i].caption); + mainsizer -> Add (staticText[i], 0, wxALL | wxEXPAND, 1); + + wxString initialMessage = wxString::Format("initial value %d", i + 1); + textEntry[i] = new wxTextCtrl(this, wxID_ANY, + initialMessage, + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE); + textEntry[i]->SetValue(data[i].data); + mainsizer -> Add(textEntry[i], 0, wxALL | wxEXPAND, 10); + + staticLine[i] = new wxStaticLine(this); + mainsizer -> Add(staticLine[i], 0, wxALL | wxEXPAND, 1); + } + + mainsizer -> Add (CreateButtonSizer( wxOK|wxCANCEL ), 0, wxCENTER|wxALL, 10 ); + SetSizer( mainsizer ); // use the sizer for layout + + mainsizer->SetSizeHints( this ); // set size hints to honour minimum size + + + + for (int j = enabledControls; j < MaxMembers; j++) { + staticText[j] = NULL; + textEntry[j] = NULL; + staticLine[j] = NULL; + } +} + +bool Information::TransferDataFromWindow() +{ + for (int i = 0; i < enabledControls; i++) + data[i].data = textEntry[i]->GetValue().Trim(true).Trim(false); + + return true; +} + Added: sofaswitch/trunk/callflow/src/information.h ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/information.h Wed Sep 6 18:04:47 2006 @@ -0,0 +1,89 @@ +#ifndef _information_h +#define _information_h +//insert new code here + +#include <wx/statline.h> +#include <wx/hash.h> + +/**The information of Caption and contents, which is each block of the + Information dialog */ +class InformationSection : public wxObject +{ + public: + /**Constructor. The string and caption are initialised to empty by + the wxString constructor */ + InformationSection() { } + + /**Constructor to specified caption and data values */ + InformationSection(const wxString & _caption, const wxString & _data); + + /**Destructor. Placed here for "completness". It does nothing */ + ~InformationSection() {} + + /**The caption for this section. Made public for ease of use */ + wxString caption; + + /**The actual data the user will edit. Made public for ease of use */ + wxString data; +}; + +///////////////////////////////////////////////////////////////////////////// +/**Declare a dictionary of the InformationSections. This dictionary + can be accessed in a linear fashion via an iterator, or via an + integer. + + This class stores the Caption and current contents for each of the + fields in the Information class. This class is stored in the + DndShape, and passed by reference to the Information class. Values + entered in the information class are optionally passed back, + depending on the final OK/Cancel response */ + +WX_DECLARE_HASH_MAP(int, InformationSection, wxIntegerHash, wxIntegerEqual, InformationData); + +///////////////////////////////////////////////////////////////////////////// + + +/** This modal information dialog builds up the different answers from + the user as to specifics on the specific control being + handled. Things like desired tooltip, for loop handlers etc can be + described in here. */ +class Information : public wxDialog +{ + public: + /**Construct this class, with the specific number of controls */ + Information(wxFrame *parent, const wxString & newTitle, InformationData & _data); + + protected: + /**An integer to specify howmany possible controls this dialog can handle */ + enum MemberCount { + MaxMembers = 5 /**This dialog can only handle 5 controls, indexed as 0..4 */ + }; + + + /**The data we were passed on what data to present, and report */ + InformationData &data; + + /**The OK button was pressed, which will close this window, We want + to now transfer the data from the window to the InformationData + structure */ + virtual bool TransferDataFromWindow(); + + /**The label that goes over each text entry widget */ + wxStaticText * staticText[MaxMembers]; + + /**Each actual text entry widget */ + wxTextCtrl * textEntry[MaxMembers]; + + /**The line spacer between each group of controls */ + wxStaticLine * staticLine[MaxMembers]; + + /**the number of controls to display on the widget frame */ + int enabledControls; + + /**The sizer that holds every widget */ + wxBoxSizer * mainsizer; + + DECLARE_EVENT_TABLE(); +}; + +#endif Added: sofaswitch/trunk/callflow/src/shapelist.cpp ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/shapelist.cpp Wed Sep 6 18:04:47 2006 @@ -0,0 +1,395 @@ +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif +#include <wx/textfile.h> + + +#include "shapelist.h" +#include "callflow.h" +#include "drawshape.h" + + + +///////////////////////////////////////////////////////////////////////////// + +void MyListShapesExtended::AddNewShapes(const wxString & newData, bool isSelected) +{ + MyTokenizer bits(newData, DndShape::GetEndShape()); + + while ( bits.HasMoreTokens() ) { + wxString description = bits.GetToken(); + DndShape *newShape = DndShape::Construct(description); + + if (newShape != NULL) { + newShape->SetSelected(isSelected); + Append(newShape); + } + } +} + + +void MyListShapesExtended::RemoveSelectedShapes() +{ + MyListShapes::iterator it = begin(); + while (it != end()) { + MyListShapes::iterator it_del = it; + it++; + + if (it_del->second->IsSelected()) { + delete it_del->second; + erase (it_del); + } + } +} + +void MyListShapesExtended::RemoveCurrentShapes() +{ + MyListShapes::iterator it = begin(); + while (it != end()) { + MyListShapes::iterator it_del = it; + it++; + + delete it_del->second; + erase (it_del); + } +} + +void MyListShapesExtended::UnselectAllShapes() +{ + MyListShapes::iterator it = begin(); + while (it != end()) { + it->second->SetSelected(false); + it++; + } +} + +void MyListShapesExtended::ClearConnectionPoints() +{ + MyListShapes::iterator masterIt = begin(); + while (masterIt != end()) { + DndShape *masterShape = masterIt->second; + if (masterShape != NULL) + masterShape->AdjustIoPoints(); + + masterIt++; + } +} + +void MyListShapesExtended::MarkConnectionPoints() +{ + MyListShapes::iterator masterIt = begin(); + while (masterIt != end()) { + DndShape *masterShape = masterIt->second; + if (masterShape != NULL) { + MyListPoints & masterInputPoints = masterShape->GetInputPoints(); + + MyListShapes::iterator compareIt = begin(); + while (compareIt != end()) { + DndShape *compareShape = compareIt->second; + if ((compareShape != NULL) && (compareShape != masterShape)) { + compareShape->MarkMatchingPoints(masterInputPoints); + } + compareIt ++; + } + } + masterIt++; + } + + MarkJoinBlockConnectionPoints(); +} + +void MyListShapesExtended::MarkJoinBlockConnectionPoints() +{ + MyListShapes::iterator masterIt = begin(); + while (masterIt != end()) { + DndShape *masterShape = masterIt->second; + if (masterShape != NULL) { + if (masterShape->GetKind() == DndShape::JoinBlocks) { + DndShapeJoinBlocks *joinShape = (DndShapeJoinBlocks *)masterShape; + + wxPoint firstPoint, lastPoint; + if (!joinShape->GetFirstPoint(firstPoint)) + continue; + + if (!joinShape->GetLastPoint(lastPoint)) + continue; + + LookForMatchingShapes(firstPoint, lastPoint); + } + } + masterIt++; + } +} + +void MyListShapesExtended::LookForMatchingShapes(const wxPoint & firstPoint, const wxPoint & lastPoint) +{ + MyListShapes::iterator masterIt = begin(); + while (masterIt != end()) { + DndShape *masterShape = masterIt->second; + + MyListShapes::iterator compareIt = masterIt; + compareIt++; + while (compareIt != end()) { + DndShape *compareShape = compareIt->second; + if (compareShape != masterShape) { + compareShape->MarkMatchingPoints(masterShape, firstPoint, lastPoint); + } + compareIt ++; + } + masterIt++; + } +} + +void MyListShapesExtended::Append(DndShape *newShape) +{ + if (newShape == NULL) + return; + + wxString key = newShape->GetKey(); + + (*this)[key] = newShape; +} + +void MyListShapesExtended::PrintContents() +{ + MyListShapes::iterator it = begin(); + while (it != end()) { + DndShape *thisShape = it->second; + thisShape->PrintContents(); + it++; + } +} + +int MyListShapesExtended::GetKindFor(const wxString & label) +{ + DndShape * shape = (*this)[label]; + if (shape == NULL) { + return DndShape::None; + } + return shape->GetKind(); +} + +bool MyListShapesExtended::WriteGraphData(wxTextFile & file) +{ + wxString graphName(file.GetName()); + graphName = graphName + ".graph"; + wxTextFile graphFile(graphName); + if (!graphFile.Exists()) + graphFile.Create(); + graphFile.Open(); + if (!graphFile.IsOpened()) { + return false; + } + + graphFile.Clear(); + + graphFile.AddLine("#!/usr/bin/python"); + graphFile.AddLine(" "); + graphFile.AddLine(" data = {"); + + + MyListShapes::iterator it = begin(); + while (it != end()) { + DndShape *thisShape = it->second; + bool writeOk = thisShape->WriteThisShapeInfo(graphFile); + if (!writeOk) + return false; + it++; + } + graphFile.AddLine("}"); + + graphFile.AddLine(" "); + + graphFile.Write(); + graphFile.Close(); + + return true; +} + + +bool MyListShapesExtended::Compile(wxTextFile & file) +{ + ClearConnectionPoints(); + MarkConnectionPoints(); + + /***Zero, go through and remove all previous compiler errors */ + MyListShapes::iterator it = begin(); + while (it != end()) { + DndShape *thisShape = it->second; + thisShape->ClearCompileError(); + it++; + } + + /**First, go through and check all output points link to something. */ + bool pointsLinked = true; + it = begin(); + while (it != end()) { + DndShape *thisShape = it->second; + bool thisLinked = thisShape->CheckOutputPointsLinked(); + if (!thisLinked) + thisShape->SetCompileError("Not all output points are linked"); + pointsLinked = pointsLinked && thisLinked; + it++; + } + if (!pointsLinked) + return false; + + /**second go through and calculate reverse links etc. */ + it = begin(); + while (it != end()) { + DndShape *thisShape = it->second; + bool linksOk = thisShape->SearchOtherNodes(*this); + if (!linksOk) { + thisShape->SetCompileError(wxT("Does not link to an EndFor structure")); + return false; + } + it++; + } + + + /**third, go through and set the kind variable on all input&output points */ + it = begin(); + pointsLinked = true; + while (it != end()) { + DndShape *thisShape = it->second; + if (thisShape != NULL) { + + bool linksOk = + thisShape->GetOutputPoints().SetKindValue(*this) && + thisShape->GetInputPoints().SetKindValue(*this); + if (linksOk) { + it ++; + } else{ + printf("Failed in links on %s\n", thisShape->GetName().c_str()); + thisShape->SetCompileError("Not all output points are linked"); + it = end(); + pointsLinked = false; + } + } + } + if (!pointsLinked) + return false; + + + /*** + Completed all initialisation tasks. Now, we have enough information to write to disk + + ******/ + if (!WriteGraphData(file)) + return false; + + file.Clear(); + + bool shapeInitialised[DndShape::KnownShapes]; + + file.AddLine("#!/usr/bin/python"); + file.AddLine(" "); + file.AddLine("import sys"); + file.AddLine("import os"); + file.AddLine("import time"); + file.AddLine("import socket"); + file.AddLine("import Queue"); + file.AddLine("import distutils"); + file.AddLine("import thread"); + file.AddLine("from twisted.internet import reactor, protocol"); + file.AddLine(" "); + + file.AddLine("class EchoClient(protocol.Protocol):"); + + file.AddLine(" def connectionMade(self): "); + file.AddLine(" self.myId = \"\" "); + file.AddLine(" self.countReceived = 0 "); + file.AddLine(" self.transport.write(\"?\0\") "); + file.AddLine(" self.transport.write(\"whoami\0\");"); + file.AddLine(" self.colonChar = \':\' "); + file.AddLine(" "); + file.AddLine(" def connectionLost(self, reason): "); + file.AddLine(" print \"connection lost\" "); + file.AddLine(" "); + file.AddLine(" def dataReceived(self, data): "); + file.AddLine(" ssdata = str(data).split(\'\0\') "); + file.AddLine(" for oneMessage in ssdata: "); + file.AddLine(" self.countReceived = self.countReceived + 1"); + file.AddLine(" if self.countReceived == 1: "); + file.AddLine(" self.myId = oneMessage; "); + file.AddLine(" else: "); + file.AddLine(" self.processReceivedMessage(oneMessage)"); + file.AddLine(" "); + file.AddLine(" def replyNow(self, data):"); + file.AddLine(" self.transport.write(self.tstring) "); + file.AddLine(" "); + file.AddLine(" "); + + file.AddLine("class Controller(EchoClient):"); + file.AddLine(" "); + + file.AddLine(" def processReceivedMessage(self, thisMessage): "); + file.AddLine(" print \"Received \", thisMessage "); + file.AddLine(" "); + + file.AddLine(" def __init__(self):"); + file.AddLine(" self.endProgramNow = False"); + char c= 34; + wxString tString = wxString::Format(" self.quote = \"\\%c\"", c); + file.AddLine(tString.c_str()); + + bool keepLooking = true; + it = begin(); + while ((it != end()) && keepLooking) { + DndShape *thisShape = it->second; + if (thisShape->GetKind() == DndShape::StartHere) + keepLooking = false; + else + it++; + } + if (keepLooking) + return false; + + wxString startNode = wxString::Format(" self.firstNode = \"%s\"", it->second->GetKey().c_str()); + file.AddLine(startNode); + + file.AddLine(" sTuple = \"(\" + self.quote + self.firstNode + self.quote + \", 0, \" +self.quote + \"Start_Processing\" + self.quote + \")\""); + file.AddLine(" self.DoWork(eval(sTuple))"); + file.AddLine(" "); + file.AddLine(" def DoWork(self, sTuple): "); + file.AddLine(" a,b,c = sTuple"); + file.AddLine(" "); + file.AddLine(" self.keepGoing = True "); + file.AddLine(" "); + file.AddLine(" while self.keepGoing:"); + file.AddLine(" command = \"self.\" + str(c) + \"(\" + str(sTuple) + \")\""); + file.AddLine(" a,b,c = sTuple = eval(command)"); + file.AddLine(" "); + file.AddLine(" "); + + + + for (int i = 0; i < DndShape::KnownShapes; i++) + shapeInitialised[i] = false; + + it = begin(); + while (it != end()) { + DndShape *thisShape = it->second; + if (!shapeInitialised[thisShape->GetKind()]) { + shapeInitialised[thisShape->GetKind()] = true; + bool writeOk = thisShape->WriteSystemCode(file); + if (!writeOk) + return false; + } + it++; + } + + file.AddLine("a=Controller()"); + + + file.AddLine(" "); + file.Write(); + return true; +} Added: sofaswitch/trunk/callflow/src/shapelist.h ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/src/shapelist.h Wed Sep 6 18:04:47 2006 @@ -0,0 +1,88 @@ +#ifndef _shapelist_h +#define _shapelist_h +//insert new code here + +class DndShape; +class wxTextFile; + +/**Declare a dictionary of the shapes we hold. This dictionary can be + accessed in a linear fashion via an iterator, or via a keyword */ +WX_DECLARE_STRING_HASH_MAP(DndShape *, MyListShapes); + + +/**Take the list of shapes, and add some public methods for adding + things, and removing things */ +class MyListShapesExtended : public MyListShapes +{ + public: + /**Have some new shapes to append to this list It is up to the + calling routine to do a refresh. */ + void AddNewShapes(const wxString & newShapes, + bool markSelected = false ///If true, mark new shapes as being selected. + ); + + /**Remove the shapes from this list that are marked as being selected. + It is up to the calling routine to do a refresh.*/ + void RemoveSelectedShapes(); + + /**Remove all current shapes from this list. It is up to the calling + routine to do the display updating */ + void RemoveCurrentShapes(); + + /**Mark all current shapes in this list as unselected. It is up to the calling + routine to do the display updating */ + void UnselectAllShapes(); + + /**Go through this list, and look for all connecting points between + different elements */ + void MarkConnectionPoints(); + + /**Go through this list, and remove all connecting points between + different elements */ + void ClearConnectionPoints(); + + /**Add a new shape to this list. The shape supplied has its own key, which is used to + determine where to put the shape in this list */ + void Append(DndShape *newShape); + + /**Report the DndShape;:Kind value used by the shape in this list of the supplied label */ + int GetKindFor(const wxString & label); + + /**Take the map in this list of shapes, and compile it to runnable + code. By default, it will generate python, but that is "changeable" + with some effort. + + The resultant code is stored in the specified file.. + + Returns true on success, false on failure.*/ + bool Compile(wxTextFile & file); + + /**Print this shape info to the launching console, for debug purposes */ + void PrintContents(); + + protected: + + /**A lower down method of this class, which is a subset of the compile + process. For the given list of shapes, write the textual flow + information to a file, whose name is derived from the supplied + arguement. After the compile to "a.py" (say) all the code to execute is + in a.py, with the pattern to execute in a.py.graph + + @return true if the write succeeded, false on failure.*/ + bool WriteGraphData(wxTextFile & file); + + /**Go through this list, and look for JoinBlock structrues. Find out + what each joinBlock structure joins together, and label them as + joined together */ + void MarkJoinBlockConnectionPoints(); + + /**The second part of MarkJoinBlockConnectionPoints(). Given two + points, see if there is a matching pair of input/output points + which match these coordinates. If there is a match found, mark + them accordingly */ + void LookForMatchingShapes(const wxPoint & firstPoint, const wxPoint & lastPoint); +}; + + + +#endif