OSDN Git Service

Implement some GUI progress metering dialogue enhancements.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Thu, 13 Jun 2013 15:55:23 +0000 (16:55 +0100)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Thu, 13 Jun 2013 15:55:23 +0000 (16:55 +0100)
ChangeLog
src/guiexec.cpp
src/guimain.rc
src/pkgbase.h
src/pkgbind.cpp
src/pmihook.cpp [new file with mode: 0644]

index 899ad0a..5c7e6f4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2013-06-13  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
+       Implement some GUI progress metering dialogue enhancements.
+
+       * src/pkgbase.h (pkgProgressMeter): Don't pre-empt private features
+       of derived progress metering classes; hence, we no longer need this...
+       (AppWindowMaker): ...as a forward class declaration; delete it.
+
+       * src/guimain.rc (IDD_REPO_UPDATE): Resize, and adjust layout.
+       (IDD_PROGRESS_VAL, IDD_PROGRESS_MAX, IDD_PROGRESS_PCT): Add these
+       dialogue box progress counter display elements.
+
+       * src/pkgbind.cpp (pkgRepository::GetPackageList): Adjust style of
+       progress status messages, to suit reporting via GUI dialogue box or
+       CLI console, as appropriate.
+
+       * src/guiexec.cpp (ProgressMeterMaker): Redefine class, in terms of...
+       (PROGRESS_METER_CLASS): ...this new generic class name macro.
+       Reimplement private members, previously inherited from base class;
+       adjust class constructor to ensure that they are initialised.
+       Delete explicit destructor; a default destructor is now sufficient.
+       (ProgressMeterMaker::SetRange, ProgressMeterMaker::SetValue):
+       (ProgressMeterMaker::Annotate): Factor out; reimplement them...
+
+       * src/pmihook.cpp: ...in this new file, as generalised methods of...
+       (PROGRESS_METER_CLASS): ...the class named by this macro.
+       (PROGRESS_METER_CLASS::PutVal): New private method; implement it.
+
 2013-05-31  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        Avoid a potential macro definition conflict.
index 1313c74..32cef95 100644 (file)
  */
 EXTERN_C void dmh_setpty( HWND );
 
-class ProgressMeterMaker: public pkgProgressMeter
+#define PROGRESS_METER_CLASS   ProgressMeterMaker
+
+class PROGRESS_METER_CLASS: public pkgProgressMeter
 {
   /* A locally defined class, supporting progress metering
    * for package catalogue update and load operations.
    */
   public:
-    ProgressMeterMaker( HWND, HWND, AppWindowMaker * );
+    PROGRESS_METER_CLASS( HWND, AppWindowMaker * );
+    ~PROGRESS_METER_CLASS(){ referrer->DetachProgressMeter( this ); }
 
     virtual int Annotate( const char *, ... );
     virtual void SetRange( int, int );
     virtual void SetValue( int );
 
-  protected:
-    HWND message_line, progress_bar;
+  private:
+    AppWindowMaker *referrer;
+    HWND annotation, count, lim, frac, progress_bar;
+    void PutVal( HWND, const char *, ... );
+    int total;
 };
 
 inline
@@ -82,55 +88,23 @@ inline void AppWindowMaker::DetachProgressMeter( pkgProgressMeter *meter )
   }
 }
 
-/* We need to provide a destructor for the abstract base class, from which
- * our progress meters are derived; here is as good a place as any.
- */
-pkgProgressMeter::~pkgProgressMeter(){ referrer->DetachProgressMeter( this ); }
-
 /* We must also provide the implementation of our local progress meter class.
  */
