/*
* File name: mainframe.cpp
* Location: See Matrox Example Launcher in the MIL Control Center
* 
*/
//
// Copyright (C) Matrox Electronic Systems Ltd., 1992-2020.
// All Rights Reserved

#include <mil.h>
#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <stdlib.h>
#include "mainframe.h"
#include "childframe.h"
#include "mdispgtkview.h"
#include "mdispgtkapp.h"
static void activate_toggle (GSimpleAction *action,
                             GVariant      *parameter,
                             gpointer       user_data)
   {
   GVariant *state;
   state = g_action_get_state (G_ACTION (action));
   g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));
   g_variant_unref (state);
   }

static  GtkRadioActionEntry view_mode_entries[] = {
   { "Default", NULL,    "M_DEFAULT",      NULL,"M_DEFAULT", VIEW_MODE_DEFAULT },                  
   { "Transparent", NULL,"M_TRANSPARENT",  NULL,"M_TRANSPARENT", VIEW_MODE_TRANSPARENT }, 
   { "AutoScale", NULL,  "M_AUTO_SCALE",  NULL,"M_AUTO_SCALE",VIEW_MODE_AUTO_SCALE },      
   { "MultiBytes", NULL, "M_MULTI_BYTES", NULL,"M_MULTI_BYTES",VIEW_MODE_MULTI_BYTES },      
   { "BitShift2", NULL,  "M_BIT_SHIFT:2", NULL,"M_BIT_SHIFT:2 ",VIEW_MODE_BIT_SHIFT2 },      
   { "BitShift4", NULL,  "M_BIT_SHIFT:4", NULL,"M_BIT_SHIFT:4",VIEW_MODE_BIT_SHIFT4 },      
   { "BitShift8", NULL,  "M_BIT_SHIFT:8", NULL,"M_BIT_SHIFT:8",VIEW_MODE_BIT_SHIFT8 },      

};
static guint n_view_mode_entries = G_N_ELEMENTS (view_mode_entries);

static GActionEntry win_entries[] = {
   // File
   { "new", MainFrame::fileNew, NULL, NULL, NULL },
   { "open", MainFrame::fileOpen, NULL, NULL, NULL },
   { "close", MainFrame::fileClose, NULL, NULL, NULL },
   { "save", MainFrame::fileSave, NULL, NULL, NULL },
   { "saveas", MainFrame::fileSaveAs, NULL, NULL, NULL },
   { "quit", MainFrame::fileQuit, NULL, NULL, NULL },
   
   // View
   { "standard_toolbar", activate_toggle, NULL, "true", MainFrame::viewStandardToolbar },
   { "display_toolbar", activate_toggle, NULL, "true", MainFrame::viewDisplayToolbar },
   
   //Display
   { "overlay", activate_toggle, NULL, "false", MainFrame::dispOverlay },
   { "scale", activate_toggle, NULL, "false", MainFrame::dispScaleDisplay },
   { "graannotations", activate_toggle, NULL, "false", MainFrame::dispGraphicsAnnotations },
   
   // Display -> Graphics
   { "grarectangle", MainFrame::dispNewRectangle, NULL, NULL, NULL },
   { "graarc", MainFrame::dispNewArc, NULL, NULL, NULL },
   { "grapolygon", MainFrame::dispNewPolygon, NULL, NULL, NULL },
   { "graorientedrect", MainFrame::dispNewOrientedRect, NULL, NULL, NULL },
   { "graarcthreepoints", MainFrame::dispNewArcThreePoints, NULL, NULL, NULL },
   { "graselectcolor", MainFrame::dispSelectGraphicColor, NULL, NULL, NULL },
   { "grafill", MainFrame::dispFillGraphic, NULL, NULL, NULL },
   { "gradrawdir", MainFrame::dispDrawDir, NULL, NULL, NULL },
   
   // Display -> Zoom
   { "nozoom", MainFrame::dispNoZoom, NULL, NULL, NULL },
   { "zoomin", MainFrame::dispZoomIn, NULL, NULL, NULL },
   { "zoomout", MainFrame::dispZoomOut, NULL, NULL, NULL },

   // Display -> DistributedMIL->ASyncghronous
   { "dmilasync", MainFrame::dmilASync, "s", "'disabled'", NULL },

   // Display -> DistributedMIL->Compression
   { "dmilcompression", MainFrame::dmilCompression, "s", "'none'", NULL },

   // Display -> DistributedMIL->QFactor
   { "dmilqfactor", MainFrame::dmilQFactor, "s", "'60'", NULL },

   //Display->Exclusive Display->Restrict Cursor
   { "restrictcursor", activate_toggle, NULL, "false", MainFrame::dispRestrictCursor },
   
   // Grab
   { "grabstart", MainFrame::dispGrabStart, NULL, NULL, NULL },
   { "grabstop", MainFrame::dispGrabStop, NULL, NULL, NULL },

   // About
   { "about", MainFrame::about, NULL, NULL, NULL },
};

