Fixing file explorer for Windows
authorlaurent
Thu, 28 Jun 2012 16:42:07 +0200
changeset 783 f5cea1a6851e
parent 782 6f0e10085df9
child 784 a1d970365e41
Fixing file explorer for Windows
images/icons.svg
images/tree_drive.png
util/FileManagementPanel.py
--- a/images/icons.svg	Thu Jun 28 12:07:21 2012 +0200
+++ b/images/icons.svg	Thu Jun 28 16:42:07 2012 +0200
@@ -43,9 +43,9 @@
      pagecolor="#ffffff"
      id="base"
      showgrid="false"
-     inkscape:zoom="14.481548"
-     inkscape:cx="571.21601"
-     inkscape:cy="800.14078"
+     inkscape:zoom="7.2407738"
+     inkscape:cx="596.13887"
+     inkscape:cy="800.65537"
      inkscape:window-x="0"
      inkscape:window-y="24"
      inkscape:current-layer="svg2"
@@ -87673,6 +87673,204 @@
        id="linearGradient3065"
        xlink:href="#linearGradient2536-8"
        inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient8226-8"
+       y2="104.28"
+       gradientUnits="userSpaceOnUse"
+       x2="53.991001"
+       gradientTransform="matrix(0.12421,0,0,0.1864,0.23313,-3.9907)"
+       y1="87.896004"
+       x1="53.991001">
+      <stop
+         id="stop2223-6-4"
+         style="stop-color:#7a7a7a"
+         offset="0" />
+      <stop
+         id="stop2219-1-2"
+         style="stop-color:#474747"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient8223"
+       y2="35.280998"
+       gradientUnits="userSpaceOnUse"
+       x2="24.688"
+       gradientTransform="matrix(0.55458,0,0,0.35955,-1.6911,1.3146)"
+       y1="35.280998"
+       x1="7.0625">
+      <stop
+         id="stop6311-0"
+         offset="0" />
+      <stop
+         id="stop6313-7"
+         style="stop-color:#bbb;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient8220"
+       y2="33.758999"
+       gradientUnits="userSpaceOnUse"
+       x2="12.222"
+       gradientTransform="matrix(0.55458,0,0,0.35955,-2.1323,1.7913)"
+       y1="37.206001"
+       x1="12.277">
+      <stop
+         id="stop4238-4-4"
+         style="stop-color:#eee"
+         offset="0" />
+      <stop
+         id="stop4240-3-9"
+         style="stop-color:#eee;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       id="radialGradient8215"
+       gradientUnits="userSpaceOnUse"
+       cy="2.3118"
+       cx="4.1992998"
+       gradientTransform="matrix(1.1767,1.0377,-0.76928,0.87233,1.0364,-3.2772)"
+       r="8">
+      <stop
+         id="stop7064-4-6"
+         style="stop-color:#e6e6e6"
+         offset="0" />
+      <stop
+         id="stop7060-2-1"
+         style="stop-color:#c8c8c8"
+         offset="1" />
+    </radialGradient>
+    <linearGradient
+       id="linearGradient8217"
+       y2="6.8646998"
+       gradientUnits="userSpaceOnUse"
+       x2="2.2246001"
+       gradientTransform="matrix(0.64516,0,0,0.97976,0.25806,-6.7257)"
+       y1="11.321"
+       x1="4.6104002">
+      <stop
+         id="stop3486-2-4"
+         style="stop-color:#969696"
+         offset="0" />
+      <stop
+         id="stop3488-0-2"
+         style="stop-color:#b4b4b4"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       id="radialGradient8211"
+       xlink:href="#linearGradient4035-5"
+       gradientUnits="userSpaceOnUse"
+       cy="206.42999"
+       cx="141.75"
+       gradientTransform="matrix(0.12709,-0.0021289,9.4059e-4,0.12249,-10.298,-14.5)"
+       r="78.727997" />
+    <linearGradient
+       id="linearGradient4035-5">
+      <stop
+         id="stop4037-8"
+         style="stop-color:#f5f5f5"
+         offset="0" />
+      <stop
+         id="stop4039-7"
+         style="stop-color:#e7e7e7"
+         offset=".47026" />
+      <stop
+         id="stop4041-0"
+         style="stop-color:#8c8c8c"
+         offset=".69349" />
+      <stop
+         id="stop4043-4"
+         style="stop-color:#ddd"
+         offset=".83543" />
+      <stop
+         id="stop4045-8"
+         style="stop-color:#a8a8a8"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       id="radialGradient8208"
+       xlink:href="#linearGradient4035-5"
+       gradientUnits="userSpaceOnUse"
+       cy="191.85001"
+       cx="142.62"
+       gradientTransform="matrix(0.061651,0,0,-0.065372,-1.0371,17.524)"
+       r="78.727997" />
+    <linearGradient
+       id="linearGradient3066">
+      <stop
+         id="stop3068"
+         style="stop-color:#f5f5f5"
+         offset="0" />
+      <stop
+         id="stop3070"
+         style="stop-color:#e7e7e7"
+         offset=".47026" />
+      <stop
+         id="stop3072"
+         style="stop-color:#8c8c8c"
+         offset=".69349" />
+      <stop
+         id="stop3074"
+         style="stop-color:#ddd"
+         offset=".83543" />
+      <stop
+         id="stop3076"
+         style="stop-color:#a8a8a8"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       id="radialGradient8201"
+       gradientUnits="userSpaceOnUse"
+       cy="42"
+       cx="24"
+       gradientTransform="matrix(0.33333,0,0,0.14286,6.5e-7,8)"
+       r="21">
+      <stop
+         id="stop6312-6-2"
+         style="stop-color:#fff"
+         offset="0" />
+      <stop
+         id="stop6314-6-0"
+         style="stop-color:#fff;stop-opacity:0"
+         offset="1" />
+    </radialGradient>
+    <radialGradient
+       id="radialGradient8198"
+       gradientUnits="userSpaceOnUse"
+       cy="143.83"
+       cx="127.32"
+       gradientTransform="matrix(0.041797,-0.013884,0.0033869,0.037975,-0.54191,-0.79595)"
+       r="78.727997">
+      <stop
+         id="stop8107"
+         style="stop-color:#f5f5f5"
+         offset="0" />
+      <stop
+         id="stop8109"
+         style="stop-color:#e7e7e7"
+         offset=".25028" />
+      <stop
+         id="stop8111"
+         style="stop-color:#8c8c8c"
+         offset=".69349" />
+      <stop
+         id="stop8113"
+         style="stop-color:#ddd"
+         offset=".83543" />
+      <stop
+         id="stop8115-9"
+         style="stop-color:#a8a8a8"
+         offset="1" />
+    </radialGradient>
+    <radialGradient
+       r="78.727997"
+       cy="143.83"
+       cx="127.32"
+       gradientTransform="matrix(0.041797,-0.013884,0.0033869,0.037975,-0.54191,-0.79595)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient3101"
+       xlink:href="#radialGradient8198"
+       inkscape:collect="always" />
   </defs>
   <g
      id="g19063"
