]> cygwin.com Git - cygwin-apps/setup.git/commitdiff
2002-01-20 Robert Collins <rbtcollins@hotmail.com> cygwin-1-3-7-1
authorRobert Collins <rbtcollins@hotmail.com>
Sat, 19 Jan 2002 13:33:17 +0000 (13:33 +0000)
committerRobert Collins <rbtcollins@hotmail.com>
Sat, 19 Jan 2002 13:33:17 +0000 (13:33 +0000)
        * Makefile.in (OBJS): Add win32.o - win32 support functions.
        * README: Update todos.
        * archive.cc (extract_file): Support a suffix for appending to extracted files.
        * archive.h: Ditto.
        * choose.cc (set_view_mode): Use the new view::views class.
        (view::views::Unknown): New static for defaulting view::views variables.
        (view::views::PackageFull): New static for the current view.
        (view::views::Package): Ditto.
        (view::views::Category): Ditto.
        (topbucket::paint): Remove.
        (topbucket::empty): Rename to pick_category_line::empty.
        (topbucket::~topbucket): Remove.
        (paint): Use the new view::views class.
        Don't paint 'all' as a category when showing package categoies.
        (pick_category_line::actiontext): New method.
        (pick_category_line::paint): Make showing the category optional, and show the
        'category action'.
        (pick_category_line::click): Make showing the category optional, and
        differentiate between the name being clicked, and the action description.
        (view::view): Use the new view::views class.
        (view::set_view_mode): Ditto.
        (view::mode_caption): Ditto.
        (view::views::caption): New method.
        (view::set_headers): Use the new view::views class.
        (view::clear_view): Ditto.
        (viewsplusplus): Replaced by
        (view::views::operator++): New operator.
        (set_view_mode): Use the new view::views class.
        (create_listview): Ditto.
        (dialog_cmd): Ditto.
        * choose.h (actions): Remove.
        (views): Remove.
        (pick_line): Add a new convenience constructor.
        (top_bucket): Remove.
        (pick_category_line): Reparent under pick_line, and adsorb top_bucket.
        (view::views): New class.
        * ini.h: Don't include choose.h
        (is_download_action): Remove.
        (is_upgrade_action): Remove.
        (is_uninstall_action): Remove.
        (is_full_action): Remove.
        * install.cc (num_replacements): New static.
        (rebootneeded): Ditto.
        (replace_one): Handle upgrades separate from removal or new installs.
        (install_one_source): Handle in use files.
        (install_one): Don't repeat upgrades.
        (do_install_thread): Initialize new statics.
        Order actions as uninstall, replace, install.
        Warn about rebooting if needed.
        * res.rc (IDS_REBOOT_REQUIRED): New string.
        * resource.h (IDS_REBOOT_REQUIRED): Give value.
        * win32.h: Declare class Win32, and update copyright and intent message.
        * win32.cc: New file.

13 files changed:
ChangeLog
Makefile.in
README
archive.cc
archive.h
choose.cc
choose.h
ini.h
install.cc
res.rc
resource.h
win32.cc [new file with mode: 0644]
win32.h

index c21a74a518415dedc9075b97e08d47e0ec068fa2..4190111903298ef6d0f8d517a664702b80163971 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,59 @@
+2002-01-20  Robert Collins  <rbtcollins@hotmail.com>
+
+       * Makefile.in (OBJS): Add win32.o - win32 support functions.
+       * README: Update todos.
+       * archive.cc (extract_file): Support a suffix for appending to extracted files.
+       * archive.h: Ditto.
+       * choose.cc (set_view_mode): Use the new view::views class.
+       (view::views::Unknown): New static for defaulting view::views variables.
+       (view::views::PackageFull): New static for the current view.
+       (view::views::Package): Ditto.
+       (view::views::Category): Ditto.
+       (topbucket::paint): Remove.
+       (topbucket::empty): Rename to pick_category_line::empty.
+       (topbucket::~topbucket): Remove.
+       (paint): Use the new view::views class.
+       Don't paint 'all' as a category when showing package categoies.
+       (pick_category_line::actiontext): New method.
+       (pick_category_line::paint): Make showing the category optional, and show the
+       'category action'.
+       (pick_category_line::click): Make showing the category optional, and
+       differentiate between the name being clicked, and the action description.
+       (view::view): Use the new view::views class.
+       (view::set_view_mode): Ditto.
+       (view::mode_caption): Ditto.
+       (view::views::caption): New method.
+       (view::set_headers): Use the new view::views class.
+       (view::clear_view): Ditto.
+       (viewsplusplus): Replaced by 
+       (view::views::operator++): New operator.
+       (set_view_mode): Use the new view::views class.
+       (create_listview): Ditto.
+       (dialog_cmd): Ditto.
+       * choose.h (actions): Remove.
+       (views): Remove.
+       (pick_line): Add a new convenience constructor.
+       (top_bucket): Remove.
+       (pick_category_line): Reparent under pick_line, and adsorb top_bucket.
+       (view::views): New class.
+       * ini.h: Don't include choose.h
+       (is_download_action): Remove.
+       (is_upgrade_action): Remove.
+       (is_uninstall_action): Remove.
+       (is_full_action): Remove.
+       * install.cc (num_replacements): New static.
+       (rebootneeded): Ditto.
+       (replace_one): Handle upgrades separate from removal or new installs.
+       (install_one_source): Handle in use files.
+       (install_one): Don't repeat upgrades.
+       (do_install_thread): Initialize new statics.
+       Order actions as uninstall, replace, install.
+       Warn about rebooting if needed.
+       * res.rc (IDS_REBOOT_REQUIRED): New string.
+       * resource.h (IDS_REBOOT_REQUIRED): Give value.
+       * win32.h: Declare class Win32, and update copyright and intent message.
+       * win32.cc: New file.
+
 2002-01-15  Corinna Vinschen  <corinna@vinschen.de>
 
        * io_stream.cc (io_stream::gets): Eliminate trailing new line chars.
