home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / ProgressM.C < prev    next >
C/C++ Source or Header  |  1998-11-19  |  5KB  |  167 lines

  1. // $Id: ProgressM.C,v 1.3 1998/11/19 20:38:31 zeller Exp $ -*- C++ -*-
  2. // Data Display progress meter
  3.  
  4. // Copyright (C) 1998 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char ProgressMeter_rcsid[] = 
  30.     "$Id: ProgressM.C,v 1.3 1998/11/19 20:38:31 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "ProgressM.h"
  37.  
  38. #include "Command.h"
  39. #include "DispValue.h"
  40. #include "charsets.h"
  41. #include "ddd.h"
  42. #include "string-fun.h"
  43. #include "verify.h"
  44. #include "version.h"
  45. #include "wm.h"
  46.  
  47. #include <Xm/Scale.h>
  48. #include <Xm/MessageB.h>
  49.  
  50. // Update progress meter every UPDATE_THRESHOLD characters
  51. const int ProgressMeter::UPDATE_THRESHOLD = 256;
  52.  
  53. // Popup working dialog when updating from at least DIALOG_THRESHOLD chars.
  54. const int ProgressMeter::DIALOG_THRESHOLD = 4096;
  55.  
  56. Widget ProgressMeter::dialog = 0;
  57. Widget ProgressMeter::scale  = 0;
  58.  
  59. ProgressMeter *ProgressMeter::active = 0;
  60.  
  61. ProgressMeter::ProgressMeter(const string& _msg)
  62.     : current(0), base(0), total(0), msg(_msg),
  63.       delay(_msg), last_shown(0),
  64.       old_background(DispValue::background),
  65.       aborted(false)
  66. {
  67.     DispValue::background = _process;
  68.     active = (ProgressMeter *)this;
  69.  
  70.     if (dialog == 0)
  71.     {
  72.     Arg args[10];
  73.     Cardinal arg = 0;
  74.     XtSetArg(args[arg], XmNdialogStyle, 
  75.          XmDIALOG_FULL_APPLICATION_MODAL); arg++;
  76.     dialog = verify(XmCreateWorkingDialog(find_shell(), 
  77.                           "update_displays_dialog", 
  78.                           args, arg));
  79.     XtUnmanageChild(XmMessageBoxGetChild(dialog, 
  80.                          XmDIALOG_OK_BUTTON));
  81.     XtUnmanageChild(XmMessageBoxGetChild(dialog, 
  82.                          XmDIALOG_HELP_BUTTON));
  83.  
  84.     arg = 0;
  85.     XtSetArg(args[arg], XmNorientation, XmHORIZONTAL); arg++;
  86.     XtSetArg(args[arg], XmNeditable, False);           arg++;
  87. #if XmVersion >= 2000
  88.     XtSetArg(args[arg], XmNslidingMode, XmTHERMOMETER); arg++;
  89. #endif
  90.     scale = verify(XmCreateScale(dialog, "scale", args, arg));
  91.     XtManageChild(scale);
  92.     }
  93. }
  94.  
  95. ProgressMeter::~ProgressMeter()
  96. {
  97.     DispValue::background = old_background;
  98.     if (active == this)
  99.     active = 0;
  100.  
  101.     if (aborted)
  102.     delay.outcome = "aborted";
  103.     XtRemoveCallback(dialog, XmNcancelCallback, CancelCB, 
  104.              XtPointer(&aborted));
  105.     XtUnmanageChild(dialog);
  106. }
  107.  
  108. void ProgressMeter::CancelCB(Widget, XtPointer client_data, XtPointer)
  109. {
  110.     bool *flag = (bool *)client_data;
  111.     *flag = true;
  112. }
  113.  
  114. bool ProgressMeter::_process(int remaining_length)
  115. {
  116.     if (active == 0)
  117.     return true;        // Treat inconsistency like abort
  118.  
  119.     return active->process(remaining_length);
  120. }
  121.  
  122. bool ProgressMeter::process(int remaining_length)
  123. {
  124.     int processed = base + current - remaining_length;
  125.  
  126. #if 0
  127.     clog << "Processed " << processed << "/" <<  total << " characters\n";
  128. #endif
  129.  
  130.     if (!aborted && total >= DIALOG_THRESHOLD && !XtIsManaged(dialog))
  131.     {
  132.     MString mmsg = rm(msg + "...");
  133.     XtVaSetValues(dialog, XmNmessageString, mmsg.xmstring(), NULL);
  134.     string title = DDD_NAME ": " + capitalize(msg);
  135.     XtVaSetValues(XtParent(dialog), XmNtitle, (char *)title, NULL);
  136.     XtAddCallback(dialog, XmNcancelCallback, CancelCB, 
  137.               XtPointer(&aborted));
  138.     manage_and_raise(dialog);
  139.     wait_until_mapped(dialog);
  140.     }
  141.  
  142.     if (processed - last_shown >= UPDATE_THRESHOLD)
  143.     {
  144.     // Another bunch of characters processed.  Wow!
  145.     int percent = (processed * 100) / total;
  146.  
  147.     if (XtIsManaged(dialog))
  148.         XmScaleSetValue(scale, percent);
  149.     else
  150.         set_status(msg + "... (" + itostring(percent) + "% processed)", 
  151.                true);
  152.  
  153.     last_shown = processed;
  154.     }
  155.  
  156.     // Interrupt if emergency
  157.     if (!aborted && process_emergencies())
  158.     aborted = true;
  159.  
  160.     // If we have a dialog, process its events
  161.     // (The dialog is modal, such that we cannot be called recursively)
  162.     if (!aborted && XtIsManaged(dialog))
  163.     process_pending_events();
  164.  
  165.     return aborted;
  166. }
  167.