-ProgressMeterMaker::ProgressMeterMaker
-( HWND annotation, HWND indicator, AppWindowMaker *owner ):
-pkgProgressMeter( owner ), message_line( annotation ), progress_bar( indicator )
+#define IDD( DLG, ITEM ) GetDlgItem( DLG, IDD_PROGRESS_##ITEM )
+PROGRESS_METER_CLASS::PROGRESS_METER_CLASS( HWND dlg, AppWindowMaker *owner ):
+referrer( owner ), annotation( IDD( dlg, MSG ) ), progress_bar( IDD( dlg, BAR ) ),
+count( IDD( dlg, VAL ) ), lim( IDD( dlg, MAX ) ), frac( IDD( dlg, PCT ) )
 {
   /* Constructor creates an instance of the progress meter class, attaching it
    * to the main application window, with an initial metering range of 0..100%,
    * and a starting indicated completion state of 0%.
    */
   owner->AttachProgressMeter( this );
-  SetRange( 0, 100 );
+  SetRange( 0, 1 ); SetValue( 0 );
   SetValue( 0 );
 }
 
-int ProgressMeterMaker::Annotate( const char *fmt, ... )
-{
-  /* Method to add a printf() style annotation to the progress meter dialogue.
-   */
-  va_list argv;
-  va_start( argv, fmt );
-  char annotation[1 + vsnprintf( NULL, 0, fmt, argv )];
-  int len = vsnprintf( annotation, sizeof( annotation ), fmt, argv );
-  va_end( argv );
-
-  SendMessage( message_line, WM_SETTEXT, 0, (LPARAM)(annotation) );
-  return len;
-}
-
-void ProgressMeterMaker::SetRange( int min, int max )
-{
-  /* Method to adjust the range of the progress meter, to represent any
-   * arbitrary range of discrete values, rather than percentage units.
-   */
-  SendMessage( progress_bar, PBM_SETRANGE, 0, MAKELPARAM( min, max ) );
-}
-
-void ProgressMeterMaker::SetValue( int value )
-{
-  /* Method to update the indicated completion state of a progress meter,
-   * to represent any arbitrary value within its assigned metering range.
-   */
-  SendMessage( progress_bar, PBM_SETPOS, value, 0 );
-}
+#include "pmihook.cpp"
 
 /* Implementation of service routines, for loading the package catalogue
  * from its defining collection of XML files.
@@ -215,20 +189,18 @@ static void pkgInvokeInitDataLoad( void *window )
    * we subject it to progress metering, to ensure that the user is
    * not left staring at an apparently hung, blank window.
    */
-  HWND msg = GetDlgItem( (HWND)(window), IDD_PROGRESS_MSG );
-  HWND dlg = GetDlgItem( (HWND)(window), IDD_PROGRESS_BAR );
   AppWindowMaker *app = GetAppWindow( GetParent( (HWND)(window) ));
   SendMessage( (HWND)(window),
       WM_SETTEXT, 0, (LPARAM)("Loading Package Catalogue")
     );
-  ProgressMeterMaker ui( msg, dlg, app );
+  ProgressMeterMaker ui( (HWND)(window), app );
 
   /* For this activity, we request automatic dismissal of the dialogue,
    * when loading has been completed; the user will have an opportunity
    * to countermand this choice, if loading is delayed by the required
    * download of any missing local catalogue file.
    */
-  dlg = GetDlgItem( (HWND)(window), IDD_AUTO_CLOSE_OPTION );
+  HWND dlg = GetDlgItem( (HWND)(window), IDD_AUTO_CLOSE_OPTION );
   SendMessage( dlg, WM_SETTEXT, 0,
       (LPARAM)("Close dialogue automatically, when loading is complete.")
     );
@@ -267,10 +239,8 @@ static void pkgInvokeUpdate( void *window )
    * subject it to progress metering, to ensure that the user is
    * not left staring at an apparently hung, blank window.
    */
-  HWND msg = GetDlgItem( (HWND)(window), IDD_PROGRESS_MSG );
-  HWND dlg = GetDlgItem( (HWND)(window), IDD_PROGRESS_BAR );
   AppWindowMaker *app = GetAppWindow( GetParent( (HWND)(window) ));
-  ProgressMeterMaker ui( msg, dlg, app );
+  ProgressMeterMaker ui( (HWND)(window), app );
 
   /* After setting up the progress meter, we clear out any data
    * which was previously loaded into the package list, reload it
@@ -292,8 +262,8 @@ static void pkgInvokeUpdate( void *window )
   else
   { /* ...otherwise, we activate the manual dismissal button...
      */
