Save MapDocument
WidgetSetup.cpp
// Copyright 2011 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

  
#include "WidgetSetup.h"

extern IPageLayoutControlPtr g_ipPageLayoutControl;
extern IToolbarControlPtr g_ipToolbarControl;
extern ITOCControlPtr g_ipTOCControl;
extern IMapDocumentPtr g_ipMapDoc;

Widget g_mainWindow;
Widget g_currentMapText;
Widget g_selectFile;
Widget g_saveFile;
Widget g_saveAsButton;
Widget g_saveButton;

void SetUpForm(int argc, char* argv[], XtAppContext* app_context)
{
  // Initialize the Motif toolkit and create the parent widget
  XtSetLanguageProc(NULL, NULL, NULL);
  Widget topLevel = XtVaAppInitialize(app_context, "XApplication", 
                                      NULL, 0, &argc, argv, NULL, NULL);

  XtVaSetValues(topLevel, XmNtitle, "Save Map Document", NULL);
  
  // Set the application size by resizing the created widget
  XtResizeWidget(topLevel, 660, 480, 1);
  
  g_mainWindow = XtVaCreateWidget("g_mainWindow", xmMainWindowWidgetClass, topLevel, NULL);
  
  Widget mainForm = XtVaCreateWidget("mainForm",
                                     xmFormWidgetClass,           g_mainWindow,
                                     XmNtopAttachment,            XmATTACH_WIDGET,
                                     XmNtopWidget,                g_mainWindow,
                                     XmNbottomAttachment,         XmATTACH_WIDGET,
                                     XmNbottomWidget,             g_mainWindow,
                                     XmNleftAttachment,           XmATTACH_WIDGET,
                                     XmNleftWidget,               g_mainWindow,
                                     XmNrightAttachment,          XmATTACH_WIDGET,
                                     XmNrightWidget,              g_mainWindow,
                                     XmNfractionBase,             100,
                                     NULL);

  // Create and place rightPanel
  Widget rightPanel = XtVaCreateWidget("rightPanel",
                                       xmFormWidgetClass,         mainForm,
                                       XmNtopAttachment,          XmATTACH_FORM,
                                       XmNrightAttachment,        XmATTACH_FORM,
                                       XmNbottomAttachment,       XmATTACH_FORM,
                                       XmNwidth,                  140,
                                       XmNfractionBase,           140,
                                       NULL);

  // Create and place leftpanel
  Widget leftPanel = XtVaCreateWidget("leftPanel",
                                      xmFormWidgetClass,          mainForm,
                                      XmNtopAttachment,           XmATTACH_FORM,
                                      XmNleftAttachment,          XmATTACH_FORM,
                                      XmNbottomAttachment,        XmATTACH_FORM,
                                      XmNrightAttachment,         XmATTACH_WIDGET,
                                      XmNrightWidget,             rightPanel,     
                                      XmNleftOffset,              5,
                                      NULL);

  // Create and place currentMapText
  g_currentMapText = XtVaCreateWidget("currentMapText",
                                      xmTextFieldWidgetClass,     leftPanel,
                                      XmNalignment,               XmALIGNMENT_BEGINNING,
                                      XmNleftAttachment,          XmATTACH_FORM,
                                      XmNrightAttachment,         XmATTACH_FORM,
                                      XmNbottomAttachment,        XmATTACH_FORM,
                                      XmNeditable,                False,
                                      XmNcursorPositionVisible,   False,
                                      XmNbottomOffset,            5,
                                      NULL);
                                           
  // Create and place controlsPanel
  Widget controlsPanel = XtVaCreateWidget("controlsPanel",
                                          xmFormWidgetClass,      leftPanel,
                                          XmNtopAttachment,       XmATTACH_FORM,
                                          XmNleftAttachment,      XmATTACH_FORM,
                                          XmNrightAttachment,     XmATTACH_FORM,
                                          XmNbottomAttachment,    XmATTACH_WIDGET,
                                          XmNbottomWidget,        g_currentMapText,
                                          XmNbottomOffset,        5,
                                          NULL);
  
  // Create and place toolbarWidget
  Widget toolbarWidget = XtVaCreateWidget("toolbarWidget",
                                          mwCtlWidgetClass,       controlsPanel,
                                          XmNtopAttachment,       XmATTACH_FORM,
                                          XmNleftAttachment,      XmATTACH_FORM,
                                          XmNrightAttachment,     XmATTACH_FORM,
                                          MwNprogID,              AoPROGID_ToolbarControl,
                                          XmNtopOffset,           5,
                                          NULL);
  XtVaSetValues(toolbarWidget, XmNheight, 25, NULL);
  MwCtlGetInterface(toolbarWidget, (IUnknown**)&g_ipToolbarControl);

  // Create and place tocPLPanel
  Widget tocPLPanel = XtVaCreateWidget("tocPLPanel",
                                       xmFormWidgetClass,         controlsPanel,
                                       XmNtopAttachment,          XmATTACH_WIDGET,
                                       XmNtopWidget,              toolbarWidget,
                                       XmNleftAttachment,         XmATTACH_FORM,
                                       XmNrightAttachment,        XmATTACH_FORM,
                                       XmNbottomAttachment,       XmATTACH_FORM,
                                       XmNtopOffset,              5,
                                       NULL);

  // Create and place tocWidget
  Widget tocWidget = XtVaCreateWidget("tocWidget",
                                      mwCtlWidgetClass,           tocPLPanel,
                                      XmNtopAttachment,           XmATTACH_FORM,
                                      XmNleftAttachment,          XmATTACH_FORM,
                                      XmNbottomAttachment,        XmATTACH_FORM,
                                      MwNprogID,                  AoPROGID_TOCControl,
                                      NULL);
  XtVaSetValues(tocWidget, XmNwidth, 150, NULL);
  MwCtlGetInterface(tocWidget, (IUnknown**)&g_ipTOCControl);

  // Create and place pageLayoutWidget
  Widget pageLayoutWidget = XtVaCreateWidget("pageLayoutWidget",
                                             mwCtlWidgetClass,        tocPLPanel,
                                             XmNbottomAttachment,     XmATTACH_FORM,
                                             XmNtopAttachment,        XmATTACH_FORM,
                                             XmNrightAttachment,      XmATTACH_FORM,
                                             XmNleftAttachment,       XmATTACH_WIDGET,
                                             XmNleftWidget,           tocWidget,
                                             MwNprogID,      AoPROGID_PageLayoutControl,
                                             NULL);
  MwCtlGetInterface(pageLayoutWidget, (IUnknown**)&g_ipPageLayoutControl);

  // Create and place openButton
  XmString label = XmStringCreateLocalized("Open Document...");
  Widget openButton = XtVaCreateWidget("openButton",
                                       xmPushButtonWidgetClass, rightPanel,
                                       XmNlabelString,          label,
                                       XmNleftAttachment,       XmATTACH_POSITION,
                                       XmNleftPosition,         5,
                                       XmNtopAttachment,        XmATTACH_POSITION,
                                       XmNtopPosition,          10,
                                       XmNrightAttachment,      XmATTACH_POSITION,
                                       XmNrightPosition,        135,
                                       XmNheight,               35,
                                       XmNwidth,                100,
                                       NULL);
  XmStringFree(label);
  XtAddCallback(openButton, XmNactivateCallback, OpenClick, NULL);

  // Create and place openButton
  label = XmStringCreateLocalized("Save Document As...");
  g_saveAsButton = XtVaCreateWidget("g_saveAsButton",
                                    xmPushButtonWidgetClass, rightPanel,
                                    XmNlabelString,          label,
                                    XmNleftAttachment,       XmATTACH_POSITION,
                                    XmNleftPosition,         5,
                                    XmNtopAttachment,        XmATTACH_WIDGET,
                                    XmNtopWidget,            openButton,
                                    XmNrightAttachment,      XmATTACH_POSITION,
                                    XmNrightPosition,        135,
                                    XmNheight,               35,
                                    XmNwidth,                100,
                                    XmNtopOffset,            5,
                                    XmNsensitive,            false,
                                    NULL);
  XmStringFree(label);
  XtAddCallback(g_saveAsButton, XmNactivateCallback, SaveAsClick, NULL);

  // Create and place openButton
  label = XmStringCreateLocalized("Save Document");
  g_saveButton = XtVaCreateWidget("g_saveButton",
                                  xmPushButtonWidgetClass, rightPanel,
                                  XmNlabelString,          label,
                                  XmNleftAttachment,       XmATTACH_POSITION,
                                  XmNleftPosition,         5,
                                  XmNtopAttachment,        XmATTACH_WIDGET,
                                  XmNtopWidget,            g_saveAsButton,
                                  XmNrightAttachment,      XmATTACH_POSITION,
                                  XmNrightPosition,        135,
                                  XmNheight,               35,
                                  XmNwidth,                100,
                                  XmNtopOffset,            5,
                                  XmNsensitive,            false,
                                  NULL);
  XmStringFree(label);
  XtAddCallback(g_saveButton, XmNactivateCallback, SaveClick, NULL);

  // Create a file selection dialog with a *.mxd mask
  XmString mask  = XmStringCreateLocalized("*.mxd");
  Arg args[1];
  XtSetArg(args[0], XmNdirMask, mask);
  g_selectFile = XmCreateFileSelectionDialog(mainForm, "Select File", args, 1);
  XtAddCallback(g_selectFile, XmNokCallback, FileSelected, NULL);
  XtAddCallback(g_selectFile, XmNnoMatchCallback, FileSelected, NULL);
  XtAddCallback(g_selectFile, XmNcancelCallback, FileSelected, NULL);
  // Disable the Help button
  XtSetSensitive(XmFileSelectionBoxGetChild(g_selectFile, XmDIALOG_HELP_BUTTON), False);
  // Set the name of the FileSelectionDialog  
  XtVaSetValues(g_selectFile, 
                XmNdialogTitle, XmStringCreateLocalized("Browse to Map Document"), 
                NULL);

  // Create a file save dialog with a *.mxd mask
  g_saveFile = XmCreateFileSelectionDialog(mainForm, "Save", args, 1);
  XtAddCallback(g_saveFile, XmNokCallback, SaveAsSelected, NULL);
  XtAddCallback(g_saveFile, XmNnoMatchCallback, SaveAsSelected, NULL);
  XtAddCallback(g_saveFile, XmNcancelCallback, SaveAsSelected, NULL);
  // Disable the Help button
  XtSetSensitive(XmFileSelectionBoxGetChild(g_saveFile, XmDIALOG_HELP_BUTTON), False);
  // Have the OK button display "save" instead
  Widget saveButton = XmFileSelectionBoxGetChild(g_saveFile, XmDIALOG_OK_BUTTON);
  XtVaSetValues(saveButton, XmNlabelString, XmStringCreateLocalized("Save"), NULL);
  // Set the name of the FileSelectionDialog  
  XtVaSetValues(g_saveFile, 
                XmNdialogTitle, XmStringCreateLocalized("Save Map Document As"), 
                NULL);
  
  XtManageChild(g_mainWindow);              
  XtManageChild(mainForm);      
  XtManageChild(rightPanel);
  XtManageChild(leftPanel);
  XtManageChild(g_currentMapText);
  XtManageChild(controlsPanel);
  XtManageChild(toolbarWidget);
  XtManageChild(tocPLPanel);
  XtManageChild(tocWidget);
  XtManageChild(pageLayoutWidget);
  XtManageChild(openButton);
  XtManageChild(g_saveAsButton);
  XtManageChild(g_saveButton);

  // Buddy the toolbar and the TOC with the PageLayout
  g_ipTOCControl->SetBuddyControl(g_ipPageLayoutControl);
  g_ipToolbarControl->SetBuddyControl(g_ipPageLayoutControl);

  AddToolbarItems();

  // Handle the window manager message that the window is about to be closed 
  Atom wm_delete_window = XmInternAtom(XtDisplay(topLevel), "WM_DELETE_WINDOW", FALSE);
  XmAddWMProtocolCallback(topLevel, wm_delete_window, CloseAppCallback, NULL);

  // Start the application running 
  XtRealizeWidget(topLevel);
}

