Overview
Overview.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 "Overview.h"

// Motif Widgets
Widget g_topLevel;                // application
Widget g_mainWindow;              
Widget g_mainForm;      
Widget g_leftPanel;
Widget g_loadText;
Widget g_mainPage;
Widget g_rightPanel;
Widget g_loadButton;
Widget g_zoomPageButton;
Widget g_howToLabel;
Widget g_overviewPage;
Widget g_selectFile;

// Control interfaces
IPageLayoutControlPtr g_ipMainPageLayout;
IPageLayoutControlPtr g_ipOverviewPageLayout;

IFillSymbolPtr g_ipFillSymbol;
PageLayoutControlEvents* g_pageEvents;
IEventListenerHelperPtr g_ipPageLayoutControlEventHelper;

int main(int argc, char* argv[])
{
  // Initialize the Engine
  ::AoInitialize(NULL);
  {
    IAoInitializePtr ipInit(CLSID_AoInitialize);
    esriLicenseStatus status;
    ipInit->Initialize(esriLicenseProductCodeEngine, &status);
    if (status != esriLicenseCheckedOut)
    {
      std::cerr << "Invalid Licensing." << std::endl;
      AoExit(0);  
    }
  }
  
  XtSetLanguageProc(NULL, NULL, NULL);
  XtAppContext app_context;
  
  // Initialize the Motif toolkit and create the parent widget
  g_topLevel = XtVaAppInitialize(&app_context, "XApplication", 
                                 NULL, 0, &argc, argv, NULL, NULL);
  XtVaSetValues(g_topLevel, 
                XmNtitle, "Overview",
                NULL);
  
  // Set the application size by resizing the created widget
  XtResizeWidget(g_topLevel, 500, 500, 1);
  
  g_mainWindow = XtVaCreateWidget("mainwindow", 
                                  xmMainWindowWidgetClass, g_topLevel,
                                  NULL);
  
  g_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
  g_rightPanel = XtVaCreateWidget("rightpanel",
                                  xmFormWidgetClass,    g_mainForm,
                                  XmNtopAttachment,     XmATTACH_WIDGET,
                                  XmNrightAttachment,   XmATTACH_FORM,
                                  XmNbottomAttachment,  XmATTACH_FORM,
                                  NULL);

  // Create and place loadButton
  XmString label = XmStringCreateLocalized("Load Map Document");
  g_loadButton = XtVaCreateWidget("loadbutton",
                                  xmPushButtonWidgetClass, g_rightPanel,
                                  XmNlabelString,          label,
                                  XmNrightAttachment,      XmATTACH_FORM,
                                  XmNtopAttachment,        XmATTACH_FORM,
                                  XmNleftAttachment,       XmATTACH_FORM,
                                  XmNheight,               35,
                                  XmNwidth,                100,
                                  NULL);
  XmStringFree(label);
  XtAddCallback(g_loadButton, XmNactivateCallback, LoadClick, NULL);

  // Create and place zoomPageButton
  label = XmStringCreateLocalized("Zoom to Page");
  g_zoomPageButton = XtVaCreateWidget("zoompagebutton",
                                      xmPushButtonWidgetClass, g_rightPanel,
                                      XmNlabelString,          label,
                                      XmNleftAttachment,       XmATTACH_FORM,
                                      XmNrightAttachment,      XmATTACH_FORM,
                                      XmNbottomAttachment,     XmATTACH_FORM,
                                      XmNheight,               35,
                                      XmNwidth,                100,
                                      NULL);
  XmStringFree(label);
  XtAddCallback(g_zoomPageButton, XmNactivateCallback, ZoomToPageClick, NULL);

  // Create and place the PageLayoutControl
  g_overviewPage = XtVaCreateWidget("overviewpage",
                                    mwCtlWidgetClass,       g_rightPanel,
                                    XmNtopAttachment,       XmATTACH_WIDGET,
                                    XmNtopWidget,           g_loadButton,
                                    XmNleftAttachment,      XmATTACH_FORM,
                                    XmNrightAttachment,     XmATTACH_FORM,
                                    XmNheight,              200,
                                    MwNprogID,              AoPROGID_PageLayoutControl,
                                    NULL);
  MwCtlGetInterface(g_overviewPage, (IUnknown**)&g_ipOverviewPageLayout);

  // Create and place howToLabel
  label = XmStringCreateLocalized(" Use the left mouse button \n to drag a rectangle and \n the right mouse button to \n pan.");
  g_howToLabel = XtVaCreateWidget("howtolabel",
                                  xmLabelWidgetClass,  g_rightPanel,
                                  XmNlabelString,      label,
                                  XmNalignment,        XmALIGNMENT_BEGINNING,
                                  XmNleftAttachment,   XmATTACH_FORM,
                                  XmNbottomAttachment, XmATTACH_WIDGET,
                                  XmNbottomWidget,     g_zoomPageButton,
                                  XmNtopAttachment,    XmATTACH_WIDGET,
                                  XmNtopWidget,        g_overviewPage,
                                  NULL);
  XmStringFree(label);

  // Create and place leftPanel
  g_leftPanel = XtVaCreateWidget("leftpanel",
                                 xmFormWidgetClass,    g_mainForm,
                                 XmNtopAttachment,     XmATTACH_FORM,
                                 XmNbottomAttachment,  XmATTACH_FORM,
                                 XmNleftAttachment,    XmATTACH_FORM,
                                 XmNrightAttachment,   XmATTACH_WIDGET,
                                 XmNrightWidget,       g_rightPanel,
                                 NULL);

  // Create and place loadText
  g_loadText = XtVaCreateWidget("loadtext",
                                xmTextFieldWidgetClass,   g_leftPanel,
                                XmNrightAttachment,       XmATTACH_FORM,
                                XmNleftAttachment,        XmATTACH_FORM,
                                XmNtopAttachment,         XmATTACH_FORM,
                                XmNheight,                35,
                                XmNeditable,              False,
                                XmNcursorPositionVisible, False,
                                NULL);
  
  // Create and place the PageLayoutControl
  g_mainPage = XtVaCreateWidget("mainpage",
                                mwCtlWidgetClass,       g_leftPanel,
                                XmNtopAttachment,       XmATTACH_WIDGET,
                                XmNtopWidget,           g_loadText,
                                XmNleftAttachment,      XmATTACH_FORM,
                                XmNbottomAttachment,    XmATTACH_FORM,
                                XmNrightAttachment,     XmATTACH_FORM,
                                MwNprogID,              AoPROGID_PageLayoutControl,
                                NULL);
  MwCtlGetInterface(g_mainPage, (IUnknown**)&g_ipMainPageLayout);

  // Create a file selection dialog with a *.mxd mask
  XmString mask;
  Arg args[1];
  mask  = XmStringCreateLocalized("*.mxd");
  XtSetArg(args[0], XmNdirMask, mask);
  g_selectFile = XmCreateFileSelectionDialog(g_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  
  XmString title;
  title = XmStringCreateLocalized("Browse to Map Document");
  XtVaSetValues(g_selectFile, XmNdialogTitle, title, NULL);
  XmStringFree(title);

  XtManageChild(g_mainWindow);              
  XtManageChild(g_mainForm);      
  XtManageChild(g_leftPanel);
  XtManageChild(g_loadText);
  XtManageChild(g_mainPage);
  XtManageChild(g_rightPanel);
  XtManageChild(g_loadButton);
  XtManageChild(g_zoomPageButton);
  XtManageChild(g_howToLabel);
  XtManageChild(g_overviewPage);

  // Set PageLayout properties
  g_ipMainPageLayout->put_Enabled(VARIANT_TRUE);
  g_ipOverviewPageLayout->put_Enabled(VARIANT_FALSE);
  g_ipMainPageLayout->put_Appearance(esri3D);
  g_ipOverviewPageLayout->put_Appearance(esriFlat);
  g_ipMainPageLayout->put_BorderStyle(esriBorder); 
  g_ipOverviewPageLayout->put_BorderStyle(esriNoBorder);

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

  // Listen for PageLayoutControlEvents
  g_pageEvents = new PageLayoutControlEvents();
  g_ipPageLayoutControlEventHelper.CreateInstance(CLSID_PageLayoutControlEventsListener);
  g_ipPageLayoutControlEventHelper->Startup(
    static_cast<IPageLayoutControlEventsHelper*> (g_pageEvents));
  g_ipPageLayoutControlEventHelper->AdviseEvents(g_ipMainPageLayout, NULL);

  // Start the application running 
  XtRealizeWidget(g_topLevel);
  MwCtlAppMainLoop(app_context);
}

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

void CloseAppCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
  // Event and globals cleanup
  g_ipPageLayoutControlEventHelper->UnadviseEvents();
  g_ipPageLayoutControlEventHelper->Shutdown();
  g_ipPageLayoutControlEventHelper = 0;
  delete g_pageEvents;

  g_ipMainPageLayout = 0;
  g_ipOverviewPageLayout = 0;
  g_ipFillSymbol = 0;
  
  // Uninitialize the engine
  {
    IAoInitializePtr ipInit(CLSID_AoInitialize);
    ipInit->Shutdown();
  }
  ::AoUninitialize();

  AoExit(0);
}