-    if( (dlg = GetDlgItem( (HWND)(window), IDOK )) != NULL )
-      EnableWindow( dlg, TRUE );
+    HWND dlg = GetDlgItem( (HWND)(window), IDOK );
+    if( dlg != NULL ) EnableWindow( dlg, TRUE );
 
     /* ...and notify the user that it must be clicked to continue.
      */
index 104975f..b40d745 100644 (file)
@@ -151,25 +151,30 @@ ID_PKGSTATE_BROKEN                ICON    DISCARDABLE     "state11.ico"
 ID_PKGSTATE_REMOVE             ICON    DISCARDABLE     "state12.ico"
 ID_PKGSTATE_PURGE              ICON    DISCARDABLE     "state13.ico"
 
+#define SS_CTEXTBOX                    SS_SUNKEN | SS_CENTER
+#define ES_VT100                       ES_LEFT | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL
+
 /* Template for progress meter dialogue box.
  */
-IDD_REPO_UPDATE DIALOG DISCARDABLE     10, 20, 270, 60
+IDD_REPO_UPDATE DIALOG DISCARDABLE     10, 20, 270, 78
 CAPTION                                "Update Package Catalogue"
 STYLE                                  DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_CAPTION | WS_DLGFRAME
 FONT                                   10, "Verdana"
 BEGIN
-  GROUPBOX                             "Actions", IDD_CLOSE_OPTIONS, 5, 31, 260, 25
-  DEFPUSHBUTTON                        "Close", IDOK, 219, 39, 40, 12, WS_GROUP | WS_DISABLED
+  GROUPBOX                             "Actions", IDD_CLOSE_OPTIONS, 5, 48, 260, 25
+  DEFPUSHBUTTON                        "Close", IDOK, 219, 56, 40, 12, WS_GROUP | WS_DISABLED
   AUTOCHECKBOX                         "Close dialogue automatically, when update is complete.", \
-                                       IDD_AUTO_CLOSE_OPTION, 10, 41, 200, 11
+                                       IDD_AUTO_CLOSE_OPTION, 10, 58, 200, 11
+  CONTROL                              "", IDD_PROGRESS_VAL, "STATIC", SS_CTEXTBOX, 6, 19, 96, 10
+  CTEXT                                        "of", IDD_PROGRESS_TXT, 102, 19, 18, 10
+  CONTROL                              "", IDD_PROGRESS_MAX, "STATIC", SS_CTEXTBOX, 120, 19, 96, 10
+  CTEXT                                        ":", IDD_PROGRESS_TXT, 213, 19, 10, 10
+  CONTROL                              "", IDD_PROGRESS_PCT, "STATIC", SS_CTEXTBOX, 223, 19, 41, 10
   CONTROL                              "", IDD_PROGRESS_BAR, PROGRESS_CLASS, WS_CHILD \
-                                       | PBS_SMOOTH, 6, 20, 258, 10
+                                       | PBS_SMOOTH, 6, 34, 258, 10
   LTEXT                                "", IDD_PROGRESS_MSG, 7, 6, 256, 12
 END
 
-#define SS_CTEXTBOX                    SS_SUNKEN | SS_CENTER
-#define ES_VT100                       ES_LEFT | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL
-
 /* Template for dialogue requesting user confirmation of intent
  * to proceed with scheduled change actions.
  */
index 9a48507..a801467 100644 (file)
@@ -50,10 +50,6 @@ EXTERN_C int pkgPutEnv( int, char* );
 class pkgSpecs;
 class pkgDirectory;
 
