OSDN Git Service

Add content compiler for package data sheet "general" tab.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Thu, 1 Nov 2012 15:00:18 +0000 (15:00 +0000)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Thu, 1 Nov 2012 15:00:18 +0000 (15:00 +0000)
ChangeLog
src/pkgbase.h
src/pkgdata.cpp
src/pkginet.cpp

index c857555..812eccb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2012-11-01  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
+       Add content compiler for package data sheet "general" tab.
+
+       * src/pkgbase.h (pkgActionItem::PrintURI): Make it public.  Add a
+       call-back reference argument, for output function; assign puts() as
+       default, where previously had hard coded printf() emulating puts()
+
+       * src/pkginet.cpp (pkgActionItem::PrintURI): Use call-back hook.
+
+       * src/pkgdata.cpp (DataSheetMaker::Display): New static property; it
+       stores a reference to the active class instance, so static call-back
+       methods may delegate processing requests to non-static methods.
+       (DataSheetMaker::Advance): New static property; it is used to instruct
+       call-back methods to interpose paragraph leading it the output stream.
+       (DataSheetMaker::FormatRecord): New private method; implement it.
+       (DataSheetMaker::FormatText): Don't pass "canvas" as an argument; we
+       can access it directly as a class property.  Update all callers as
+       necessary, to conform to modified function prototype.
+       (pkgListSelection): New static function; implement it, and...
+       (DataSheetMaker::OnPaint): ...use it in switch cases, when calling...
+       [PKG_DATASHEET_GENERAL]: DataSheetMaker::DisplayGeneralData(), and...
+       [PKG_DATASHEET_DESCRIPTION]: DataSheetMaker::DisplayDescription().
+       (DataSheetMaker::DisplayGeneralData): New public method; implement it.
+       (DataSheetMaker::DisplayPackageURL): New static method; implement it.
+       (DataSheetMaker::DisplayLicenceURL): Likewise.
+       (DataSheetMaker::DisplaySourceURL): Likewise.
+
 2012-10-30  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        Fix error in counting of catalogue files during loading.
index 4857d1e..4cd1956 100644 (file)
@@ -274,10 +274,6 @@ class pkgActionItem
      */
     pkgXmlNode* selection[ selection_types ];
 
-    /* Method to display the URI whence a package may be downloaded.
-     */
-    void PrintURI( const char* );
-
     /* Methods for retrieving packages from a distribution server.
      */
     void DownloadArchiveFiles( pkgActionItem* );
@@ -324,6 +320,10 @@ class pkgActionItem
     }
     void ConfirmInstallationStatus();
 
+    /* Method to display the URI whence a package may be downloaded.
+     */
+    void PrintURI( const char*, int (*)( const char* ) = puts );
+
     /* Methods to download and unpack one or more source archives.
      */
     void GetSourceArchive( pkgXmlNode*, unsigned long );
index 05e70e8..7307dca 100644 (file)
@@ -35,6 +35,7 @@
 #include "pkgdata.h"
 #include "pkgkeys.h"
 #include "pkglist.h"
+#include "pkgtask.h"
 
 using WTK::StringResource;
 using WTK::WindowClassMaker;
@@ -263,16 +264,28 @@ class DataSheetMaker: public ChildWindowMaker
     virtual long OnPaint();
 
     HWND PackageRef, DataClass;
+    static DataSheetMaker *Display;
     HDC canvas; RECT bounding_box; 
     HFONT NormalFont, BoldFont;
 
+    static int Advance;
     long offset; char *desc;
+    void DisplayGeneralData( pkgXmlNode * );
+    static int DisplaySourceURL( const char * );
+    static int DisplayLicenceURL( const char * );
+    static int DisplayPackageURL( const char * );
     inline void DisplayDescription( pkgXmlNode * );
     void ComposeDescription( pkgXmlNode *, pkgXmlNode * );
-    inline void FormatText( HDC, const char * );
+    int FormatRecord( int, const char *, const char * );
+    inline void FormatText( const char * );
     long LineSpacing;
 };
 
+/* Don't forget to instantiate the static member variables...
+ */
+int DataSheetMaker::Advance;
+DataSheetMaker *DataSheetMaker::Display;
+
 enum
 { /* Tab identifiers for the available data sheet collection.
    */
@@ -340,7 +353,7 @@ void DataSheetMaker::DisplayData( HWND tab, HWND package )
   UpdateWindow( AppWindow );
 }
 