/////////////////////////////////////////////////////////////////////////////
// MainFrame
// Create the Main Window
//
MainFrame::MainFrame(GtkApplication *gtkApp)
   {
   m_Quit = false;
   m_ChildList              = NULL;
   GtkBuilder *builder      = NULL;
   GtkWidget *grid          = NULL;
   GtkToolItem* item_view   = NULL;
   
   
   m_MainWindow = gtk_application_window_new (GTK_APPLICATION (gtkApp));
   g_action_map_add_action_entries (G_ACTION_MAP (m_MainWindow), win_entries, G_N_ELEMENTS (win_entries), this);
   builder = gtk_builder_new ();
   gtk_builder_add_from_resource (builder, "/images/mdispgtk.ui", NULL);
   
   grid = (GtkWidget *)gtk_builder_get_object (builder, "grid1");
   m_ToolbarStd = (GtkWidget *)gtk_builder_get_object (builder, "toolbarstd");
   m_ToolbarDisp = (GtkWidget *)gtk_builder_get_object (builder, "toolbardisp");

   // view mode
   item_view = (GtkToolItem *)gtk_builder_get_object (builder, "viewitem");
   if(item_view)
      {
      m_ViewComboBox = gtk_combo_box_text_new();
      for (int i=0 ; i< (int) n_view_mode_entries; i++)
         {
         gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(m_ViewComboBox),NULL,view_mode_entries[i].label);
         }
 
      gtk_combo_box_set_active (GTK_COMBO_BOX(m_ViewComboBox),0);
      gtk_container_add(GTK_CONTAINER(item_view),m_ViewComboBox);
      }
   gtk_widget_show(m_ViewComboBox);

   
   gtk_container_add (GTK_CONTAINER (m_MainWindow), grid);
   
   g_signal_connect (m_ViewComboBox,"changed",G_CALLBACK(MainFrame::OnCbViewChanged),this);
   g_signal_connect (m_MainWindow,"destroy",G_CALLBACK(MainFrame::OnDestroy),this);
   
   g_object_unref (builder);
   updateActions(NULL);
   }

/////////////////////////////////////////////////////////////////////////////
// MainFrame
// Destructor
//
MainFrame::~MainFrame()
   {
   }
/////////////////////////////////////////////////////////////////////////////
// setcf
// set current child frame
//
void MainFrame::setcf(ChildFrame* cf)
   {
   m_cf= cf; 
   updateActions(cf);
   }

/////////////////////////////////////////////////////////////////////////////
// remove
// remove child frame from the list
// 
void MainFrame::remove(ChildFrame *cf)
   {
   m_ChildList = g_list_remove(m_ChildList,cf);
   if(g_list_length(m_ChildList))
      {
      GList* l = g_list_last(m_ChildList);
      setcf((ChildFrame *) l->data);
      }
   else
      {
      setcf(NULL);
      }
   }
