/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #ifndef _EditorWindow_h #define _EditorWindow_h #include "defines.h" #include #include "List.h" #include "Command.h" #include "DXWindow.h" #include "ControlPanel.h" #include "Cacheability.h" #include "InsertNetworkDialog.h" typedef long NodeStatusChange; // // Class name definition: // #define ClassEditorWindow "EditorWindow" // // XtCallbackProc (*CB), XtEventHandler (*EH) and XtActionProc (*AP) // DialogCallback (*DCB), XtInputCallbackProc (*ICP), XtWorkProc (*WP) // functions for this and derived classes // extern "C" void EditorWindow_EditMenuMapCB(Widget, XtPointer, XtPointer); extern "C" void EditorWindow_WindowMenuMapCB(Widget, XtPointer, XtPointer); extern "C" void EditorWindow_FileMenuMapCB(Widget, XtPointer, XtPointer); extern "C" void EditorWindow_OptionsMenuMapCB(Widget, XtPointer, XtPointer); extern "C" void EditorWindow_SetDecoratorStyleCB(Widget, XtPointer, XtPointer); extern "C" boolean EditorWindow_ConvertSelectionCB(Widget, Atom *, Atom *, Atom *, XtPointer *, unsigned long *, int *); extern "C" void EditorWindow_LoseSelectionCB(Widget, Atom *); extern "C" void EditorWindow_SelectionDoneCB(Widget, Atom *, Atom *); extern "C" void EditorWindow_SelectionReadyCB (Widget , XtPointer , Atom *, Atom *, XtPointer , unsigned long *, int *); // // Referenced classes: // class Network; class CommandScope; class CommandInterface; class ControlPanel; class NodeDefinition; class ToolSelector; class EditorWorkSpace; class VPERoot; class Arc; class Node; class StandIn; class FindToolDialog; class GridDialog; class CreateMacroDialog; class InsertNetworInsertNetworkkDialog; class List; class NoUndoEditorCommand; class DeleteNodeCommand; class PanelAccessManager; class PanelGroupManager; class ControlPanelGroupDialog; class ProcessGroupCreateDialog; class ProcessGroupAssignDialog; class DXApplication; class DeferrableAction; class CascadeMenu; class Dialog; class Decorator; class DecoratorStyle; class GetSetConversionDialog; class TransmitterNode; #if WORKSPACE_PAGES class GroupManager; class GroupRecord; class PageGroupManager; class AnnotationGroupManager; class Dictionary; class PageSelector; #endif // // EditorWindow class definition: // class EditorWindow : public DXWindow { friend class DXApplication; // For the constructor friend class NoUndoEditorCommand; friend class DeleteNodeCommand; friend ControlPanel::~ControlPanel(); private: // // Private class data: // static boolean ClassInitialized; static String DefaultResources[]; static const char* SequenceNet; friend void EditorWindow_FileMenuMapCB(Widget, XtPointer, XtPointer); friend void EditorWindow_OptionsMenuMapCB(Widget, XtPointer, XtPointer); friend void EditorWindow_WindowMenuMapCB(Widget, XtPointer, XtPointer); friend void EditorWindow_EditMenuMapCB(Widget, XtPointer, XtPointer); friend void EditorWindow_SetDecoratorStyleCB(Widget, XtPointer, XtPointer); friend boolean EditorWindow_ConvertSelectionCB(Widget, Atom *, Atom *, Atom *, XtPointer *, unsigned long *, int *); friend void EditorWindow_LoseSelectionCB(Widget, Atom *); friend void EditorWindow_SelectionDoneCB(Widget, Atom *, Atom *); friend void EditorWindow_SelectionReadyCB (Widget , XtPointer , Atom *, Atom *, XtPointer , unsigned long *, int *); static void SetOwner(void*); static void DeleteSelections(void*); static void Select(void*); boolean initialNetwork; FindToolDialog *findToolDialog; Dialog *printProgramDialog; Dialog *saveAsCCodeDialog; GridDialog *gridDialog; ProcessGroupCreateDialog *processGroupCreateDialog; ProcessGroupAssignDialog *processGroupAssignDialog; ControlPanelGroupDialog *panelGroupDialog; CreateMacroDialog *createMacroDialog; InsertNetworkDialog *insertNetworkDialog; Network *pendingPaste; char *copiedNet; char *copiedCfg; void postProcessGroupCreateDialog(); void postPanelGroupDialog(); void postGridDialog(); void postFindToolDialog(); void postPrintProgramDialog(); void postSaveAsCCodeDialog(); void postCreateMacroDialog(); void postInsertNetworkDialog(); void selectNodes(int how); // // Used to defer the calls to setCommandActivation() when used with // this->deferrableCommandActivation. // We allow for the ability to defer the activation when // it is known that an operation will cause an activation. For example // when many selections are done, it is sufficient to to a single // activation at the end of the operation instead of for each selection. // // static void SetCommandActivation(void *editor, void *requestData); // // Origin of the workspace window, used for error node finding // int Ox, Oy; void openSelectedINodes(); // // Virtual function called at the beginning/end of Command::execute // We must turn off tool selection and make sure the cursor is // back to the normal cursor (i.e. not the Tool placement cursor). // virtual void beginCommandExecuting(); // // This is a helper method for this->areSelectedNodesMacrofiable(). // It recursively descends the connections from the given node to determine // if it connected to a selected node. If ignoreDirectConnect is TRUE, // then we do not care about selected nodes that are directly connected // to selected nodes. // Returns TRUE if there is a downstream selected node, otherwise FALSE. // boolean isSelectedNodeDownstream(Node *srcNode,boolean ignoreDirectConnect); // // Just call Network's method to optimize output cacheability. // void optimizeNodeOutputCacheability(); #ifndef FORGET_GETSET // // Convert nets to use GetLocal/Global and SetLocal/Global // instead of Get and Set (nodes). // void EditorWindow::postGetSetConversionDialog(); static void EditorWindow::ConvertToLocal(); static void EditorWindow::ConvertToGlobal(boolean global = TRUE); void convertToGlobal(boolean global); static Command* EditorWindow::SelectedToGlobalCmd; static Command* EditorWindow::SelectedToLocalCmd; CascadeMenu *programVerifyCascade; Command *toGlobalCmd; Command *toLocalCmd; Command *postGetSetCmd; static GetSetConversionDialog* EditorWindow::GetSetDialog; #endif // // This is the last TransmitterNode that was seen to go through // handleNodeStatusChange(). We use this to allow the ReceiverNode // to hook itself to if non-NULL. // TransmitterNode *lastSelectedTransmitter; // // Record each node as it's highlighted during and execution. Later on we // can change the label colors to show what executed. The list should be // cleared whenever the net gets marked dirty. // set transmitters_added to TRUE after examining executed_nodes for connections // to transmitters/receivers. It would be possible to add transmitters/recievers // as the executed_nodes list is built up, however it saves time to do it only // if the user requests the operation, so transmitters_added tells us if we've // done it already or not. // // Record the executing node because if it's in a page which hasn't been populated // yet, it won't turn green. If you populate the page after its module started // executing, then need some way to turn the standin green. This is provided // as a member field and not static because you could (I think) have 2 standins // green at the same time - if 1 were a MacroNode and the other were in the the // vpe for that macro. // List* executed_nodes; List* errored_standins; Node* executing_node; boolean transmitters_added; void resetExecutionList(); void resetErrorList(boolean reset_all=TRUE); void resetColorList() { this->resetExecutionList(); this->resetErrorList(); } protected: // // State information: // Network* network; ControlPanel *currentPanel; boolean panelVisible; boolean hit_detection; // // Used to defer the calls to setCommandActivation(). // DeferrableAction *deferrableCommandActivation; // // Editor commands: // Command* undoCmd; Command* toolPanelCmd; Command* hitDetectionCmd; Command* showExecutedCmd; Command* newControlPanelCmd; Command* openControlPanelCmd; Command* valuesCmd; Command* addInputTabCmd; Command* removeInputTabCmd; Command* addOutputTabCmd; Command* removeOutputTabCmd; Command* hideAllTabsCmd; Command* revealAllTabsCmd; Command* deleteNodeCmd; Command* cutNodeCmd; Command* copyNodeCmd; Command* pasteNodeCmd; Command* selectAllNodeCmd; Command* selectConnectedNodeCmd; Command* selectUnconnectedNodeCmd; Command* selectUpwardNodeCmd; Command* selectDownwardNodeCmd; Command* deselectAllNodeCmd; Command* selectUnselectedNodeCmd; Command* editMacroNameCmd; Command* editCommentCmd; Command* findToolCmd; Command* insertNetCmd; Command* addAnnotationCmd; Command* macroifyCmd; #if WORKSPACE_PAGES Command* pagifyCmd; Command* pagifySelectedCmd; Command* moveSelectedCmd; Command* autoChopSelectedCmd; Command* autoFuseSelectedCmd; Command* deletePageCmd; Command* configurePageCmd; #endif Command* javifyNetCmd; Command* unjavifyNetCmd; Command* gridCmd; Command* setPanelGroupCmd; Command* setPanelAccessCmd; Command* closeCmd; Command* printProgramCmd; Command* saveAsCCodeCmd; Command* createProcessGroupCmd; Command* openImageCmd; Command* openMacroCmd; Command* openColormapCmd; Command* cacheAllOutputsCmd; Command* cacheLastOutputsCmd; Command* cacheNoOutputsCmd; Command* showCacheAllOutputsCmd; Command* showCacheLastOutputsCmd; Command* showCacheNoOutputsCmd; Command* optimizeCacheabilityCmd; // // Editor components: // // ToolSelector *toolSelector; #if WORKSPACE_PAGES PageSelector *pageSelector; #endif VPERoot *workSpace; Widget scrolledWindow; // // Menus & pulldowns: // Widget fileMenu; Widget editMenu; Widget windowsMenu; Widget optionsMenu; Widget fileMenuPulldown; Widget editMenuPulldown; Widget windowsMenuPulldown; Widget optionsMenuPulldown; // // File menu options: // CommandInterface* newOption; CommandInterface* openOption; CommandInterface* loadMacroOption; CommandInterface* loadMDFOption; CommandInterface* saveOption; CommandInterface* saveAsOption; CascadeMenu* settingsCascade; CommandInterface* saveCfgOption; CommandInterface* openCfgOption; CommandInterface* printProgramOption; CommandInterface* saveAsCCodeOption; CommandInterface* quitOption; CommandInterface* closeOption; // // Edit menu options: // CommandInterface* valuesOption; CommandInterface* findToolOption; CascadeMenu *editTabsCascade; CascadeMenu *editSelectCascade; CascadeMenu *outputCacheabilityCascade; CascadeMenu *editOutputCacheabilityCascade; #if WORKSPACE_PAGES CascadeMenu *pageCascade; #endif CascadeMenu *javaCascade; CommandInterface* deleteOption; CommandInterface* cutOption; CommandInterface* copyOption; CommandInterface* pasteOption; CommandInterface* macroNameOption; CommandInterface* insertNetworkOption; CommandInterface* addAnnotationOption; CommandInterface* createMacroOption; CommandInterface* commentOption; CommandInterface* createProcessGroupOption; CommandInterface* assignProcessGroupOption; // // Windows menu options: // CommandInterface* newControlPanelOption; CommandInterface* openControlPanelOption; CommandInterface* openAllControlPanelsOption; CommandInterface* openControlPanelByNameOption; CascadeMenu *openControlPanelByNameMenu; CommandInterface* openMacroOption; CommandInterface* openImageOption; CommandInterface* openColormapEditorOption; CommandInterface* messageWindowOption; // // Options menu options: // CommandInterface* toolPalettesOption; CommandInterface* hitDetectionOption; CommandInterface* gridOption; CommandInterface* panelGroupOption; CommandInterface* panelAccessOption; CommandInterface* showExecutedOption; // // Help menu options: // CommandInterface* onVisualProgramOption; #if 00 void newNetwork(); #endif void drawArcs(); // // Creates the editor window workarea (as required by MainWindow class). // virtual Widget createWorkArea(Widget parent); // // Creates the editor window menus (as required by DXWindow class). // virtual void createMenus(Widget parent); // // Creation routine for each of the editor menus: // Intended to be used in derived class createMenus(), if needed, // to better control the menu creation, or to be overriden in // the derived classes. // virtual void createFileMenu(Widget parent); virtual void createEditMenu(Widget parent); virtual void createWindowsMenu(Widget parent); virtual void createOptionsMenu(Widget parent); virtual void createHelpMenu(Widget parent); // // De/Activate any commands that have to do with editing. // Should be called when a node is added or deleted or there is a selection // // Called through deferrableCommandActivation via SetCommandActivation(), // but this can also be called directly. It is used to set the activation // state of all commands owned by the Editor. // FIXME: should this be virtual? // void setCommandActivation(); // // Perform various command functions. // boolean selectDownwardNodes(); boolean selectUpwardNodes(); boolean selectConnectedNodes(); boolean selectUnconnectedNodes(); boolean setSelectedNodeTabVisibility(boolean v); boolean selectConnection(int direction, boolean connected); // // Implements the 'Add/Remove Input/Output Tab' commands. // If 'adding' is TRUE, we ADD either inputs or outputs, otherwise // REMOVE. // If 'input' is true, we operate on the input parameters, otherwise // the outputs. // boolean editSelectedNodeTabs(boolean adding, boolean input); // // Methods that are used by the DeleteCommand to help implement // undelete. // void removeSelectedNodes(); #ifdef OBSOLETE void restoreRemovedNodes(List *toRestore); #endif void deleteNodes(List *toDelete); virtual void serverDisconnected(); // // Edit/{Cut,Copy,Paste} operations // boolean cutSelectedNodes(); boolean copySelectedNodes(boolean delete_property = FALSE); boolean pasteCopiedNodes(); // // When the user clicks the Edit/Add Decorator option, we create a new // decorator, stick it in a list. Then a callback in EditorWorkSpace // will let us know when the user clicks in the workspace. The // decorator(s) is the list will be added to the workspace at that location. // Any decorator in this list is not yet managed. // This list increases is size in an extern C callback, not thru NoUndoEditorCommand // because it is modal in nature. The coding is copied from ControlPanel which // does the same thing when adding either interactors or decorators. // List *addingDecorators; // // Constructor: // THIS CONSTRUCTOR SHOULD NEVER BE CALLED FROM ANYWHERE BUT // DXApplication::newNetworkEditor OR A SUBCLASS OF NETWORK. ANY // SUBCLASSES CONSTRUCTOR SHOULD ONLY BE CALLED FROM A VIRTUAL // REPLACEMENT OF DXApplication::newNetworkEditor. // EditorWindow(boolean isAnchor, Network* network); // // Install the default resources for this class and then call the // same super class method to get the default resources from the // super classes. // virtual void installDefaultResources(Widget baseWidget); #if WORKSPACE_PAGES EditorWorkSpace *getPage(const char *name); Dictionary *pageDictionary; GroupRecord *getGroupOfWorkSpace(EditorWorkSpace*); int getPageMemberCount(WorkSpace*); void destroyStandIns(List*); #endif // // Do what ever is necessary just before changing the current network. // To make things run faster we turn off line routing. This should // be followed by a call to endNetworkChange(), which will re-enable // line routing. // void beginNetworkChange(); void endNetworkChange(); // // Put up a little dialog with page configuration options // boolean configurePage(); // // Prepare to place a new decorator (vpe annotation) // boolean placeDecorator(); public: // // Flags for highlighting nodes. // enum { ERRORHIGHLIGHT, EXECUTEHIGHLIGHT, REMOVEHIGHLIGHT }; // // Destructor: // ~EditorWindow(); // // this->workSpace subclasses off EditorWorkSpace but is no longer an EditorWorkSpace // EditorWorkSpace *getWorkSpace() { return (EditorWorkSpace*)this->workSpace; } // // look through the network list and make a list of all selected nodes. // If no selected interactors were found then NULL is returned. // The return list must be freed by the caller. // List *makeSelectedNodeList(const char *classname = NULL); List *makeSelectedDecoratorList(); // // Look through the node list and make a list of existing module names. // List *makeModuleList(); // // EditorWorkSpace needs access to the object to support drag-n-drop // ToolSelector *getToolSelector() { return this->toolSelector; }; // // Properly deal with a nodes status change. // Currently, this only include selection and deselection. // void handleNodeStatusChange(Node *n, NodeStatusChange status); void handleDecoratorStatusChange() { this->setCommandActivation(); } // // Determine the number of selected nodes // int getNodeSelectionCount(const char *classname = NULL); // // Highlighting node. // void highlightNodes(int flag, List *l = NULL); void highlightNode(Node *n, int flag); void highlightNode(const char* name, int instance, int flag); boolean selectNode(Node *node, boolean select, boolean moveto = TRUE); boolean selectNode(char* name, int instance, boolean select); void selectUnselectedNodes(); void deselectAllNodes(); void selectAllNodes(); // // Process group fuctions. // #if WORKSPACE_PAGES void setGroup(GroupRecord *grec, Symbol groupID); void resetGroup(const char* name, Symbol groupID); void selectGroup(const char* name, Symbol groupID); void clearGroup(const char* name, Symbol groupID); boolean changeGroup (const char* old_group, const char* new_name, Symbol groupID); #else void setProcessGroup(const char* name); void resetProcessGroup(const char* name); void selectProcessGroup(const char* name); void clearProcessGroup(const char* name); #endif // // Handle client messages (not from the exec). // virtual void notify (const Symbol message, const void *msgdata=NULL, const char *msg=NULL); // // Sets the tool panel to be visible or invisible // based on the current state. // void toggleToolPanel(); void doSelectedNodesDefaultAction(); // // Change the label color of standins whose nodes ran in the most recent // execution // boolean showExecutedNodes(); // // look through the network list for selected nodes // and open the configuration dialog associated with // the node. // void openSelectedNodesCDB(); // // Implements the 'Values' command. // void showValues(); // EditorWindow cursor functions void setCursor(int cursorType); void resetCursor(); // // add the node selected in the toolList to the vpe at x,y // void addCurrentNode(int x, int y, EditorWorkSpace *where); void addNode (NodeDefinition *, int x, int y, EditorWorkSpace *where); // // Move the workspace window if the selected error node is not shown // void moveWorkspaceWindow(StandIn*); // // Move the workSpace inside the scrolled window so that the given x,y // position is at the upper left corner of the scrolled window unless // centered is TRUE in which case x,y is the center of the scrolled // window. Currently only implmented for x=y=0 && centered == FALSE. // void moveWorkspaceWindow(int x, int y, boolean centered = TRUE); // // Supply scrollbar positions so that they can be recorded/reset when // switching pages. // void getWorkspaceWindowPos (int *x, int *y); // // Reset the origin flag // void resetOrigin() { this->Ox = -1; } // // Data access routines: // Network* getNetwork() { return this->network; } // // Return a pointer to the editor's notion of the 'current' ControlPanel. // The return panel may or may not be managed. // virtual ControlPanel *getCurrentControlPanel(void); Widget getScrolledWindow() { return this->scrolledWindow; } boolean isPanelVisible() { return this->panelVisible; } void newNode(Node *n, EditorWorkSpace *where); void newDecorator(Decorator* dec, EditorWorkSpace* where=NUL(EditorWorkSpace*)); // // notify the a standIn that an arc has been added to the // node // void notifyArc(Arc *a); FindToolDialog* getFindDialog() { return (findToolDialog); } virtual void manage(); void installWorkSpaceInfo(WorkSpaceInfo *info); Command *getDeleteNodeCmd(){return this->deleteNodeCmd;}; #ifndef FORGET_GETSET static Command* EditorWindow::GetGlobalCmd() { return EditorWindow::SelectedToGlobalCmd; }; static Command* EditorWindow::GetLocalCmd() { return EditorWindow::SelectedToLocalCmd; }; #endif // // Do what ever is necessary just before and after reading a new network // These should be called in pairs. // void prepareForNewNetwork(); void completeNewNetwork(); // // Notify control panel related dialogs of the change of panel list. // void notifyCPChange(boolean newList = TRUE); // // Adjust the name of the editor window based on the current network // name. // void resetWindowTitle(); void openSelectedMacros(); void openSelectedImageWindows(); boolean anySelectedNodes(const char *classname); boolean anySelectedColormaps(); boolean anySelectedMacros(); boolean anySelectedDisplayNodes(); // // Turn selected nodes into a macro // virtual boolean macroifySelectedNodes(const char *name, const char *cat, const char *desc, const char *fileName); // // Turn selected nodes into a vpe page // #if WORKSPACE_PAGES virtual boolean pagifySelectedNodes(boolean require_selected_nodes=FALSE); virtual boolean pagifySelectedNodes(EditorWorkSpace* ); virtual boolean postMoveSelectedDialog(); virtual boolean autoChopSelectedNodes(); virtual boolean autoFuseSelectedNodes(); Command *getMoveSelectedCmd() { return this->moveSelectedCmd; } boolean pagifyNetNodes (Network* tmpnet, EditorWorkSpace*, boolean try_current_page = FALSE ); virtual boolean deletePage(const char* page_name=NUL(char*)); void moveStandIns (EditorWorkSpace *page, List *selectedNodes, int xoff, int yoff, List *dl); void moveDecorators (EditorWorkSpace *page, List *seldec, int xoff, int yoff, List *nl); #endif EditorWorkSpace *getNodesBBox (int *minx, int *miny, int *maxx, int *maxy, List *l, List *dl); // // Change the decorator style of the selected decorator(s) // void setDecoratorStyle (List *decors, DecoratorStyle *newds); #if 11 void newNetwork(); #endif // // Print the visual program as a PostScript file using geometry and not // bitmaps. We set up the page so that it maps to the current workspace // and then as the StandIns and ArcStandIns to print themselves. // If the scale allows and the label_parameters arg is set, then // label the parameters and display the values. // We return FALSE and issue and error message if an error occurs. // boolean printVisualProgramAsPS(const char *filename, float x_pagesize, float y_pagesize, boolean label_parameters); boolean printVisualProgramAsPS(FILE*, const char* filename, float x_pagesize, float y_pagesize, boolean label_parameters, EditorWorkSpace*, int, int); // // Set the cacheability of all outputs of the selected tools to one of // OutputFullyCached, OutputNotCached or OutputCacheOnce. // A warning is issued on those nodes that do not have writeable // cacheability. // void setSelectedNodesOutputCacheability(Cacheability c); // // Show (select) the nodes with given cacheability // OutputFullyCached, OutputNotCached or OutputCacheOnce. // void selectNodesWithOutputCacheability(Cacheability c); // // Determine if the currently selected set of nodes is macrofiable. In // particular, we check for selections that would result in an output // being connected to on input of the newly created macro. To do this // we look at each selected node and determine if its immediate downstream // unselected nodes are connected (possibly through intermediate nodes) // to another of the selected nodes. // Returns TRUE if macrofiable, else returns FALSE and issues and error // message. // boolean areSelectedNodesMacrofiable(); #if WORKSPACE_PAGES // // Determine if the currently selected set of nodes is pagifiable. // This means that no selected node has an arc to an unselected node. // The only way data flow into or out of a page is thru Input, Output, // Transmitter, Receiver nodes. // The report flag tells if we should report failure to the user via // an ErrorMessage. boolean areSelectedNodesPagifiable(boolean report=FALSE); void populatePage(EditorWorkSpace* ews); PageSelector* getPageSelector() { return this->pageSelector; } // // Help for Network::mergeNetworks(). It's wrong to use {begin,end}NetworkChnage // because that would operate on all pages. They operate only on the current page. // Aside: the current page better not change in between calls to begin, end. // It would be just as dangerous to record the page upon which the operation was // initiated because the page could be deleted. // void beginPageChange(); void endPageChange(); void removeNodes(List* toDelete); #endif TransmitterNode *getMostRecentTransmitterNode(); #if EXPOSE_SET_SELECTION // // On behalf of VPEAnnotators which have the ability to snarf whole nets and // set them back into the selection via XtOwnSelection... // void EditorWindow::setCopiedNet(const char*); #endif // // Change a resource in the Workspace widget that lets the user know // if things will overlap - during the course of moving // boolean toggleHitDetection(); // // Create a special java page and fill it up. // boolean javifyNetwork(); boolean unjavifyNetwork(); // // Returns a pointer to the class name. // const char* getClassName() { return ClassEditorWindow; } }; #endif // _EditorWindow_h