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