/////////////////////////////////////////////////////////////////////////////
// add
// add child frame tio list of childs
//
void MainFrame::add(ChildFrame *cf)
   {
   if(cf)
      {
      m_ChildList = g_list_append(m_ChildList,cf);
      }
   }
/////////////////////////////////////////////////////////////////////////////
// setEnable
// Enable action
//
void MainFrame::setEnable(const gchar* name, bool value)
   {
   GSimpleAction* action = NULL;
   action = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP (m_MainWindow), name));
   if(action)
      {
      g_simple_action_set_enabled (action,value);
      }
   }
/////////////////////////////////////////////////////////////////////////////
// setActive
// Activate action
//
void MainFrame::setActive(const gchar* name, bool newvalue)
   {
   GAction *action = NULL;
   bool oldvalue;
   action = g_action_map_lookup_action(G_ACTION_MAP (m_MainWindow), name);
   if(action)
      {
      oldvalue =  g_action_get_state (action);
      if(oldvalue != newvalue)
         {
         Update(false);
         g_action_change_state (action, g_variant_new_boolean (newvalue));
         Update(true);
         }
      }
   }
/////////////////////////////////////////////////////////////////////////////
// setActive
// Activate a radio action
//
void MainFrame::setActive(const gchar* name, const gchar *newvalue)
   {
   GAction *action = NULL;
   GVariant* oldvalue;
   action = g_action_map_lookup_action(G_ACTION_MAP (m_MainWindow), name);
   if(action)
      {
      oldvalue =  g_action_get_state (action);
      if (!g_variant_equal(oldvalue ,newvalue))
         {
         Update(false);
         g_action_change_state (action, g_variant_new_string (newvalue));
         Update(true);
         }
      }
   }

/////////////////////////////////////////////////////////////////////////////
// dispGtkApp
// Get App 
// 
MdispGtkApp* MainFrame::dispGtkApp()
   {
   void *UserData = g_object_get_data(G_OBJECT(m_MainWindow),"App");
   return (MdispGtkApp *) UserData;
   }

/////////////////////////////////////////////////////////////////////////////
// fileNew
// 
//
void MainFrame::fileNew (GSimpleAction *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = new ChildFrame(mf);

   if(!cf->View()->newDoc())
      {
      cf->close();
      }
   else
      {
      mf->add(cf);
      }
   }

/////////////////////////////////////////////////////////////////////////////
// fileOpen
//
//
void MainFrame::fileOpen (GSimpleAction *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   GtkWidget *dialog = gtk_file_chooser_dialog_new ("Open File",
                                                    NULL,
                                                    GTK_FILE_CHOOSER_ACTION_OPEN,
                                                    "_Cancel", GTK_RESPONSE_CANCEL,
                                                    "_Open", GTK_RESPONSE_ACCEPT,
                                                    NULL);
     
   GtkFileFilter*imageFilter = gtk_file_filter_new();
   gtk_file_filter_set_name(imageFilter,"Images  Files (*.mim:*.bmp:*..tif;*.jpg;*.jp2;*.png)");
   gtk_file_filter_add_pattern(imageFilter,"*.mim");
   gtk_file_filter_add_pattern(imageFilter,"*.bmp");
   gtk_file_filter_add_pattern(imageFilter,"*.tif");
   gtk_file_filter_add_pattern(imageFilter,"*.jpg");
   gtk_file_filter_add_pattern(imageFilter,"*.jp2");
   gtk_file_filter_add_pattern(imageFilter,"*.png");
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),imageFilter);
     
   GtkFileFilter* allFilter = gtk_file_filter_new();
   gtk_file_filter_set_name(allFilter,"All Files (*.*)");
   gtk_file_filter_add_pattern(allFilter,"*.*");
   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),allFilter);

   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
      {
      gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
      if(filename)
         {
         ChildFrame* cf = new ChildFrame(mf);
         if ( !cf->View()->load(filename) )
            {
            GtkWidget *dialog = gtk_message_dialog_new (NULL,
                                                        GTK_DIALOG_DESTROY_WITH_PARENT,
                                                        GTK_MESSAGE_ERROR,
                                                        GTK_BUTTONS_CLOSE,
                                                        "Could not load image from %s", filename);
            gtk_dialog_run (GTK_DIALOG (dialog));
            gtk_widget_destroy (dialog);
            cf->close();
            delete cf;
            cf = NULL;
            }
         else
            {
            cf->setTitle(g_path_get_basename(filename));
            mf->add(cf);
            }
         g_free(filename);
         mf->updateActions(cf); 
         }
      }

   gtk_widget_destroy (dialog);
   }