index 41a3dedd589ed16ba89bd2270d2f599a96c70233..38fbfeede537ae828e56e63a0be10585532748c7 100644 (file)
@@ -143,6 +143,7 @@ OBJS = \
        state.o \
        threebar.o \
        version.o \
+       win32.o \
        window.o \
        $E
 
diff --git a/README b/README
index 3520273fc413400784448808dba5b931ad42ab56..392fdfca0f4f85a7304d37324175cceccb903816 100644 (file)
--- a/README
+++ b/README
@@ -2,6 +2,7 @@ This directory contains the source for the setup program for the cygwin
 net releases.
 
 TODO:
+* Remove "/" from symlinks (etags.exe->/ctags.exe is an example
 * Src tickbox /source only can be confusing.
 * support rpm/deb files for reading the package from. (To allow the maintainers the use of rpm/deb tools to create packages.)
   * make a librar(y|ies) for setup and cygcheck to use containing 
index d3f8b24e7793d340304c78cf1621a47074471fe3..0b464692c8920f6454e1da75470f2377906bdea8 100644 (file)
@@ -78,11 +78,11 @@ archive::extract (io_stream * original)
 }
 
 int
-archive::extract_file (archive * source, const char *prefix)
+archive::extract_file (archive * source, const char *prefix, const char *suffix)
 {
   if (!source)
     return 1;
-  const char *destfilename = concat (prefix, source->next_file_name (), 0);
+  const char *destfilename = concat (prefix, source->next_file_name (), suffix, 0);
   switch (source->next_file_type ())
     {
     case ARCHIVE_FILE_REGULAR:
index 313e454448a8d080b82fa4e0dd748a34c7a5dbb4..22d2d2fd795df3bffcae122335918e9ac6aa1653 100644 (file)
--- a/archive.h
+++ b/archive.h
@@ -50,10 +50,11 @@ public:
    * The stream is not taken over - it will not be automatically deleted
    */
   virtual io_stream *extract_file () = NULL;
-  /* extract the next file to the given prefix in one step
+  /* extract the next file to the given prefix in one step, and name it with the
+   * given suffix.
    * returns 1 on failure.
    */
-  static int extract_file (archive *, const char *);
+  static int extract_file (archive *, const char *, const char * = NULL);
 
   /* 
    * To create a stream that will be compressed, you should open the url, and then get a new stream
index bc826ed35b75c2540b6925fdb2cd45718feb4287..8081d016103f9eb1b51ccedbc22f81fc34e2a215 100644 (file)
--- a/choose.cc
+++ b/choose.cc
@@ -103,7 +103,13 @@ static struct _header cat_headers[] = {
   {0, 0, 0, 0}
 };
 
-static void set_view_mode (HWND h, views mode);
+static void set_view_mode (HWND h, view::views mode);
+
+// view:: views
+const view::views view::views::Unknown (0);
+const view::views view::views::PackageFull (1);
+const view::views view::views::Package = view::views (2);
+const view::views view::views::Category (3);
 
 packageversion *
 pkgtrustp (packagemeta const &pkg, trusts const t)
@@ -156,18 +162,7 @@ add_required (packagemeta & pkg, size_t depth = 0)
 }
 
 void
-topbucket::paint (HDC hdc, int x, int y, int row, int show_cat)
-{
-  int accum_row = row;
-  for (size_t n = 1; n <= bucket.number (); n++)
-    {
-      bucket[n]->paint (hdc, x, y, accum_row, show_cat);
-      accum_row += bucket[n]->itemcount ();
-    }
-}
-
-void
-topbucket::empty (void)
+pick_category_line::empty (void)
 {
   while (bucket.number ())
     {
@@ -176,25 +171,6 @@ topbucket::empty (void)
     }
 }
 
-topbucket::~topbucket (void)
-{
-  empty ();
-}
-
-int
-topbucket::click (int const myrow, int const ClickedRow, int const x)
-{
-  int accum_row = myrow;
-  for (size_t n = 1; n <= bucket.number (); n++)
-    {
-      accum_row += bucket[n]->itemcount ();
-      if (accum_row > ClickedRow)
-       return bucket[n]->click (accum_row - bucket[n]->itemcount (),
-                                ClickedRow, x);
-    }
-  return 0;
-}
-
 static void
 paint (HWND hwnd)
 {
@@ -218,7 +194,7 @@ paint (HWND hwnd)
                     cr.bottom);
 
   chooser->contents.paint (hdc, x, y, 0, (chooser->get_view_mode () ==
-                                         VIEW_CATEGORY) ? 0 : 1);
+                                         view::views::Category) ? 0 : 1);
 
   if (chooser->contents.itemcount () == 0)
     {
@@ -635,12 +611,15 @@ pick_pkg_line::paint (HDC hdc, int x, int y, int row, int show_cat)
   /* shows "first" category - do we want to show any? */
   if (pkg.Categories.number () && show_cat)
     {
+      int index = 1;
+      if (!strcasecmp (pkg.Categories[1]->key.name, "All"))
+       index = 2;
       IntersectClipRect (hdc, x + chooser->headers[chooser->cat_col].x, by,
                         x + chooser->headers[chooser->cat_col].x +
                         chooser->headers[chooser->cat_col].x, by + 11);
       TextOut (hdc, x + chooser->headers[chooser->cat_col].x + HMARGIN / 2, r,
-              pkg.Categories[1]->key.name,
-              strlen (pkg.Categories[1]->key.name));
+              pkg.Categories[index]->key.name,
+              strlen (pkg.Categories[index]->key.name));
       SelectClipRgn (hdc, oldClip2);
     }
 
@@ -664,6 +643,20 @@ pick_pkg_line::paint (HDC hdc, int x, int y, int row, int show_cat)
   RestoreDC (hdc, oldDC);
 }
 