-inline void DataSheetMaker::FormatText( HDC canvas, const char *text )
+inline void DataSheetMaker::FormatText( const char *text )
 {
   /* Helper method to transfer text to the display device, formatting
    * it to fill as many lines of the viewing window as may be required,
@@ -351,6 +364,110 @@ inline void DataSheetMaker::FormatText( HDC canvas, const char *text )
     ;
 }
 
+int DataSheetMaker::FormatRecord( int offset, const char *tag, const char *text )
+{
+  /* Helper method to transfer text to the display device, prefacing
+   * it with a specified record key, before formatting as above.
+   */
+  const char *fmt = "%s: %s";
+  int span = snprintf( NULL, 0, fmt, tag, text );
+  char record[ 1 + span ]; snprintf( record, sizeof( record ), fmt, tag, text );
+  if( offset == 0 )
+    bounding_box.top += PARAGRAPH_MARGIN;
+  FormatText( record );
+  return offset + span;
+}
+
+void DataSheetMaker::DisplayGeneralData( pkgXmlNode *ref )
+{
+  /* Method to compile the package data, which is to be displayed
+   * on the general information tab; we begin by displaying the
+   * identification records for the selected package, and the
+   * subsystem to which it belongs.
+   */
+  FormatRecord( 0, "SubSystem",
+      ref->GetContainerAttribute( subsystem_key, value_unknown )
+    );
+  FormatRecord( 1, "Package Name",
+      ref->GetContainerAttribute( name_key, value_unknown )
+    );
+  if( ref->IsElementOfType( component_key ) )
+    FormatRecord( 1, "Component Class",
+       ref->GetPropVal( class_key, value_unknown )
+      );
+
+  /* Using a temporary action item, collect information on the
+   * available and installed (if any) versions of the selected
+   * package.
+   */
+  pkgActionItem avail;
+  ref = ref->FindFirstAssociate( release_key );
+  while( ref != NULL )
+  {
+    /* ...to scan all associated release keys, and select the
+     * most recent recorded in the database as available...
+     */
+    avail.SelectIfMostRecentFit( ref );
+    if( ref->GetInstallationRecord( ref->GetPropVal( tarname_key, NULL )) != NULL )
+      /*
+       * ...also noting if any is marked as installed...
+       */
+      avail.SelectPackage( ref, to_remove );
+
+    /* ...until all release keys have been inspected...
+     */
+    ref = ref->FindNextAssociate( release_key );
+  }
+  /* ...and performing a final check on installation status.
+   */
+  avail.ConfirmInstallationStatus();
+
+  /* Now print the applicable version information, noting that
+   * "none" may be appropriate for the installed version.
+   */
+  FormatRecord( 0, "Installed Version",
+      ((ref = avail.Selection( to_remove )) != NULL)
+       ? ref->GetPropVal( tarname_key, value_unknown ) : value_none
+    );
+  FormatRecord( 1, "Repository Version",
+      (ref = avail.Selection())->GetPropVal( tarname_key, value_unknown )
+    );
+
+  /* Finally, report the download URLs for the selected package,
+   * and its associated source and licence archives; (note that we
+   * must save static callback references, so that the PrintURI()
+   * method can access this data sheet context).
+   */
+  Display = this; Advance = 0;
+  avail.PrintURI( ref->ArchiveName(), DisplayPackageURL );
+  avail.PrintURI( ref->SourceArchiveName( ACTION_LICENCE ), DisplayLicenceURL );
+  avail.PrintURI( ref->SourceArchiveName( ACTION_SOURCE ), DisplaySourceURL );
+}
+
+int DataSheetMaker::DisplayPackageURL( const char *uri )
+{
+  /* Static helper method, which may be passed to pkgActionItem::PrintURI(),
+   * to display the package download URL on the active data sheet panel.
+   */
+  return Advance = Display->FormatRecord( Advance, "Package URL", uri );
+}
+
+int DataSheetMaker::DisplaySourceURL( const char *uri )
+{
+  /* Static helper method, which may be passed to pkgActionItem::PrintURI(),
+   * to display the source download URL on the active data sheet panel.
+   */
+  return Advance = Display->FormatRecord( Advance, "Source URL", uri );
+}
+
+int DataSheetMaker::DisplayLicenceURL( const char *uri )
+{
+  /* Static helper method, which may be passed to pkgActionItem::PrintURI(),
+   * to display the licence download URL on the active data sheet panel.
+   */
+  return Advance = Display->FormatRecord( Advance, "Licence URL", uri );
+}
+
 inline void DataSheetMaker::DisplayDescription( pkgXmlNode *ref )
 {
   /* A convenience method to invoke the recursive retrieval of any
@@ -394,7 +511,7 @@ void DataSheetMaker::ComposeDescription( pkgXmlNode *ref, pkgXmlNode *root )
                  /* ...before laying out the visible text of
                   * this paragraph, (if any).
                   */
-                 FormatText( canvas, ref->GetText() );
+                 FormatText( ref->GetText() );
 
                  /* Cycle, to process any further paragraphs
                   * which are included within the current
@@ -411,6 +528,17 @@ void DataSheetMaker::ComposeDescription( pkgXmlNode *ref, pkgXmlNode *root )
   }
 }
 
+static pkgXmlNode *pkgListSelection( HWND package_ref, LVITEM *lookup )
+{
+  /* Helper function, to retrieve the active selection from the
+   * package list, as displayed in the upper right data pane.
+   */
+  lookup->iSubItem = 0;
+  lookup->mask = LVIF_PARAM;
+  ListView_GetItem( package_ref, lookup );
+  return (pkgXmlNode *)(lookup->lParam);
+}
+
 long DataSheetMaker::OnPaint()
 {
   /* Handler for WM_PAINT message messages, sent to any window
@@ -467,7 +595,7 @@ long DataSheetMaker::OnPaint()
     char desc[256];
     SelectObject( canvas, BoldFont );
     ListView_GetItemText( PackageRef, lookup.iItem, 5, desc, sizeof( desc ) );
-    FormatText( canvas, desc );
+    FormatText( desc );
     if( offset > 0 )
     {
       /* ...adjusting as appropriate, when the heading is scrolled
@@ -484,14 +612,19 @@ long DataSheetMaker::OnPaint()
     SelectObject( canvas, NormalFont );
     switch( tab )
     {
+      case PKG_DATASHEET_GENERAL:
+       /* This comprises package and subsystem identification,
+        * followed by latest version availability, installation
+        * status, and package download URLs.
+        */
+       DisplayGeneralData( pkgListSelection( PackageRef, &lookup ) );
+       break;
+
       case PKG_DATASHEET_DESCRIPTION:
        /* This represents the package description, provided by
         * the package maintainer, within the XML specification.
         */
-       lookup.iSubItem = 0;
-       lookup.mask = LVIF_PARAM;
-       ListView_GetItem( PackageRef, &lookup );
-       DisplayDescription( (pkgXmlNode *)(lookup.lParam) );
+       DisplayDescription( pkgListSelection( PackageRef, &lookup ) );
        break;
 
       default:
@@ -499,7 +632,7 @@ long DataSheetMaker::OnPaint()
         * to provide a compiling routine.
         */
        bounding_box.top += TOP_MARGIN;
-       FormatText( canvas,
+       FormatText(
            "FIXME:data sheet unavailable; a compiler for this "
            "data category has yet to be implemented."
          );
@@ -509,11 +642,11 @@ long DataSheetMaker::OnPaint()
   { /* There is no active package selection; advise accordingly.
      */
     bounding_box.top += TOP_MARGIN << 1;
-    FormatText( canvas,
+    FormatText(
        "No package selected."
       );
     bounding_box.top += PARAGRAPH_MARGIN << 1;
-    FormatText( canvas,
+    FormatText(
        "Please select a package from the list above, "
        "to view related data."
       );
index 368b338..12b5775 100644 (file)
@@ -640,9 +640,10 @@ int pkgInternetStreamingAgent::Get( const char *from_url )
   return dl_status;
 }
 
-void pkgActionItem::PrintURI( const char *package_name )
+void pkgActionItem::PrintURI
+( const char *package_name, int (*output)( const char * ) )
 {
-  /* Private method to display the URI from which a package archive
+  /* Public method to display the URI from which a package archive
    * may be downloaded; called with "package_name" assigned by either
    * ArchiveName() or SourceArchiveName() as appropriate, and...
    */
@@ -666,7 +667,7 @@ void pkgActionItem::PrintURI( const char *package_name )
       /* ...then, rather than actually initiate the download,
        * we simply write out the generated URI to stdout.
        */
-      printf( "%s\n", package_url );
+      output( package_url );
     }
   }
 }