/////////////////////////////////////////////////////////////////////////////
// fileSave
// 
//
void MainFrame::fileSave (GSimpleAction *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   if(mf)
      mf->fileSaveAs(action, NULL, user_data);
   }

/////////////////////////////////////////////////////////////////////////////
// fileClose
// 
//
void MainFrame::fileClose (GSimpleAction *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->close();
      }
   
   }
/////////////////////////////////////////////////////////////////////////////
// fileSaveAs
// 
//
void MainFrame::fileSaveAs (GSimpleAction *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame*  mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if(cf)
      {
      GtkWidget *dialog = gtk_file_chooser_dialog_new ("Save File",
                                                       NULL,
                                                       GTK_FILE_CHOOSER_ACTION_SAVE,
                                                       "_Cancel", GTK_RESPONSE_CANCEL,
                                                       "_Save", GTK_RESPONSE_ACCEPT,
                                                       NULL);
      
      gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (dialog),cf->View()->filename());
      
      if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
         {
         gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
         cf->View()->save(filename);
         cf->setTitle(g_path_get_basename(filename));
         g_free(filename);
         }
      gtk_widget_destroy (dialog);
      }
   }

/////////////////////////////////////////////////////////////////////////////
// fileQuit
// 
//
void MainFrame::fileQuit (GSimpleAction *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   if(mf)
      {
      mf->OnDestroy(NULL,mf);
      g_application_quit(g_application_get_default());
      }
   }

/////////////////////////////////////////////////////////////////////////////
// viewStandardToolbar
// 
//
void MainFrame::viewStandardToolbar(GSimpleAction  *action,
                                    GVariant       *state,
                                    gpointer        user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   gboolean active = g_variant_get_boolean(state);
   if(active)
      gtk_widget_show(mf->m_ToolbarStd);
   else
      gtk_widget_hide(mf->m_ToolbarStd);

   g_simple_action_set_state (action, state);

   }

/////////////////////////////////////////////////////////////////////////////
// viewDisplayToolbar
// 
//
void MainFrame::viewDisplayToolbar(GSimpleAction  *action,
                                   GVariant       *state,
                                   gpointer        user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   gboolean active = g_variant_get_boolean(state);
   if(active)
      gtk_widget_show(mf->m_ToolbarDisp);
   else
      gtk_widget_hide(mf->m_ToolbarDisp);

   g_simple_action_set_state (action, state);

   }
/////////////////////////////////////////////////////////////////////////////
// dispOverlay
// 
//
void MainFrame::dispOverlay(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   if(mf->Update())
      {
      ChildFrame* cf = (ChildFrame*) mf->cf();
      if (cf)
         {
         bool on = g_variant_get_boolean(state);
         cf->View()->Overlay(on);
         mf->updateActions(cf);
         }
      }
   
   g_simple_action_set_state (action, state);
   }

/////////////////////////////////////////////////////////////////////////////
// dispScaleDisplay
// 
//
void MainFrame::dispScaleDisplay(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   if(mf->Update())
      {
      ChildFrame* cf = (ChildFrame*) mf->cf();
      if (cf)
         {
         bool on = g_variant_get_boolean(state);
         cf->View()->ScaleDisplay(on);
         mf->updateActions(cf);
         }
      }
   g_simple_action_set_state (action, state);
   }