+char const *
+pick_category_line::actiontext ()
+{
+  switch (current_default)
+  {
+    case Default_action: return "Default";
+    case Install_action: return "Install";
+    case Reinstall_action: return "Reinstall";
+    case Uninstall_action: return "Uninstall";
+  }
+  // Pacify GCC: (all case options are checked above)
+  return 0;
+}
+
 void
 pick_category_line::paint (HDC hdc, int x, int y, int row, int show_cat)
 {
@@ -673,14 +666,23 @@ pick_category_line::paint (HDC hdc, int x, int y, int row, int show_cat)
       int by = r + tm.tmHeight - 11;
       TextOut (hdc, x + chooser->headers[chooser->cat_col].x + HMARGIN / 2 + depth * 8, 
          r, cat.name, strlen (cat.name));
-      SIZE s;
-      GetTextExtentPoint32 (hdc, cat.name, strlen (cat.name), &s);
+      if (!labellength)
+        { 
+         SIZE s;
+         GetTextExtentPoint32 (hdc, cat.name, strlen (cat.name), &s);
+         labellength = s.cx;
+       }
       SelectObject (bitmap_dc, bm_spin);
       BitBlt (hdc,
                  x + chooser->headers[chooser->cat_col].x + 
-                 s.cx + depth * 8 +
+                 labellength + depth * 8 +
                  ICON_MARGIN +
                  HMARGIN / 2, by, 11, 11, bitmap_dc, 0, 0, SRCCOPY);
+      TextOut (hdc,
+              x + chooser->headers[chooser->cat_col].x + 
+              labellength + depth * 8 + 
+              ICON_MARGIN + SPIN_WIDTH +
+              HMARGIN, r, actiontext(), strlen (actiontext()));
     }
   if (collapsed)
     return;