@@ -93015,9 +93213,9 @@
        y="253.14807"
        x="518.62115"
        id="tspan16195-3"
-       sodipodi:role="line">%% tree_folder tree_file %%</tspan></text>
+       sodipodi:role="line">%% tree_drive tree_folder tree_file %%</tspan></text>
   <g
-     transform="translate(641.9507,260.10161)"
+     transform="translate(711.12206,260.10161)"
      id="layer1-3">
     <path
        inkscape:connector-curvature="0"
@@ -93041,7 +93239,7 @@
        d="m 9.2941,0.8409 c 0.9879,0 0.7059,3.181 0.7059,3.181 0,0 2.272,-0.5007 3.171,0.9099 0.163,0.2556 0.036,-1.008 -0.041,-1.129 C 12.587,2.9553 10.707,1.1697 10.025,0.8726 9.9696,0.84836 9.5814,0.8409 9.2941,0.8409 z" />
   </g>
   <g
-     transform="translate(681.24244,260.14902)"
+     transform="translate(750.4138,260.14902)"
      style="display:inline"
      id="tree_file"
      inkscape:export-xdpi="90"
@@ -93055,7 +93253,7 @@
        inkscape:label="#rect2160" />
   </g>
   <g
-     transform="translate(607.49098,259.77752)"
+     transform="translate(676.66234,259.77752)"
      style="display:inline"
      id="tree_folder"
      inkscape:export-xdpi="90"
@@ -93069,7 +93267,7 @@
        inkscape:label="#rect2160" />
   </g>
   <g
-     transform="translate(567.4222,259.12098)"
+     transform="translate(636.59356,259.12098)"
      id="layer1-39">
     <g
        id="layer6-8"
@@ -93117,4 +93315,87 @@
        style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px"
        d="M 3.499,14 V 5.5 h 11.5" />
   </g>