/////////////////////////////////////////////////////////////////////////////
// dispGraphicsAnnotations
// 
//
void MainFrame::dispGraphicsAnnotations(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   if(mf->Update())
      {
      ChildFrame* cf = (ChildFrame*) mf->cf();
      if (cf)
         {
         bool on = g_variant_get_boolean(state);
         cf->View()->GraphicsAnnotations(on);
         mf->updateActions(cf);
         }
      }
   g_simple_action_set_state (action, state);
   }

/////////////////////////////////////////////////////////////////////////////
// dispNewRectangle
//
//
void MainFrame::dispNewRectangle(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnGraRectangle();
      mf->updateActions(cf);
      }
   }

/////////////////////////////////////////////////////////////////////////////
// dispNewArc
//
//
void MainFrame::dispNewArc(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnGraCircle();
      mf->updateActions(cf);
      }

   }

/////////////////////////////////////////////////////////////////////////////
// dispNewPolygon
//
//
void MainFrame::dispNewPolygon(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnGraPolygon();
      mf->updateActions(cf);
      }

   }

/////////////////////////////////////////////////////////////////////////////
// dispNewOrientedRect
//
//
void MainFrame::dispNewOrientedRect(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnGraOrientedRect();
      mf->updateActions(cf);
      }

   }

/////////////////////////////////////////////////////////////////////////////
// dispNewArcThreePoints
//
//
void MainFrame::dispNewArcThreePoints(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnGraArcThreePoints();
      mf->updateActions(cf);
      }

   }

/////////////////////////////////////////////////////////////////////////////
// dispSelectGraphicColor
//
//
void MainFrame::dispSelectGraphicColor(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnGraChooseColor();
      mf->updateActions(cf);
      }
   }

/////////////////////////////////////////////////////////////////////////////
// dispFillGraphic
//
//
void MainFrame::dispFillGraphic(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnGraFill();
      mf->updateActions(cf);
      }

   }

/////////////////////////////////////////////////////////////////////////////
// dispDrawDir
//
//
void MainFrame::dispDrawDir(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->OnDrawDir();
      mf->updateActions(cf);
      }

   }

/////////////////////////////////////////////////////////////////////////////
// dispNoZoom
// 
//
void MainFrame::dispNoZoom(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->NoZoom();
      mf->updateActions(cf);
      }
   }
/////////////////////////////////////////////////////////////////////////////
// dispZoomIn
// 
//
void MainFrame::dispZoomIn(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->ZoomIn();
      mf->updateActions(cf);
      }
   }
/////////////////////////////////////////////////////////////////////////////
// dmilASync
// 
//
void MainFrame::dmilASync(GSimpleAction  *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
       const gchar *name;
       const gchar *value;
       MIL_INT val = M_DISABLE;
       name = g_action_get_name (G_ACTION (action));
       value = g_variant_get_string (parameter, NULL);
       if (value)
          {
          if (!strcmp(value, "1"))
             val = 1;
          else if (!strcmp(value, "5"))
             val = 5;
          else if (!strcmp(value, "10"))
             val = 10;
          else if (!strcmp(value, "15"))
             val = 15;
          else if (!strcmp(value, "30"))
             val = 30;
          else if (!strcmp(value, "maxrate"))
             val = M_INFINITE;
          
          cf->View()->ChangeAsynchronousMode(val!=M_DISABLE, val);
          g_action_change_state (G_ACTION (action), parameter);
          mf->updateActions(cf);
          }
      }
   }
/////////////////////////////////////////////////////////////////////////////
// dmilCompression
// 
//
void MainFrame::dmilCompression(GSimpleAction  *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
       const gchar *name;
       const gchar *value;
       MIL_INT val = M_NULL;
       name = g_action_get_name (G_ACTION (action));
       value = g_variant_get_string (parameter, NULL);
       if (value)
          {
          if (!strcmp(value, "lossy"))
             val = M_JPEG_LOSSY;
          else if (!strcmp(value, "lossless"))
             val = M_JPEG_LOSSLESS;

          cf->View()->ChangeCompressionType(val);
          g_action_change_state (G_ACTION (action), parameter);
          mf->updateActions(cf);
          }
      }
   }