@@ -716,11 +718,23 @@ pick_category_line::click (int const myrow, int const ClickedRow, int const x)
 {
   if (myrow == ClickedRow && show_label)
     {
-      collapsed = !collapsed;
-      int accum_row = 0;
-      for (size_t n = 1; n <= bucket.number (); n++)
-       accum_row += bucket[n]->itemcount ();
-      return collapsed ? accum_row : -accum_row;
+      if ((size_t) x >= chooser->headers[chooser->cat_col].x +
+       labellength + depth * 8 +
+       ICON_MARGIN +
+       HMARGIN / 2)
+        {
+         for (size_t n = 1; n <= bucket.number (); n++)
+          ; 
+         return 0;
+        }
+      else
+        {
+          collapsed = !collapsed;
+          int accum_row = 0;
+          for (size_t n = 1; n <= bucket.number (); n++)
+           accum_row += bucket[n]->itemcount ();
+          return collapsed ? accum_row : -accum_row;
+       }
     }
   else
     {
@@ -798,10 +812,10 @@ contents (cat, 0, false, true), listview (lv)
 
   header_height = wp.cy;
 
-  view_mode = VIEW_PACKAGE;
+  view_mode = view::views::Package;
   set_headers ();
   init_headers (dc);
-  view_mode = VIEW_CATEGORY;
+  view_mode = view::views::Category;
   set_headers ();
   init_headers (dc);
 
@@ -812,27 +826,28 @@ contents (cat, 0, false, true), listview (lv)
 }
 
 void
-view::set_view_mode (views _mode)
+view::set_view_mode (view::views _mode)
 {
-  if (_mode == NVIEW)
-    view_mode = VIEW_PACKAGE_FULL;
-  else
-    view_mode = _mode;
+  view_mode = _mode;
   set_headers ();
 }
 
 const char *
 view::mode_caption ()
 {
-  switch (view_mode)
+  return view_mode.caption ();
+}
+
+const char *
+view::views::caption ()
+{
+  switch (_value)
     {
-    case VIEW_UNKNOWN:
-      return "";
-    case VIEW_PACKAGE_FULL:
+    case 1:
       return "Full";
-    case VIEW_PACKAGE:
+    case 2:
       return "Partial";
-    case VIEW_CATEGORY:
+    case 3:
       return "Category";
     default:
       return "";
@@ -844,12 +859,11 @@ int DoInsertItem (HWND hwndHeader, int iInsertAfter, int nWidth, LPSTR lpsz);
 void
 view::set_headers ()
 {
-  switch (view_mode)
+  if (view_mode == views::Unknown)
+    return;
+  if (view_mode == views::PackageFull ||
+      view_mode == views::Package)
     {
-    case VIEW_UNKNOWN:
-      return;
-    case VIEW_PACKAGE_FULL:
-    case VIEW_PACKAGE:
       headers = pkg_headers;
       current_col = 0;
       new_col = 1;
@@ -857,8 +871,9 @@ view::set_headers ()
       cat_col = 3;
       pkg_col = 4;
       last_col = 4;
-      break;
-    case VIEW_CATEGORY:
+    }
+  else if (view_mode == views::Category)
+    {
       headers = cat_headers;
       current_col = 1;
       new_col = 2;
@@ -866,10 +881,9 @@ view::set_headers ()
       cat_col = 0;
       pkg_col = 4;
       last_col = 4;
-      break;
-    default:
-      return;
     }
+  else
+    return;
   while (int n = SendMessage (listheader, HDM_GETITEMCOUNT, 0, 0))
     {
       SendMessage (listheader, HDM_DELETEITEM, n - 1, 0);
@@ -931,7 +945,7 @@ view::init_headers (HDC dc)
 void
 view::insert_pkg (packagemeta & pkg)
 {
-  if (view_mode != VIEW_CATEGORY)
+  if (view_mode != views::Category)
     {
       pick_pkg_line & line = *new pick_pkg_line (pkg);
       contents.insert (line);
@@ -972,38 +986,22 @@ void
 view::clear_view (void)
 {
   contents.empty ();
-  switch (view_mode)
-  {
-  case VIEW_UNKNOWN:
-    break;
-  case VIEW_PACKAGE_FULL:
-  case VIEW_PACKAGE:
+  if (view_mode == views::Unknown)
+    return;
+  if (view_mode == views::PackageFull ||
+      view_mode == views::Package)
     contents.ShowLabel (false);
-    break;
-  case VIEW_CATEGORY:
+  else if (view_mode == views::Category)
     contents.ShowLabel ();
-    break;
-  default:
-    return;
-  }
 }
 
-static views
-viewsplusplus (views theview)
+view::views& 
+view::views::operator++ ()
 {
-  switch (theview)
-    {
-    case VIEW_UNKNOWN:
-      return VIEW_PACKAGE_FULL;
-    case VIEW_PACKAGE_FULL:
-      return VIEW_PACKAGE;
-    case VIEW_PACKAGE:
-      return VIEW_CATEGORY;
-    case VIEW_CATEGORY:
-      return NVIEW;
-    default:
-      return VIEW_UNKNOWN;
-    }
+  ++_value;
+  if (_value > Category._value)
+    _value = 1;
+  return *this;
 }
 
 int
@@ -1013,15 +1011,14 @@ view::click (int row, int x)
 }
 
 static void
-set_view_mode (HWND h, views mode)
+set_view_mode (HWND h, view::views mode)
 {
   chooser->set_view_mode (mode);
 
   chooser->clear_view ();
   packagedb db;
-  switch (chooser->get_view_mode ())
+  if (chooser->get_view_mode () == view::views::Package)
     {
-    case VIEW_PACKAGE:
       for (size_t n = 1; n <= db.packages.number (); n++)
        {
          packagemeta & pkg = *db.packages[n];
@@ -1030,21 +1027,20 @@ set_view_mode (HWND h, views mode)
                  && (pkg.desired->srcpicked || pkg.desired->binpicked)))
            chooser->insert_pkg (pkg);
        }
-      break;
-    case VIEW_PACKAGE_FULL:
+    }
+  else if (chooser->get_view_mode () == view::views::PackageFull)
+    {
       for (size_t n = 1; n <= db.packages.number (); n++)
        {
          packagemeta & pkg = *db.packages[n];
          chooser->insert_pkg (pkg);
        }
-      break;
-    case VIEW_CATEGORY:
+    }
+  else if (chooser->get_view_mode () == view::views::Category)
+    {
       /* start collapsed. TODO: make this a chooser flag */
       for (size_t n = 1; n <= db.categories.number (); n++)
        chooser->insert_category (db.categories[n], CATEGORY_COLLAPSED);
-      break;
-    default:
-      break;
     }
 
   RECT r;
@@ -1110,10 +1106,10 @@ create_listview (HWND dlg, RECT * r)
                       hinstance, 0);
   ShowWindow (lv, SW_SHOW);
   packagedb db;
-  chooser = new view (VIEW_CATEGORY, lv, db.categories.registerbykey("All"));
+  chooser = new view (view::views::Category, lv, db.categories.registerbykey("All"));
 
   default_trust (lv, TRUST_CURR);
-  set_view_mode (lv, VIEW_CATEGORY);
+  set_view_mode (lv, view::views::Category);
   if (!SetDlgItemText (dlg, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ()))
     log (LOG_BABBLE, "Failed to set View button caption %ld",
         GetLastError ());
@@ -1162,7 +1158,7 @@ dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
       set_view_mode (lv, chooser->get_view_mode ());
       break;
     case IDC_CHOOSE_VIEW:
-      set_view_mode (lv, viewsplusplus (chooser->get_view_mode ()));
+      set_view_mode (lv, ++chooser->get_view_mode ());
       if (!SetDlgItemText
          (h, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ()))
        log (LOG_BABBLE, "Failed to set View button caption %ld",
index c1c37906f550f0e30ffe525042f0b9aafc553930..b7ee67a4f23d19803c97960ae6e4cb689ab5ee3c 100644 (file)
--- a/choose.h
+++ b/choose.h
@@ -24,43 +24,6 @@ class packagemeta;
 #define CATEGORY_EXPANDED  0
 #define CATEGORY_COLLAPSED 1
 
-typedef enum
-{
-  /* Note that the next four items must be in the same order as the
-     TRUST items in ini.h. */
-  ACTION_UNKNOWN,
-  ACTION_PREV,
-  ACTION_CURR,
-  ACTION_TEST,
-  ACTION_SKIP,
-  ACTION_UNINSTALL,
-  ACTION_REDO,
-  ACTION_SRC_ONLY,
-  ACTION_LAST,
-  ACTION_ERROR,
-  /* Use ACTION_SAME when you want to leve the current version unaltered
-   * even if it that version is not in setup.ini
-   */
-  ACTION_SAME = 100,
-  /* Actions taken when installed version matches the selected version. */
-  ACTION_SAME_PREV = ACTION_PREV + ACTION_SAME,
-  ACTION_SAME_CURR = ACTION_CURR + ACTION_SAME,
-  ACTION_SAME_TEST = ACTION_TEST + ACTION_SAME,
-  /* Last action. */
-  ACTION_SAME_LAST
-}
-actions;
-
-typedef enum
-{
-  VIEW_UNKNOWN,
-  VIEW_PACKAGE_FULL,
-  VIEW_PACKAGE,
-  VIEW_CATEGORY,
-  NVIEW
-}
-views;
-
 struct _header
 {
   const char *text;
@@ -90,9 +53,8 @@ public:
   {
   };
 protected:
-  pick_line ()
-  {
-  };
+  pick_line ()  {  };
+  pick_line (char const *aKey):key(aKey) {};
   pick_line (pick_line const &);
   pick_line & operator= (pick_line const &);
 };
@@ -121,44 +83,12 @@ private:
   packagemeta & pkg;
 };
 
-class topbucket:public pick_line
-{
-public:
-  topbucket ()
-  {
-    key = 0;
-  };
-  virtual void paint (HDC hdc, int x, int y, int row, int show_cat);
-  virtual int click (int const myrow, int const ClickedRow, int const x);
-  virtual int itemcount () const
-  {
-    int t = 0;
-    for (size_t n = 1; n <= bucket.number (); n++)
-        t += bucket[n]->itemcount ();
-      return t;
-  };
-  virtual bool IsContainer (void) const
-  {
-    return true;
-  }
-  virtual void insert (pick_line & aLine)
-  {
-    bucket.registerbyobject (aLine);
-  }
-  virtual void empty (void);
-  virtual ~ topbucket ();
-protected:
-  topbucket (topbucket const &);
-  topbucket & operator= (topbucket const &);
-  list < pick_line, char const *, strcasecmp > bucket;
-};
-
-
-class pick_category_line:public topbucket
+class pick_category_line:public pick_line
 {
 public:
   pick_category_line (Category & _cat, size_t thedepth = 0, bool aBool =
-                     true, bool aBool2 = true):cat (_cat), depth(thedepth)
+                     true, bool aBool2 = true):pick_line (_cat.key), current_default (Default_action), 
+  cat (_cat), labellength (0), depth(thedepth)
   {
     if (aBool)
       {
@@ -170,9 +100,8 @@ public:
        collapsed = false;
        show_label = aBool2;
       }
-    
-    key = _cat.key;
   };
+  ~pick_category_line (){ empty (); }
   void ShowLabel(bool aBool = true) {show_label = aBool; if (!show_label) collapsed = false;}
   virtual void paint (HDC hdc, int x, int y, int row, int show_cat);
   virtual int click (int const myrow, int const ClickedRow, int const x);
@@ -185,15 +114,36 @@ public:
         t += bucket[n]->itemcount ();
       return t;
   };
+  virtual bool IsContainer (void) const
+  {
+    return true;
+  }
+  virtual void insert (pick_line & aLine)
+  {
+    bucket.registerbyobject (aLine);
+  }
+  void empty ();
 private:
+  enum _actions {
+    Default_action,
+    Install_action,
+    Reinstall_action,
+    Uninstall_action
+  } current_default;
+  char const * actiontext();
   Category & cat;
   bool collapsed;
   bool show_label;
+  size_t labellength;
   size_t depth;
+  pick_category_line (pick_category_line const &);
+  pick_category_line & operator= (pick_category_line const &);
+  list < pick_line, char const *, strcasecmp > bucket;
 };
 
 class view
 {
+  class views;
 public:
   int num_columns;
   views get_view_mode () 
@@ -221,6 +171,26 @@ public:
     return listheader;
   }
 
+
+  class views {
+    public:
+    static const views Unknown;
+    static const views PackageFull;
+    static const views Package;
+    static const views Category;
+    static const views NView;
+    views () : _value (0) {};
+    views (int aInt) { _value = aInt; if (_value < 0 || _value > 3)
+      _value = 0;}
+    views& operator++ ();
+    bool operator == (views const &rhs) {return _value == rhs._value;}
+    bool operator != (views const &rhs) {return _value != rhs._value;}
+    const char * caption ();
+    
+    private:
+     int _value;
+  };
+  
 private:
     HWND listview;
   HWND listheader;
diff --git a/ini.h b/ini.h
index 4be9161801652d42a3670a20290c3a100f2873f7..ff015f28522109d97e3ee988a6a8f2b2ed4dd0ae 100644 (file)
--- a/ini.h
+++ b/ini.h
@@ -21,8 +21,6 @@ void ini_init (io_stream *, char const *);
 #define YYSTYPE char *
 
 #ifdef __cplusplus
-/* For enums */
-#include "choose.h"
 
 /* When setup.ini is parsed, the information is stored according to
    the declarations here.  ini.cc (via inilex and iniparse)
@@ -52,29 +50,6 @@ typedef enum
 }
 excludes;
 
-#define is_download_action(pkg) \
-  ((pkg)->action == ACTION_PREV || \
-   (pkg)->action == ACTION_CURR || \
-   (pkg)->action == ACTION_TEST || \
-   (pkg)->action == ACTION_REDO || \
-   (pkg)->action == ACTION_SRC_ONLY)
-
-#define is_upgrade_action(pkg) \
-  (((pkg)->action >= ACTION_CURR && \
-    (pkg)->action <= ACTION_TEST) || \
-   (pkg)->action == ACTION_REDO)
-
-#define is_uninstall_action(pkg) \
-  (is_upgrade_action (pkg) || \
-   (pkg)->action == ACTION_PREV || \
-   (pkg)->action == ACTION_UNINSTALL)
-
-#define is_full_action(pkg) \
-  (((pkg)->action >= ACTION_SAME_PREV && (pkg)->action <= ACTION_SAME_TEST) \
-   || (pkg)->action == ACTION_SKIP)
-
-#define SRCACTION_NO           0
-#define SRCACTION_YES          1
 #endif
 
 #endif /* _INI_H_ */
index 1dbdcaa3e87f109cd9081a343c62c78964aeaf83..2b4d5307bba77225b52869adf6e7b357ebe22aad 100644 (file)
@@ -20,8 +20,7 @@
    files in /etc/setup/\* and create the mount points. */
 
 #if 0
-static const char *cvsid =
-  "\n%%% $Id$\n";
+static const char *cvsid = "\n%%% $Id$\n";
 #endif
 
 #include "win32.h"
@@ -111,7 +110,12 @@ static const char *standard_dirs[] = {
   0
 };
 
-static int num_installs, num_uninstalls;
+static int num_installs, num_replacements, num_uninstalls;
+static void uninstall_one (packagemeta &);
+static int replace_one (packagemeta &);
+static int install_one_source (packagemeta &, packagesource &, char const *,
+                              package_type_t);
+static bool rebootneeded;
 
 /* FIXME: upgrades should be a method too */
 static void
@@ -124,6 +128,28 @@ uninstall_one (packagemeta & pkgm)
   num_uninstalls++;
 }
 
+/* uninstall and install a package, preserving configuration
+ * files and the like.
+ * This method should also know about replacing in-use file.
+ * ASSUMPTIONS: pkgm is installed.
+ *             pkgm has a desired package.
+ */
+static int
+replace_one (packagemeta & pkg)
+{
+  int errors = 0;
+  Progress.SetText1 ("Replacing...");
+  Progress.SetText2 (pkg.name);
+  log (0, "Replacing %s", pkg.name);
+  pkg.uninstall ();
+
+  errors +=
+    install_one_source (pkg, pkg.desired->bin, "cygfile:///", package_binary);
+  if (!errors)
+    pkg.installed = pkg.desired;
+  num_replacements++;
+  return errors;
+}
 
 
 /* install one source at a given prefix. */
@@ -183,8 +209,87 @@ install_one_source (packagemeta & pkgm, packagesource & source,
          log (LOG_BABBLE, "Installing file %s%s", prefix, fn);
          if (archive::extract_file (thefile, prefix) != 0)
            {
-             log (0, "Unable to install file %s%s", prefix, fn);
-             errors++;
+             //extract to temp location
+             if (archive::extract_file (thefile, prefix, ".new") != 0)
+               {
+                 log (0, "Unable to install file %s%s", prefix, fn);
+                 errors++;
+               }
+             else
+               //switch Win32::OS
+               {
+                 switch (Win32::OS ())
+                   {
+                   case Win32::Win9x:{
+                     /* Get the short file names */
+                     char source[MAX_PATH];
+                     unsigned int len =
+                       GetShortPathName (cygpath ("/", fn, ".new", 0),
+                                         source, MAX_PATH);
+                     if (!len || len > MAX_PATH)
+                       {
+                         log (0,
+                              "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+                              cygpath ("/", fn, 0), cygpath ("/", fn, ".new",
+                                                             0),
+                              GetLastError ());
+                         ++errors;
+                       }
+                     else
+                       {
+                         char dest[MAX_PATH];
+                         len =
+                           GetShortPathName (cygpath ("/", fn, 0), dest,
+                                             MAX_PATH);
+                         if (!len || len > MAX_PATH)
+                           {
+                             log (0,
+                                  "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+                                  cygpath ("/", fn, 0), cygpath ("/", fn,
+                                                                 ".new", 0),
+                                  GetLastError ());
+                             ++errors;
+
+                           }
+                         else
+                           /* trigger a replacement on reboot */
+                         if (!WritePrivateProfileString
+                               ("rename", dest, source, "WININIT.INI"))
+                           {
+                             log (0,
+                                  "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+                                  cygpath ("/", fn, 0), cygpath ("/", fn,
+                                                                 ".new", 0),
+                                  GetLastError ());
+                             ++errors;
+                           }
+
+                       }
+                   }
+                     break;
+                   case Win32::WinNT:
+                     /* XXX FIXME: prefix may not be / for in use files -
+                      * although it most likely is
+                      * - we need a io method to get win32 paths 
+                      * or to wrap this system call
+                      */
+                     if (!MoveFileEx (cygpath ("/", fn, ".new", 0),
+                                      cygpath ("/", fn, 0),
+                                      MOVEFILE_DELAY_UNTIL_REBOOT |
+                                      MOVEFILE_REPLACE_EXISTING))
+                       {
+                         log (0,
+                              "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+                              cygpath ("/", fn, 0), cygpath ("/", fn, ".new",
+                                                             0),
+                              GetLastError ());
+                         ++errors;
+                       }
+                     else
+                       rebootneeded = true;
+                     break;
+                   }
+               }
            }
 
          progress (tmp->tell ());