void LoadClick(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("File Open Error", "INTERNAL ERROR PROCESSING FILE");
    XtUnmanageChild(w);
    return;
  }
  if (!*fileName) 
  {
    ShowMessage("File Open Error", "NO FILE SELECTED");
    XtUnmanageChild(w);
    return;
  }

  // Try to add the layer to the main PageLayoutControl
  if (cbs->reason != XmCR_NO_MATCH)
  {
    VARIANT_BOOL varbool;
    g_ipMainPageLayout->CheckMxFile(CComBSTR(fileName), &varbool);
    if (varbool)
    {
      // Set mouse pointers
      g_ipMainPageLayout->put_MousePointer(esriPointerHourglass);
    
      // Set the text box to the file path    
      XmTextFieldSetString(g_loadText, fileName);
    
      // Load the map document
      g_ipMainPageLayout->LoadMxFile(CComBSTR(fileName));
    
      // Set mouse pointers
      g_ipMainPageLayout->put_MousePointer(esriPointerDefault);
    }
    else
    {
      ShowMessage("Invalid MXD", "Not a valid ArcMap Document");
      XtUnmanageChild(w);
      return;
    }
      
    // Hide file selection dialog
    XtUnmanageChild(w);
  }
}

void ZoomToPageClick(Widget w, XtPointer client_data, XtPointer call_data)
{
  g_ipMainPageLayout->ZoomToWholePage();

  // Get the IElement interface by finding an element by its name
  IElementPtr ipElement;
  g_ipOverviewPageLayout->FindElementByName(CComBSTR(L"ZoomExtent"), 
                                            1, &ipElement);
  if (ipElement)
  {
    // Delete it
    IGraphicsContainerPtr ipGraphicsContainer;
    g_ipOverviewPageLayout->get_GraphicsContainer(&ipGraphicsContainer);
    ipGraphicsContainer->DeleteElement(ipElement);
    g_ipOverviewPageLayout->Refresh(esriViewGraphics);
  }
}