/////////////////////////////////////////////////////////////////////////////
// dmilQFactor
// 
//
void MainFrame::dmilQFactor(GSimpleAction  *action, GVariant *parameter, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
       const gchar *name;
       const gchar *value;
       MIL_INT val =60;
       name = g_action_get_name (G_ACTION (action));
       value = g_variant_get_string (parameter, NULL);
       if (value)
          {
          if (!strcmp(value, "70"))
             val = 70;
          else if (!strcmp(value, "75"))
             val = 75;
          else if (!strcmp(value, "80"))
             val = 80;
          else if (!strcmp(value, "82"))
             val = 82;
          else if (!strcmp(value, "85"))
             val = 85;
          else if (!strcmp(value, "87"))
             val = 87;
          else if (!strcmp(value, "90"))
             val = 90;
          else if (!strcmp(value, "92"))
             val = 92;
          else if (!strcmp(value, "95"))
             val = 92;
          else if (!strcmp(value, "99"))
             val = 99;

          cf->View()->ChangeQFactor(val);
          g_action_change_state (G_ACTION (action), parameter);
          mf->updateActions(cf);
          }
      }
   }
/////////////////////////////////////////////////////////////////////////////
// dispRestrictcursor
// 
//
void MainFrame::dispRestrictCursor(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   if(mf->Update())
      {
      ChildFrame* cf = (ChildFrame*) mf->cf();
      if (cf)
         {
         bool on = g_variant_get_boolean(state);
         cf->View()->RestrictCursor(on);
         mf->updateActions(cf);
         }
      }
   
   g_simple_action_set_state (action, state);
   }

/////////////////////////////////////////////////////////////////////////////
// dispZoomOut
// 
//
void MainFrame::dispZoomOut(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->ZoomOut();
      mf->updateActions(cf);
      }
   }

/////////////////////////////////////////////////////////////////////////////
// dispGrabStart
//
//
void MainFrame::dispGrabStart(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->GrabStart();
      mf->updateActions(cf);
      }
   }

/////////////////////////////////////////////////////////////////////////////
// dispGrabStop
//
//
void MainFrame::dispGrabStop(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   if (cf)
      {
      cf->View()->GrabStop();
      mf->updateActions(cf);
      }

   }

/////////////////////////////////////////////////////////////////////////////
// About
// 
//
void MainFrame::about(GSimpleAction  *action, GVariant *state, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   g_return_if_fail(mf);
   GtkWidget *dialog;
   GtkWidget *milLogo;

   GInputStream *stream = g_resources_open_stream ("/images/about.png", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
   GdkPixbuf *pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
   
   dialog = gtk_dialog_new_with_buttons("MDispGtk",
                                        GTK_WINDOW(mf->m_MainWindow),
                                        GTK_DIALOG_DESTROY_WITH_PARENT,
                                        "_Ok",
                                        GTK_RESPONSE_NONE,
                                        NULL);
   milLogo = gtk_image_new_from_pixbuf(pixbuf);
   gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area (GTK_DIALOG(dialog))),milLogo,true, true,0);
   g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
   gtk_widget_show_all (dialog);
   }


/////////////////////////////////////////////////////////////////////////////
// Ondestroy
// when the window is closed
//
void MainFrame::OnDestroy(GtkWidget *widget, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;
   if(mf)
      {
      for(GList* l = mf->m_ChildList; l != NULL; l = l->next)
         {
         ChildFrame* cf = (ChildFrame *)l->data;
         if(cf)
            {
            cf->Destroy();
            delete cf;
            }
         }
      g_list_free(mf->m_ChildList);
      }
   }