+  <g
+     transform="translate(567.48083,260.67786)"
+     id="g3119">
+    <path
+       inkscape:connector-curvature="0"
+       id="rect2992-5"
+       style="fill:url(#linearGradient8226-8);stroke:#353537;stroke-linejoin:round"
+       d="m 15.497,12.5 c -0.30416,2.535 -0.22639,2.9839 -0.77717,2.9839 -0.21573,0.03617 -8.6983,0 -13.47,0 -0.59814,0 -0.447,0.04932 -0.7499,-2.9839 4.8142,0.13977 10.032,-0.37056 14.997,0 z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="rect9146-5"
+       style="fill:url(#linearGradient8223);fill-rule:evenodd"
+       d="m 2,13 h 10 v 2 H 2.2256 L 2,13 z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path9148-2"
+       style="opacity:0.81142997;fill:url(#linearGradient8220);fill-rule:evenodd"
+       d="M 2.2256,15 2.07522,13.5577 C 3.09312,14.7008 6.82662,15 9.40042,15 h -7.1749 z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="rect2990-9"
+       style="fill:url(#radialGradient8215);stroke:url(#linearGradient8217);stroke-linecap:round;stroke-linejoin:round"
+       d="M 1.4897,1.4658 0.51475,12.4888 C 0.505,12.4888 0.5,12.4918 0.5,12.4998 h 15 c 0,-0.0082 -0.005,-0.01111 -0.01475,-0.01111 l -1.005,-11.241 c 0,0 -0.18775,-0.7434 -0.90964,-0.7434 -0.68815,0 -10.535,-0.004447 -11.26,-0.004447 -0.75868,0 -0.82051,0.96576 -0.82051,0.96576 z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path2215-0"
+       style="opacity:0.7;fill:none;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round"
+       d="m 1.4763,12.5 h 13.047" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path8117"
+       style="fill:url(#radialGradient8211)"
+       d="M 9.875,1.0312 C 9.5425,1.0312 9.2896,1.1934 9.2812,1.4375 7.5462,4.2547 3.716,3.331 2.1875,6.6875 2.1073,7.5502 2.3134,8.6701 3.0938,9.375 4.236,10.407 6.138,11.041 8.1562,11 12.322,10.915 15.991,8.1998 12.812,4.6562 12.795,4.4114 12.562,1.4375 12.562,1.4375 12.545,1.1967 12.268,1.0312 11.938,1.0312 H 9.8755 z M 9.84375,1.4687 h 2.0625 c 0.1199,0 0.214,0.027064 0.21875,0.09375 l -0.437,3.0938 c 3.473,2.8052 0.258,5.1235 -3.438,5.25 -3.3581,0.1148 -5.2801,-1.0583 -5.0938,-3.0624 1.1782,-3.3771 5.7075,-1.762 6.4688,-5.2813 -0.0195,-0.0627 0.1015,-0.0937 0.2188,-0.0937 z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path9400"
+       style="fill:url(#radialGradient8208)"
+       d="M 7.9999,8.9999 C 7.3338,9.004 6.6179,8.7648 6.2183,8.2045 5.8879,7.7377 5.9413,7.0421 6.3494,6.638 6.8328,6.1198 7.5867,5.9505 8.2719,6.0129 8.879,6.0691 9.5104,6.3443 9.8354,6.883 10.087,7.317 10.047,7.9042 9.7165,8.2869 9.3098,8.7948 8.6299,8.9998 7.9999,8.9999 z M 8.033429,6.9404 c -0.4657,0.0106 -0.9649,-0.0032 -1.3803,0.2407 -0.2744,0.1909 -0.298,0.6023 -0.1132,0.8636 0.2517,0.392 0.7264,0.5638 1.1687,0.6235 0.5705,0.0718 1.1976,-0.0568 1.6262,-0.4584 0.2414,-0.24 0.3518,-0.6735 0.1113,-0.9512 -0.2382,-0.2503 -0.6084,-0.2735 -0.932,-0.3044 -0.16,-0.0106 -0.3204,-0.0122 -0.4806,-0.0138 z" />
+    <g
+       id="g9436"
+       transform="matrix(-0.046858,0,0,0.077502,4.3055,-2.9911)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9438"
+         style="fill:#535353"
+         d="m 37.925,187.15 c 0.31446,3.4586 5.0238,6.279 10.514,6.279 5.4879,0 9.6432,-2.8205 9.2763,-6.279 -0.36437,-3.4402 -5.0712,-6.2181 -10.507,-6.2181 -5.438,0.002 -9.5933,2.7778 -9.2838,6.2181 z" />
+    </g>
+    <g
+       id="g9496"
+       transform="matrix(-0.046858,0,0,0.077502,16.206,-2.9911)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9498"
+         style="fill:#535353"
+         d="m 37.925,187.15 c 0.31446,3.4586 5.0238,6.279 10.514,6.279 5.4879,0 9.6432,-2.8205 9.2763,-6.279 -0.36437,-3.4402 -5.0712,-6.2181 -10.507,-6.2181 -5.438,0.002 -9.5933,2.7778 -9.2838,6.2181 z" />
+    </g>
+    <rect
+       id="rect6300-3-2"
+       style="opacity:0.2;fill:url(#radialGradient8201)"
+       height="2"
+       width="14"
+       y="13"
+       x="1" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path8125"
+       style="fill:url(#radialGradient3101)"
+       d="M 3.549,1.2794 C 3.5821,1.4639 3.5033,1.6681 3.4766,1.8578 3.3642,2.438 3.2481,3.0174 3.1388,3.5982 3.0365,3.9765 3.4034,3.8226 3.4488,3.861 3.9285,3.6779 4.4038,3.4775 4.8814,3.2862 5.3796,3.0824 5.8809,2.8849 6.3773,2.6771 6.6903,2.4909 6.7821,2.3238 6.8636,2.0429 6.9085,1.799 6.9139,1.5263 6.792,1.3034 6.7139,1.1494 6.5435,1.0842 6.3798,1.1074 H 3.7772 L 3.549,1.2794 z m 0.58899,0.44397 c 0.59213,0 1.1843,-1e-7 1.7764,-1e-7 0.1871,0.070513 0.054625,0.21948 -0.083295,0.23252 -0.6014,0.2439 -1.2028,0.4878 -1.8041,0.7317 -0.1446,0.0544 -0.155,-0.1673 -0.1113,-0.2613 0.037079,-0.20752 0.074157,-0.41504 0.11124,-0.62256 0.041217,-0.021125 0.065659,-0.065363 0.11102,-0.080349 z" />
+  </g>
+  <g
+     transform="translate(607.62908,260.74427)"
+     style="display:inline"
+     id="tree_drive"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90">
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:none;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
+       d="m -40,0 0,16 16,0 0,-16 -16,0 z m 1,1 14,0 0,14 -14,0 0,-14 z"
+       id="path3806-1-6-1-9-8-0-5"
+       sodipodi:nodetypes="cccccccccc"
+       inkscape:label="#rect2160" />
+  </g>
 </svg>