// Dispay a MessageDialog
void ShowMessage(char *dialogtitle, char *text)
{
  // Create a MessageDialog
  Widget msgBox;
  Arg args[1];
  int n = 0;
  XtSetArg(args[n], XmNmessageString, XmStringCreateLocalized(text));
  n++;
  msgBox = XmCreateMessageDialog(g_mainWindow, "error", args, n);
  
  // Remove the help and cancel buttons
  XtUnmanageChild(XmMessageBoxGetChild(msgBox, XmDIALOG_HELP_BUTTON));
  XtUnmanageChild(XmMessageBoxGetChild(msgBox, XmDIALOG_CANCEL_BUTTON));
  
  // Set the title of the MessageDialog
  XtVaSetValues(msgBox, XmNdialogTitle, XmStringCreateLocalized(dialogtitle), NULL);
  
  XtManageChild(msgBox);
}

void OpenClick(Widget w, XtPointer client_data, XtPointer call_data)
{
  XtManageChild(g_selectFile);
}

void FileSelected(Widget w, XtPointer client_data, XtPointer call_data)
{
  char* fileName;
  XmFileSelectionBoxCallbackStruct *cbs;
  cbs = (XmFileSelectionBoxCallbackStruct *)call_data;
  
  // Hide the dialog if they canceled
  if (cbs->reason == XmCR_CANCEL)
  {
    XtUnmanageChild(w);
    return;
  }

  // Get the file name and check for errors
  if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &fileName))
  {
    ShowMessage("ERROR", "INTERNAL ERROR PROCESSING FILE");
    XtUnmanageChild(w);
    return;
  }
  if (!*fileName) 
  {
    ShowMessage("ERROR", "NO FILE SELECTED");
    XtUnmanageChild(w);
    return;
  }
  
  bool bOpened;
  if (cbs->reason != XmCR_NO_MATCH)
  {
    bOpened = OpenDocument(fileName);
  }

  // Hide file selection dialog
  XtUnmanageChild(w);
  
  if (bOpened)
  {
    // Enable the saving buttons
    XtVaSetValues(g_saveAsButton, XmNsensitive, true, NULL);
    XtVaSetValues(g_saveButton, XmNsensitive, true, NULL);  
  }
}