/////////////////////////////////////////////////////////////////////////////
// OnCbViewChanged
// 
//
void MainFrame::OnCbViewChanged(GtkWidget *widget, gpointer user_data)
   {
   MainFrame* mf = (MainFrame *) user_data;   
   g_return_if_fail(mf);
   ChildFrame* cf = (ChildFrame*) mf->cf();
   gint value = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
   if (cf && value < (gint) n_view_mode_entries)
      {
      switch(value)
         {
         case VIEW_MODE_BIT_SHIFT8 :
            cf->View()->ChangeViewMode(M_BIT_SHIFT,9);
            break;
         case VIEW_MODE_BIT_SHIFT4:
            cf->View()->ChangeViewMode(M_BIT_SHIFT,4);
            break;
         case VIEW_MODE_BIT_SHIFT2:
            cf->View()->ChangeViewMode(M_BIT_SHIFT,2);
            break;
         case VIEW_MODE_MULTI_BYTES:
            cf->View()->ChangeViewMode(M_MULTI_BYTES);
            break;
         case VIEW_MODE_AUTO_SCALE:
            cf->View()->ChangeViewMode(M_AUTO_SCALE);
            break;
         case VIEW_MODE_TRANSPARENT:
            cf->View()->ChangeViewMode(M_TRANSPARENT);
            break;
         case VIEW_MODE_DEFAULT:
            cf->View()->ChangeViewMode(M_DEFAULT);
            break;
         }
      mf->updateActions(cf);
      }
   }