@@ -213,7 +318,7 @@ install_one (packagemeta & pkg)
 {
   int errors = 0;
 
-  if (pkg.desired->binpicked)
+  if (pkg.installed != pkg.desired && pkg.desired->binpicked)
     {
       errors +=
        install_one_source (pkg, pkg.desired->bin, "cygfile:///",
@@ -306,7 +411,8 @@ do_install_thread (HINSTANCE h, HWND owner)
   int i;
   int errors = 0;
 
-  num_installs = 0, num_uninstalls = 0;
+  num_installs = 0, num_uninstalls = 0, num_replacements = 0;
+  rebootneeded = false;
 
   next_dialog = IDD_DESKTOP;
 
@@ -356,13 +462,33 @@ do_install_thread (HINSTANCE h, HWND owner)
        }
     }
 
+  /* start with uninstalls - remove files that new packages may replace */
   for (size_t n = 1; n <= db.packages.number (); n++)
     {
       packagemeta & pkg = *db.packages[n];
       if (pkg.installed && (!pkg.desired || pkg.desired != pkg.installed))
+       uninstall_one (pkg);
+    }
+
+  /* now in-place binary upgrades/reinstalls, as these may remove fils 
+   * that have been moved into new packages
+   */
+
+  for (size_t n = 1; n <= db.packages.number (); n++)
+    {
+      packagemeta & pkg = *db.packages[n];
+      if (pkg.installed && pkg.desired && pkg.desired->binpicked)
        {
-         uninstall_one (pkg);
+         int e = 0;
+         e += replace_one (pkg);
+         if (e)
+           errors++;
        }
+    }
+
+  for (size_t n = 1; n <= db.packages.number (); n++)
+    {
+      packagemeta & pkg = *db.packages[n];
 
       if (pkg.desired && (pkg.desired->srcpicked || pkg.desired->binpicked))
        {
@@ -375,6 +501,9 @@ do_install_thread (HINSTANCE h, HWND owner)
        }
     }                          // end of big package loop
 
+  if (rebootneeded)
+    note (owner, IDS_REBOOT_REQUIRED);
+
   int temperr;
   if ((temperr = db.flush ()))
     {
diff --git a/res.rc b/res.rc
index 5844c28a8b10758cde983fdef25f86ee31907ba3..c35db272fb8708c268d0365b0c00ca3052210efd 100644 (file)
--- a/res.rc
+++ b/res.rc
@@ -462,6 +462,7 @@ BEGIN
     IDS_ERR_RENAME          "Can't rename %s to %s: %s"
     IDS_NOTHING_INSTALLED   "Nothing needed to be installed"
     IDS_INSTALL_COMPLETE    "Installation Complete"
+    IDS_REBOOT_REQUIRED     "In-use files have been replaced. You need to reboot as soon as possible to activate the new versions. Cygwin may operate incorrectly until you reboot."
 END
 
 STRINGTABLE DISCARDABLE 
index 926ef9348f757bb00b9a543cab8fdcb8a1ab876b..5718f15be8c036ad7902a49f6eff350b1a8aaf59 100644 (file)
 #define IDC_STATIC_WELCOME_TITLE        1061
 #define IDC_EDIT_USER_URL               1062
 #define IDC_BUTTON_ADD_URL              1063
+#define IDS_REBOOT_REQUIRED            1064
 #define IDC_STATIC                      -1
 
 // Next default values for new objects
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        129
 #define _APS_NEXT_COMMAND_VALUE         40003
-#define _APS_NEXT_CONTROL_VALUE         1064
+#define _APS_NEXT_CONTROL_VALUE         1065
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
diff --git a/win32.cc b/win32.cc
new file mode 100644 (file)
index 0000000..ad3acf6
--- /dev/null
+++ b/win32.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2002, Robert Collins
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ * Written by Robert Collins <rbtcollins@hotmail.com>
+ *
+ */
+
+/* The purpose of this file is to centralize all the message
+   functions. */
+
+#if 0
+static const char *cvsid =
+  "\n%%% $Id$\n";
+#endif
+
+#include "win32.h"
+
+enum Win32::_os
+Win32::OS ()
+{
+  OSVERSIONINFO VersionInfo;
+  VersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+  if (!GetVersionEx (&VersionInfo))
+    {
+      // Throw an exception or something ??
+    }
+  if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+    return Win9x;
+  else
+    return WinNT;
+}
diff --git a/win32.h b/win32.h
index cefc5639a44c7989a66757e537f0d6d47f7b225a..98d8e6a22065f96833e4656409b31fc8a62277d3 100644 (file)
--- a/win32.h
+++ b/win32.h
  *     http://www.gnu.org/
  *
  * Written by DJ Delorie <dj@cygnus.com>
+ * and Robert Collins <rbtcollins@hotmail.com>
  *
  */
 
-/* The purpose of this file is to limit the number of Win32 headers we
+/* The inital purpose of this file was limit the number of Win32 headers we
    actually have to parse.  The Setup program only uses a few of them,
    so there's no point in parsing them all (even lean-n-mean).  Doing
-   this cuts compile time in half. */
+   this cuts compile time in half. Now it's also the header for the Win32
+   class which provides runtime information about the OS
+ */
+
+#ifndef SETUP_WIN32_H
+#define SETUP_WIN32_H
 
 #define NOCOMATTRIBUTE
 
 
 #include <wininet.h>
 #include <windowsx.h>
+
+/* =========================== */
+#ifdef __cplusplus
+class Win32 {
+  public:
+    enum _os {
+      Win9x,
+      WinNT
+    };
+  static enum _os OS ();
+};
+
+#endif //_cplusplus
+#endif // SETUP_WIN32_H
This page took 0.065688 seconds and 5 git commands to generate.