-#ifndef GUIMAIN_H
-class AppWindowMaker;
-#endif
-
 class pkgProgressMeter
 {
   /* An abstract base class, from which the controller class
@@ -63,11 +59,6 @@ class pkgProgressMeter
     virtual void SetValue( int ) = 0;
     virtual void SetRange( int, int ) = 0;
     virtual int Annotate( const char *, ... ) = 0;
-
-  protected:
-    AppWindowMaker *referrer;
-    pkgProgressMeter( AppWindowMaker *ref = NULL ): referrer( ref ){}
-    ~pkgProgressMeter();
 };
 
 class pkgXmlNode : public TiXmlElement
index a6de809..b6559c6 100644 (file)
@@ -104,8 +104,10 @@ void pkgRepository::GetPackageList( const char *dname )
 
       /* Set up diagnostics for reporting catalogue loading progress.
        */
-      const char *mode = force_update ? "Retaining" : "Loading";
-      const char *fmt = "%s catalogue: %s.xml; (item %d of %d)\n";
+      const char *mode = force_update ? "Checking" : "Loading";
+      const char *fmt = (owner->ProgressMeter() == NULL)
+       ? "%s catalogue: %s.xml; (item %d of %d)\n"
+       : "%s catalogue: %s.xml\n";
 
       /* Check for a locally cached copy of the "package-list" file...
        */
diff --git a/src/pmihook.cpp b/src/pmihook.cpp
new file mode 100644 (file)
index 0000000..0f1ca59
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * pmihook.cpp
+ *
+ * $Id$
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Copyright (C) 2013, MinGW.org Project
+ *
+ *
+ * Implementation of the generic methods required by an "item counting"
+ * progress meter, such as used by the setup tool and GUI installer, when
+ * synchronising local catalogue files with the repository.  This file is
+ * compiled by inclusion at point of use, after PROGRESS_METER_CLASS has
+ * been defined to appropriately identify the name of the class with
+ * which these methods are to be associated.
+ *
+ *
+ * This is free software.  Permission is granted to copy, modify and
+ * redistribute this software, under the provisions of the GNU General
+ * Public License, Version 3, (or, at your option, any later version),
+ * as published by the Free Software Foundation; see the file COPYING
+ * for licensing details.
+ *
+ * Note, in particular, that this software is provided "as is", in the
+ * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
+ * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
+ * PARTICULAR PURPOSE.  Under no circumstances will the author, or the
+ * MinGW Project, accept liability for any damages, however caused,
+ * arising from the use of this software.
+ *
+ */
+void PROGRESS_METER_CLASS::SetRange( int min, int max )
+{
+  /* Method to adjust the range of the progress meter, to represent any
+   * arbitrary range of discrete values, rather than percentage units.
+   */
+  SendMessage( progress_bar, PBM_SETRANGE, 0, MAKELPARAM( min, total = max ) );
+}
+
+void PROGRESS_METER_CLASS::SetValue( int value )
+{
+  /* Method to update the indicated completion state of a progress meter,
+   * to represent any arbitrary value within its assigned metering range.
+   */
+  const char *plural = "s";
+  if( total == 1 ) ++plural;
+  PutVal( count, "Processed %d", value );
+  PutVal( lim, "%d item%s", total, plural );
+  SendMessage( progress_bar, PBM_SETPOS, value, 0 );
+  PutVal( frac, "%d %%", (value * 100UL) / total );
+}
+
+int PROGRESS_METER_CLASS::Annotate( const char *fmt, ... )
+{
+  /* Method to add a printf() style annotation to the progress meter dialogue.
+   */
+  va_list argv;
+  va_start( argv, fmt );
+  char text[1 + vsnprintf( NULL, 0, fmt, argv )];
+  int len = vsnprintf( text, sizeof( text ), fmt, argv );
+  va_end( argv );
+
+  SendMessage( annotation, WM_SETTEXT, 0, (LPARAM)(text) );
+  return len;
+};
+
+void PROGRESS_METER_CLASS::PutVal( HWND viewport, const char *fmt, ... )
+{
+  /* Private method, called by SetValue(), to display the numeric values
+   * of the progress counters, in their appropriate viewports.
+   */
+  va_list argv; va_start( argv, fmt );
+  char text[1 + vsnprintf( NULL, 0, fmt, argv )]; vsprintf( text, fmt, argv );
+  SendMessage( viewport, WM_SETTEXT, 0, (LPARAM)(text) );
+  va_end( argv );
+}
+
+/* $RCSfile$: end of file */