/////////////////////////////////////////////////////////////////////////////
// updateActions
// 
//
void MainFrame::updateActions(ChildFrame *cf)
   {
   guint ViewValue;
   if(Quit())
      return;
      
   gtk_widget_set_sensitive(GTK_WIDGET(m_ViewComboBox), cf != NULL);

   setEnable("close",cf != NULL);
   setEnable("save",cf != NULL);
   setEnable("saveas",cf != NULL);
   setEnable("overlay",cf != NULL);
   setEnable("graannotations",cf != NULL);
   setEnable("graannotations",cf != NULL);

   if (cf)
      {
      MdispGtkApp* app = (MdispGtkApp*) dispGtkApp();
      MdispGtkView* view = cf->View();
      setEnable("grabstart",app->m_numberOfDigitizer != 0 && !(app->m_pGrabView && app->m_isGrabStarted));
      setEnable("grabstop", app->m_pGrabView && app->m_isGrabStarted );
      setActive("scale", cf->View()->IsScaleDisplayEnabled() );
      setActive("Overlay",cf->View()->IsOverlayEnabled() );
      setActive("graannotations", cf->View()->IsGraphicsAnnotationsEnabled() );

      setEnable("grarectangle", cf->View()->IsGraphicsAnnotationsEnabled());
      setEnable("graarc", cf->View()->IsGraphicsAnnotationsEnabled());
      setEnable("grapolygon", cf->View()->IsGraphicsAnnotationsEnabled());
      setEnable("graorientedrect", cf->View()->IsGraphicsAnnotationsEnabled());
      setEnable("graarcthreepoints", cf->View()->IsGraphicsAnnotationsEnabled());
      setEnable("graselectcolor", cf->View()->IsGraphicsAnnotationsEnabled());
      setEnable("grafill", cf->View()->IsGraphicsAnnotationsEnabled());
      setEnable("gradrawdir", cf->View()->IsGraphicsAnnotationsEnabled());
       
      if ( view->IsScaleDisplayEnabled() )
         {
         setEnable("nozoom",false);
         setEnable("zoomin",false);
         setEnable("zoomout",false);
         }
      else
         {
         setEnable("zoomin",  cf->View()->CurrentZoomFactorX() < 16.0 );
         setEnable("zoomout", cf->View()->CurrentZoomFactorX() > 1.0/16.0 );
         setEnable("nozoom", true);
         }
      
      setEnable("scale", ( !cf->View()->IsExclusive()));;
      setEnable("restrictcursor", cf->View()->IsExclusive());     
      

      ViewValue = VIEW_MODE_DEFAULT;
      switch(view->CurrentViewMode())
         {
         case M_DEFAULT: 
            ViewValue = VIEW_MODE_DEFAULT;
            break;
         case M_TRANSPARENT: 
            ViewValue = VIEW_MODE_TRANSPARENT;
            break;
         case M_AUTO_SCALE: 
            ViewValue = VIEW_MODE_AUTO_SCALE;
            break;
         case M_MULTI_BYTES:
            ViewValue = VIEW_MODE_MULTI_BYTES;
            break;
         case M_BIT_SHIFT:
            {
            if(view->CurrentShiftValue() == 2)
               ViewValue = VIEW_MODE_BIT_SHIFT2;
            else if(view->CurrentShiftValue() == 4)
               ViewValue = VIEW_MODE_BIT_SHIFT4;
            else if(view->CurrentShiftValue() == 8)
               ViewValue = VIEW_MODE_BIT_SHIFT8;
            }
            break;
         }     
      gtk_combo_box_set_active (GTK_COMBO_BOX(m_ViewComboBox),ViewValue);

      // DMILs menu
      setEnable("dmilasync", view->IsNetworkedSystem());
      setEnable("dmilcompression", view->IsNetworkedSystem());
      setEnable("dmilqfactor", view->IsNetworkedSystem());
      
      if(view->IsNetworkedSystem())
         {
         if(!view->IsInAsynchronousMode())
            setActive("dmilasync","disabled");
         else
            {
            switch(view->AsynchronousFrameRate())
               {
               case 1:
                  setActive("dmilasync","1");
                  break;
               case 5:
                  setActive("dmilasync","5");
                  break;
               case 10:
                  setActive("dmilasync","10");
                  break;
               case 15:
                  setActive("dmilasync","15");
                  break;
               case 30:
                  setActive("dmilasync","30");
                  break;
               case M_INFINITE:
                  setActive("dmilasync","maxrate");
                  break;
               }
            }

         switch(view->CompressionType())
            {
            case M_NULL:
               setActive("dmilcompression","none");
               break;
            case M_JPEG_LOSSY:
               setActive("dmilcompression","lossy");
               break;
            case M_JPEG_LOSSLESS:
               setActive("dmilcompression","lossless");
               break;
            }

         switch(view->QFactor())
            {
            case 60:
               setActive("dmilqfactor","60");
               break;
            case 70:
               setActive("dmilqfactor","70");
               break;
            case 75:
               setActive("dmilqfactor","75");
               break;                
            case 80:
               setActive("dmilqfactor","80");
               break;
            case 82:
               setActive("dmilqfactor","82");
               break;
            case 85:
               setActive("dmilqfactor","85");
               break;                
            case 87:
               setActive("dmilqfactor","87");
               break;
            case 90:
               setActive("dmilqfactor","90");
               break;
            case 92:
               setActive("dmilqfactor","92");
               break;       
            case 95:
               setActive("dmilqfactor","95");
               break;
            case 99:
               setActive("dmilqfactor","99");
               break;
            }
         }
      }
   else
      {
      setEnable("new",true);
      setEnable("open",true);
      setEnable("save",false);
      setEnable("close",false);
      setEnable("saveas",false);
      setEnable("grabstart",false);
      setEnable("grabstop",false);
      setEnable("overlay",false);
      setEnable("graannotations",false);
      setEnable("zoomin",false);
      setEnable("nozoom",false);
      setEnable("zoomout",false);
      setEnable("scale",false);
      setEnable("grarectangle", false);
      setEnable("graarc", false);
      setEnable("grapolygon", false);
      setEnable("graorientedrect", false);
      setEnable("graarcthreepoints", false);
      setEnable("graselectcolor", false);
      setEnable("grafill", false);
      setEnable("gradrawdir", false);
      setEnable("dmilasync", false);
      setEnable("dmilcompression", false);
      setEnable("dmilqfactor", false);
      setEnable("restrictcursor", false);
      }
   }