home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / g / gina15.zip / demos / addr.C < prev    next >
C/C++ Source or Header  |  1992-02-27  |  14KB  |  502 lines

  1. /* @(#)addr.C    1.8 7/29/91 */
  2.  
  3. #include <Gina/Gina.h>
  4.  
  5. #ifdef INCLUDE_SRC
  6. #include "Gina.C"
  7. #include "AddressView.C"
  8. #endif
  9.  
  10. #include "KeySortCltn.h"
  11. #include "ArrayOb.h"
  12. #include "Assoc.h"
  13. #include "OIOnih.h"
  14. #include "Integer.h"
  15.  
  16. #include "Address.h"
  17. #include "AddressView.h"
  18.  
  19. class AddressesApplication : public GnApplication {
  20.   public:
  21.     GnDocument *create_document ();
  22.  
  23.     char * app_class () { return "Addresses" ; }
  24.     char * app_signature() { return "addresses" ; }
  25.     char * app_file_type() { return ".addresses" ; }
  26. };
  27.  
  28.  
  29. class AddressesDocument : public GnDocument {
  30.   public:
  31.     AddressesDocument();
  32.  
  33.     virtual void create_windows(int new_width = 0, int new_height = 0);
  34.     virtual void wipe_out();
  35.  
  36.     // Methods
  37.     void AddAddress(Address *);
  38.     void RemoveAddress(Address *);
  39.     void UpdatePosition(Address *);
  40.     void InitializeCollections();
  41.     
  42.     // Callbacks (Menu Bar)
  43.     void DumpAddresses(caddr_t);
  44.     void AddOwnAddress(caddr_t);
  45.     void AddHundred(caddr_t);
  46.     void ListSorted(caddr_t);
  47.  
  48.     // Callbacks (AddressView)
  49.     void AddFromView(caddr_t);
  50.  
  51.     // Callbacks (Panel)
  52.     void ModeChanged(caddr_t);
  53.     void SortChanged(caddr_t);
  54.     void MoveNext(caddr_t);
  55.     void MovePrevious(caddr_t);
  56.     
  57.   protected:
  58.     void UpdateButtons();
  59.     
  60.     // Document IO
  61.     virtual Boolean write_to_stream ( ostream & );
  62.     virtual Boolean read_from_stream ( istream & );
  63.  
  64.     // Data structures for the addresses
  65.     KeySortCltn *sort_by_name;
  66.     KeySortCltn *sort_by_city;
  67.     KeySortCltn *sort_by_street;
  68.     KeySortCltn *all_addresses;
  69.     KeySortCltn *current_collection;
  70.  
  71.     ArrayOb    *all_collections; // Needed for efficient Save/Restore
  72.     int current_position;
  73.  
  74.     // Widgets
  75.     AddressView       address_view;
  76.     GnRowColumn        panel;
  77.     GnRadioButtonGroup mode_group;
  78.     GnRadioButtonGroup sort_group;
  79.     GnPushButton       go_next;
  80.     GnPushButton       go_previous;
  81.     GnScrollBar        db_scroller;
  82.  
  83.     // Items
  84.     GnWidgetItem *mode_item_add;
  85.     GnWidgetItem *mode_item_change;
  86.     GnWidgetItem *mode_item_browse;
  87.  
  88.     GnWidgetItem *sort_item_unsorted;
  89.     GnWidgetItem *sort_item_name;
  90.     GnWidgetItem *sort_item_city;
  91.     GnWidgetItem *sort_item_street;
  92.  
  93.     // Modes
  94.     GnWidgetItem *view_mode;
  95. };
  96.  
  97. //---------------------------------------------------------------------
  98.  
  99. GnDocument *AddressesApplication ::
  100. create_document ()
  101. {
  102.     return new AddressesDocument;
  103. }
  104.  
  105. AddressesDocument::AddressesDocument()
  106. {
  107.     all_collections = new ArrayOb(5);
  108.     (*all_collections)[0]  = new KeySortCltn;
  109.     (*all_collections)[1]  = new KeySortCltn;
  110.     (*all_collections)[2]  = new KeySortCltn;
  111.     (*all_collections)[3]  = new KeySortCltn;
  112.     (*all_collections)[4]  = (*all_collections)[3];
  113.     InitializeCollections();
  114. }
  115.  
  116. void AddressesDocument::
  117. InitializeCollections()
  118. {
  119.     sort_by_name       = (KeySortCltn *)(*all_collections)[0];
  120.     sort_by_city       = (KeySortCltn *)(*all_collections)[1];
  121.     sort_by_street     = (KeySortCltn *)(*all_collections)[2];
  122.     all_addresses      = (KeySortCltn *)(*all_collections)[3];
  123.     current_collection = (KeySortCltn *)(*all_collections)[4];
  124.     current_position   = current_collection->size() > 0 ? 0 : -1;
  125.     
  126. }
  127.  
  128. void AddressesDocument ::
  129. create_windows(int new_width, int new_height)
  130. {
  131.     main_shell = new GnDocumentShell( this, new_width, new_height);
  132.     main_shell->create(GnApplication::get()->get_application_shell(), "shell");
  133.  
  134.     main_shell->add_menu_command("Testing", "Dump (cout)",
  135.                  CALLBACK(AddressesDocument, DumpAddresses,
  136.                       this));
  137.     
  138.     main_shell->add_menu_command("Testing", "Add own address",
  139.                  CALLBACK(AddressesDocument, AddOwnAddress,
  140.                       this));
  141.     
  142.     main_shell->add_menu_command("Testing", "Add 100 address",
  143.                  CALLBACK(AddressesDocument, AddHundred,
  144.                       this));
  145.     
  146.     main_shell->add_menu_command("Testing", "List (sorted)",
  147.                  CALLBACK(AddressesDocument, ListSorted,
  148.                       this));
  149.  
  150.     GnForm *main_form = new GnForm;
  151.     main_form->create(main_shell, "mainForm");
  152.     
  153.     address_view.setR_leftAttachment(XmATTACH_FORM);
  154.     address_view.setR_topAttachment(XmATTACH_FORM);
  155.     address_view.setR_editable(True);
  156.     address_view.create(main_form, "addressView");
  157.     address_view.add_value_changed_callback(CALLBACK(AddressesDocument,
  158.                              AddFromView, this));
  159.  
  160.     GnSeparator *form_separator = new GnSeparator;
  161.     form_separator->setR_orientation(XmVERTICAL);
  162.     form_separator->setR_topAttachment(XmATTACH_FORM);
  163.     form_separator->setR_bottomAttachment(XmATTACH_FORM);
  164.     form_separator->setR_leftAttachment(XmATTACH_WIDGET);
  165.     form_separator->setR_leftWidget(&address_view);
  166.     form_separator->create(main_form, "formSeparator");
  167.     
  168.     panel.setR_topAttachment(XmATTACH_FORM);
  169.     panel.setR_leftAttachment(XmATTACH_WIDGET);
  170.     panel.setR_leftWidget(form_separator);
  171.     panel.create(main_form, "panel");
  172.  
  173.     mode_item_add    = new GnWidgetItem(GnXMSTRING_LTOR("Add"), True);
  174.     mode_item_change = new GnWidgetItem(GnXMSTRING_LTOR("Change"));
  175.     mode_item_browse = new GnWidgetItem(GnXMSTRING_LTOR("Browse"));
  176.  
  177.     mode_group.add(mode_item_add);
  178.     mode_group.add(mode_item_change);
  179.     mode_group.add(mode_item_browse);
  180.     mode_group.setR_orientation(XmVERTICAL);
  181.     mode_group.create(&panel, "modeGroup");
  182.     mode_group.add_selectionCallback(CALLBACK(AddressesDocument,
  183.                           ModeChanged, this));
  184.     view_mode = mode_item_add;
  185.     
  186.     GnSeparator *sep1 = new GnSeparator;
  187.     sep1->setR_orientation(XmHORIZONTAL);
  188.     sep1->create(&panel, "sep1");
  189.  
  190.     sort_item_unsorted = new GnWidgetItem(GnXMSTRING_LTOR("Unsorted"));
  191.     sort_item_name     = new GnWidgetItem(GnXMSTRING_LTOR("Sort by Name"));
  192.     sort_item_city     = new GnWidgetItem(GnXMSTRING_LTOR("Sort by City"));
  193.     sort_item_street   = new GnWidgetItem(GnXMSTRING_LTOR("Sort by Street"));
  194.  
  195.     sort_group.add(sort_item_unsorted);
  196.     sort_group.add(sort_item_name);
  197.     sort_group.add(sort_item_city);
  198.     sort_group.add(sort_item_street);
  199.     sort_group.setR_orientation(XmVERTICAL);
  200.     sort_group.create(&panel, "sortGroup");
  201.     sort_group.add_selectionCallback(CALLBACK(AddressesDocument,
  202.                           SortChanged, this));
  203.     GnSeparator *sep2 = new GnSeparator;
  204.     sep2->setR_orientation(XmHORIZONTAL);
  205.     sep2->create(&panel, "sep2");
  206.  
  207.     go_previous.setR_labelString("Previous");
  208.     go_previous.setR_alignment(XmALIGNMENT_CENTER);
  209.     go_previous.create(&panel, "goPrevious");
  210.     go_previous.add_activateCallback(CALLBACK(AddressesDocument,
  211.                            MovePrevious, this));
  212.     go_next.setR_labelString("Next");
  213.     go_next.setR_alignment(XmALIGNMENT_CENTER);
  214.     go_next.create(&panel, "goNext");
  215.     go_next.add_activateCallback(CALLBACK(AddressesDocument,
  216.                        MoveNext, this));
  217.     db_scroller.setR_orientation(XmHORIZONTAL);
  218.     db_scroller.setR_minimum(0);
  219.     db_scroller.setR_maximum(1);
  220.     db_scroller.setR_sliderSize(1);
  221.     db_scroller.setR_value(0);
  222.     db_scroller.create(&panel, "dbScroller");
  223.     
  224.     UpdateButtons();
  225. }
  226.  
  227. void AddressesDocument::
  228. AddAddress(Address *a)
  229. {
  230.     Object *i_key = a->KeyNumber();
  231.     Object *n_key = a->LastName();
  232.     Object *c_key = a->CityCode();
  233.     Object *s_key = a->Street();
  234.     
  235.     all_addresses->addAssoc(*i_key, *a);
  236.     sort_by_name->addAssoc(*n_key, *a);
  237.     sort_by_city->addAssoc(*c_key, *a);
  238.     sort_by_street->addAssoc(*s_key, *a);
  239.  
  240.     UpdatePosition(a);
  241.     UpdateButtons();
  242.     set_modified(True);
  243. }
  244.  
  245. void AddressesDocument::
  246. RemoveAddress(Address *a)
  247. {
  248. }
  249.  
  250. void AddressesDocument::
  251. UpdatePosition(Address *a)
  252. {
  253.     if( current_collection == all_addresses ) 
  254.     current_position = current_collection->findIndexOf(*a->KeyNumber());
  255.     else
  256.     if( current_collection == sort_by_name )
  257.         current_position = current_collection->findIndexOf(*a->LastName());
  258.     else
  259.         if( current_collection == sort_by_city )
  260.         current_position = current_collection->findIndexOf(*a->City());
  261.         else
  262.         if( current_collection == sort_by_street )
  263.             current_position =
  264.             current_collection->findIndexOf(*a->Street());
  265.         else
  266.            Ensure(False);
  267. }
  268.  
  269. void AddressesDocument::
  270. UpdateButtons()
  271. {
  272.     if( view_mode == mode_item_browse || view_mode == mode_item_change ) {
  273.     go_previous.setR_sensitive(current_position <= 0 ? False : True);
  274.     if(current_position == (current_collection->size() - 1))
  275.         go_next.setR_sensitive(False);
  276.     else
  277.         go_next.setR_sensitive(True);
  278.     } else {
  279.     go_previous.setR_sensitive(False);
  280.     go_next.setR_sensitive(False);
  281.     }
  282.     go_next.SetValues();
  283.     go_previous.SetValues();
  284.     db_scroller.setR_maximum(MAX((int)current_collection->size(), (int)1));
  285.     db_scroller.setR_value(current_position == -1 ? 0 : current_position);
  286.     db_scroller.SetValues();
  287. }
  288.  
  289. void AddressesDocument::
  290. ModeChanged(caddr_t call_data)
  291. {
  292.     GnWidgetItemListIterator *it = (GnWidgetItemListIterator *)call_data;
  293.  
  294.     Require((void *)it->item()->Value() == (void *)it->item());
  295.  
  296.     GnWidgetItem *new_view_mode = it->item();
  297.     
  298.     if( view_mode != new_view_mode ) {
  299.     if( new_view_mode == mode_item_browse ) {
  300.         if( view_mode == mode_item_add &&
  301.            current_collection->size() > 0 ) {
  302.         address_view.Show((Address *)current_collection
  303.                   ->valueAt(current_position));
  304.         }
  305.         address_view.setR_editable(False);
  306.         address_view.SetValues();
  307.     }
  308.     if( new_view_mode == mode_item_change ) {
  309.         if( view_mode == mode_item_add &&
  310.            current_collection->size() > 0 ) {
  311.         address_view.Show((Address *)current_collection
  312.                   ->valueAt(current_position));
  313.         }
  314.         address_view.setR_editable(True);
  315.         address_view.SetValues();
  316.     }
  317.     if( new_view_mode == mode_item_add ) {
  318.         address_view.Show(0);
  319.         address_view.setR_editable(True);
  320.         address_view.SetValues();
  321.     }
  322.  
  323.     view_mode = new_view_mode;
  324.     UpdateButtons();
  325.     }
  326. }
  327.  
  328. void AddressesDocument::
  329. SortChanged(caddr_t call_data)
  330. {
  331.     GnWidgetItemListIterator *it = (GnWidgetItemListIterator *)call_data;
  332.  
  333.     Require((void *)it->item()->Value() == (void *)it->item());
  334.  
  335.     GnWidgetItem *sel = it->item();
  336.     Address *obj_at;
  337.  
  338.     // Take care if sort mode is changed when the database is empty
  339.  
  340.     if( current_position >= 0 )
  341.     obj_at = (Address *)current_collection->valueAt(current_position);
  342.  
  343.     // Find the new current collection
  344.     
  345.     if( sel == sort_item_unsorted ) {
  346.     current_collection = all_addresses;
  347.     } else {
  348.     if( sel == sort_item_name ) {
  349.         current_collection = sort_by_name;
  350.     } else {
  351.         if( sel == sort_item_city ) {
  352.         current_collection = sort_by_city;
  353.         } else {
  354.         if( sel == sort_item_street ) {
  355.             current_collection = sort_by_street;
  356.         } else {
  357.             Ensure(False);
  358.         }
  359.         }
  360.     }
  361.     }
  362.  
  363.     (*all_collections)[4] = current_collection;
  364.  
  365.     if( current_position >= 0 )
  366.     UpdatePosition(obj_at);
  367.     
  368.     UpdateButtons();
  369. }
  370.  
  371. void AddressesDocument::
  372. MoveNext(caddr_t)
  373. {
  374.     current_position++;
  375.     
  376.     address_view.Show((Address *)current_collection->valueAt(current_position));
  377.     UpdateButtons();
  378. }
  379.  
  380. void AddressesDocument::
  381. MovePrevious(caddr_t)
  382. {
  383.     current_position--;
  384.     
  385.     address_view.Show((Address *)current_collection->valueAt(current_position));
  386.     UpdateButtons();
  387. }
  388.  
  389. void AddressesDocument::
  390. DumpAddresses(caddr_t)
  391. {
  392.     all_collections->dumpOn(cout);
  393.     cout.flush();
  394. }
  395.  
  396. void AddressesDocument::
  397. AddOwnAddress(caddr_t)
  398. {
  399.     if( view_mode == mode_item_add ) {
  400.     Address *a = new Address(new String("Baecker"), new String("Andreas"),
  401.                  new String("Goethealle"),  new String("64"),
  402.                  new String("Germany"), new String("5300"),
  403.                  new String("Bonn"),  new String("3"),
  404.                  new String("+49-0228-460901"),
  405.                  new String("baecker@gmdzi.gmd.de"),
  406.                  new Date(), new Date(),
  407.                  new Integer(current_collection->size()),
  408.                  False);
  409.     Address *b = new Address(new String("Hornef"),
  410.                  new String("Beatrix Mechthild Maria"),
  411.                  new String("Saynstrasse"),  new String("3"),
  412.                  new String("Germany"), new String("5300"),
  413.                  new String("Bonn"),  new String("3"),
  414.                  new String("+49-0228-484299"),
  415.                  new String("bea@gmdzi.gmd.de"),
  416.                  new Date(), new Date(), 
  417.                  new Integer(current_collection->size()),
  418.                  False);
  419.     AddAddress(b);
  420.     AddAddress(a);
  421.     }
  422. }
  423.  
  424. void AddressesDocument::
  425. AddHundred(caddr_t)
  426. {
  427.     if( view_mode == mode_item_add )
  428.     for( int i = 0; i < 50; i++)
  429.         AddOwnAddress((caddr_t) 0);
  430. }
  431.  
  432. void AddressesDocument::
  433. ListSorted(caddr_t)
  434. {
  435.     Iterator it(*current_collection);
  436.     while( it++ ) {
  437.     ((Assoc *)it())->value()->dumpOn(cout);
  438.     cout.flush();
  439.     }
  440. }
  441.  
  442. void AddressesDocument::
  443. AddFromView(caddr_t call_data)
  444. {
  445.     Address *a = (Address *)call_data;
  446.  
  447.     if( view_mode == mode_item_change ) {
  448.     // Remove address at current Position
  449.     RemoveAddress((Address *)current_collection->valueAt(current_position));
  450.     }
  451.     AddAddress(a);
  452.     if(view_mode == mode_item_add)
  453.     address_view.Show(0);
  454. }
  455.  
  456. void AddressesDocument::
  457. wipe_out()
  458. {
  459. }
  460.  
  461. Boolean AddressesDocument ::
  462. write_to_stream( ostream &ofs )
  463. {
  464.     all_collections->storeOn(OIOnihout(ofs));
  465.     return True;
  466. }
  467.  
  468. Boolean AddressesDocument ::
  469. read_from_stream ( istream &ifs )
  470. {
  471.     delete sort_by_name;
  472.     delete sort_by_city;
  473.     delete sort_by_street;
  474.     delete all_addresses;
  475.     delete all_collections;
  476.     
  477.     all_collections = ArrayOb::readFrom(OIOnihin(ifs));
  478.     InitializeCollections();
  479.  
  480.     //all_collections->dumpOn(cout);
  481.     cout.flush();
  482.     
  483.     if(current_collection->size() > 0) {
  484.     mode_item_browse->Selected(True);
  485.     view_mode = mode_item_browse;
  486.     address_view.setR_editable(False);
  487.     address_view.SetValues();
  488.     //current_collection->valueAt(current_position)->dumpOn(cout);
  489.     //cout.flush();
  490.     address_view.Show((Address *)current_collection->valueAt(current_position));
  491.     }
  492.     UpdateButtons();
  493.     return ifs.fail() ? False : True;
  494. }
  495.  
  496. int main (unsigned int argc, char ** argv)
  497. {
  498.     AddressesApplication aa;
  499.  
  500.     aa.run ( argc, argv );
  501. }
  502.