1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 
12 
13 #include "PageTab.h"
14 #include "PageGroupManager.h"
15 #include "Application.h"
16 #include "PageSelector.h"
17 #include "EditorWindow.h"
18 
19 //
20 // In order to use EditorWorkSpace::DXDropSite methods
21 //
22 #include "EditorWorkSpace.h"
23 
24 String PageTab::DefaultResources[] = {
25     ".recomputeSize:	False",
26     ".topOffset:	0",
27     ".leftOffset:	0",
28     ".bottomOffset:	0",
29     NUL(char*)
30 };
31 
32 // gethostname is needed by decodeDropType which is part of drag-n-drop
33 #if defined(NEEDS_GETHOSTNAME_DECL)
34 extern "C" int gethostname(char *address, int address_len);
35 #endif
36 
37 Pixmap PageTab::AnimationPixmap = NUL(Pixmap);
38 Pixmap PageTab::AnimationMaskPixmap = NUL(Pixmap);
39 boolean PageTab::ClassInitialized = FALSE;
40 Dictionary* PageTab::DropTypeDictionary = new Dictionary;
41 Dictionary* PageTab::DragTypeDictionary = new Dictionary;
42 Widget PageTab::DragIcon = NUL(Widget);
43 
44 #include "pagedrag.bm"
45 #include "pagedragmask.bm"
46 #include "animation.bm"
47 #include "anim_mask.bm"
48 
49 #define DXPAGETRASH "DXPAGETRASH"
50 #define DXPAGENAME  "DXPAGENAME"
51 #define DXMODULES "DXMODULES"
52 
PageTab(PageSelector * sel,WorkSpace * ws,const char * group)53 PageTab::PageTab(PageSelector* sel, WorkSpace* ws, const char* group) :
54     NotebookTab(group)
55 {
56     this->workSpace = ws;
57     this->selector = sel;
58     this->set = FALSE;
59     this->group_rec = NUL(PageGroupRecord*);
60     this->position = 0;
61     this->has_desired_position = FALSE;
62     this->color_timer = 0;
63     this->group_name = DuplicateString(group);
64 }
65 
getDesiredPosition()66 int PageTab::getDesiredPosition()
67 {
68     ASSERT(this->hasDesiredPosition());
69     return this->desired_position;
70 }
71 
activate()72 void PageTab::activate()
73 {
74     this->NotebookTab::activate();
75     this->selector->togglePage(this);
76 }
77 
createButton(Widget p,PageGroupRecord * prec)78 void PageTab::createButton (Widget p, PageGroupRecord* prec)
79 {
80     this->has_desired_position = TRUE;
81     this->desired_position = prec->order_in_list;
82     this->createButton(p);
83     this->setGroup(prec);
84 }
createButton(Widget p)85 void PageTab::createButton (Widget p)
86 {
87     this->NotebookTab::createButton(p);
88     if (!PageTab::ClassInitialized) {
89 	this->setDefaultResources (theApplication->getRootWidget(),
90 	    PageTab::DefaultResources);
91         this->DXDropSite::addSupportedType (PageTab::PageName, DXPAGENAME, TRUE);
92 
93 	this->DXDropSite::addSupportedType (PageTab::Modules, DXMODULES, TRUE);
94         this->DragSource::addSupportedType (PageTab::PageName, DXPAGENAME, TRUE);
95 
96         PageTab::DragIcon = this->createDragIcon(pagedrag_width, pagedrag_height,
97 	     (char *)pagedrag_bits, (char *)pagedragmask_bits);
98 	PageTab::AnimationPixmap = XCreateBitmapFromData(XtDisplay(p),
99 	      XtWindow(p), animation_bits, animation_width, animation_height);
100 	      PageTab::AnimationMaskPixmap = XCreateBitmapFromData(XtDisplay(p),
101 	      XtWindow(p), anim_mask_bits, anim_mask_width, anim_mask_height);
102 	PageTab::ClassInitialized = TRUE;
103     }
104 
105     Widget w = this->getRootWidget();
106 
107     this->setDragWidget(w);
108     this->setDragIcon(PageTab::DragIcon);
109     this->setIntraShellBehavior(TRUE);
110 }
111 
~PageTab()112 PageTab::~PageTab()
113 {
114     if (this->group_name) delete this->group_name;
115     if (this->color_timer) XtRemoveTimeOut(this->color_timer);
116 }
117 
setState(boolean value)118 void PageTab::setState(boolean value)
119 {
120     this->NotebookTab::setState(value);
121     if (this->group_rec) this->group_rec->showing = value;
122 }
123 
setGroup(PageGroupRecord * rec)124 void PageTab::setGroup(PageGroupRecord* rec)
125 {
126     if (this->group_name) delete this->group_name;
127     this->group_rec = rec;
128     const char* rec_name = rec->getName();
129     this->group_name = DuplicateString(rec_name);
130     this->setLabel(this->group_name);
131     this->setPosition (this->position);
132 }
133 
setPosition(int order,boolean designated_by_user)134 void PageTab::setPosition (int order, boolean designated_by_user)
135 {
136     this->position = order;
137 
138     if (designated_by_user) this->has_desired_position = FALSE;
139     if (this->group_rec) this->group_rec->order_in_list = order;
140 }
141 
getPosition()142 int PageTab::getPosition ()
143 {
144     if (this->group_rec)
145 	this->position = this->group_rec->order_in_list;
146     return this->position;
147 }
148 
149 //
150 // It might be nice to set a timer to set the color because we're really going
151 // to just walk thru the net turning things on, then off, then moving to the
152 // next node.  If you're turning lots of nodes in 1 page on/off, then we would
153 // save some time by not changing the color of the page's tab.
154 //
setColor(Pixel fg)155 void PageTab::setColor (Pixel fg)
156 {
157     if (this->color_timer)
158 	XtRemoveTimeOut(this->color_timer);
159 
160     XtAppContext apcxt = theApplication->getApplicationContext();
161     this->pending_fg = fg;
162     this->color_timer =
163 	XtAppAddTimeOut (apcxt, 100, (XtTimerCallbackProc)
164 		PageTab_ColorTimerTO, (XtPointer)this);
165 }
166 
167 //
168 // Does the saved info for this group say the page should be visible?
169 // This is used to put up the same page which was showing when the net
170 // was saved.
171 //
getDesiredShowing()172 boolean PageTab::getDesiredShowing()
173 {
174     return (this->group_rec?this->group_rec->showing:FALSE);
175 }
176 
177 extern "C"
PageTab_ColorTimerTO(XtPointer clientData,XtIntervalId *)178 void PageTab_ColorTimerTO (XtPointer clientData, XtIntervalId* )
179 {
180     PageTab* pt = (PageTab*)clientData;
181     ASSERT(pt);
182     XtVaSetValues (pt->getRootWidget(), XmNforeground, pt->pending_fg, NULL);
183     pt->setDirty(TRUE,TRUE);
184     pt->color_timer = 0;
185 }
186 
187 // Called to consumate a dnd operation
decodeDropType(int tag,char * type,XtPointer value,unsigned long len,int,int)188 boolean PageTab::decodeDropType
189 (int tag, char *type, XtPointer value, unsigned long len, int, int)
190 {
191 boolean retVal;
192 int x,y;
193 int width,height;
194 EditorWorkSpace* ews = (EditorWorkSpace*)this->getWorkSpace();
195 
196     switch (tag) {
197 
198 	case PageTab::Modules:
199 
200 	    //
201 	    // Put the new nodes below whatever net we already have.
202 	    //
203 	    ews->getMaxWidthHeight (&width, &height);
204 	    if ((height > width) && (width < 400)) {
205 		y = 0;
206 		x = width + 10;
207 	    } else {
208 		x = 0;
209 		y = height + 10;
210 	    }
211 	    retVal = this->transfer(type, value, len, x,y);
212 	    break;
213 
214 	case PageTab::PageName:
215 	    //
216 	    // A page name is held in *value.  Notify the PageSelector to move
217 	    // the corresponding tab right after me.
218 	    //
219 	    retVal = this->selector->changeOrdering (this, (char*)value);
220 	    break;
221 	default:
222 	    retVal = FALSE;
223 	    break;
224     }
225     return retVal;
226 }
227 
decodeDragType(int tag,char * a,XtPointer * value,unsigned long * length,long operation)228 boolean PageTab::decodeDragType (int tag,
229 	char *a, XtPointer *value, unsigned long *length, long operation)
230 {
231 boolean retVal;
232 
233     if (this->isIntraShell() == FALSE)
234 	return FALSE;
235 
236     const char* gname = this->getGroupName();
237     char* cp = DuplicateString(gname);
238 
239     switch(tag) {
240 
241 #if 0
242 	case PageTab::PageTrash:
243 	    gname = this->getGroupName();
244 	    if (!gname)
245 		retVal = FALSE;
246 	    else if (EqualString(gname, "Untitled"))
247 		retVal = FALSE;
248 	    else {
249 		*value = (XtPointer)cp;
250 		*length = strlen(cp);
251 		retVal = TRUE;
252 	    }
253 	    break;
254 #endif
255 	case PageTab::PageName:
256 	    //
257 	    // get some space and put a string there.  The string says the name
258 	    // of the button which is being moved.  The drop site will move me.
259 	    //
260 	    *value = (XtPointer)cp;
261 	    *length = strlen(cp);
262 	    retVal = TRUE;
263 	    break;
264 
265 	default:
266 	    retVal = FALSE;
267 	    break;
268     }
269     return retVal;
270 }
271 
272 #if 0
273 void PageTab::dropFinish(long operation, int tag, unsigned char status)
274 {
275     if (tag == PageTab::PageTrash) {
276 	const char* gname = this->getGroupName();
277 	if (gname)
278 	    this->selector->requestPageDeletion (gname);
279     }
280 }
281 #endif
282 
283 
manage()284 void PageTab::manage()
285 {
286     if (this->isManaged()) return ;
287     this->setDropWidget(this->getRootWidget(), XmDROP_SITE_SIMPLE,
288 	PageTab::AnimationPixmap, PageTab::AnimationMaskPixmap);
289     this->UIComponent::manage();
290 }
291 
unmanage()292 void PageTab::unmanage()
293 {
294     this->UIComponent::unmanage();
295     XmDropSiteUnregister (this->getRootWidget());
296 }
297 
298 //
299 // A drop has deposited a network for placement in the workspace corresponding
300 // to this tab.  We already set x,y to lead us to empty space in the page.
301 // In order to get the drop to hit our page, we must remove its page group info
302 // and replace it with our own.
303 //
mergeNetElements(Network * tmpnet,List * tmppanels,int x,int y)304 boolean PageTab::mergeNetElements (Network* tmpnet, List* tmppanels, int x, int y)
305 {
306     EditorWorkSpace* ews = (EditorWorkSpace*)this->getWorkSpace();
307     EditorWindow* ew = this->selector->getEditor();
308     ASSERT(ew);
309     if (!ew->pagifyNetNodes (tmpnet, ews)) return FALSE;
310     boolean retVal = ews->mergeNetElements (tmpnet, tmppanels, x, y);
311     if (retVal) ews->setMembersInitialized(FALSE);
312     return retVal;
313 }
314 
multiClick()315 void PageTab::multiClick()
316 {
317     this->selector->postPageNamePrompt(this);
318 }
319 
320