+2012-12-10 Keith Marshall <keithmarshall@users.sourceforge.net>
+
+ Implement GUI bindings for package download agent.
+
+ * src/guimain.h (IDD_PROGRESS_VAL, IDD_PROGRESS_MAX):
+ (IDD_PROGRESS_PCT): New manifest resource IDs; define them. They will
+ be used to identify dialogue controls, to be associated with...
+ (IDD_APPLY_DOWNLOAD): ...this new dialogue template ID; define it.
+ (AppWindowMaker::DownloadArchiveFiles): New inline method; declare it.
+
+ * src/guidata.rc (IDD_APPLY_DOWNLOAD): Implement dialogue template.
+
+ * src/pkgbase.h (pkgActionItem::DownloadArchiveFiles): New public
+ inline method; declare it. It overloads an existing private method of
+ the same name, which it subsequently invokes.
+
+ * src/pkginet.h: New header file; it declares...
+ (pkgInvokeDownload): ...this new extern "C" function prototype, and...
+ (pkgDownloadMeter): ...this abstract class; it is factored from its
+ original implementation in pkginet.cpp, augmented by addition of...
+ (pkgDownloadMeter::primary): New static member variable; declare it.
+ (pkgDownloadMeter::UseGUI): New public method; implement it inline.
+ (pkgDownloadMeter::ResetGUI): New public method; declare it, providing
+ a do-nothing inline default implementation. Any derived class, which
+ supports GUI capability, should override this.
+
+ * src/pkgnget.cpp: New file; it implements...
+ (pkgDownloadMeterGUI): New class, derived from pkgDownloadMeter.
+ (pkgActionItem::DownloadArchiveFiles): New overloaded inline method.
+ (AppWindowMaker::DownloadArchiveFiles): New inline method.
+ (pkgInvokeDownload): New dialogue box worker thread handler.
+
+ * src/pkginet.cpp: Include pkginet.h; hence...
+ (pkgDownloadMeter): ...remove redundant class declaration.
+ (pkgDownloadMeter::primary): Define and initialise it.
+ (pkgInternetStreamingAgent::Get) [pkgDownloadMeter::UseGUI]: Delegate
+ progress metering to referenced pkgDownloadMeterGUI class instance.
+ [! pkgDownloadMeter::UseGUI]: Continue to use the existing built-in
+ pkgDownloadMeterTTY mechanism.
+ (pkgActionItem::DownloadSingleArchive) [ACTION_DOWLOAD_FAILED]: Assert
+ this initially; subsequently clear it on successful completion.
+ (pkgActionItem::DownloadArchiveFiles): Collect diagnostic messages
+ into a single DMH_BEGIN_DIGEST ... DMH_END_DIGEST group.
+
+ * src/guixmld.cpp: Include pkginet.h; it is required by...
+ (AppWindowMaker::OnCommand) [IDD_REPO_APPLY]: Use pkgInvokeDownload.
+
+ * Makefile.in (GUIMAIN_OBJECTS): Include pkgnget.$OBJEXT
+
2012-12-08 Keith Marshall <keithmarshall@users.sourceforge.net>
Implement "Discard" handler for GUI "Apply Changes" dialogue.
GUIMAIN_OBJECTS = \
guimain.$(OBJEXT) guidata.$(OBJEXT) guixmld.$(OBJEXT) guidmh.$(OBJEXT) \
- approot.$(OBJEXT) pkgview.$(OBJEXT) pkglist.$(OBJEXT) pkgdata.$(OBJEXT)
+ approot.$(OBJEXT) pkgview.$(OBJEXT) pkglist.$(OBJEXT) pkgdata.$(OBJEXT) \
+ pkgnget.$(OBJEXT)
GUIMAIN_LIBS = -lwtklite -lcomctl32
* $Id$
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2012, MinGW Project
+ * Copyright (C) 2012, MinGW.org Project
*
*
* Resource definitions for the mingw-get GUI implementation.
EDITTEXT IDD_APPLY_INSTALLS_PACKAGES, 7, 148, 292, 36, WS_VSCROLL | ES_VT100
END
+/* Template for GUI styled package download monitoring dialogue box.
+ */
+IDD_APPLY_DOWNLOAD DIALOG DISCARDABLE 10, 20, 280, 52
+CAPTION "Download Package"
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_CAPTION | WS_DLGFRAME
+FONT 10, "Verdana"
+BEGIN
+ LTEXT "Connecting...", IDD_PROGRESS_MSG, 7, 6, 266, 10
+ CONTROL "", IDD_PROGRESS_VAL, "STATIC", SS_CTEXTBOX, 6, 20, 100, 10
+ CTEXT "of", IDD_PROGRESS_TXT, 106, 20, 18, 10
+ CONTROL "", IDD_PROGRESS_MAX, "STATIC", SS_CTEXTBOX, 124, 20, 100, 10
+ CTEXT ":", IDD_PROGRESS_TXT, 224, 20, 10, 10
+ CONTROL "", IDD_PROGRESS_PCT, "STATIC", SS_CTEXTBOX, 234, 20, 40, 10
+ CONTROL "", IDD_PROGRESS_BAR, PROGRESS_CLASS, WS_CHILD \
+ | PBS_SMOOTH, 6, 35, 268, 10
+END
+
/* $RCSfile$: end of file */
* $Id$
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2012, MinGW Project
+ * Copyright (C) 2012, MinGW.org Project
*
*
* Resource definitions and window management class declarations for
#define IDD_AUTO_CLOSE_OPTION 612
#define IDD_PROGRESS_BAR 613
#define IDD_PROGRESS_MSG 614
+#define IDD_PROGRESS_VAL 615
+#define IDD_PROGRESS_MAX 616
+#define IDD_PROGRESS_PCT 617
#define IDD_PROGRESS_TXT 618
#define IDD_APPLY_APPROVE 630
+#define IDD_APPLY_DOWNLOAD 631
#define IDD_APPLY_REMOVES_PACKAGES 633
#define IDD_APPLY_REMOVES_SUMMARY 634
inline void DetachProgressMeter( pkgProgressMeter * );
inline unsigned long EnumerateActions( int = 0 );
+ inline void DownloadArchiveFiles( void );
private:
virtual long OnCreate();
*/
#include "guimain.h"
#include "pkgbase.h"
+#include "pkginet.h"
#include "pkgkeys.h"
#include "pkglist.h"
#include "pkgtask.h"
* download any required packages, and invoke the scheduled
* remove, upgrade, or install actions.
*
- * FIXME: the pkgInvokeDownload() and pkgApplyChanges() thread
- * handlers have yet to be implemented.
+ * FIXME: the pkgInvokeDownload() thread handler has yet to
+ * be implemented.
*/
-// DispatchDialogueThread( IDD_APPLY_DOWNLOAD, pkgInvokeDownload );
+ DispatchDialogueThread( IDD_APPLY_DOWNLOAD, pkgInvokeDownload );
// DispatchDialogueThread( IDD_APPLY_MONITORED, pkgApplyChanges );
/* After applying changes, we fall through...
* $Id$
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2009, 2010, 2011, 2012, MinGW Project
+ * Copyright (C) 2009, 2010, 2011, 2012, MinGW.org Project
*
*
* Public interface for the package directory management routines;
void GetSourceArchive( pkgXmlNode*, unsigned long );
void GetScheduledSourceArchives( unsigned long );
- /* Method for processing all scheduled actions.
+ /* Methods for processing all scheduled actions.
*/
void Execute();
+ inline void DownloadArchiveFiles( void );
/* Method to manipulate error trapping, control, and state
* flags for the schedule of actions.
* $Id$
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2009, 2010, 2011, 2012, MinGW Project
+ * Copyright (C) 2009, 2010, 2011, 2012, MinGW.org Project
*
*
* Implementation of the package download machinery for mingw-get.
#include "debug.h"
#include "pkgbase.h"
+#include "pkginet.h"
#include "pkgkeys.h"
#include "pkgtask.h"
-class pkgDownloadMeter
-{
- /* Abstract base class, from which facilities for monitoring the
- * progress of file downloads may be derived.
- */
- public:
- /* The working method to refresh the download progress display;
- * each derived class MUST furnish an implementation for this.
- */
- virtual int Update( unsigned long length ) = 0;
-
- protected:
- /* Storage for the expected size of the active download...
- */
- unsigned long content_length;
-
- /* ...and a method to format it for human readable display.
- */
- int SizeFormat( char*, unsigned long );
-};
+/* This static member variable of the pkgDownloadMeter class
+ * provides a mechanism for communicating with a pre-existing
+ * download monitoring dialogue, such as is employed in the GUI.
+ * We MUST define it, and we also initialise it to NULL. While
+ * it remains thus, (as it always does in the CLI), no attempt
+ * will be made to access any pre-existing dialogue, and local
+ * monitoring objects will be employed; the GUI sets this to
+ * refer to its dialogue, when this is activated.
+ */
+pkgDownloadMeter *pkgDownloadMeter::primary = NULL;
class pkgDownloadMeterTTY : public pkgDownloadMeter
{
/* With the download transaction fully specified, we may
* request processing of the file transfer...
*/
- pkgDownloadMeterTTY download_meter
- (
- from_url, pkgDownloadAgent.QueryContentLength( dl_host )
- );
- dl_meter = &download_meter;
- dl_status = TransferData( fd );
+ if( (dl_meter = pkgDownloadMeter::UseGUI()) != NULL )
+ {
+ /* ...with progress monitoring delegated to the GUI's
+ * dialogue box, when running under its auspices...
+ */
+ dl_meter->ResetGUI(
+ filename, pkgDownloadAgent.QueryContentLength( dl_host )
+ );
+ dl_status = TransferData( fd );
+ }
+ else
+ { /* ...otherwise creating our own TTY progress monitor,
+ * when running under the auspices of the CLI.
+ */
+ pkgDownloadMeterTTY download_meter(
+ from_url, pkgDownloadAgent.QueryContentLength( dl_host )
+ );
+ dl_meter = &download_meter;
+
+ /* Note that the following call MUST be kept within the
+ * scope in which the progress monitor was created; thus,
+ * it CANNOT be factored out of this "else" block scope,
+ * even though it also appears at the end of the scope
+ * of the preceding "if" block.
+ */
+ dl_status = TransferData( fd );
+ }
}
else DEBUG_INVOKE_IF( DEBUG_REQUEST( DEBUG_TRACE_INTERNET_REQUESTS ),
dmh_printf( "OpenURL:error:%d\n", GetLastError() )
if( ((flags & ACTION_DOWNLOAD) == ACTION_DOWNLOAD)
&& ((access( download.DestFile(), R_OK ) != 0) && (errno == ENOENT)) )
{
- /* ...if not, ask the download agent to fetch it...
+ /* ...if not, ask the download agent to fetch it,
+ * anticipating that this may fail...
*/
+ flags |= ACTION_DOWNLOAD_FAILED;
const char *url_template = get_host_info( Selection(), uri_key );
if( url_template != NULL )
{
mkpath( package_url, url_template, package_name, mirror );
if( download.Get( package_url ) > 0 )
/*
- * Download was successful; clear the pending flag.
+ * Download was successful; clear the pending and failure flags.
*/
- flags &= ~(ACTION_DOWNLOAD);
+ flags &= ~(ACTION_DOWNLOAD | ACTION_DOWNLOAD_FAILED);
else
/* Diagnose failure; leave pending flag set.
*/
*/
while( current != NULL )
{
- /* ...while we haven't run off the end...
+ /* ...while we haven't run off the end, and collecting any diagnositic
+ * messages relating to any one package into a common digest...
*/
+ dmh_control( DMH_BEGIN_DIGEST );
if( (current->flags & ACTION_INSTALL) == ACTION_INSTALL )
{
/* For all packages specified in the current action list,
*/
current->DownloadSingleArchive( package_name, pkgArchivePath() );
}
- /* Repeat download action, for any additional packages specified
+ /* Flush out any diagnostics relating to the current package, then
+ * repeat the download action, for any additional packages specified
* in the current "actions" list.
*/
+ dmh_control( DMH_END_DIGEST );
current = current->next;
}
}
--- /dev/null
+#ifndef PKGINET_H
+/*
+ * pkginet.h
+ *
+ * $Id$
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Copyright (C) 2009, 2010, 2011, 2012, MinGW.org Project
+ *
+ *
+ * Public declaration of the download metering class, and support
+ * functions provided by the internet download agent.
+ *
+ *
+ * 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.
+ *
+ */
+#define PKGINET_H 1
+
+class pkgDownloadMeter
+{
+ /* Abstract base class, from which facilities for monitoring the
+ * progress of file downloads may be derived.
+ */
+ public:
+ /* Hooks for use in the implementation of the GUI download
+ * monitoring dialogue; in a CLI context, these effectively
+ * become no-ops.
+ */
+ static pkgDownloadMeter *UseGUI(){ return primary; }
+ virtual void ResetGUI( const char *, unsigned long ){}
+
+ /* The working method to refresh the download progress display;
+ * each derived class MUST furnish an implementation for this.
+ */
+ virtual int Update( unsigned long ) = 0;
+
+ protected:
+ /* Reference pointer to the primary instance of the download
+ * meter in the GUI; always set to NULL, in a CLI context.
+ */
+ static pkgDownloadMeter *primary;
+
+ /* Storage for the expected size of the active download...
+ */
+ unsigned long content_length;
+
+ /* ...and a method to format it for human readable display.
+ */
+ int SizeFormat( char *, unsigned long );
+};
+
+/* Entry point for the worker thread associated with the download
+ * monitoring dialogue, in the GUI context.
+ */
+EXTERN_C void pkgInvokeDownload( void * );
+
+#endif /* PKGINET_H: $RCSfile$: end of file */
--- /dev/null
+/*
+ * pkgnget.cpp
+ *
+ * $Id$
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Copyright (C) 2012, MinGW.org Project
+ *
+ *
+ * Implementation of the network download agent interface, through
+ * which the mingw-get GUI requests the services of the mingw-get DLL
+ * to get (download) package archives from internet repositories.
+ *
+ *
+ * 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.
+ *
+ */
+#include "guimain.h"
+#include "pkgbase.h"
+#include "pkginet.h"
+
+class pkgDownloadMeterGUI: public pkgDownloadMeter
+{
+ /* A locally defined class, through which the download agent
+ * may transmit progress monitoring data to the designated GUI
+ * download monitoring dialogue box.
+ */
+ public:
+ pkgDownloadMeterGUI( HWND );
+
+ virtual void ResetGUI( const char *, unsigned long );
+ virtual int Update( unsigned long );
+
+ inline ~pkgDownloadMeterGUI();
+
+ private:
+ HWND file_name, file_size, copy_size, copy_frac, progress_bar;
+};
+
+/* Constructor...
+ */
+pkgDownloadMeterGUI::pkgDownloadMeterGUI( HWND dialogue )
+{
+ /* Establish the global reference, through which the download
+ * agent will obtain access to the GUI dialogue...
+ */
+ primary = this;
+
+ /* ...and store references to its data controls.
+ */
+ file_name = GetDlgItem( dialogue, IDD_PROGRESS_MSG );
+ file_size = GetDlgItem( dialogue, IDD_PROGRESS_MAX );
+ copy_size = GetDlgItem( dialogue, IDD_PROGRESS_VAL );
+ copy_frac = GetDlgItem( dialogue, IDD_PROGRESS_PCT );
+ progress_bar = GetDlgItem( dialogue, IDD_PROGRESS_BAR );
+}
+
+void pkgDownloadMeterGUI::ResetGUI( const char *filename, unsigned long size )
+{
+ /* Method to reset the displayed content of the dialogue box to
+ * an appropriate initial state, in preparation for monitoring the
+ * download of a new archive file; the name of this file, and its
+ * anticipated size are preset, as specified by the arguments.
+ */
+ char size_buf[12]; SizeFormat( size_buf, 0 );
+ SendMessage( file_name, WM_SETTEXT, 0, (LPARAM)(filename) );
+ SendMessage( copy_size, WM_SETTEXT, 0, (LPARAM)(size_buf) );
+ SizeFormat( size_buf, content_length = size );
+ SendMessage( file_size, WM_SETTEXT, 0, (LPARAM)(size_buf) );
+ SendMessage( copy_frac, WM_SETTEXT, 0, (LPARAM)("0 %") );
+ SendMessage( progress_bar, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
+ SendMessage( progress_bar, PBM_SETPOS, 0, 0 );
+}
+
+int pkgDownloadMeterGUI::Update( unsigned long count )
+{
+ /* Method to update the download progress report; the download
+ * agent invokes this after each block of archive data has been
+ * received from the repository host, so that this method may
+ * refresh the progress counters in the dialogue box.
+ */
+ char size_buf[12];
+
+ /* First, we update the display of the actual byte count...
+ */
+ SizeFormat( size_buf, count );
+ SendMessage( copy_size, WM_SETTEXT, 0, (LPARAM)(size_buf) );
+
+ /* ...then we convert that byte count to a percentage of
+ * the anticipated file size, using the result to update
+ * the percentage completed, and the progress bar.
+ */
+ count = (count * 100) / content_length;
+ if( snprintf( size_buf, sizeof( size_buf ), "%d %", count ) >= sizeof( size_buf ) )
+ strcpy( size_buf, "*** %" );
+ SendMessage( copy_frac, WM_SETTEXT, 0, (LPARAM)(size_buf) );
+ SendMessage( progress_bar, PBM_SETPOS, count, 0 );
+}
+
+/* Destructor...
+ */
+inline pkgDownloadMeterGUI::~pkgDownloadMeterGUI()
+{
+ /* This must reset the global reference pointer, so the download
+ * agent will not attempt to access a dialogue box which has been
+ * closed by the GUI application.
+ */
+ primary = NULL;
+}
+
+inline void pkgActionItem::DownloadArchiveFiles( void )
+{
+ /* Helper method, invoked by the GUI application, to initiate
+ * an in-order traversal of the schedule of actions...
+ */
+ pkgActionItem *current;
+ if( (current = this) != NULL )
+ {
+ /* ...ensuring that the traversal commences at the first of
+ * the scheduled actions...
+ */
+ while( current->prev != NULL ) current = current->prev;
+
+ /* ...to download all requisite archive files.
+ */
+ DownloadArchiveFiles( current );
+ }
+}
+
+inline void AppWindowMaker::DownloadArchiveFiles( void )
+{
+ /* Helper method to redirect a request to initiate package
+ * download, from the controlling application window object
+ * to its associated schedule of actions object.
+ */
+ pkgData->Schedule()->DownloadArchiveFiles();
+}
+
+EXTERN_C void pkgInvokeDownload( void *window )
+{
+ /* Worker thread procedure, invoked by the OnCommand() method
+ * of the application window object, when initiating the archive
+ * download process via the appropriate monitoring dialogue.
+ */
+ pkgDownloadMeterGUI metered( (HWND)(window) );
+ GetAppWindow( GetParent( (HWND)(window) ))->DownloadArchiveFiles();
+ SendMessage( (HWND)(window), WM_COMMAND, (WPARAM)(IDOK), 0 );
+}
+
+/* $RCSfile$: end of file */