sofaswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
September 2006
- 2 participants
- 78 discussions
[Sofaswitch-svn] [commit] r75 - sofaswitch/trunk/callflow/autom4te.cache
by SofaSWITCH SVN 06 Sep '06
by SofaSWITCH SVN 06 Sep '06
06 Sep '06
Author: derek
Date: Wed Sep 6 18:15:04 2006
New Revision: 75
Removed:
sofaswitch/trunk/callflow/autom4te.cache/output.0
sofaswitch/trunk/callflow/autom4te.cache/requests
sofaswitch/trunk/callflow/autom4te.cache/traces.0
Log:
Remove these tempory work files.
1
0
Author: derek
Date: Wed Sep 6 18:14:12 2006
New Revision: 74
Removed:
sofaswitch/trunk/callflow/Makefile
sofaswitch/trunk/callflow/callflow.rc
sofaswitch/trunk/callflow/configure
sofaswitch/trunk/callflow/drawshape.h
sofaswitch/trunk/callflow/information.cpp
sofaswitch/trunk/callflow/information.h
sofaswitch/trunk/callflow/shapelist.cpp
Log:
Remove these files, as they are now in the src subdirectory.
1
0
Author: derek
Date: Wed Sep 6 18:10:03 2006
New Revision: 73
Removed:
sofaswitch/trunk/callflow/callflow.cpp
sofaswitch/trunk/callflow/callflow.h
sofaswitch/trunk/callflow/canvas.cpp
sofaswitch/trunk/callflow/canvas.h
sofaswitch/trunk/callflow/config.log
sofaswitch/trunk/callflow/config.status
sofaswitch/trunk/callflow/config_err.log
sofaswitch/trunk/callflow/dnd.cpp
sofaswitch/trunk/callflow/dnd.h
sofaswitch/trunk/callflow/drawshape.cpp
sofaswitch/trunk/callflow/shapelist.h
Log:
Remove these files, as they are now in the src directory.
1
0
Author: derek
Date: Wed Sep 6 18:07:23 2006
New Revision: 72
Added:
sofaswitch/trunk/callflow/autogen.sh (contents, props changed)
Removed:
sofaswitch/trunk/callflow/Makefile.in
sofaswitch/trunk/callflow/configure.in
Log:
Add these files, as we move away from the wxhatch generated approach.
Added: sofaswitch/trunk/callflow/autogen.sh
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/callflow/autogen.sh Wed Sep 6 18:07:23 2006
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+export WANT_AUTOCONF_2_5="1"
+export WANT_AUTOMAKE_1_7="1"
+
+aclocal
+libtoolize --automake --force --copy
+automake -a -c
+autoconf
+
1
0
Author: derek
Date: Wed Sep 6 18:05:53 2006
New Revision: 71
Added:
sofaswitch/trunk/callflow/README
Log:
Initial release of this file.
Added: sofaswitch/trunk/callflow/README
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/callflow/README Wed Sep 6 18:05:53 2006
@@ -0,0 +1,50 @@
+CallFlow
+
+* About
+ This is a graphical environment for creating python control
+ scripts. These Python control scripts are required to manage the operation
+ of the different entities in the sofa switch suite of utilities.
+
+* The Problem.
+ The different entities in the SofaSwitch suite of utilities are controlled
+ by a series of TCP commands to a centralised messaging serving. Responses
+ come back at some (seemingly) random time later which describe the outcome
+ of those commands. Further, events detected by members of the SofaSwitch
+ suite of utilities are reported (via the centralised messaging server) to us.
+
+ Writing code to manage all of this in python was found to be quite labour
+ intensive, and prone to error. Further, the text interface in python is not
+ intuitive, and makes it harder for people to get started in using sofa to
+ solve real world telephony problems.
+
+ This gui entity was written to make the process of generating control scripts
+ simple and quick. In the authors view, CallFlow nicely transforms a problem
+ that is, inherently, multi threaded by nature (and therefore hideously
+ complex) into something that is easily understood and managed.
+
+* Build
+Just do
+./autogen.sh
+./configure
+make
+
+
+* Todo
+ More documentation.
+
+
+* Thanks
+ A million thanks to Linus McCabe, who wrote the wxAuto package. Thanks
+ to his work, I have a sample bit of code to get CallFlow working properly
+ with the auto tools.
+
+
+* Notes
+ wxAuto - Autoconf example project Copyright (C) 2004 Linus McCabe.
+
+* History
+2006 4 September Copy Auto tools environment from wxAuto (thanks Linus McCabe)
+
+
+
+
1
0
06 Sep '06
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(a)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
1
0
01 Sep '06
Author: derek
Date: Fri Sep 1 01:05:59 2006
New Revision: 69
Added:
sofaswitch/trunk/callflow/bitmaps/miniclock.xpm
Log:
Add this file, to describe a timer.
Added: sofaswitch/trunk/callflow/bitmaps/miniclock.xpm
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/callflow/bitmaps/miniclock.xpm Fri Sep 1 01:05:59 2006
@@ -0,0 +1,23 @@
+/* XPM */
+static char * miniclock_xpm[] = {
+"16 16 4 1",
+" c None s None",
+". c Black",
+"X c White",
+"o c #c0c0c0",
+" ",
+" ..... ",
+" ..XXXXX.. ",
+" .oXXX.XXXo. ",
+" .XXXX.XXXX. ",
+" .XXXXX.XXXXX. ",
+" .XXXXX.XXXXX. ",
+" .XXXX..XXXXX. ",
+" .XXXXX..XXXX. ",
+" .XXXXX.X.XXX. ",
+" .XXXXXXXXX. ",
+" .oXXXXXXXo. ",
+" ..XXXXX.. ",
+" ..... ",
+" ",
+" "};
1
0
[Sofaswitch-svn] [commit] r68 - in sofaswitch/trunk/callflow: . bitmaps
by SofaSWITCH SVN 01 Sep '06
by SofaSWITCH SVN 01 Sep '06
01 Sep '06
Author: derek
Date: Fri Sep 1 00:58:20 2006
New Revision: 68
Added:
sofaswitch/trunk/callflow/bitmaps/RequestNode.xpm
Modified:
sofaswitch/trunk/callflow/callflow.cpp
sofaswitch/trunk/callflow/callflow.h
sofaswitch/trunk/callflow/config.log
sofaswitch/trunk/callflow/dnd.cpp
sofaswitch/trunk/callflow/dnd.h
sofaswitch/trunk/callflow/drawshape.cpp
sofaswitch/trunk/callflow/drawshape.h
Log:
Add a structure for requesting a worker node.
This structure will send off the request, nothing more.
Added: sofaswitch/trunk/callflow/bitmaps/RequestNode.xpm
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/callflow/bitmaps/RequestNode.xpm Fri Sep 1 00:58:20 2006
@@ -0,0 +1,23 @@
+/* XPM */
+static char *RequestNode[]={
+"16 15 5 1",
+". c None",
+"# c #00c000",
+"b c #303030",
+"c c #585858",
+"a c #ffc0c0",
+"................",
+"....#.###.......",
+"....##aaa#......",
+"....#aaaaa#.....",
+"....##aaa#......",
+"...##.###..b##b.",
+"...##......##c#b",
+"...#.#....c#...b",
+"...#.#....#...#b",
+"..#...#......#b.",
+"..#....#.....#c.",
+"..#.........#c..",
+"..#.........c...",
+".#..........c...",
+"............#..."};
Modified: sofaswitch/trunk/callflow/callflow.cpp
==============================================================================
--- sofaswitch/trunk/callflow/callflow.cpp (original)
+++ sofaswitch/trunk/callflow/callflow.cpp Fri Sep 1 00:58:20 2006
@@ -28,8 +28,8 @@
#include "bitmaps/HelpAbout.xpm"
//#include "bitmaps/newshape.xpm"
-#include "bitmaps/EditCut.xpm"
#include "bitmaps/EditCopy.xpm"
+#include "bitmaps/EditCut.xpm"
#include "bitmaps/EditPaste.xpm"
#include "bitmaps/FileNew.xpm"
#include "bitmaps/FileOpen.xpm"
@@ -37,6 +37,7 @@
#include "bitmaps/FileSave__As.xpm"
#include "bitmaps/JoinObjects.xpm"
#include "bitmaps/Python.xpm"
+#include "bitmaps/RequestNode.xpm"
#include "bitmaps/compile.xpm"
class MyFrame ;
@@ -58,31 +59,32 @@
#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_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_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)
+ 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_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()
;
@@ -130,6 +132,7 @@
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_CONTROLSFOR, wxT("for"), wxT(""));
@@ -280,7 +283,7 @@
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_CONTROLSFOR, wxBitmap ( Controlsfor_xpm ), wxT("Start a for loop"));
@@ -309,7 +312,13 @@
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;
@@ -451,4 +460,3 @@
file.Close();
}
-
Modified: sofaswitch/trunk/callflow/callflow.h
==============================================================================
--- sofaswitch/trunk/callflow/callflow.h (original)
+++ sofaswitch/trunk/callflow/callflow.h Fri Sep 1 00:58:20 2006
@@ -17,6 +17,7 @@
wxH_FILEE_XIT,
wxH_CONTROLSSTARTHERE,
wxH_CONTROLSENDHERE,
+ wxH_CONTROLSREQUESTNODE,
wxH_CONTROLSEND,
wxH_CONTROLSIF,
wxH_CONTROLSFOR,
@@ -62,6 +63,7 @@
void InitToolBar(wxToolBar* toolBar);
void OnControlsstarthere (wxCommandEvent & event);
void OnControlsendhere (wxCommandEvent & event);
+ void OnControlsrequestnode (wxCommandEvent & event);
void OnControlsend (wxCommandEvent & event);
void OnControlsif (wxCommandEvent & event);
void OnControlsfor (wxCommandEvent & event);
Modified: sofaswitch/trunk/callflow/config.log
==============================================================================
--- sofaswitch/trunk/callflow/config.log (original)
+++ sofaswitch/trunk/callflow/config.log Fri Sep 1 00:58:20 2006
@@ -4,13 +4,13 @@
It was created by configure, which was
generated by GNU Autoconf 2.57. Invocation command line was
- $ ./configure --with-wxWINDIR=/usr/local/src/wxWidgets-2.6.3
+ $ ./configure
## --------- ##
## Platform. ##
## --------- ##
-hostname = dhcp22
+hostname = kauri
uname -m = x86_64
uname -r = 2.6.16.13-4-smp
uname -s = Linux
@@ -46,21 +46,11 @@
configure:1196: Configuring callflow...
configure:1198: Checking for wxWidgets (formerly wxWindows) library...
-configure:1221: checking for /usr/local/src/wxWidgets-2.6.3
-configure:1236: result: yes
-configure:1252: checking for /usr/local/src/wxWidgets-2.6.3/wx-config
-configure:1267: result: yes
-configure:1270: essential wxWidgets file - wx-config - found
-configure:1282: checking for /wx-config.in
-configure:1297: result: no
-configure:1304: checking for /usr/local/src/wxWidgets-2.6.3/wx-config.in
-configure:1319: result: yes
-configure:1362: Checking if wxWidgets library is < 2.4.3
-configure:1402: required wxWidgets version (>2.5.0) found
-configure:1408: Checking if wxWidgets library has been built
-configure:1411: wxWidgets has been built
-configure:1423: using configuration from wxWidgets config.status
-configure:1431: Makefile timestamp is
+configure:1221: checking for
+configure:1236: result: no
+configure:1243: error: directory passed on command line -
+ - does not exist!!
+ Did you type the command line --with-wxWINDIR=DIR correctly ??
## ---------------- ##
## Cache variables. ##
@@ -72,10 +62,7 @@
ac_cv_env_host_alias_value=
ac_cv_env_target_alias_set=
ac_cv_env_target_alias_value=
-ac_cv_file__usr_local_src_wxWidgets_2_6_3=yes
-ac_cv_file__usr_local_src_wxWidgets_2_6_3_wx_config=yes
-ac_cv_file__usr_local_src_wxWidgets_2_6_3_wx_config_in=yes
-ac_cv_file__wx_config_in=no
+ac_cv_file_=no
## ----------------- ##
## Output variables. ##
@@ -122,4 +109,4 @@
#define PACKAGE_TARNAME ""
#define PACKAGE_VERSION ""
-configure: exit 0
+configure: exit 1
Modified: sofaswitch/trunk/callflow/dnd.cpp
==============================================================================
--- sofaswitch/trunk/callflow/dnd.cpp (original)
+++ sofaswitch/trunk/callflow/dnd.cpp Fri Sep 1 00:58:20 2006
@@ -333,6 +333,9 @@
if (thisKind == EndHere)
return DndShapeEndHere::GetKindName();
+ if (thisKind == RequestNode)
+ return DndShapeRequestNode::GetKindName();
+
if (thisKind == StartFor)
return DndShapeStartFor::GetKindName();
@@ -447,6 +450,9 @@
if (shapeRequired == EndHere)
return new DndShapeEndHere();
+ if (shapeRequired == RequestNode)
+ return new DndShapeRequestNode();
+
if (shapeRequired == EndCall)
return new DndShapeEndCall();
Modified: sofaswitch/trunk/callflow/dnd.h
==============================================================================
--- sofaswitch/trunk/callflow/dnd.h (original)
+++ sofaswitch/trunk/callflow/dnd.h Fri Sep 1 00:58:20 2006
@@ -250,6 +250,7 @@
/* 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*/,
/* 11*/ KnownShapes /**Indicates the number of known shapes we can manage */
};
Modified: sofaswitch/trunk/callflow/drawshape.cpp
==============================================================================
--- sofaswitch/trunk/callflow/drawshape.cpp (original)
+++ sofaswitch/trunk/callflow/drawshape.cpp Fri Sep 1 00:58:20 2006
@@ -79,12 +79,9 @@
DrawBox(dc, 30, 15, 20, 20);
dc.DrawLine(pA, pB);
+ DrawArrow(dc, pB, ArrowDown, OutputPointConnected(0) ? Connected : Loose);
+
- if (OutputPointConnected(0))
- DrawArrow(dc, pB, ArrowDown, Connected);
- else
- DrawArrow(dc, pB, ArrowDown, Loose);
-
DndShape::Draw(dc);
// dc.SetBrush(wxBrush(m_col, wxSOLID));
// dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
@@ -139,12 +136,8 @@
DrawBox(dc, 30, 15, 20, 20);
dc.DrawLine(pA, pB);
+ DrawArrow(dc, pA, ArrowDown, InputPointConnected(0) ? Connected : Loose);
- if (InputPointConnected(0))
- DrawArrow(dc, pA, ArrowDown, Connected);
- else
- DrawArrow(dc, pA, ArrowDown, Loose);
-
DndShape::Draw(dc);
// dc.SetBrush(wxBrush(m_col, wxSOLID));
// dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
@@ -176,6 +169,87 @@
return true;
}
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+DndShapeRequestNode::DndShapeRequestNode()
+ : DndShape(RequestNode)
+{
+ wxSize newSize(50, 50);
+ SetSize(newSize);
+
+ displayData[displayData.size()] =
+ InformationSection(wxT("request node from "), wxT("voip"));
+
+ relInputPoints.Add(25, 0);
+ relOutputPoints.Add(25, 50);
+ AdjustIoPoints();
+}
+
+void DndShapeRequestNode::Draw(wxDC& dc)
+{
+ DrawCompileError(dc);
+ dc.SetPen(*wxBLACK_PEN);
+
+ wxPoint p1(m_rect.GetPosition());
+ wxPoint pA(p1.x + 25, p1.y + 0);
+ wxPoint pB(p1.x + 25, p1.y + 50);
+
+
+ dc.DrawLine(pA, pB);
+
+ wxString text("R ?");
+ wxFont f = wxFont(*wxITALIC_FONT);
+ f.SetPointSize(20);
+ dc.SetFont(f);//*wxITALIC_FONT);
+ wxCoord w, h;
+ dc.GetTextExtent(text, &w, &h);
+
+ int xPos = m_rect.x + 0 + ((50 - w)/2);
+ int yPos = m_rect.y + 10 + ((21 - h)/2);
+ dc.DrawText(text, xPos, yPos);
+
+ DrawArrow(dc, pA, ArrowDown, InputPointConnected(0) ? Connected : Loose);
+ DrawArrow(dc, pB, ArrowDown, OutputPointConnected(0) ? Connected : Loose);
+
+ DndShape::Draw(dc);
+ // dc.SetBrush(wxBrush(m_col, wxSOLID));
+ // dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
+}
+
+bool DndShapeRequestNode::WriteSystemCode(wxTextFile & file)
+{
+ file.AddLine(" def Request_Node(self, aTuple): ");
+ file.AddLine(" id,y,z = aTuple");
+ file.AddLine(" return data[id][\"Output\"]");
+ file.AddLine("");
+ return true;
+}
+
+bool DndShapeRequestNode::WriteThisShapeInfo(wxTextFile & file)
+{
+ file.AddLine(wxString::Format("\"%s\" : { ", GetKey().c_str()));
+
+ wxNode *inputNode = (wxNode *)GetInputPoints().GetFirst();
+ const wxString & inputLabel = ((LabelledPoint *)inputNode->GetData())->GetFullLabel();
+ file.AddLine(wxString::Format(" \"Input\" : "));
+ file.AddLine(wxString::Format(" %s, ", inputLabel.c_str()));
+
+ wxNode *outputNode = (wxNode *)GetOutputPoints().GetFirst();
+ const wxString & outputLabel = ((LabelledPoint *)outputNode->GetData())->GetFullLabel();
+ file.AddLine(wxString::Format(" \"Output\" : "));
+ file.AddLine(wxString::Format(" %s, ", outputLabel.c_str()));
+
+
+ file.AddLine(wxString::Format(" \"request node from\" : "));
+ file.AddLine(wxString::Format(" \"%s\", ", displayData[1].data.c_str()));
+
+ file.AddLine(wxString::Format(" },"));
+
+ return true;
+}
+
/////////////////////////////////////////////////////////////////////////////
DndShapePython::DndShapePython()
Modified: sofaswitch/trunk/callflow/drawshape.h
==============================================================================
--- sofaswitch/trunk/callflow/drawshape.h (original)
+++ sofaswitch/trunk/callflow/drawshape.h Fri Sep 1 00:58:20 2006
@@ -86,6 +86,36 @@
virtual bool WriteThisShapeInfo(wxTextFile & file);
};
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+/**Define a request node shape. This code will return almost immediately, and we leave it to
+ the timer object to recover from if there was an answer, or noting
+ Store values for size, location, input & output points.
+ This instance has the ability to draw this shape to a specified location on the canvas */
+class DndShapeRequestNode : public DndShape
+{
+public:
+ /**Construtor, Define this shape in terms of size and points etc */
+ DndShapeRequestNode();
+
+ /**Destroy this shape, and log it */
+ virtual ~DndShapeRequestNode()
+ {
+ }
+
+ /**Draw this particular shape to the screen..*/
+ virtual void Draw(wxDC& dc);
+
+ /** Used to report the name of this particular class. */
+ static wxString GetKindName() { return wxString("Request Node"); }
+
+ /**Write the code generic to this StartHere shape */
+ virtual bool WriteSystemCode(wxTextFile & file);
+
+ /**Write the dictionary containing relevant points for this shape */
+ virtual bool WriteThisShapeInfo(wxTextFile & file);
+};
+
//////////////////////////////////////////////////////////////////////////////////////////////
/**Define a shape to indicate the start of a foor loop. Store values
for size, location, input & output points. This instance has the
1
0