Ignore:
Timestamp:
Jan 20, 2011, 9:32:28 AM (14 years ago)
Author:
Sam Habiel
Message:

calendarGrid: Removed MouseEnter event and added it to CGView which now has to handle it properly.
CGAppointments: now supports cloning.
CGDocument: Added RefreshDocumentAsync, which retrives data from the server w/o asking the grid to refersh.
CGDocumentManager: CGView.InitializeDocView does not take appointments as argument; callers are changed.
CGView: Many Changes:

  • Opening a Schedule nows calls up a splash and a wait cursor while loading.
  • Events coming from the server are now handled asynchronously (not on UI thread). This results in much better responsiveness.
  • Appointments, Availabilities, Resources are all set in the CalendarGrid by UpdateArrays; as a centralized point of drawing the grid.
  • A mistaken "feature"--stealing focus from each others windows, was removed--CalendarGrid.Focus event only fired now if the form is the Active Form. This is accomplished using GetActiveWindow() from user32.dll (a Win32 API).

LoadingSplash: Opacity removed; form resized.

Location:
Scheduling/trunk/cs/bsdx0200GUISourceCode
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • Scheduling/trunk/cs/bsdx0200GUISourceCode/CGAppointments.cs

    r622 r1073  
    88    /// </summary>
    99    [Serializable]
    10     public class CGAppointments : IEnumerable
     10    public class CGAppointments : IEnumerable, ICloneable
    1111    {
    1212        private Hashtable apptList = new Hashtable();
     
    5656            }
    5757        }
     58
     59        //smh test
     60        //one problem: Hashtable is a shallow copy.
     61        //so it shouldn't work. But let's see.
     62        public object Clone()
     63        {
     64            CGAppointments appts = new CGAppointments();
     65            appts.apptList = (Hashtable)apptList.Clone();
     66            return appts;
     67        }
    5868    }
    5969}
  • Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocument.cs

    r1071 r1073  
    270270        }
    271271
    272 
    273         public void RefreshDocument()
     272        //sam: This is a test that duplicates RefreshDocument, but without the UpdateAllViews,
     273        // as that has to be done synchornously.
     274        //XXXXXX: Needs to be refactored obviously, but now for testing.
     275        public void RefreshDocumentAsync()
    274276        {
    275277            bool bRet = false;
     
    290292
    291293            bRet = RefreshSchedule();
     294        }
     295
     296       
     297        public void RefreshDocument()
     298        {
     299            bool bRet = false;
     300            if (m_sResourcesArray.Count == 0)
     301                return;
     302            if (m_sResourcesArray.Count == 1)
     303            {
     304                bRet = this.WeekNeedsRefresh(1, m_dSelectedDate, out this.m_dStartDate, out this.m_dEndDate);
     305            }
     306            else
     307            {
     308                this.m_dStartDate = m_dSelectedDate;
     309                this.m_dEndDate = m_dSelectedDate;
     310                this.m_dEndDate = this.m_dEndDate.AddHours(23);
     311                this.m_dEndDate = this.m_dEndDate.AddMinutes(59);
     312                this.m_dEndDate = this.m_dEndDate.AddSeconds(59);
     313            }
     314
     315            bRet = RefreshSchedule();
     316           
    292317            this.UpdateAllViews();
    293318        }
     
    344369                        this.DocManager,
    345370                        m_dStartDate,
    346                         this.Appointments,
    347371                        this.DocName);
    348372
  • Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs

    r1071 r1073  
    207207            //A view is a specific arrangement of appointments and availabilites that constitute a document
    208208            CGView view = new CGView();
    209             view.InitializeDocView(doc, _current, doc.StartDate, doc.Appointments, _current.WindowText);
     209            view.InitializeDocView(doc, _current, doc.StartDate, _current.WindowText);
    210210
    211211            //Handle BMX Event
     
    10681068
    10691069                CGView view = new CGView();
    1070                 view.InitializeDocView(doc, _current, doc.StartDate, doc.Appointments, _current.WindowText);
     1070                view.InitializeDocView(doc, _current, doc.StartDate, _current.WindowText);
    10711071
    10721072                view.Show();
     
    11171117
    11181118                CGView view = new CGView();
    1119                 view.InitializeDocView(doc, _current, doc.StartDate, doc.Appointments, _current.WindowText);
     1119                view.InitializeDocView(doc, _current, doc.StartDate, _current.WindowText);
    11201120
    11211121                view.Show();
  • Scheduling/trunk/cs/bsdx0200GUISourceCode/CGView.cs

    r1071 r1073  
    88using System.Threading;
    99using IndianHealthService.BMXNet;
    10 
     10using System.Runtime.InteropServices;
    1111
    1212namespace IndianHealthService.ClinicalScheduling
     
    128128                        CGDocumentManager docMgr,
    129129                        DateTime dStartDate,
    130                         CGAppointments cgAppts,
    131130                        string sText)
    132131                {
     
    135134                        this.StartDate = dStartDate;
    136135                        this.Document = doc;
    137                         this.Appointments = cgAppts;
    138                        
     136           
     137            //Rather strangely, this line is needed for God knows Why...
     138            //Without it, the Grid tries to draw appointments, but can't.
     139            //Making a constructor in the Calendar Grid itself didn't work. Don't know why.
     140            //XXX: For later investigation.
     141            this.Appointments = new CGAppointments();
     142           
     143
    139144            // Set username and division up top
    140145            this.Text = this.DocManager.ConnectInfo.UserName;
     
    150155
    151156                private BMXNetConnectInfo.BMXNetEventDelegate m_bmxDelegate;
    152                 delegate void OnUpdateScheduleDelegate();
    153 
    154                 private void BMXNetEventHandler(Object obj, BMXNet.BMXNetEventArgs e)
    155                 {
    156                         try
    157                         {
    158                                 if (e.BMXEvent == "BMXNet AutoFire")
    159                                 {
    160                                         Debug.Write("CGView caught AutoFire event.\n");
    161                                         if (this == null)
    162                                                 return;
    163                                         OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
    164                                         this.BeginInvoke(ousd);
    165                                         return;
    166                                 }
    167 
    168                                 if (e.BMXEvent != "BSDX SCHEDULE")
    169                                 {
    170                                         return;
    171                                 }
    172                                 string sResourceName;
    173                                 for (int j=0; j < m_Document.m_sResourcesArray.Count; j++)
    174                                 {
    175                                         sResourceName = m_Document.m_sResourcesArray[j].ToString();
    176                                         if (e.BMXParam == sResourceName)
    177                                         {
    178                                                 OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
    179                                                 if (this == null)
    180                                                         return;
    181                                                 this.BeginInvoke(ousd);
    182                                                 Debug.Write("CGView caught BSDX SCHEDULE event.\n");
    183                                                 break;
    184                                         }
    185                                 }
    186                         }
    187                         catch (Exception ex)
    188                         {
    189                                 Debug.Write(ex.Message);
    190                         }
    191         }
     157               
    192158
    193159        #endregion initialization
     
    651617            this.tvSchedules.Location = new System.Drawing.Point(0, 0);
    652618            this.tvSchedules.Name = "tvSchedules";
    653             this.tvSchedules.Size = new System.Drawing.Size(128, 437);
     619            this.tvSchedules.Size = new System.Drawing.Size(128, 395);
    654620            this.tvSchedules.Sorted = true;
    655621            this.tvSchedules.TabIndex = 1;
     
    698664            this.panelRight.Location = new System.Drawing.Point(941, 0);
    699665            this.panelRight.Name = "panelRight";
    700             this.panelRight.Size = new System.Drawing.Size(128, 437);
     666            this.panelRight.Size = new System.Drawing.Size(128, 395);
    701667            this.panelRight.TabIndex = 3;
    702668            this.panelRight.Visible = false;
     
    796762            this.panelCenter.Location = new System.Drawing.Point(136, 24);
    797763            this.panelCenter.Name = "panelCenter";
    798             this.panelCenter.Size = new System.Drawing.Size(802, 389);
     764            this.panelCenter.Size = new System.Drawing.Size(802, 347);
    799765            this.panelCenter.TabIndex = 7;
    800766            //
     
    818784            this.calendarGrid1.Resources = ((System.Collections.ArrayList)(resources.GetObject("calendarGrid1.Resources")));
    819785            this.calendarGrid1.SelectedAppointment = 0;
    820             this.calendarGrid1.Size = new System.Drawing.Size(802, 389);
     786            this.calendarGrid1.Size = new System.Drawing.Size(802, 347);
    821787            this.calendarGrid1.StartDate = new System.DateTime(2003, 1, 27, 0, 0, 0, 0);
    822788            this.calendarGrid1.TabIndex = 0;
     
    826792            this.calendarGrid1.CGSelectionChanged += new IndianHealthService.ClinicalScheduling.CalendarGrid.CGSelectionChangedHandler(this.calendarGrid1_CGSelectionChanged);
    827793            this.calendarGrid1.DoubleClick += new System.EventHandler(this.calendarGrid1_DoubleClick);
     794            this.calendarGrid1.MouseEnter += new System.EventHandler(this.calendarGrid1_MouseEnter);
    828795            //
    829796            // ctxCalendarGrid
     
    910877            this.panelBottom.Controls.Add(this.statusBar1);
    911878            this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
    912             this.panelBottom.Location = new System.Drawing.Point(136, 413);
     879            this.panelBottom.Location = new System.Drawing.Point(136, 371);
    913880            this.panelBottom.Name = "panelBottom";
    914881            this.panelBottom.Size = new System.Drawing.Size(802, 24);
     
    928895            this.splitter1.Location = new System.Drawing.Point(128, 24);
    929896            this.splitter1.Name = "splitter1";
    930             this.splitter1.Size = new System.Drawing.Size(8, 413);
     897            this.splitter1.Size = new System.Drawing.Size(8, 371);
    931898            this.splitter1.TabIndex = 9;
    932899            this.splitter1.TabStop = false;
     
    937904            this.splitter2.Location = new System.Drawing.Point(938, 24);
    938905            this.splitter2.Name = "splitter2";
    939             this.splitter2.Size = new System.Drawing.Size(3, 413);
     906            this.splitter2.Size = new System.Drawing.Size(3, 371);
    940907            this.splitter2.TabIndex = 10;
    941908            this.splitter2.TabStop = false;
     
    949916            //
    950917            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
    951             this.ClientSize = new System.Drawing.Size(1069, 437);
     918            this.ClientSize = new System.Drawing.Size(1069, 395);
    952919            this.Controls.Add(this.panelCenter);
    953920            this.Controls.Add(this.panelBottom);
     
    10601027
    10611028                #endregion
     1029
    10621030
    10631031                #region AppointmentMenu Handlers
     
    15121480                        }
    15131481
    1514                         //If this Document has no resources then use it (happens when the GUI has nothing open, typically after log-in)
     1482            //So if it is not a view that's already open, it means we have to grab the data for
     1483            //So we tell the user to wait wait wait
     1484            this.Cursor = Cursors.WaitCursor;
     1485            this.LoadSplash();  //Open "Loading" splash
     1486           
     1487           
     1488            //If this Document has no resources then use it (happens when the GUI has nothing open, typically after log-in)
    15151489                        //Else, create a new document
    15161490            CGDocument doc;
     
    15481522                        v =this.DocManager.GetViewByResource(sSelectedTreeResourceArray);
    15491523                       
    1550             //Position the Grid
     1524            //Position the Grid to start at a certain day.
    15511525            //XXX: This must be a better way to do this.
    15521526            v.dateTimePicker1.Value = dDate;
     
    16281602                        v.calendarGrid1.SetOverlapTable();
    16291603                        v.calendarGrid1.Refresh();
     1604
     1605            // Set cursor back and stop splash screen
     1606            this.Cursor = Cursors.Default;
     1607            StopSplash();
    16301608                }
    16311609
     
    22242202                }
    22252203
     2204        #region BMX Event Processing and Callbacks
     2205        /// <summary>
     2206        /// Loosely typed delegate used several times below.
     2207        /// </summary>
     2208        delegate void OnUpdateScheduleDelegate();
     2209       
     2210        /// <summary>
     2211        /// Subscription point for each CGView to process BMX events polled from the server
     2212        /// </summary>
     2213        /// <param name="obj">Not used</param>
     2214        /// <param name="e">BMXEvent Args:
     2215        /// e.BMXEvent is free text for Event Type; e.BMXParam is free text for Event Arguments</param>
     2216        private void BMXNetEventHandler(Object obj, BMXNet.BMXNetEventArgs e)
     2217        {
     2218            try
     2219            {
     2220                // if this class is undefined (e.g. if the user just closed the form, do nothing
     2221                if (this == null) return;
     2222
     2223                // if event is Autofire event
     2224                if (e.BMXEvent == "BMXNet AutoFire")
     2225                {
     2226                    Debug.Write("CGView caught AutoFire event.\n");
     2227                   
     2228                    //Create a delegate to OnUpdateSchedule and call Async
     2229                    //Once Async Call is done, go to OnUpdateScheduleCallback
     2230                    OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
     2231                    ousd.BeginInvoke(OnUpdateScheduleCallback, null);
     2232
     2233                    return;
     2234                }
     2235
     2236                // if event is BSDX SCHEDULE
     2237                else if (e.BMXEvent == "BSDX SCHEDULE")
     2238                {
     2239                    //See if any of the resources in the event argument matches BSDX Schedule.
     2240                    //If yes, fire off the delegate
     2241                    string sResourceName;
     2242                    for (int j = 0; j < m_Document.m_sResourcesArray.Count; j++)
     2243                    {
     2244                        sResourceName = m_Document.m_sResourcesArray[j].ToString();
     2245                        if (e.BMXParam == sResourceName)
     2246                        {
     2247                            Debug.Write("CGView caught BSDX SCHEDULE event.\n");
     2248
     2249                            //Create a delegate to OnUpdateSchedule and call Async
     2250                            //Once Async Call is done, go to OnUpdateScheduleCallb
     2251                            OnUpdateScheduleDelegate ousd = new OnUpdateScheduleDelegate(OnUpdateSchedule);
     2252                            ousd.BeginInvoke(OnUpdateScheduleCallback, null);
     2253                           
     2254                            break;
     2255                        }
     2256                    }
     2257                }
     2258            }
     2259            catch (Exception ex)
     2260            {
     2261                Debug.Write(ex.Message);
     2262            }
     2263        }
     2264
     2265        /// <summary>
     2266        /// Update Appointments and Availabilites using Document.RefreshDocumentAsync on a different thread
     2267        /// </summary>
     2268        /// <remarks>
     2269        /// This method is expected to be called asynchornously.
     2270        /// </remarks>
    22262271                public void OnUpdateSchedule()
    22272272                {
    22282273                        try
    22292274                        {
    2230                                 this.Cursor = Cursors.WaitCursor;
    2231                                 m_Document.RefreshDocument();
     2275                                m_Document.RefreshDocumentAsync(); //new
    22322276                        }
    22332277                        catch (Exception ex)
     
    22352279                                MessageBox.Show("Unable to refresh document " +  ex.Message, "Clinical Scheduling");
    22362280                        }
    2237                         finally
    2238                         {
    2239                                 this.Cursor = Cursors.Default;
    2240                         }
    2241                 }
     2281                }
     2282
     2283        /// <summary>
     2284        /// Callback for when OnUpdateSchedule is done. Triggers the Grid to redraw itself by calling UpdateArrays.
     2285        /// </summary>
     2286        /// <param name="itfAR">not used</param>
     2287        /// <remarks>Calls UpdateArrays via this.Invoke to make sure that the grid is redrawn on the UI thread</remarks>
     2288        private void OnUpdateScheduleCallback(IAsyncResult itfAR)
     2289        {
     2290            OnUpdateScheduleDelegate d = new OnUpdateScheduleDelegate(UpdateArrays);
     2291            this.Invoke(d);
     2292        }
     2293
     2294        /// <summary>
     2295        /// Create a new event in RPMS. Wrapper around BMXConnectInfo.RaiseEvent
     2296        /// </summary>
     2297        /// <param name="sEvent">Name of Event to Raise</param>
     2298        /// <param name="sParams">Parameter of Event to Raise</param>
     2299        public void RaiseRPMSEvent(string sEvent, string sParams)
     2300        {
     2301            try
     2302            {
     2303                //Signal RPMS to raise an event
     2304                m_ConnectInfo.RaiseEvent(sEvent, sParams, true);
     2305            }
     2306            catch (Exception ex)
     2307            {
     2308                Debug.Write(ex.Message);
     2309            }
     2310        }
     2311
     2312        #endregion
    22422313
    22432314        /// <summary>
     
    22512322                        try
    22522323                        {
    2253                                 this.calendarGrid1.AvailabilityArray = this.m_Document.AvailabilityArray;
     2324                //Tell the grid about Avails, Appts, and Resources.
     2325                this.calendarGrid1.AvailabilityArray = this.m_Document.AvailabilityArray;
     2326                //Appts are cloned b/c if we tie into  the class directly, we shoot off errors when we manipulate it.
     2327                this.calendarGrid1.Appointments = (CGAppointments)this.m_Document.Appointments.Clone(); //smh new line again
    22542328                                this.calendarGrid1.Resources = this.m_Document.Resources;
    2255                 // this.calendarGrid1.Columns = 7; //test
    2256                 // this.calendarGrid1.StartDate = DateTime.Parse("10-10-2007"); // another test
     2329                //Redraw the calendar grid
    22572330                                this.calendarGrid1.OnUpdateArrays(); // this draws the Calendar
    22582331                                this.lblResource.Text = this.m_Document.DocName;
     
    22622335                        {
    22632336                                MessageBox.Show("Unable to update arrays " +  ex.Message, "Clinical Scheduling");
    2264                         }
    2265                 }
    2266 
    2267                 public void RaiseRPMSEvent(string sEvent, string sParams)
    2268                 {
    2269                         try
    2270                         {
    2271                                 //Signal RPMS to raise an event
    2272                                 m_ConnectInfo.RaiseEvent(sEvent, sParams, true);
    2273                         }
    2274                         catch (Exception ex)
    2275                         {
    2276                                 Debug.Write(ex.Message);
    22772337                        }
    22782338                }
     
    23722432                #region Events
    23732433
    2374                 private void CGView_Load(object sender, System.EventArgs e)
     2434        /// <summary>
     2435        /// Special import to get the GetActiveWindow method from Win32
     2436        /// </summary>
     2437        /// <returns>Windows Handle number for Foregreound Active Window</returns>
     2438        [DllImport("user32.dll")]
     2439        static extern IntPtr GetActiveWindow();
     2440
     2441        /// <summary>
     2442        /// If a mouse enters the grid, check if the grid is on the active form first before stealing the focus
     2443        /// </summary>
     2444        /// <param name="sender"></param>
     2445        /// <param name="e"></param>
     2446        private void calendarGrid1_MouseEnter(object sender, EventArgs e)
     2447        {
     2448            if (GetActiveWindow() == this.Handle)
     2449                calendarGrid1.Focus();
     2450        }
     2451       
     2452        private void CGView_Load(object sender, System.EventArgs e)
    23752453                {
    23762454                        Debug.Assert (this.Document != null);
     
    31633241        }
    31643242
     3243       
     3244
     3245
    31653246    }//End class
    31663247}
  • Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs

    r1068 r1073  
    7171            this.m_selectedRange = new CGRange();
    7272            this.m_SelectedAppointments = new CGAppointments();
     73            //this.m_Appointments = new CGAppointments();
    7374            this.m_dtStart = new DateTime(2003, 1, 27);
    7475            this.m_ApptOverlapTable = new Hashtable();
     
    8990            this.m_sfHour.Alignment = StringAlignment.Far;
    9091            this.m_bInitialUpdate = false;
    91             this.MouseEnter += new EventHandler(CalendarGrid_MouseEnter);
    92         }
    93 
    94         void CalendarGrid_MouseEnter(object sender, EventArgs e)
    95         {
    96             this.Focus();
    9792        }
    9893
  • Scheduling/trunk/cs/bsdx0200GUISourceCode/LoadingSplash.Designer.cs

    r1070 r1073  
    3939            this.lblLoading.AutoSize = true;
    4040            this.lblLoading.Font = new System.Drawing.Font("Tahoma", 48F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
    41             this.lblLoading.Location = new System.Drawing.Point(228, 181);
     41            this.lblLoading.Location = new System.Drawing.Point(138, 108);
    4242            this.lblLoading.Name = "lblLoading";
    4343            this.lblLoading.Size = new System.Drawing.Size(255, 77);
     
    5151            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    5252            this.BackColor = System.Drawing.SystemColors.ControlLightLight;
    53             this.ClientSize = new System.Drawing.Size(722, 449);
     53            this.ClientSize = new System.Drawing.Size(537, 315);
    5454            this.Controls.Add(this.lblLoading);
    5555            this.ForeColor = System.Drawing.SystemColors.ControlLight;
    5656            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    5757            this.Name = "LoadingSplash";
    58             this.Opacity = 0.8D;
    5958            this.ShowIcon = false;
    6059            this.ShowInTaskbar = false;
Note: See TracChangeset for help on using the changeset viewer.