+2012-11-17 Keith Marshall <keithmarshall@users.sourceforge.net>
+
+ Refactor to consolidate three instances of duplicate code.
+
+ * src/pkglist.h (pkgGetStatus): New function; declare it.
+ * src/pkglist.cpp (pkgGetStatus): Implement it; factor out from...
+ (pkgListViewMaker::InsertItem): ...here, whence use it.
+ * src/pkgdata.cpp (pkgMarkSchedule): Likewise here...
+ (DataSheetMaker::DisplayGeneralData): ...and here.
+
2012-11-16 Keith Marshall <keithmarshall@users.sourceforge.net>
Add GUI support for install, upgrade, and remove action scheduling.
);
/* Using a temporary action item, collect information on the
- * available and installed (if any) versions of the selected
- * package.
+ * latest available version, and the installed version if any,
+ * of the selected package; print the applicable information,
+ * noting that "none" may be appropriate in the case of the
+ * installed version.
*/
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
+ ((ref = pkgGetStatus( ref, &avail )) != NULL)
+ ? ref->GetPropVal( tarname_key, value_unknown )
+ : value_none
);
FormatRecord( 1, "Repository Version",
(ref = avail.Selection())->GetPropVal( tarname_key, value_unknown )
}
}
else
- { /* A previously scheduled action has been cancelled.
+ { /* A previously scheduled action has been cancelled;
+ * retrieve the package release status attributes, so
+ * we may reinstate the appropriate unmarked icon.
*/
pkgActionItem avail;
pkgXmlNode *rel = ref->Selection();
if( rel == NULL ) rel = ref->Selection( to_remove );
- rel = rel->GetParent()->FindFirstAssociate( release_key );
- while( rel != NULL )
- {
- /* Examine each available release specification for the nominated
- * package; select the one which represents the latest (most recent)
- * available release.
- */
- avail.SelectIfMostRecentFit( rel );
-
- /* Also check for the presence of an installation record for each
- * release; if found, mark it as the currently installed release;
- * (we assign the "to-remove" attribute, but we don't action it).
- */
- if( rel->GetInstallationRecord( rel->GetPropVal( tarname_key, NULL )) != NULL )
- avail.SelectPackage( rel, to_remove );
-
- /* Cycle, until all known releases have been examined.
+ if( (rel = pkgGetStatus( rel->GetParent(), &avail )) == NULL )
+ /*
+ * For a package which has not been installed, this
+ * indicates an available package...
*/
- rel = rel->FindNextAssociate( release_key );
- }
- avail.ConfirmInstallationStatus();
- if( (rel = avail.Selection( to_remove )) == NULL )
lookup.iImage = PKGSTATE( AVAILABLE );
+
else
- {
+ { /* ...while for an installed package, it indicates
+ * currency or upgradeability, as appropriate.
+ */
pkgSpecs current( rel );
pkgSpecs latest( avail.Selection() );
lookup.iImage = (latest > current) ? PKGSTATE( INSTALLED_OLD )
: PKGSTATE( INSTALLED_CURRENT );
}
}
- /* Apply new icon selection...
+ /* Apply the new icon selection...
*/
ListView_SetItem( pkglist, &lookup );
}
content.iItem = -1;
}
-void pkgListViewMaker::InsertItem( pkgXmlNode *pkg, char *class_name )
+EXTERN_C pkgXmlNode *pkgGetStatus( pkgXmlNode *pkg, pkgActionItem *avail )
{
- /* Private method to add a single package record, as an individual
- * row item, to the displayed list view table.
- */
- content.state = 0;
- content.iItem += 1;
- content.iSubItem = 0;
- content.lParam = (unsigned long)(pkg);
- content.pszText = "";
-
- /* Assign a temporary action item, through which we may identify
- * the latest available, and currently installed (if any), version
- * attributes for the package under consideration.
+ /* Helper function to acquire release availability and installation
+ * status attributes for a specified package.
*/
- pkgActionItem avail;
- pkgXmlNode *rel = pkg->FindFirstAssociate( release_key );
- while( rel != NULL )
+ pkg = pkg->FindFirstAssociate( release_key );
+ while( pkg != NULL )
{
/* Examine each available release specification for the nominated
* package; select the one which represents the latest (most recent)
* available release.
*/
- avail.SelectIfMostRecentFit( rel );
+ avail->SelectIfMostRecentFit( pkg );
/* Also check for the presence of an installation record for each
* release; if found, mark it as the currently installed release;
* (we assign the "to-remove" attribute, but we don't action it).
*/
- if( rel->GetInstallationRecord( rel->GetPropVal( tarname_key, NULL )) != NULL )
- avail.SelectPackage( rel, to_remove );
+ if( pkg->GetInstallationRecord( pkg->GetPropVal( tarname_key, NULL )) != NULL )
+ avail->SelectPackage( pkg, to_remove );
/* Cycle, until all known releases have been examined.
*/
- rel = rel->FindNextAssociate( release_key );
+ pkg = pkg->FindNextAssociate( release_key );
}
/* Check the identification of any currently installed release; this
* will capture property data for any installed release which may have
* been subsequently withdrawn from distribution.
*/
- avail.ConfirmInstallationStatus();
+ avail->ConfirmInstallationStatus();
+
+ /* Finally, return a pointer to the specification for the installed
+ * release, if any, of the package under consideration.
+ */
+ return avail->Selection( to_remove );
+}
+
+void pkgListViewMaker::InsertItem( pkgXmlNode *pkg, char *class_name )
+{
+ /* Private method to add a single package record, as an individual
+ * row item, to the displayed list view table.
+ */
+ content.state = 0;
+ content.iItem += 1;
+ content.iSubItem = 0;
+ content.lParam = (unsigned long)(pkg);
+ content.pszText = "";
+
+ /* Assign a temporary action item, through which we may identify
+ * the latest available, and currently installed (if any), version
+ * attributes for the package under consideration.
+ */
+ pkgActionItem avail;
+ pkgXmlNode *rel = pkgGetStatus( pkg, &avail );
/* Decompose the package tarname identifier for the latest available
* release, into its individual package specification properties.
*/
- pkgSpecs latest( rel = avail.Selection() );
+ pkgSpecs latest( pkg = avail.Selection() );
/* Allocate a temporary working text buffer, in which to format
* package property values for display...
*/
- size_t len = strlen( rel->GetPropVal( tarname_key, value_none ) );
- if( (rel = avail.Selection( to_remove )) != NULL )
+ size_t len = strlen( pkg->GetPropVal( tarname_key, value_none ) );
+ if( rel != NULL )
{
/* ...ensuring that it is at least as large as the longer of the
* latest or installed release tarname.
* an installed package with an available update...
*/
content.iImage = PKGSTATE( INSTALLED_OLD );
+
else
/* ...or, when the latest available is NOT NEWER than
* the installed version, then we choose the alternative
pkgDirectory *next;
};
+/* The following helper function is used to retrieve release availability
+ * and installation status attributes for any specified package, from the
+ * XML database, returning specifications for the latest available release
+ * and the installed release, if any, in the to_install and the to_remove
+ * selection fields of the passed pkgActionItem structure respectively.
+ */
+EXTERN_C pkgXmlNode *pkgGetStatus( pkgXmlNode *, pkgActionItem * );
+
#endif /* PKGLIST_H: $RCSfile$: end of file */