Binary file images/tree_drive.png has changed
--- a/util/FileManagementPanel.py	Thu Jun 28 12:07:21 2012 +0200
+++ b/util/FileManagementPanel.py	Thu Jun 28 16:42:07 2012 +0200
@@ -30,12 +30,14 @@
 from controls import EditorPanel
 from utils.BitmapLibrary import GetBitmap
 
+DRIVE, FOLDER, FILE = range(3)
+
 FILTER = _("All files (*.*)|*.*|CSV files (*.csv)|*.csv")
 
 def sort_folder(x, y):
     if x[1] == y[1]:
         return cmp(x[0], y[0])
-    elif x[1]:
+    elif x[1] != FILE:
         return -1
     else:
         return 1
@@ -62,7 +64,11 @@
                     wx.TR_HIDE_ROOT|
                     wx.TR_LINES_AT_ROOT|
                     wx.TR_EDIT_LABELS)
-        self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnTreeItemExpanded, self.Tree)
+        if wx.Platform == '__WXMSW__':
+            self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTreeItemExpanded, self.Tree)
+            self.Tree.Bind(wx.EVT_LEFT_DOWN, self.OnTreeLeftDown)
+        else:
+            self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnTreeItemExpanded, self.Tree)
         self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnTreeItemCollapsed, self.Tree)
         self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTreeBeginLabelEdit, self.Tree)
         self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTreeEndLabelEdit, self.Tree)
@@ -78,8 +84,11 @@
         self.Editable = editable
         
         self.TreeImageList = wx.ImageList(16, 16)
-        self.FOLDER_IMAGE = self.TreeImageList.Add(GetBitmap("tree_folder"))
-        self.FILE_IMAGE = self.TreeImageList.Add(GetBitmap("tree_file"))
+        self.TreeImageDict = {}
+        for item_type, bitmap in [(DRIVE, "tree_drive"),
+                                  (FOLDER, "tree_folder"),
+                                  (FILE, "tree_file")]:
+            self.TreeImageDict[item_type] = self.TreeImageList.Add(GetBitmap(bitmap))
         self.Tree.SetImageList(self.TreeImageList)
         
         self.Filters = {}
