Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtfile / MultiView.c
1 /* $XConsortium: MultiView.c /main/5 1996/10/15 10:08:30 mustafa $ */
2 /************************************<+>*************************************
3  ****************************************************************************
4  *
5  *   FILE:           MultiView.c
6  *
7  *   COMPONENT_NAME: Desktop File Manager (dtfile)
8  *
9  *   Description:    Contains the shared code for managing multiple toplevel
10  *                   main application window.
11  *
12  *   FUNCTIONS: CreateMenuBtn
13  *              _DtCreateMenuSystem
14  *              _DtGlobalRestoreMenuSensitivity
15  *              _DtGlobalSetMenuSensitivity
16  *              _DtGlobalUpdateMenuItemState
17  *
18  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
19  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
20  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
21  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
22  *
23  ****************************************************************************
24  ************************************<+>*************************************/
25
26  
27
28 #include <stdio.h>
29 #include <signal.h>
30 #include <pwd.h>
31 #include <time.h>
32
33 #include <Xm/XmP.h>
34 #include <Xm/CascadeBG.h>
35 #include <Xm/PushBG.h>
36 #include <Xm/RowColumn.h>
37 #include <Xm/SeparatoG.h>
38 #include <Xm/ToggleBG.h>
39 #include <Xm/MenuShellP.h>
40
41 #include <X11/ShellP.h>
42
43 #include <Dt/DtP.h>
44 #include <Dt/DtNlUtils.h>
45 #include <Dt/Connect.h>
46
47 #include "Encaps.h"
48 #include "MultiView.h"
49
50
51 /********    Static Function Declarations    ********/
52
53 extern void _DtGlobalUpdateMenuItemState(
54                         Widget btn,
55                         unsigned int mask,
56                         unsigned int on,
57                         unsigned int * globalMenuStates) ;
58 extern void _DtGlobalSetMenuSensitivity(
59                         Widget w,
60                         XtPointer client_data,
61                         XtPointer call_data) ;
62 extern void _DtGlobalRestoreMenuSensitivity(
63                         Widget w,
64                         XtPointer client_data,
65                         XtPointer call_data) ;
66 static Widget CreateMenuBtn(
67                         Widget parent,
68                         Boolean isPushButton,
69                         MenuDesc * menuDesc,
70                         int btnIndex) ;
71
72 /********    End Static Function Declarations    ********/
73
74 extern Widget * findBtn;
75 extern Widget * change_directoryBtn;
76 extern Widget * preferencesBtn;
77 extern Widget * defaultEnvBtn;
78 extern Widget * filterBtn;
79
80 Widget
81 _DtCreateMenuSystem(
82         Widget parent,
83         char * menuBarName,
84         XtCallbackProc helpCallback,
85         XtPointer helpData,
86         Boolean createSharedComponents,
87         MenuDesc * menuDesc,
88         int numMenuComponents,
89         void (*getMenuDataProc)(),
90         void (*setMenuSensitivity)(),
91         void (*restoreMenuSensitivity)() )
92
93 {
94    int n;
95    int i;
96    Arg args[20];
97    Widget menubar;
98    Widget lastCascadeBtn = NULL;
99    Widget lastMenuPane = NULL;
100    char lastMenuPaneType = MENU_PANE;
101    Boolean firstMenuPane = True;
102    Widget child;
103    XmString labelString;
104    int pulldownIndex = 1;
105    int menuPaneIndex = 1;
106    int menuBtnIndex = 1;
107
108    /* Use our own menu control functions, if none specified */
109    if (setMenuSensitivity == NULL)
110       setMenuSensitivity = _DtGlobalSetMenuSensitivity;
111    if (restoreMenuSensitivity == NULL)
112       restoreMenuSensitivity = _DtGlobalRestoreMenuSensitivity;
113
114    /*  Create the pulldown menu  */
115    n = 0;
116    XtSetArg(args[n], XmNorientation, XmHORIZONTAL);     n++;
117    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
118    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);        n++;
119    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
120    menubar = XmCreateMenuBar(parent, menuBarName, args, n);
121    XtManageChild(menubar);
122    if (helpCallback)
123       XtAddCallback(menubar, XmNhelpCallback, helpCallback, helpData);
124
125    for (i = 0; i < numMenuComponents; i++)
126    {
127       n = 0;
128
129       switch (menuDesc[i].type)
130       {
131          case MENU_PULLDOWN_BUTTON:
132          {
133             labelString = XmStringCreateLocalized(menuDesc[i].label);
134             XtSetArg(args[n], XmNlabelString, labelString);   n++;
135             if (menuDesc[i].mnemonic)
136             {
137                XtSetArg(args[n], XmNmnemonic, menuDesc[i].mnemonic[0]);   n++;
138             }
139             XtSetArg(args[n], XmNmarginWidth, 6);   n++;
140             child = XmCreateCascadeButtonGadget(menubar, menuDesc[i].name, 
141                                                 args, n);
142             if (menuDesc[i].helpCallback)
143             {
144                XtAddCallback(child, XmNhelpCallback, 
145                              menuDesc[i].helpCallback, menuDesc[i].helpData);
146             }
147             if (menuDesc[i].isHelpBtn)
148             {
149                XtSetArg(args[0], XmNmenuHelpWidget, child);
150                XtSetValues(menubar, args, 1);
151             }
152             XtManageChild(child);
153             XmStringFree(labelString);
154             lastCascadeBtn = menuDesc[i].widget = child;
155             pulldownIndex++;
156             break;
157          }
158
159          case SHARED_MENU_PANE:
160          case MENU_PANE:
161          {
162             if (createSharedComponents || (menuDesc[i].type == MENU_PANE))
163             {
164                child = XmCreatePulldownMenu(menubar, menuDesc[i].name, NULL, 0);
165
166                if (firstMenuPane)
167                {
168                   XtAddCallback(XtParent(child), XmNpopupCallback, 
169                                 setMenuSensitivity, 
170                                 (XtPointer)getMenuDataProc);
171                   XtAddCallback(XtParent(child), XmNpopdownCallback, 
172                                 restoreMenuSensitivity, 
173                                 (XtPointer)getMenuDataProc);
174                   firstMenuPane = False;
175                }
176
177                if (menuDesc[i].helpCallback)
178                {
179                   XtAddCallback(child, XmNhelpCallback, 
180                              menuDesc[i].helpCallback, menuDesc[i].helpData);
181                }
182
183                menuDesc[i].widget = child;
184             }
185
186             lastMenuPane = menuDesc[i].widget;
187             lastMenuPaneType = menuDesc[i].type;
188             XtSetArg(args[0], XmNsubMenuId, lastMenuPane);
189             XtSetValues(lastCascadeBtn, args, 1);
190             menuBtnIndex = 1;
191             menuPaneIndex++;
192             break;
193          }
194
195          case MENU_TOGGLE_BUTTON:
196          case MENU_BUTTON:
197          {
198             /* Need to always make btns for non-shared menupanes */
199             if ((createSharedComponents) || (lastMenuPaneType == MENU_PANE))
200             {
201                child = CreateMenuBtn (lastMenuPane, 
202                                       (menuDesc[i].type == MENU_BUTTON),
203                                       menuDesc + i, menuBtnIndex);
204                XtManageChild(child);
205                menuDesc[i].widget = child;
206             }
207             menuBtnIndex++;
208             break;
209          }
210
211          case MENU_SEPARATOR:
212          {
213             /* Need to always make components for non-shared menupanes */
214             if ((createSharedComponents) || (lastMenuPaneType == MENU_PANE))
215             {
216                child = XmCreateSeparatorGadget(lastMenuPane, menuDesc[i].name, 
217                                                NULL, 0);
218                XtManageChild(child);
219                menuDesc[i].widget = child;
220             }
221             break;
222          }
223       }
224    }
225
226
227    return(menubar);
228 }
229
230
231
232 /* ARGSUSED */
233 void
234 _DtGlobalSetMenuSensitivity(
235         Widget w,
236         XtPointer client_data,
237         XtPointer call_data )
238
239 {
240    Arg menuPaneArgs[1];
241    Widget mbar;
242    XmMenuShellWidget mshell = (XmMenuShellWidget) w;
243    void (*getMenuData)() = (void(*)())client_data;
244    XtPointer mainRecord;
245    MenuDesc * menuDesc;
246    int menuItemCount;
247    unsigned int * globalMenuStates;
248    unsigned int * viewMenuStates;
249    int i;
250
251    _XmGetActiveTopLevelMenu(mshell->composite.children[0], &mbar);
252    (*getMenuData)(mbar, &mainRecord, &menuDesc, &menuItemCount,
253                   &globalMenuStates, &viewMenuStates);
254    XtSetArg(menuPaneArgs[0], XmNuserData, mainRecord);
255
256    for (i = 0; i < menuItemCount; i++)
257    {
258       switch (menuDesc[i].type)
259       {
260          case SHARED_MENU_PANE:
261          case MENU_PANE:
262          {
263             /* Need to do this to get help working */
264             XtSetValues(menuDesc[i].widget, menuPaneArgs, 1);
265             break;
266          }
267
268          case MENU_BUTTON:
269          {
270             if ((menuDesc[i].maskBit) &&
271                ((*globalMenuStates & menuDesc[i].maskBit) != 
272                 (*viewMenuStates & menuDesc[i].maskBit)))
273             {
274                _DtGlobalUpdateMenuItemState(menuDesc[i].widget, 
275                                          menuDesc[i].maskBit, 
276                                          *viewMenuStates & menuDesc[i].maskBit,
277                                          globalMenuStates);
278             }
279             break;
280          }
281       }
282    }
283 }
284
285
286 /* ARGSUSED */
287 void
288 _DtGlobalRestoreMenuSensitivity(
289         Widget w,
290         XtPointer client_data,
291         XtPointer call_data )
292
293 {
294    Widget mbar;
295    XmMenuShellWidget mshell = (XmMenuShellWidget) w;
296    void (*getMenuData)() = (void (*)())client_data;
297    XtPointer mainRecord;
298    MenuDesc * menuDesc;
299    int menuItemCount;
300    unsigned int * globalMenuStates;
301    unsigned int * viewMenuStates;
302    int i;
303
304    _XmGetActiveTopLevelMenu(mshell->composite.children[0], &mbar);
305    (*getMenuData)(mbar, &mainRecord, &menuDesc, &menuItemCount,
306                   &globalMenuStates, &viewMenuStates);
307
308    for (i = 0; i < menuItemCount; i++)
309    {
310       if (menuDesc[i].type == MENU_BUTTON)
311       {
312          if ((menuDesc[i].maskBit) && 
313              ((*globalMenuStates & menuDesc[i].maskBit) == 0))
314          {
315             _DtGlobalUpdateMenuItemState(menuDesc[i].widget, 
316                                       menuDesc[i].maskBit, 
317                                       True,
318                                       globalMenuStates);
319          }
320       }
321    }
322 }
323
324
325 void
326 _DtGlobalUpdateMenuItemState(
327         Widget btn,
328         unsigned int mask,
329         unsigned int on,
330         unsigned int * globalMenuStates )
331
332 {
333    if (on != 0)
334    {
335       XtSetSensitive(btn, True);
336       *globalMenuStates |= mask;
337    }
338    else
339    {
340       if(btn != *findBtn             &&
341          btn != *change_directoryBtn && 
342          btn != *preferencesBtn      && 
343          btn != *defaultEnvBtn       && 
344          btn != *filterBtn               ) 
345       {
346         XtSetSensitive(btn, False);
347         *globalMenuStates &= ~mask;
348       }
349    }
350 }
351
352
353 static Widget
354 CreateMenuBtn (
355    Widget parent,
356    Boolean isPushButton,
357    MenuDesc * menuDesc,
358    int btnIndex )
359 {
360    int n;
361    Arg args[10];
362    Widget child;
363    XmString labelString;
364
365    n = 0;
366    labelString = XmStringCreateLocalized(menuDesc->label);
367    XtSetArg(args[n], XmNlabelString, labelString);              n++;
368    XtSetArg(args[n], XmNmnemonic, menuDesc->mnemonic[0]);       n++;
369    if (isPushButton)
370       child = XmCreatePushButtonGadget(parent, menuDesc->name, args, n);
371    else
372    {
373       XtSetArg(args[n], XmNvisibleWhenOff,TRUE);n++;
374       child = XmCreateToggleButtonGadget(parent, menuDesc->name, args, n);
375    }
376    if (menuDesc->helpCallback)
377    {
378       XtAddCallback(child, XmNhelpCallback, menuDesc->helpCallback, 
379                     menuDesc->helpData);
380    }
381    if (menuDesc->activateCallback)
382    {
383       if (isPushButton)
384       {
385          XtAddCallback(child, XmNactivateCallback, menuDesc->activateCallback, 
386                        menuDesc->activateData);
387       }
388       else
389       {
390          XtAddCallback(child, XmNvalueChangedCallback, 
391                        menuDesc->activateCallback, menuDesc->activateData);
392       }
393    }
394    XmStringFree(labelString);
395    return (child);
396 }