dtinfo subtree dtinfo
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / Agents / GraphicAgentMotif.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $TOG: GraphicAgentMotif.C /main/30 1998/04/17 11:32:58 mgreess $
25  *
26  * Copyright (c) 1992 HAL Computer Systems International, Ltd.
27  * All rights reserved.  Unpublished -- rights reserved under
28  * the Copyright Laws of the United States.  USE OF A COPYRIGHT
29  * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
30  * OR DISCLOSURE.
31  * 
32  * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
33  * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.  USE,
34  * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
35  * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
36  * INTERNATIONAL, LTD.
37  * 
38 *                         RESTRICTED RIGHTS LEGEND
39  * Use, duplication, or disclosure by the Government is subject
40  * to the restrictions as set forth in subparagraph (c)(l)(ii)
41  * of the Rights in Technical Data and Computer Software clause
42  * at DFARS 252.227-7013.
43  *
44  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
45  *                  1315 Dell Avenue
46  *                  Campbell, CA  95008
47  * 
48  */
49
50 #ifdef JBM
51 #include <tml/tml_objects.hxx>
52 #endif
53
54 #define C_TOC_Element
55 #define L_Basic
56
57 #define C_PixmapGraphic
58 #define C_PostScript
59 #define L_Graphics
60
61 #define C_MessageMgr
62 #define C_GraphicsMgr
63 #define C_NodeMgr
64 #define C_GhostScriptEventMgr
65 #define L_Managers
66
67 #define C_HelpAgent
68 #define C_GraphicAgent
69 #define L_Agents
70
71 #include <WWL/WTopLevelShell.h>
72 #include <WWL/WXmMenu.h>
73 #include <WWL/WXmForm.h>
74 #include <WWL/WXmPushButton.h>
75 #include <WWL/WXmToggleButton.h>
76 #include <WWL/WXmFrame.h>
77 #include <WWL/WXmSeparator.h>
78
79 #include "Managers/CatMgr.hh"
80 #include "Other/XmStringLocalized.hh"
81
82 #include <Prelude.h>
83 #include <iostream>
84 using namespace std;
85 #include <string.h>
86 #include <stdio.h>
87
88 #include "Registration.hh"
89
90 #include "Widgets/WXawPorthole.h"
91 #include "Widgets/WXawPanner.h"
92 #include "Widgets/WPixmap.h"
93
94 #include "utility/funcs.h"
95
96 #define CLASS GraphicAgent
97 #include "create_macros.hh"
98
99 enum { PANNER_UPPER_LEFT,
100        PANNER_UPPER_RIGHT,
101        PANNER_LOWER_RIGHT,
102        PANNER_LOWER_LEFT,
103        PANNER_NONE,
104        PANNER_NUM_STATES };
105
106 inline int
107 min(int i1, int i2)
108 {
109   return i1 < i2 ? i1 : i2 ;
110 }
111
112 // /////////////////////////////////////////////////////////////////////////
113 // Constructor
114 // /////////////////////////////////////////////////////////////////////////
115
116 GraphicAgent::GraphicAgent (UAS_Pointer<UAS_Common> &node_ptr,
117                             UAS_Pointer<Graphic> &gr)
118 : f_shell (NULL),
119   f_node_ptr(node_ptr),
120   f_graphic (gr),
121   f_panner_state (PANNER_NONE),
122   f_current_scale (100),
123   f_scale_button(NULL),
124   f_setcustom(0)
125
126 {
127   f_graphic->pixmap_graphic()->agent(this);
128
129   UAS_Common::request ((UAS_Receiver<UAS_LibraryDestroyedMsg> *) this);
130 }
131
132 // /////////////////////////////////////////////////////////////////////////
133 // Destructor
134 // /////////////////////////////////////////////////////////////////////////
135
136 GraphicAgent::~GraphicAgent()
137 {
138   f_graphic->pixmap_graphic()->agent(NULL);
139   Pixmap pixmap = f_pixmap_widget->Picture();
140   if (pixmap && pixmap != f_graphic->pixmap_graphic()->pixmap())
141     {
142       XFreePixmap(XtDisplay(*f_pixmap_widget),
143                   pixmap);      // a scaled pixmap...give it back 
144
145     }
146   if(f_shell != 0)
147     f_shell.Destroy();
148 }
149
150 // /////////////////////////////////////////////////////////////////////////
151 // popup
152 // /////////////////////////////////////////////////////////////////////////
153
154 void 
155 GraphicAgent::popup()
156 {
157   if (f_shell == 0)
158     create_ui();
159
160   f_shell.Popup();
161   f_shell.DeIconify();
162 }
163
164 // /////////////////////////////////////////////////////////////////////////
165 // display
166 // /////////////////////////////////////////////////////////////////////////
167
168 void 
169 GraphicAgent::display()
170 {
171   if (f_shell == 0)
172     create_ui();
173     
174   // assume all graphics are scalable for now.
175   bool scalable;
176   scalable = True;
177   if(scalable)
178   {
179     Widget *kids = f_view_menu->Children() ;
180     int num_children = f_view_menu->NumChildren();
181     for (int i = 0 ; i < num_children; i++)
182     {
183       WXmPrimitive prim(kids[i]);
184       prim.SetSensitive(True);
185     }
186   }
187   popup();
188 }
189
190
191 void
192 GraphicAgent::receive(DisplayGraphic &message, void* /*client_data*/)
193 {
194   ON_DEBUG(cerr << "GraphicAgent::receive(DisplayGraphic( " <<
195            message.graphic()->locator() << "))" << endl);
196
197   ON_DEBUG(cerr << "local locator is " <<
198            f_graphic->locator() << endl);
199
200   if (message.graphic() == f_graphic)
201     {
202       ON_DEBUG(cerr << "GraphicAgent::receive(DISPLAY)" << endl);
203       display();
204     }
205 }
206
207 void
208 GraphicAgent::receive(ReAttachGraphic &message, void* /*client_data*/)
209 {
210   //reattach();
211 }
212
213 void
214 GraphicAgent::receive (UAS_LibraryDestroyedMsg &msg, void* /*client_data*/)
215 {
216   if(f_node_ptr->lid() == (msg.fLib)->lid())
217   {
218     graphics_mgr().remove_detached((GraphicAgent*)this);
219     delete this;
220   }
221 }
222 // /////////////////////////////////////////////////////////////////////////
223 // create ui
224 // /////////////////////////////////////////////////////////////////////////
225
226 #define AM WAutoManage
227 void
228 GraphicAgent::create_ui()
229 {
230   XmStringLocalized mtfstring;
231   String            string;
232
233   f_shell = WTopLevelShell (window_system().toplevel(), WPopup, "graphic");
234   window_system().register_shell (&f_shell);
235
236   string = CATGETS(Set_GraphicAgent, 1, "Dtinfo: Detached Graphic");
237   XtVaSetValues((Widget)f_shell, XmNtitle, string, NULL);
238
239   // just use "delete_response" instead
240   // add a destroy callback to nuke the agent when widget is destroyed.
241   f_shell.SetDestroyCallback (this, (WWL_FUN) &GraphicAgent::ui_destroyed);
242
243   DECL  (WXmForm,           form,         f_shell,      "form"         );
244   DECLMC(WXmMenuBar,        menu_bar,     form,         "menu_bar"     );
245 #ifdef hpux
246   //
247   //  rtp: hard-wire the menu bar's background, since
248   //       it comes up a bogus color. Copied from swm's
249   //       change in NodeWindowAgentMotif.C
250   //
251   Pixel bg = form.Background();
252   menu_bar.Background(bg);
253
254 #endif
255   DECLM (WXmCascadeButton,  file,         menu_bar,     "file"         );
256   DECLMC(WXmPulldownMenu,   file_menu,    menu_bar,     "file_menu"    );
257   DECLM (WXmPushButton,     attach,       file_menu,    "attach"       );
258   DECLM (WXmPushButton,     visit,        file_menu,    "visit"        );
259   DECLM (WXmPushButton,     close,        file_menu,    "close"        );
260
261   XtVaSetValues(file, XmNlabelString,
262     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 1, "File")),
263     XmNmnemonic,
264     *CATGETS(Set_AgentLabel, 2, ""),
265     NULL);
266
267   XtVaSetValues(attach, XmNlabelString,
268     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 167, "Attach")),
269     XmNmnemonic,
270     *CATGETS(Set_AgentLabel, 21, ""),
271     NULL);
272
273   XtVaSetValues(visit, XmNlabelString,
274     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel,168,"Display Section")),
275     XmNmnemonic,
276     *CATGETS(Set_AgentLabel, 119, ""),
277     NULL);
278
279   XtVaSetValues(close, XmNlabelString,
280     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 12, "Close")),
281     XmNmnemonic,
282     *CATGETS(Set_AgentLabel, 13, ""),
283     NULL);
284
285   DECLM (WXmCascadeButton,  pan,          menu_bar,     "panner"       );
286   DECLMC(WXmPulldownMenu,   panner_menu,  menu_bar,     "panner_menu"  );
287   DECLM (WXmToggleButton,   none,         panner_menu,  "none"         );
288   DECLM (WXmToggleButton,   up_left,      panner_menu,  "up_left"      );
289   DECLM (WXmToggleButton,   up_right,     panner_menu,  "up_right"     );
290   DECLM (WXmToggleButton,   low_left,     panner_menu,  "low_left"     );
291   DECLM (WXmToggleButton,   low_right,    panner_menu,  "low_right"    );
292
293   XtVaSetValues(pan, XmNlabelString,
294     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 166, "Panner")),
295     XmNmnemonic,
296     *CATGETS(Set_AgentLabel, 9, ""),
297     NULL);
298
299   XtVaSetValues(none, XmNlabelString,
300     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 178, "None")),
301     XmNmnemonic,
302     *CATGETS(Set_AgentLabel, 7, ""),
303     NULL);
304
305   XtVaSetValues(up_left, XmNlabelString,
306     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 179, "Upper Left")),
307     XmNmnemonic,
308     *CATGETS(Set_AgentLabel, 254, ""),
309     NULL);
310
311   XtVaSetValues(up_right, XmNlabelString,
312     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 180, "Upper Right")),
313     XmNmnemonic,
314     *CATGETS(Set_AgentLabel, 252, ""),
315     NULL);
316
317   XtVaSetValues(low_left, XmNlabelString,
318     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 181, "Lower Left")),
319     XmNmnemonic,
320     *CATGETS(Set_AgentLabel, 113, ""),
321     NULL);
322
323   XtVaSetValues(low_right, XmNlabelString,
324     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 182, "Lower Right")),
325     XmNmnemonic,
326     *CATGETS(Set_AgentLabel, 259, ""),
327     NULL);
328
329   // NOTE: some code in this module depends upon the exact ordering of items
330   // view menu will only be sensitive for scalable graphics 
331   DECL  (WXmCascadeButton,  view,          menu_bar,     "view"        );
332   DECLMC(WXmPulldownMenu,   view_menu,     menu_bar,     "view_menu"   );
333   DECLM (WXmPushButton,     fit_gr_to_win, view_menu,    "fit_window"  );
334   DECLM (WXmPushButton,     fit_win_to_gr, view_menu,    "fit_graphic" );
335
336   XtVaSetValues(view, XmNlabelString,
337     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 4, "View")),
338     XmNmnemonic,
339     *CATGETS(Set_AgentLabel, 5, ""),
340     NULL);
341
342   XtVaSetValues(fit_gr_to_win, XmNlabelString,
343     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 169, "Fit to Window")),
344     XmNmnemonic,
345     *CATGETS(Set_AgentLabel, 35, ""),
346     NULL);
347
348
349   XtVaSetValues(fit_win_to_gr, XmNlabelString,
350     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 170, "Fit to Graphic")),
351     XmNmnemonic,
352     *CATGETS(Set_AgentLabel, 37, ""),
353     NULL);
354
355   DECLM (WXmSeparator,      separator,    view_menu,    "separator"    );
356   DECLM (WXmToggleButton,   z_25,         view_menu,    "z_25"         );
357   DECLM (WXmToggleButton,   z_50,         view_menu,    "z_50"         );
358   DECLM (WXmToggleButton,   z_100,        view_menu,    "z_100"        );
359   DECLM (WXmToggleButton,   z_125,        view_menu,    "z_125"        );
360   DECLM (WXmToggleButton,   z_150,        view_menu,    "z_150"        );
361   DECLM (WXmToggleButton,   z_200,        view_menu,    "z_200"        );
362   DECLM (WXmToggleButton,   z_custom,     view_menu,    "z_custom"     );
363   
364   mtfstring = CATGETS(Set_AgentLabel, 171, "25 %");
365   XtVaSetValues(z_25, XmNlabelString, (XmString)mtfstring, NULL);
366   mtfstring = CATGETS(Set_AgentLabel, 172, "50 %");
367   XtVaSetValues(z_50, XmNlabelString, (XmString)mtfstring, NULL);
368   mtfstring = CATGETS(Set_AgentLabel, 173, "100 %");
369   XtVaSetValues(z_100, XmNlabelString, (XmString)mtfstring, NULL);
370   mtfstring = CATGETS(Set_AgentLabel, 174, "125 %");
371   XtVaSetValues(z_125, XmNlabelString, (XmString)mtfstring, NULL);
372   mtfstring = CATGETS(Set_AgentLabel, 175, "150 %");
373   XtVaSetValues(z_150, XmNlabelString, (XmString)mtfstring, NULL);
374   mtfstring = CATGETS(Set_AgentLabel, 176, "200 %");
375   XtVaSetValues(z_200, XmNlabelString, (XmString)mtfstring, NULL);
376
377   XtVaSetValues(z_custom, XmNlabelString,
378     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 177, "Custom...")),
379     XmNmnemonic,
380     *CATGETS(Set_AgentLabel, 13, ""),
381     NULL);
382
383   z_100.Set(1);
384   f_scale_button = (WXmToggleButton*)(Widget)z_100 ;
385   f_custom_scale = (WXmToggleButton*)(Widget)z_custom ;
386
387   f_view_menu = (WXmPulldownMenu*)(Widget)view_menu ;
388
389   DECLM (WXmCascadeButton,  help,         menu_bar,      "help"        );
390   DECLMC(WXmPulldownMenu,   help_menu,    menu_bar,      "help_menu"   );
391   DECLM (WXmPushButton,     on_window,    help_menu,     "on_window"   );
392   DECLM (WXmPushButton,     on_help,      help_menu,     "on_help"     );
393
394   XtVaSetValues(help, XmNlabelString,
395     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 48, "Help")),
396     XmNmnemonic,
397     *CATGETS(Set_AgentLabel, 39, ""),
398     NULL);
399
400   XtVaSetValues(on_window, XmNlabelString,
401     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 147, "On Window")),
402     XmNmnemonic,
403     *CATGETS(Set_AgentLabel, 35, ""),
404     NULL);
405
406   XtVaSetValues(on_help, XmNlabelString,
407     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 153, "On Help")),
408     XmNmnemonic,
409     *CATGETS(Set_AgentLabel, 39, ""),
410     NULL);
411
412   DECLM (WXmLabel, message_area, form, "message");
413   f_message_area = (WXmLabel*)(Widget)message_area ;
414
415   DECLM (WXmSeparator, sep, form, "sep2");
416
417   DECL  (WXmFrame,          frame,        form,         "frame"        );
418   DECL  (WXmForm,           subform,      frame,        "subform"      );
419   DECLM (WXawPanner,        panner,       subform,      "panner"       );
420   DECLM (WXawPorthole,      porthole,     subform,      "porthole"     );
421   DECLM (WPixmap,           pixmap,       porthole,     "pixmap"       );
422
423
424   f_panner = (WXawPanner*)(Widget)panner ;
425   f_pixmap_widget = (WPixmap*)(Widget)pixmap ;
426
427   file.SubMenuId (file_menu);
428   view.SubMenuId (view_menu);
429   pan.SubMenuId (panner_menu);
430   help.SubMenuId (help_menu);
431   menu_bar.MenuHelpWidget (help);
432     
433   WArgList args;
434
435   PixmapGraphic &pgraphic = *(f_graphic->pixmap_graphic());
436
437   Graphic *graphic = f_graphic ;
438   UAS_String titleStr(graphic->title());
439   const char *title = titleStr ;
440
441   if (title == NULL || *title == '\0')  // empty string 
442     title = (char *)CATGETS(Set_GraphicAgent, 2, "Detached Graphic");
443
444   {
445
446     UAS_String buffer = CATGETS(Set_GraphicAgent, 8, "Dtinfo: ");
447     buffer = buffer + title;
448
449     f_shell.Title((char*)buffer);
450     f_shell.IconName((char*)buffer);
451
452   }
453
454   args.Reset();
455   panner.CanvasWidth (pgraphic.width(), args);
456   panner.CanvasHeight (pgraphic.height(), args);
457   panner.Set (args);
458
459   SET_CALLBACK_D (porthole,Report,porthole_report,(Widget) panner);
460   install_new_picture(&pgraphic);
461   SET_CALLBACK_D (panner,Report,panner_report,(Widget) pixmap);
462
463   ON_ACTIVATE (visit,visit_node);
464   ON_ACTIVATE (close,close_window);
465   ON_ACTIVATE (attach,reattach);
466
467   SET_CALLBACK_D (none,ValueChanged,set_panner,PANNER_NONE);
468   SET_CALLBACK_D (up_left,ValueChanged,set_panner,PANNER_UPPER_LEFT);
469   SET_CALLBACK_D (up_right,ValueChanged,set_panner,PANNER_UPPER_RIGHT);
470   SET_CALLBACK_D (low_left,ValueChanged,set_panner,PANNER_LOWER_LEFT);
471   SET_CALLBACK_D (low_right,ValueChanged,set_panner,PANNER_LOWER_RIGHT);
472
473   ON_ACTIVATE (fit_gr_to_win,fit_graphic_to_window_callback);
474   ON_ACTIVATE (fit_win_to_gr,fit_window_to_graphic_callback);
475
476   SET_CALLBACK_D (z_25,ValueChanged,zoom_callback,25);
477   SET_CALLBACK_D (z_50,ValueChanged,zoom_callback,50);
478   SET_CALLBACK_D (z_100,ValueChanged,zoom_callback,100);
479   SET_CALLBACK_D (z_125,ValueChanged,zoom_callback,125);
480   SET_CALLBACK_D (z_150,ValueChanged,zoom_callback,150);
481   SET_CALLBACK_D (z_200,ValueChanged,zoom_callback,200);
482   SET_CALLBACK_D (z_custom,ValueChanged,zoom_callback,0);
483
484   help_agent().add_activate_help (on_window, (char*)"graphic_on_window");
485   help_agent().add_activate_help (on_help,   (char*)"graphic_on_help");
486
487   view.Manage();
488
489   // menubars for scalable graphics 
490
491   // assume all graphics are scalable
492   bool scalable = True;
493   if(scalable)
494   {
495     if (f_graphic->content_type() == "application/CGM")
496        mtfstring = CATGETS(Set_GraphicAgent, 4, "Vector illustration (scalable)");
497     else
498        mtfstring = CATGETS(Set_GraphicAgent, 9, "Raster illustration (scalable)");
499   }
500   else
501   {
502 #if !defined(VF_DEBUG)
503       for (int i = 0 ; i < view_menu.NumChildren(); i++)
504         WRect(view_menu.Children()[i]).SetSensitive(False);
505 #endif
506     mtfstring = CATGETS(Set_GraphicAgent, 3,
507                 "Raster illustration (non-scalable)");
508   }
509
510 #if EAM
511   if (f_graphic->content_type() != "application/postscript") {
512
513 #if !defined(VF_DEBUG)
514       for (int i = 0 ; i < view_menu.NumChildren(); i++)
515         WRect(view_menu.Children()[i]).SetSensitive(False);
516 #endif
517       mtfstring = CATGETS(Set_GraphicAgent, 3,
518                                 "Raster illustration (non-scalable)");
519   }
520   else {
521       mtfstring = CATGETS(Set_GraphicAgent, 4,
522                                 "Vector illustration (scalable)");
523   }
524 #endif
525
526   XtVaSetValues((Widget)f_message_area, XmNlabelString, (XmString)mtfstring, NULL);
527
528   // porthole.Manage();
529   frame.Manage();
530   subform.ShadowThickness(0);
531   subform.Manage();
532   form.ShadowThickness(0);
533   form.Manage();
534
535   // when panner first appears, it should be in upper-left corner
536   up_left.Set (TRUE);
537   adjust_panner (PANNER_UPPER_LEFT); 
538
539   // Set Max width/height if not scalable 
540   f_shell.Realize();
541
542   
543   Display *display = XtDisplay(f_shell);
544   Screen      *retScr = XtScreen(f_shell);
545   int screen =  XScreenNumberOfScreen(retScr);
546   int dw = DisplayWidth(display, screen);
547   int dh = DisplayHeight(display, screen);
548
549   Dimension width = dw, height = dh;
550
551   //if (f_graphic->content_type() == "application/CGM")
552
553   // assume all graphics are scalable
554   scalable = True;
555   if(scalable)
556   {
557     // set max size of window
558     height = min(height, dh - 100);
559     width  = min(width,  dw - 100);
560
561     f_shell.Set (WArgList (XmNmaxHeight, height,
562                            XmNmaxWidth,  width,
563                            NULL));
564
565     // don't allow window to shrink smaller than original size
566     f_shell.Get (WArgList (XmNheight, (XtArgVal) &height,
567                            NULL));
568     height = min(height, dh - 100);
569
570     f_shell.Set (WArgList (XmNminHeight, height,
571                              NULL));
572   }
573   else
574   {
575     f_shell.Get (WArgList (XmNheight, (XtArgVal) &height,
576                      XmNwidth, &width,
577                      NULL));
578     height = min(height, dh - 100);
579     width  = min(width,  dw - 100);
580
581     f_shell.Set (WArgList (XmNmaxHeight, height,
582                      XmNmaxWidth,  width,
583                      NULL));
584   }
585 }
586
587
588 void
589 GraphicAgent::close_window()
590 {
591   reattach();
592   f_shell.Popdown();
593 }
594
595 // /////////////////////////////////////////////////////////////////
596 // ui_destroyed - user nuked Motif window, so kill myself
597 // /////////////////////////////////////////////////////////////////
598  
599 void
600 GraphicAgent::ui_destroyed()
601 {
602   // Set f_shell to NULL, since Xt is destroying it for us.
603   reattach();
604   f_shell = NULL;
605 }
606
607
608 void
609 GraphicAgent::attach_graphic()
610 {
611   reattach();
612 }
613
614
615 void
616 GraphicAgent::reattach()
617 {
618   graphics_mgr().reattach_graphic(f_graphic);
619 //  Wait_Cursor bob;
620 //  UAS_String idata(*image_data);
621 //  PixmapGraphic *pgr = f_graphic->pixmap_graphic();
622
623 //  ON_DEBUG(cerr << "Graphic Agent reattach" << endl);
624 //  f_graphic->set_detached(FALSE);
625 //  f_graphic->
626 //    pixmap_graphic()->
627 //    UAS_Sender<ReAttachGraphic>::send_message(ReAttachGraphic(f_graphic));
628
629 //  graphics_mgr().remove_detached((GraphicAgent*)this);
630 //  delete this ;
631 }
632
633
634 void
635 GraphicAgent::visit_node()
636 {
637   extern char g_top_locator[];
638   extern bool g_scroll_to_locator;
639   const char *glocator = f_graphic->locator();
640   ON_DEBUG (printf ("Graphic jumping to <%s>\n", glocator));
641   ON_DEBUG (printf ("  copying to %p\n", g_top_locator));
642   strcpy (g_top_locator, &glocator[8]);
643   g_scroll_to_locator = TRUE;
644   f_node_ptr->retrieve();
645 }
646
647
648 void
649 GraphicAgent::porthole_report(WCallback *wcb)
650 {
651   XawPannerReport *repp = (XawPannerReport*)wcb->CallData();
652   XawPannerReport &rep = *repp;
653   ON_DEBUG(cerr << "got a porthole_report" << hex << rep.changed << endl);
654   if (rep.changed & (XawPRCanvasHeight | XawPRCanvasWidth)){
655     ON_DEBUG(cerr << "porthole height or width change" << endl);
656
657     WXawPorthole porthole(wcb->GetWidget());
658     WXawPanner panner((Widget)wcb->ClientData());
659
660     WCore picture(porthole.Children()[0]);
661
662     Dimension port_width  = porthole.Width();
663     Dimension port_height = porthole.Height();
664     Dimension cwidth = panner.CanvasWidth();
665     Dimension cheight= panner.CanvasHeight();
666
667     ON_DEBUG(cerr << "Canvas ( " << cwidth << ", " << cheight << ")"<<endl); 
668     ON_DEBUG(cerr << "Porthle( " << port_width << ", " << port_height << ")"
669              << endl); 
670
671     WArgList args ;
672
673     // re-adjust the slider 
674     if (rep.changed & XawPRCanvasHeight)
675       {
676         ON_DEBUG(cerr << "adjust panner SliderHeight " << port_height <<
677                  endl); 
678         panner.SliderHeight(port_height, args);
679       }
680
681     if (rep.changed & XawPRCanvasWidth)
682       {
683         ON_DEBUG(cerr << "adjust panner SliderWidth " << port_width <<
684                  endl); 
685         panner.SliderWidth(port_width, args);
686       }
687
688     panner.Set(args);
689
690
691     if ((cwidth <= port_width) &&
692          (cheight <= port_height))
693       {
694         ON_DEBUG(cerr << "PANNER UNmanage" << endl);
695         panner.Unmanage();
696       } else {
697         if (f_panner_state != PANNER_NONE)
698           panner.Manage();
699       }
700   }
701 }
702
703
704 void
705 GraphicAgent::panner_report(WCallback *wcb)
706 {
707   ON_DEBUG(cerr << "panner report " << endl);
708   XawPannerReport *repp = (XawPannerReport*)wcb->CallData();
709   XawPannerReport &rep = *repp;
710
711   // slide the picture 
712
713   WArgList args ;
714   WCore core((Widget)wcb->ClientData());
715   core.X(0 - rep.slider_x, args);
716   core.Y(0 - rep.slider_y, args);
717   core.Set(args);
718 }
719
720
721 void
722 GraphicAgent::adjust_panner(unsigned int state)
723 {
724   ON_DEBUG(cerr << "adjust_panner( " << state << ")" << endl);
725   if (state == f_panner_state)
726     return;
727
728   f_panner_state = state ;
729
730   WArgList args ;
731
732   WXawPanner &panner(*f_panner) ;
733
734   switch (state){
735   case PANNER_UPPER_LEFT:
736     {
737       /* upper left */
738       panner.LeftAttachment(XmATTACH_FORM, args);
739       panner.TopAttachment(XmATTACH_FORM, args);
740       panner.RightAttachment(XmATTACH_POSITION, args);
741       panner.RightPosition(20, args);
742       panner.BottomAttachment(XmATTACH_POSITION, args);
743       panner.BottomPosition(20, args);
744     }
745     break;
746   case PANNER_UPPER_RIGHT:
747     {
748       /* upper right */
749       panner.RightAttachment(XmATTACH_FORM, args);
750       panner.TopAttachment(XmATTACH_FORM, args);
751       panner.LeftAttachment(XmATTACH_POSITION, args);
752       panner.LeftPosition(80, args);
753       panner.BottomAttachment(XmATTACH_POSITION, args);
754       panner.BottomPosition(20, args);
755     }
756     break;
757   case PANNER_LOWER_RIGHT:
758     {
759       /* lower right */
760       panner.RightAttachment(XmATTACH_FORM, args);
761       panner.BottomAttachment(XmATTACH_FORM, args);
762       panner.LeftAttachment(XmATTACH_POSITION, args);
763       panner.LeftPosition(80, args);
764       panner.TopAttachment(XmATTACH_POSITION, args);
765       panner.TopPosition(80, args);
766     }
767     break;
768   case PANNER_LOWER_LEFT:
769     {
770       /* lower left */
771       panner.LeftAttachment(XmATTACH_FORM, args);
772       panner.BottomAttachment(XmATTACH_FORM, args);
773       panner.RightAttachment(XmATTACH_POSITION, args);
774       panner.RightPosition(20, args);
775       panner.TopAttachment(XmATTACH_POSITION, args);
776       panner.TopPosition(80, args);
777     }
778     break;
779   case PANNER_NONE:
780     {
781       /* unmanaged */
782       panner.Unmanage();
783     }
784     break;
785   default:
786     assert(0);
787     break;
788   }
789
790   panner.Set(args);
791
792   // see if we can display it 
793
794   Dimension cwidth =  panner.CanvasWidth();
795   Dimension cheight = panner.CanvasHeight();
796
797   WXawPorthole porthole(XtParent(*f_panner)) ;
798
799   ON_DEBUG(cerr << "Panner - state: " << state << " canvas ( " << cwidth
800            << ", " << cheight << ") porthole ( " << porthole.Width() <<
801            ", " << porthole.Height() << ")" << endl);
802
803   if ((state != PANNER_NONE) &&
804       ((cwidth > porthole.Width()) ||
805        (cheight > porthole.Height())))
806     {
807       panner.Manage();
808     }
809 }
810
811
812 void
813 GraphicAgent::set_panner(WCallback *wcb)
814 {
815   // adjust panner to the Set state 
816   WXmToggleButton button(wcb->GetWidget());
817   if (button.Set())
818     {
819       size_t state = (size_t)wcb->ClientData();
820       adjust_panner(state);
821     }      
822 }
823
824
825 void
826 GraphicAgent::zoom_callback(WCallback *wcb)
827 {
828   ON_DEBUG (puts ("GraphicAgent::zoom_callback() called"));
829   WXmToggleButton button(wcb->GetWidget());
830   XmToggleButtonCallbackStruct &cbs = 
831     *(XmToggleButtonCallbackStruct*)wcb->CallData();
832
833   ON_DEBUG(cerr << "cbs.set = " << cbs.set << endl);
834   ON_DEBUG(cerr << "cbs.rsn = " << cbs.reason << endl);
835   ON_DEBUG(cerr << "cbs.event = " << cbs.event << endl);
836   
837   if (button.Set())
838     {
839       size_t scale = (size_t) wcb->ClientData();
840       if (scale > 0)
841         {
842           set_zoom (scale);
843           f_scale_button = (WXmToggleButton*)(Widget)button ;
844           f_setcustom = 0 ;
845         }
846       else
847         {
848           // we get called twice when selecting already selected custom button
849           // just do nothing second time around 
850           if (f_setcustom)
851             {
852               f_setcustom = 0 ;
853               return ;
854             }
855           f_setcustom = 1 ;
856
857           UAS_String msg   = CATGETS(Set_GraphicAgent, 6,
858                                         "Enter the new scaling percentage:");
859           UAS_String title = CATGETS(Set_GraphicAgent, 7, "Dtinfo: Set Scale");
860           scale = message_mgr().
861                     get_integer((char*)msg, (char*)title, f_current_scale,
862                                 (Widget)f_shell);
863
864           ON_DEBUG(cerr << "scale value is " << scale << endl);
865           if (scale == -1)
866             {
867               // unset Custom option in list 
868               if (((Widget)*f_scale_button) != ((Widget)button))
869                 {
870                   button.Set(0);
871                   f_scale_button->Set(1);
872                   f_setcustom = 0 ;
873                 }
874               return;
875             }
876           set_zoom (scale);
877           f_scale_button = (WXmToggleButton*)(Widget)button ;
878         }
879         // maybe this should be a user option
880         //fit_window_to_graphic();
881     }
882 }
883
884
885 void
886 GraphicAgent::set_zoom(unsigned int scale)
887 {
888   // Deal with bogus values. 
889   if (scale < 10)
890     scale = 10;
891   else if (scale > 999)
892     scale = 999;
893
894   if (scale == f_current_scale)
895     return;
896
897   Wait_Cursor bob;
898
899   XmStringLocalized mtfstring = CATGETS(Set_GraphicAgent, 5,
900                                 "Scaling illustration, please wait...");
901
902   XtVaSetValues((Widget)f_message_area, XmNlabelString, (XmString)mtfstring, NULL);
903
904   XmUpdateDisplay((Widget)f_message_area);
905
906   f_current_scale = scale;
907
908   UAS_String f_graphic_content_type(f_graphic->content_type());
909   UAS_String temp_str = f_graphic->data();
910
911   PixmapGraphic *pgr = 
912       f_graphic->pixmap_graphic(temp_str, f_graphic->data_length(),
913                                  f_graphic_content_type, scale);
914   install_new_picture(pgr);
915   refresh(graphic());
916
917   if (f_graphic->content_type() == "application/CGM")
918     mtfstring = CATGETS(Set_GraphicAgent, 4, "Vector illustration (scalable)");
919   else
920     mtfstring = CATGETS(Set_GraphicAgent, 9, "Raster illustration (scalable)");
921
922   XtVaSetValues((Widget)f_message_area, XmNlabelString, (XmString)mtfstring, NULL);
923
924 }
925
926
927 void
928 GraphicAgent::refresh(const UAS_Pointer<Graphic> &)
929 {
930   // refresh by clearing window and sending in expose event
931   XClearArea(XtDisplay(*f_pixmap_widget),
932              XtWindow(*f_pixmap_widget),
933              0, 0, 0, 0, TRUE);
934
935   // update message area 
936   XmStringLocalized mtfstring;
937   if (f_graphic->content_type() == "application/CGM")
938     mtfstring = CATGETS(Set_GraphicAgent, 4, "Vector illustration (scalable)");
939   else
940     mtfstring = CATGETS(Set_GraphicAgent, 9, "Raster illustration (scalable)");
941
942   XtVaSetValues((Widget)f_message_area, XmNlabelString, (XmString)mtfstring, NULL);
943 }
944
945
946 void
947 GraphicAgent::fit_graphic_to_window_callback(WCallback *)
948 {
949   Dimension gr_width;
950   Dimension gr_height;
951   int wscale, hscale;
952   unsigned int scale_factor;
953
954   // get size of graphic
955   gr_width = f_graphic->pixmap_graphic()->width();
956   gr_height = f_graphic->pixmap_graphic()->height();
957
958   int dx, dy;
959   WXawPorthole porthole(XtParent(*f_pixmap_widget));
960   dx = abs(porthole.Width() - f_graphic->pixmap_graphic()->width());
961   dy = abs(porthole.Height() - f_graphic->pixmap_graphic()->height());
962   if (dx < dy)
963     scale_factor = 
964          (100 * porthole.Width()) / f_graphic->pixmap_graphic()->width();
965   else
966     scale_factor = 
967          (100 * porthole.Height()) / f_graphic->pixmap_graphic()->height();
968   
969
970   wscale = (100 * porthole.Width()) / gr_width;
971   hscale = (100 * porthole.Height()) / gr_height;
972
973   // scaling from dimensions of original pixmap graphic 
974   if (wscale < hscale)
975     set_zoom(wscale);
976   else
977     set_zoom(hscale);
978
979   // fit graphic to window means custom scale, so
980   // toggle the button.
981   f_scale_button->Set(0);
982   f_scale_button = f_custom_scale;
983   f_scale_button->Set(1);
984
985 }
986
987
988 void
989 GraphicAgent::fit_window_to_graphic_callback(WCallback *)
990 {
991   fit_window_to_graphic();
992 }
993 void
994 GraphicAgent::fit_window_to_graphic()
995 {
996   WXawPorthole porthole(XtParent(*f_pixmap_widget));
997   WPixmap   picture(*f_pixmap_widget) ;
998   WXawPanner panner(*f_panner);
999
1000   // desired width of porthole is in panner.Canvas{Width,Height}
1001   Dimension cwidth  = panner.CanvasWidth();
1002   Dimension cheight = panner.CanvasHeight() ;
1003
1004   // menu_bar is first child of form which is first child of f_shell 
1005   WComposite form(f_shell.Children()[0]);
1006   WComposite menu_bar(form.Children()[0]) ;
1007   // f_message_area is Children()[1]
1008   WXmSeparator separator(form.Children()[2]);
1009
1010   // account for frame margins 
1011   // frame is parent of subform is parent of panner 
1012   WXmFrame frame(XtParent(XtParent(panner)));
1013
1014   cheight += menu_bar.Height() + frame.MarginHeight() * 2 + frame.TopOffset()
1015     + frame.BottomOffset() + separator.Height() + 2 * separator.Margin() +
1016     separator.TopOffset() + separator.BottomOffset() + 
1017     f_message_area->Height() + f_message_area->TopOffset() +
1018     f_message_area->BottomOffset() + f_message_area->MarginTop() +
1019     f_message_area->MarginBottom();// + 2 * f_message_area->MarginHeight(); 
1020
1021   cwidth  += frame.MarginWidth() * 2 + frame.LeftOffset() +
1022     frame.RightOffset();
1023
1024   WArgList args ;
1025   f_shell.Width(cwidth + 4, args);
1026   f_shell.Height(cheight + 4, args);
1027   f_shell.Set(args);
1028
1029   panner.Unmanage();
1030 }
1031
1032 void
1033 GraphicAgent::install_new_picture(PixmapGraphic *pgr)
1034 {
1035   // dispose of the old Pixmap if needed 
1036   Pixmap pixmap = f_pixmap_widget->Picture() ;
1037   if (pixmap && (pixmap != f_graphic->pixmap_graphic()->pixmap()))
1038     XFreePixmap(XtDisplay(*f_pixmap_widget), pixmap);   // a scaled pixmap...give it back 
1039
1040
1041   // put the new Pixmap into the pixmap widget
1042   WArgList args ;
1043   f_pixmap_widget->Picture(pgr->pixmap(), args) ; // install the new one 
1044   f_pixmap_widget->Width(pgr->width(), args);     // update size 
1045   f_pixmap_widget->Height(pgr->height(), args);   
1046   f_pixmap_widget->Set(args);
1047
1048   // update some more UI crud
1049
1050   args.Reset();
1051   WXawPorthole porthole(XtParent(*f_pixmap_widget));
1052
1053   args.Reset();
1054   WXawPanner panner(*f_panner);
1055   panner.CanvasWidth(pgr->width(), args);
1056   panner.CanvasHeight(pgr->height(),args);
1057   panner.SliderWidth(porthole.Width(), args);
1058   panner.SliderHeight(porthole.Height(), args);
1059   panner.Set(args);
1060
1061   if ((f_panner_state != PANNER_NONE) &&
1062       ((pgr->width() > porthole.Width()) ||
1063        (pgr->height() > porthole.Height())))
1064     {
1065
1066       panner.Manage();
1067
1068     } else {
1069
1070       panner.Unmanage();
1071
1072     }
1073   
1074
1075   if (pgr != f_graphic->pixmap_graphic())
1076     {
1077       // clean up PixmapGraphic storage, but keep the X Pixmap
1078       // (its in the pixmap_widget) 
1079       pgr->set_type(PixmapGraphic::PRESERVE) ;
1080       delete pgr ;
1081     }
1082 }
1083
1084 void
1085 GraphicAgent::unset_scale_buttons()
1086 {
1087   for (int i = 0 ; i < 10; i++)
1088     WXmToggleButton((*f_view_menu).Children()[i]).Set(False);
1089 }
1090