@@ -97,18 +106,28 @@
     
     def _GetFolderChildren(self, folderpath, recursive=True):
         items = []
-        for filename in os.listdir(folderpath):
-            if not filename.startswith("."):
-                filepath = os.path.join(folderpath, filename)
-                if os.path.isdir(filepath):
-                    if recursive:
-                        children = len(self._GetFolderChildren(filepath, False))
-                    else:
-                        children = 0
-                    items.append((filename, True, children))
-                elif (self.CurrentFilter == "" or 
-                      os.path.splitext(filename)[1] == self.CurrentFilter):
-                    items.append((filename, False, None))
+        if wx.Platform == '__WXMSW__' and folderpath == "/":
+            for c in xrange(ord('a'), ord('z')):
+                drive = os.path.join("%s:\\" % chr(c))
+                if os.path.exists(drive):
+                    items.append((drive, DRIVE, self._GetFolderChildren(drive, False)))
+        else:
+            try:
+                files = os.listdir(folderpath)
+            except:
+                return []
+            for filename in files:
+                if not filename.startswith("."):
+                    filepath = os.path.join(folderpath, filename)
+                    if os.path.isdir(filepath):
+                        if recursive:
+                            children = len(self._GetFolderChildren(filepath, False))
+                        else:
+                            children = 0
+                        items.append((filename, FOLDER, children))
+                    elif (self.CurrentFilter == "" or 
+                          os.path.splitext(filename)[1] == self.CurrentFilter):
+                        items.append((filename, FILE, None))
         if recursive:
             items.sort(sort_folder)
         return items
@@ -124,26 +143,19 @@
         
     def GenerateTreeBranch(self, root, folderpath):
         item, item_cookie = self.Tree.GetFirstChild(root)
-        for idx, (filename, isdir, children) in enumerate(self._GetFolderChildren(folderpath)):
-            new = False
+        for idx, (filename, item_type, children) in enumerate(self._GetFolderChildren(folderpath)):
             if not item.IsOk():
-                item = self.Tree.AppendItem(root, filename)
+                item = self.Tree.AppendItem(root, filename, self.TreeImageDict[item_type])
                 if wx.Platform != '__WXMSW__':
                     item, item_cookie = self.Tree.GetNextChild(root, item_cookie)
-                new = True
             elif self.Tree.GetItemText(item) != filename:
-                item = self.Tree.InsertItemBefore(root, idx, filename)
-                new = True
+                item = self.Tree.InsertItemBefore(root, idx, filename, self.TreeImageDict[item_type])
             filepath = os.path.join(folderpath, filename)
-            if isdir:
-                if new:
-                    self.Tree.SetItemImage(item, self.FOLDER_IMAGE)
-                    if children > 0:
-                        self.Tree.SetItemHasChildren(item)
-                elif self.Tree.IsExpanded(item):
+            if item_type != FILE:
+                if self.Tree.IsExpanded(item):
                     self.GenerateTreeBranch(item, filepath)
-            elif new:
-                self.Tree.SetItemImage(item, self.FILE_IMAGE)
+                elif children > 0:
+                    self.Tree.SetItemHasChildren(item)
             item, item_cookie = self.Tree.GetNextChild(root, item_cookie)
         to_delete = []
         while item.IsOk():
@@ -152,6 +164,21 @@
         for item in to_delete:
             self.Tree.Delete(item)
 
+    def ExpandItem(self, item):
+        self.GenerateTreeBranch(item, self.GetPath(item))
+        self.Tree.Expand(item)
+    
+    def OnTreeItemActivated(self, event):
+        self.ExpandItem(event.GetItem())
+        event.Skip()
+    
+    def OnTreeLeftDown(self, event):
+        item, flags = self.Tree.HitTest(event.GetPosition())
+        if flags & wx.TREE_HITTEST_ONITEMBUTTON and not self.Tree.IsExpanded(item):
+            self.ExpandItem(item)
+        else:
+            event.Skip()
+    
     def OnTreeItemExpanded(self, event):
         item = event.GetItem()
         self.GenerateTreeBranch(item, self.GetPath(item))
@@ -274,7 +301,11 @@
     def __init__(self, parent, controler, name, folder, enable_dragndrop=False):
         self.Folder = os.path.realpath(folder)
         self.EnableDragNDrop = enable_dragndrop
-        self.HomeDirectory = os.path.expanduser("~")
+        
+        if wx.Platform == '__WXMSW__':
+            self.HomeDirectory = "/"
+        else:
+            self.HomeDirectory = os.path.expanduser("~")
         
         EditorPanel.__init__(self, parent, name, None, None)