void SaveAsClick(Widget w, XtPointer client_data, XtPointer call_data)
{
  XtManageChild(g_saveFile);
}

void SaveAsSelected(Widget w, XtPointer client_data, XtPointer call_data)
{
  char* fileName;
  XmFileSelectionBoxCallbackStruct *cbs;
  cbs = (XmFileSelectionBoxCallbackStruct *)call_data;
  
  // Hide the dialog if they canceled
  if (cbs->reason == XmCR_CANCEL)
  {
    XtUnmanageChild(w);
    return;
  }

  // Get the file name and check for errors
  if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &fileName))
  {
    ShowMessage("ERROR", "INTERNAL ERROR PROCESSING FILE");
    XtUnmanageChild(w);
    return;
  }
  if (!*fileName) 
  {
    ShowMessage("ERROR", "NO FILE SELECTED");
    XtUnmanageChild(w);
    return;
  }
  
  if (cbs->reason != XmCR_NO_MATCH)
  {
    SaveDocumentAs(fileName);
  }

  // Hide file selection dialog
  XtUnmanageChild(w);
}

void SaveClick(Widget w, XtPointer client_data, XtPointer call_data)
{
  SaveDocument();
}

void AddToolbarItems()
{
  long itemIndex;
  CComVariant varTool;
  
  varTool = L"esriControlCommands.ControlsPageLayoutToolbar";
  g_ipToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
                              esriCommandStyleIconOnly, &itemIndex);
  varTool = L"esriControlCommands.ControlsGraphicElementToolbar";
  g_ipToolbarControl->AddItem(varTool, 0, -1, VARIANT_TRUE, 0,
                              esriCommandStyleIconOnly, &itemIndex);
}

// Function called when WM_DELETE_WINDOW protocol is passed
void CloseAppCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
  g_ipPageLayoutControl = 0;
  g_ipToolbarControl = 0;
  g_ipTOCControl = 0;
  g_ipMapDoc = 0;

  // Uninitialize the engine
  {
    IAoInitializePtr ipInit(CLSID_AoInitialize);
    ipInit->Shutdown();
  }
  ::AoUninitialize();

  exit(0);
}