[baobab/wip/vala: 1/41] Begin rewrite in Vala



commit 2ced7a55933d7dd0bf6aa4748882a4e3bb078db4
Author: Ryan Lortie <desrt desrt ca>
Date:   Wed Jan 4 18:05:56 2012 -0500

    Begin rewrite in Vala
    
    The current baobab code is in a bad way, so after some discussion on
    IRC, we've decided that a rewrite is in order.
    
     - the core application logic will be switched to Vala
    
     - more effective use will be made of GtkBuilder
    
     - the charts (ringchart, treemap) and progress cell renderer are
       well-written, so we will keep the C versions of them around
    
     - the port will make use of GtkApplication, including GMenu
    
    This commit represents the very start of a rather large
    work-in-progress.

 configure.ac                       |    1 +
 data/baobab-main-window.ui         |  644 +++++++-----------
 src/Makefile.am                    |   48 +-
 src/baobab-application.vala        |   90 +++
 src/baobab-cellrenderers.vala      |   37 +
 src/baobab-prefs.c                 |  329 ---------
 src/baobab-prefs.h                 |   28 -
 src/baobab-remote-connect-dialog.c |  803 ---------------------
 src/baobab-remote-connect-dialog.h |   59 --
 src/baobab-scan.c                  |  380 ----------
 src/baobab-scan.h                  |   30 -
 src/baobab-scanner.vala            |  136 ++++
 src/baobab-treeview.c              |  339 ---------
 src/baobab-treeview.h              |   47 --
 src/baobab-utils.c                 |  516 --------------
 src/baobab-utils.h                 |   47 --
 src/baobab-window.vala             |   79 +++
 src/baobab.c                       | 1354 ------------------------------------
 src/baobab.h                       |  121 ----
 src/baobab.vapi                    |   34 +
 src/callbacks.c                    |  336 ---------
 src/callbacks.h                    |   59 --
 src/config.vapi                    |    6 +
 src/main.vala                      |    4 +
 24 files changed, 663 insertions(+), 4864 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9f77745..e7145e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,7 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[The name of the gettext d
 AC_PROG_CC
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
+AM_PROG_VALAC
 PKG_PROG_PKG_CONFIG([0.22])
 
 ## don't rerun to this point if we abort
diff --git a/data/baobab-main-window.ui b/data/baobab-main-window.ui
index ba90c8f..5c0d327 100644
--- a/data/baobab-main-window.ui
+++ b/data/baobab-main-window.ui
@@ -1,461 +1,319 @@
-<?xml version="1.0"?>
-<!--*- mode: xml -*-->
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <object class="GtkUIManager" id="uimanager1">
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkGrid" id="window-contents">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
     <child>
-      <object class="GtkActionGroup" id="actiongroup1">
-        <child>
-          <object class="GtkAction" id="menuitem1">
-            <property name="name">menuitem1</property>
-            <property name="label" translatable="yes">_Analyzer</property>
-          </object>
-        </child>
+      <object class="GtkToolbar" id="toolbar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="toolbar_style">icons</property>
+        <property name="show_arrow">False</property>
         <child>
-          <object class="GtkAction" id="menuscanhome">
+          <object class="GtkToolButton" id="tbscanhome1">
+            <property name="use_action_appearance">False</property>
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="has_tooltip">True</property>
+            <property name="tooltip_markup" translatable="yes">Scan home folder</property>
+            <property name="tooltip_text" translatable="yes">Scan home folder</property>
+            <property name="use_action_appearance">False</property>
+            <property name="is_important">True</property>
+            <property name="label" translatable="yes">Scan Home</property>
+            <property name="use_underline">True</property>
             <property name="stock_id">gtk-home</property>
-            <property name="name">menuscanhome</property>
-            <property name="label" translatable="yes">Scan _Home Folder</property>
-            <signal handler="on_menuscanhome_activate" last_modification_time="Wed, 23 Aug 2006 03:59:38 GMT" name="activate"/>
+            <child internal-child="accessible">
+              <object class="AtkObject" id="tbscanhome1-atkobject">
+                <property name="AtkObject::accessible-name" translatable="yes">Scan home folder</property>
+              </object>
+            </child>
           </object>
-          <accelerator key="S" modifiers="GDK_CONTROL_MASK"/>
+          <packing>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
+          </packing>
         </child>
         <child>
-          <object class="GtkAction" id="menuallfs">
+          <object class="GtkToolButton" id="tbscanall1">
+            <property name="use_action_appearance">False</property>
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="has_tooltip">True</property>
+            <property name="tooltip_markup" translatable="yes">Scan filesystem</property>
+            <property name="tooltip_text" translatable="yes">Scan filesystem</property>
+            <property name="use_action_appearance">False</property>
+            <property name="label" translatable="yes">Scan Filesystem</property>
+            <property name="use_underline">True</property>
             <property name="stock_id">gtk-harddisk</property>
-            <property name="name">menuallfs</property>
-            <property name="label" translatable="yes">Scan _Filesystem</property>
-            <signal handler="on_menuallfs_activate" last_modification_time="Tue, 05 Jul 2005 08:47:26 GMT" name="activate"/>
           </object>
-          <accelerator key="F" modifiers="GDK_CONTROL_MASK"/>
+          <packing>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
+          </packing>
         </child>
         <child>
-          <object class="GtkAction" id="menuscandir">
+          <object class="GtkToolButton" id="tbscandir1">
+            <property name="use_action_appearance">False</property>
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="has_tooltip">True</property>
+            <property name="tooltip_markup" translatable="yes">Scan a folder</property>
+            <property name="tooltip_text" translatable="yes">Scan a folder</property>
+            <property name="use_action_appearance">False</property>
+            <property name="label" translatable="yes">Scan Folder</property>
+            <property name="use_underline">True</property>
             <property name="stock_id">gtk-directory</property>
-            <property name="name">menuscandir</property>
-            <property name="label" translatable="yes">Scan F_older...</property>
-            <signal handler="on_menuscandir_activate" last_modification_time="Tue, 05 Jul 2005 08:47:26 GMT" name="activate"/>
           </object>
-          <accelerator key="O" modifiers="GDK_CONTROL_MASK"/>
+          <packing>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
+          </packing>
         </child>
         <child>
-          <object class="GtkAction" id="menu_scan_rem">
+          <object class="GtkToolButton" id="tb_scan_remote1">
+            <property name="use_action_appearance">False</property>
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="has_tooltip">True</property>
+            <property name="tooltip_markup" translatable="yes">Scan a remote folder</property>
+            <property name="tooltip_text" translatable="yes">Scan a remote folder</property>
+            <property name="use_action_appearance">False</property>
+            <property name="label" translatable="yes">Scan Remote Folder</property>
+            <property name="use_underline">True</property>
             <property name="stock_id">gtk-network</property>
-            <property name="name">menu_scan_rem</property>
-            <property name="label" translatable="yes">S_can Remote Folder...</property>
-            <signal handler="on_menu_scan_rem_activate" last_modification_time="Fri, 18 Nov 2005 18:20:25 GMT" name="activate"/>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="menustop">
-            <property name="stock_id">gtk-stop</property>
-            <property name="name">menustop</property>
-            <signal handler="on_menu_stop_activate" last_modification_time="Tue, 29 Aug 2006 04:04:57 GMT" name="activate"/>
           </object>
-          <accelerator key="Escape" modifiers="0"/>
-        </child>
-        <child>
-          <object class="GtkAction" id="menurescan">
-            <property name="stock_id">gtk-refresh</property>
-            <property name="name">menurescan</property>
-            <signal handler="on_menu_rescan_activate" last_modification_time="Sat, 28 Oct 2006 14:27:31 GMT" name="activate"/>
-          </object>
-          <accelerator key="R" modifiers="GDK_CONTROL_MASK"/>
-        </child>
-        <child>
-          <object class="GtkAction" id="menuquit">
-            <property name="stock_id">gtk-quit</property>
-            <property name="name">menuquit</property>
-            <signal handler="on_quit_activate" last_modification_time="Tue, 05 Jul 2005 08:47:26 GMT" name="activate"/>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="edit1">
-            <property name="name">edit1</property>
-            <property name="label" translatable="yes">_Edit</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="expand_all">
-            <property name="name">expand_all</property>
-            <property name="label" translatable="yes">_Expand All</property>
-            <signal handler="on_menu_expand_activate" last_modification_time="Wed, 23 Aug 2006 17:10:33 GMT" name="activate"/>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="collapse_all">
-            <property name="name">collapse_all</property>
-            <property name="label" translatable="yes">_Collapse All</property>
-            <signal handler="on_menu_collapse_activate" last_modification_time="Wed, 23 Aug 2006 17:13:24 GMT" name="activate"/>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="preferenze1">
-            <property name="stock_id">gtk-preferences</property>
-            <property name="name">preferenze1</property>
-            <signal handler="on_pref_menu" last_modification_time="Fri, 04 Nov 2005 11:19:35 GMT" name="activate"/>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="view1">
-            <property name="name">view1</property>
-            <property name="label" translatable="yes">_View</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkToggleAction" id="view_tb">
-            <property name="active">True</property>
-            <property name="name">view_tb</property>
-            <property name="label" translatable="yes">_Toolbar</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkToggleAction" id="view_sb">
-            <property name="active">True</property>
-            <property name="name">view_sb</property>
-            <property name="label" translatable="yes">St_atusbar</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkToggleAction" id="ck_allocated">
-            <property name="active">True</property>
-            <property name="name">ck_allocated</property>
-            <property name="label" translatable="yes">All_ocated Space</property>
-            <signal handler="on_ck_allocated_activate" last_modification_time="Mon, 21 Aug 2006 03:19:13 GMT" name="activate"/>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="help1">
-            <property name="name">help1</property>
-            <property name="label" translatable="yes">_Help</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAction" id="helpcontents">
-            <property name="stock_id">gtk-help</property>
-            <property name="name">helpcontents</property>
-            <property name="label" translatable="yes">_Contents</property>
-            <signal handler="on_helpcontents_activate" last_modification_time="Wed, 26 Apr 2006 07:44:52 GMT" name="activate"/>
-          </object>
-          <accelerator key="F1" modifiers="0"/>
+          <packing>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
+          </packing>
         </child>
         <child>
-          <object class="GtkAction" id="about">
-            <property name="stock_id">gtk-about</property>
-            <property name="name">about</property>
-            <signal handler="on_about_activate" last_modification_time="Tue, 05 Jul 2005 08:58:33 GMT" name="activate"/>
+          <object class="GtkSeparatorToolItem" id="separatortoolitem1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
           </object>
+          <packing>
+            <property name="expand">False</property>
+          </packing>
         </child>
-      </object>
-    </child>
-    <ui>
-      <menubar name="menubar1">
-        <menu action="menuitem1">
-          <menuitem action="menuscanhome"/>
-          <menuitem action="menuallfs"/>
-          <menuitem action="menuscandir"/>
-          <menuitem action="menu_scan_rem"/>
-          <separator/>
-          <menuitem action="menustop"/>
-          <menuitem action="menurescan"/>
-          <separator/>
-          <menuitem action="menuquit"/>
-        </menu>
-        <menu action="edit1">
-          <menuitem action="expand_all"/>
-          <menuitem action="collapse_all"/>
-          <separator/>
-          <menuitem action="preferenze1"/>
-        </menu>
-        <menu action="view1">
-          <menuitem action="view_tb"/>
-          <menuitem action="view_sb"/>
-          <menuitem action="ck_allocated"/>
-        </menu>
-        <menu action="help1">
-          <menuitem action="helpcontents"/>
-          <menuitem action="about"/>
-        </menu>
-      </menubar>
-    </ui>
-  </object>
-  <object class="GtkWindow" id="baobab_window">
-    <property name="visible">True</property>
-    <property name="title" translatable="yes">Disk Usage Analyzer</property>
-    <property name="type">GTK_WINDOW_TOPLEVEL</property>
-    <property name="window_position">GTK_WIN_POS_CENTER</property>
-    <property name="modal">False</property>
-    <property name="default_width">800</property>
-    <property name="default_height">500</property>
-    <property name="resizable">True</property>
-    <property name="destroy_with_parent">False</property>
-    <property name="decorated">True</property>
-    <property name="skip_taskbar_hint">False</property>
-    <property name="skip_pager_hint">False</property>
-    <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-    <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-    <property name="focus_on_map">True</property>
-    <property name="urgency_hint">False</property>
-    <signal handler="on_delete_activate" last_modification_time="Sun, 31 Jul 2005 16:53:49 GMT" name="delete_event"/>
-    <child>
-      <object class="GtkVBox" id="vbox1">
-        <property name="visible">True</property>
-        <property name="homogeneous">False</property>
-        <property name="spacing">0</property>
         <child>
-          <object class="GtkMenuBar" constructor="uimanager1" id="menubar1">
+          <object class="GtkToolButton" id="tbstop1">
+            <property name="use_action_appearance">False</property>
             <property name="visible">True</property>
-            <property name="pack_direction">GTK_PACK_DIRECTION_LTR</property>
-            <property name="child_pack_direction">GTK_PACK_DIRECTION_LTR</property>
+            <property name="sensitive">False</property>
+            <property name="can_focus">False</property>
+            <property name="has_tooltip">True</property>
+            <property name="tooltip_markup" translatable="yes">Stop scanning</property>
+            <property name="tooltip_text" translatable="yes">Stop scanning</property>
+            <property name="use_action_appearance">False</property>
+            <property name="stock_id">gtk-stop</property>
+            <accelerator key="Escape" signal="clicked"/>
           </object>
           <packing>
-            <property name="padding">0</property>
             <property name="expand">False</property>
-            <property name="fill">False</property>
+            <property name="homogeneous">True</property>
           </packing>
         </child>
         <child>
-          <object class="GtkToolbar" id="toolbar1">
+          <object class="GtkToolButton" id="tbrescan1">
+            <property name="use_action_appearance">False</property>
             <property name="visible">True</property>
-            <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
-            <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
-            <property name="show_arrow">False</property>
-            <style>
-            	<class name="primary-toolbar"/>
-            </style>
-            <child>
-              <object class="GtkToolButton" id="tbscanhome">
-                <property name="visible">True</property>
-                <property name="tooltip-text" translatable="yes">Scan home folder</property>
-                <property name="label" translatable="yes">Scan Home</property>
-                <property name="use_underline">True</property>
-                <property name="stock_id">gtk-home</property>
-                <property name="visible_horizontal">True</property>
-                <property name="visible_vertical">True</property>
-                <property name="is_important">True</property>
-                <accessibility>
-                </accessibility>
-                <signal handler="on_tbscanhome_clicked" last_modification_time="Wed, 23 Aug 2006 12:30:03 GMT" name="clicked"/>
-                <child internal-child="accessible">
-                  <object class="AtkObject" id="a11y-tbscanhome1">
-                    <property name="AtkObject::accessible_name" translatable="yes">Scan home folder</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="tbscanall">
-                <property name="visible">True</property>
-                <property name="tooltip-text" translatable="yes">Scan filesystem</property>
-                <property name="label" translatable="yes">Scan Filesystem</property>
-                <property name="use_underline">True</property>
-                <property name="stock_id">gtk-harddisk</property>
-                <property name="visible_horizontal">True</property>
-                <property name="visible_vertical">True</property>
-                <property name="is_important">False</property>
-                <signal handler="on_tbscanall_clicked" last_modification_time="Sat, 09 Jul 2005 20:16:36 GMT" name="clicked"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="tbscandir">
-                <property name="visible">True</property>
-                <property name="tooltip-text" translatable="yes">Scan a folder</property>
-                <property name="label" translatable="yes">Scan Folder</property>
-                <property name="use_underline">True</property>
-                <property name="stock_id">gtk-directory</property>
-                <property name="visible_horizontal">True</property>
-                <property name="visible_vertical">True</property>
-                <property name="is_important">False</property>
-                <signal handler="on_tbscandir_clicked" last_modification_time="Wed, 06 Jul 2005 13:15:40 GMT" name="clicked"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="tb_scan_remote">
-                <property name="visible">True</property>
-                <property name="tooltip-text" translatable="yes">Scan a remote folder</property>
-                <property name="label" translatable="yes">Scan Remote Folder</property>
-                <property name="use_underline">True</property>
-                <property name="stock_id">gtk-network</property>
-                <property name="visible_horizontal">True</property>
-                <property name="visible_vertical">True</property>
-                <property name="is_important">False</property>
-                <signal handler="on_tb_scan_remote_clicked" last_modification_time="Fri, 18 Nov 2005 15:56:32 GMT" name="clicked"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkSeparatorToolItem" id="separatortoolitem4">
-                <property name="visible">True</property>
-                <property name="draw">True</property>
-                <property name="visible_horizontal">True</property>
-                <property name="visible_vertical">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="tbstop">
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="tooltip-text" translatable="yes">Stop scanning</property>
-                <property name="stock_id">gtk-stop</property>
-                <property name="visible_horizontal">True</property>
-                <property name="visible_vertical">True</property>
-                <property name="is_important">False</property>
-                <signal handler="on_tbstop_clicked" last_modification_time="Sat, 09 Jul 2005 16:03:18 GMT" name="clicked"/>
-                <accelerator key="Escape" modifiers="0" signal="clicked"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="tbrescan">
-                <property name="visible">True</property>
-                <property name="tooltip-text" translatable="yes">Refresh</property>
-                <property name="sensitive">False</property>
-                <property name="stock_id">gtk-refresh</property>
-                <property name="visible_horizontal">True</property>
-                <property name="visible_vertical">True</property>
-                <property name="is_important">False</property>
-                <signal handler="on_tbrescan_clicked" last_modification_time="Sat, 28 Oct 2006 14:26:18 GMT" name="clicked"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
+            <property name="sensitive">False</property>
+            <property name="can_focus">False</property>
+            <property name="has_tooltip">True</property>
+            <property name="tooltip_markup" translatable="yes">Refresh</property>
+            <property name="tooltip_text" translatable="yes">Refresh</property>
+            <property name="use_action_appearance">False</property>
+            <property name="stock_id">gtk-refresh</property>
           </object>
           <packing>
-            <property name="padding">0</property>
             <property name="expand">False</property>
-            <property name="fill">False</property>
+            <property name="homogeneous">True</property>
           </packing>
         </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">2</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkComboBoxText" id="chart-type-combo">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="active">0</property>
+        <property name="id_column">1</property>
+        <items>
+          <item id="rings" translatable="yes">View as Rings Chart</item>
+          <item id="treemap" translatable="yes">View as Treemap Chart</item>
+        </items>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="xalign">0.30000001192092896</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkStatusbar" id="statusbar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="spacing">2</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">3</property>
+        <property name="width">2</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkPaned" id="hpaned">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
         <child>
-          <object class="GtkVBox" id="vbox2">
+          <object class="GtkScrolledWindow" id="scrolled-window">
             <property name="visible">True</property>
-            <property name="homogeneous">False</property>
-            <property name="spacing">0</property>
+            <property name="can_focus">True</property>
+            <property name="shadow_type">in</property>
             <child>
-              <object class="GtkHBox" id="hbox1">
-                <property name="border_width">2</property>
+              <object class="GtkTreeView" id="treeview">
                 <property name="visible">True</property>
-                <property name="homogeneous">False</property>
-                <property name="spacing">0</property>
+                <property name="can_focus">True</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection" id="treeview-selection1"/>
+                </child>
                 <child>
-                  <object class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes"/>
-                    <property name="use_underline">False</property>
-                    <property name="use_markup">False</property>
-                    <property name="justify">GTK_JUSTIFY_LEFT</property>
-                    <property name="wrap">False</property>
-                    <property name="selectable">False</property>
-                    <property name="xalign">0.300000011921</property>
-                    <property name="yalign">0.5</property>
-                    <property name="xpad">0</property>
-                    <property name="ypad">0</property>
-                    <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-                    <property name="width_chars">-1</property>
-                    <property name="single_line_mode">False</property>
-                    <property name="angle">0</property>
+                  <object class="GtkTreeViewColumn" id="folder-column">
+                    <property name="resizable">True</property>
+                    <property name="sizing">autosize</property>
+                    <property name="title" translatable="yes">Folder</property>
+                    <property name="expand">True</property>
+                    <property name="reorderable">True</property>
+                    <property name="sort_column_id">0</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="folder-column-text-renderer"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="padding">0</property>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                  </packing>
                 </child>
                 <child>
-                  <placeholder/>
+                  <object class="GtkTreeViewColumn" id="usage-column">
+                    <property name="sizing">autosize</property>
+                    <property name="title" translatable="yes">Usage</property>
+                    <property name="reorderable">True</property>
+                    <property name="sort_column_id">2</property>
+                    <child>
+                      <object class="BaobabCellRendererProgress" id="usage-column-bar-renderer"/>
+                      <attributes>
+                        <attribute name="perc">2</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="BaobabCellRendererPercent" id="usage-column-percent-renderer">
+                        <property name="xalign">1.0</property>
+                      </object>
+                      <attributes>
+                        <attribute name="percent">2</attribute>
+                      </attributes>
+                    </child>
+                  </object>
                 </child>
-              </object>
-              <packing>
-                <property name="padding">5</property>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkPaned" id="hpaned_main">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
                 <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-                    <property name="shadow_type">GTK_SHADOW_IN</property>
-                    <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+                  <object class="GtkTreeViewColumn" id="size-column">
+                    <property name="resizable">True</property>
+                    <property name="sizing">autosize</property>
+                    <property name="title" translatable="yes">Size</property>
+                    <property name="reorderable">True</property>
+                    <property name="sort_column_id">3</property>
                     <child>
-                      <object class="GtkTreeView" id="treeview1">
-                        <property name="width_request">500</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="headers_visible">False</property>
-                        <property name="rules_hint">True</property>
-                        <property name="reorderable">False</property>
-                        <property name="enable_search">True</property>
-                        <property name="fixed_height_mode">False</property>
-                        <property name="hover_selection">False</property>
-                        <property name="hover_expand">False</property>
+                      <object class="BaobabCellRendererSize" id="size-column-size-renderer">
+                        <property name="xalign">1.0</property>
                       </object>
+                      <attributes>
+                        <attribute name="size">3</attribute>
+                        <attribute name="alloc-size">4</attribute>
+                      </attributes>
                     </child>
                   </object>
-                  <packing>
-                    <property name="shrink">True</property>
-                    <property name="resize">False</property>
-                  </packing>
                 </child>
                 <child>
-                  <placeholder/>
+                  <object class="GtkTreeViewColumn" id="contents-column">
+                    <property name="resizable">True</property>
+                    <property name="sizing">autosize</property>
+                    <property name="title" translatable="yes">Contents</property>
+                    <property name="reorderable">True</property>
+                    <property name="sort_column_id">5</property>
+                    <child>
+                      <object class="BaobabCellRendererItems" id="contents-column-items-renderer">
+                        <property name="xalign">1.0</property>
+                      </object>
+                      <attributes>
+                        <attribute name="items">5</attribute>
+                      </attributes>
+                    </child>
+                  </object>
                 </child>
               </object>
-              <packing>
-                <property name="padding">0</property>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-              </packing>
             </child>
           </object>
           <packing>
-            <property name="padding">0</property>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
+            <property name="resize">False</property>
+            <property name="shrink">True</property>
           </packing>
         </child>
         <child>
-          <object class="GtkStatusbar" id="statusbar1">
+          <object class="GtkNotebook" id="chart-notebook">
             <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="show_tabs">False</property>
+            <property name="show_border">False</property>
+            <child>
+              <object class="BaobabRingschart" id="rings-chart">
+                <property name="visible">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="BaobabTreemap" id="treemap">
+                <property name="visible">True</property>
+              </object>
+            </child>
           </object>
           <packing>
-            <property name="padding">0</property>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
+            <property name="resize">True</property>
+            <property name="shrink">True</property>
           </packing>
         </child>
       </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+        <property name="width">2</property>
+        <property name="height">1</property>
+      </packing>
     </child>
   </object>
 </interface>
-
diff --git a/src/Makefile.am b/src/Makefile.am
index e9c7ccd..0a82df2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,6 +2,7 @@ NULL =
 
 INCLUDES = \
 	-DPREFIX=\""$(prefix)"\" 				\
+	-DGETTEXT_PACKAGE=\""$(GETTEXT_PACKAGE)"\" 		\
 	-DSYSCONFDIR=\""$(sysconfdir)"\"			\
 	-DLIBDIR=\""$(libdir)"\"				\
 	-DDATADIR=\""$(datadir)"\"				\
@@ -12,32 +13,25 @@ INCLUDES = \
 
 bin_PROGRAMS = baobab
 
+baobab_VALAFLAGS = --pkg gtk+-3.0
 baobab_SOURCES = \
-	baobab.c \
-	baobab.h \
-	baobab-cell-renderer-progress.c \
-	baobab-cell-renderer-progress.h \
-	baobab-ringschart.c \
-	baobab-ringschart.h \
-	baobab-scan.c \
-	baobab-scan.h \
-	baobab-treeview.c \
-	baobab-treeview.h \
-	baobab-utils.c \
-	baobab-utils.h \
-	callbacks.c \
-	callbacks.h \
-	baobab-prefs.c \
-	baobab-prefs.h \
-	baobab-remote-connect-dialog.c \
-	baobab-remote-connect-dialog.h \
-	baobab-chart.c \
-	baobab-chart.h \
-	baobab-treemap.c \
-	baobab-treemap.h
+	baobab.vapi			\
+	config.vapi			\
+	baobab-chart.c			\
+	baobab-treemap.c		\
+	baobab-ringschart.c		\
+	baobab-scanner.vala		\
+	baobab-cell-renderer-progress.c	\
+	baobab-cellrenderers.vala	\
+	baobab-application.vala		\
+	baobab-window.vala		\
+	main.vala
 
-baobab_CFLAGS = 			\
+AM_CFLAGS = \
 	$(BAOBAB_CFLAGS)		\
+	-Wall				\
+	-Wno-unused-but-set-variable	\
+	-Wno-unused-variable		\
 	$(NULL)
 
 baobab_LDFLAGS = -export-dynamic
@@ -46,4 +40,12 @@ baobab_LDADD = 				\
 	$(BAOBAB_LIBS)			\
 	$(NULL)
 
+MAINTAINERCLEANFILES = \
+	baobab-application.c		\
+	baobab-scanner.c		\
+	baobab-cellrenderers.c		\
+	baobab-window.c			\
+	baobab_vala.stamp		\
+	main.c
+
 -include $(top_srcdir)/git.mk
diff --git a/src/baobab-application.vala b/src/baobab-application.vala
new file mode 100644
index 0000000..0a78217
--- /dev/null
+++ b/src/baobab-application.vala
@@ -0,0 +1,90 @@
+namespace Baobab {
+	public class Application : Gtk.Application {
+		Settings desktop_settings;
+		Settings prefs_settings;
+		Settings ui_settings;
+
+		File[] excluded_locations;
+
+		static Application baobab;
+
+		protected override void activate () {
+			new Window (this);
+		}
+
+		protected override void open (File[] files, string hint) {
+			foreach (var file in files) {
+				var window = new Window (this);
+				window.scan_directory (file);
+			}
+		}
+
+		void excluded_uris_changed (Settings settings, string key) {
+			var uris = settings.get_strv (key);
+
+			excluded_locations = new File[0];
+
+			var root = File.new_for_path ("/");
+			foreach (var uri in uris) {
+				var file = File.new_for_uri (uri);
+				if (!file.equal (root)) {
+					excluded_locations += file;
+				}
+			}
+		}
+
+		protected override void startup () {
+			base.startup ();
+
+			baobab = this;
+
+			ui_settings = new Settings ("org.gnome.baobab.ui");
+			prefs_settings = new Settings ("org.gnome.baobab.preferences");
+			desktop_settings = new Settings ("org.gnome.desktop.interface");
+
+			excluded_uris_changed (prefs_settings, "excluded-uris");
+			prefs_settings.changed["excluded-uris"] += excluded_uris_changed;
+		}
+
+		protected override bool local_command_line ([CCode (array_length = false, array_null_terminated = true)] ref unowned string[] arguments, out int exit_status) {
+			if (arguments[1] == "-v") {
+				print ("%s %s\n", Environment.get_application_name (), Config.VERSION);
+				exit_status = 0;
+				return true;
+			}
+
+			return base.local_command_line (ref arguments, out exit_status);
+		}
+
+		public Application () {
+			Object (application_id: "org.gnome.baobab", flags: ApplicationFlags.HANDLES_OPEN);
+		}
+
+		public static bool is_excluded_location (File file) {
+			var app = baobab;
+
+			foreach (var location in app.excluded_locations) {
+				if (file.equal (location)) {
+					return true;
+				}
+			}
+
+			return false;
+		}
+
+		public static Settings get_desktop_settings () {
+			var app = baobab;
+			return app.desktop_settings;
+		}
+
+		public static Settings get_prefs_settings () {
+			var app = baobab;
+			return app.prefs_settings;
+		}
+
+		public static Settings get_ui_settings () {
+			var app = baobab;
+			return app.ui_settings;
+		}
+	}
+}
diff --git a/src/baobab-cellrenderers.vala b/src/baobab-cellrenderers.vala
new file mode 100644
index 0000000..b23401d
--- /dev/null
+++ b/src/baobab-cellrenderers.vala
@@ -0,0 +1,37 @@
+namespace Baobab {
+	public class CellRendererPercent : Gtk.CellRendererText {
+		public double percent {
+			set {
+				text = "%.1f %%".printf (value);
+			}
+		}
+	}
+
+	public class CellRendererSize : Gtk.CellRendererText {
+		public new uint64 size {
+			set {
+				if (!show_allocated_size) {
+					text = format_size (value);
+				}
+			}
+		}
+
+		public uint64 alloc_size {
+			set {
+				if (show_allocated_size) {
+					text = format_size (value);
+				}
+			}
+		}
+
+		public bool show_allocated_size { private get; set; }
+	}
+
+	public class CellRendererItems : Gtk.CellRendererText {
+		public int items {
+			set {
+				text = ngettext ("%d item", "%d items", value).printf (value);
+			}
+		}
+	}
+}
diff --git a/src/baobab-scanner.vala b/src/baobab-scanner.vala
new file mode 100644
index 0000000..14ab984
--- /dev/null
+++ b/src/baobab-scanner.vala
@@ -0,0 +1,136 @@
+namespace Baobab {
+	class Scanner : Gtk.TreeStore {
+		public enum Columns {
+			DISPLAY_NAME,
+			PARSE_NAME,
+			PERCENT,
+			SIZE,
+			ALLOC_SIZE,
+			ELEMENTS,
+			COLUMNS
+		}
+
+		struct HardLink {
+			uint64 inode;
+			uint32 device;
+
+			public HardLink (FileInfo info) {
+				this.inode = info.get_attribute_uint64 (FILE_ATTRIBUTE_UNIX_INODE);
+				this.device = info.get_attribute_uint32 (FILE_ATTRIBUTE_UNIX_DEVICE);
+			}
+		}
+
+		Cancellable? cancellable;
+		HardLink[] hardlinks;
+
+		static const string ATTRIBUTES =
+			FILE_ATTRIBUTE_STANDARD_NAME + "," +
+			FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME + "," +
+			FILE_ATTRIBUTE_STANDARD_TYPE + "," +
+			FILE_ATTRIBUTE_STANDARD_SIZE +  "," +
+			FILE_ATTRIBUTE_UNIX_BLOCKS + "," +
+			FILE_ATTRIBUTE_UNIX_NLINK + "," +
+			FILE_ATTRIBUTE_UNIX_INODE + "," +
+			FILE_ATTRIBUTE_UNIX_DEVICE + "," +
+			FILE_ATTRIBUTE_ACCESS_CAN_READ;
+
+		void add_directory (File directory, FileInfo info, Gtk.TreeIter? parent_iter = null) {
+			Gtk.TreeIter iter;
+			uint64 alloc_size;
+			uint64 size;
+			int elements;
+
+			elements = 0;
+
+			if (Application.is_excluded_location (directory)) {
+				return;
+			}
+
+			var display_name = info.get_display_name ();
+			var parse_name = directory.get_parse_name ();
+
+			if (info.has_attribute (FILE_ATTRIBUTE_STANDARD_SIZE)) {
+				size = info.get_size ();
+			} else {
+				size = 0;
+			}
+
+			if (info.has_attribute (FILE_ATTRIBUTE_UNIX_BLOCKS)) {
+				alloc_size = 512 * info.get_attribute_uint64 (FILE_ATTRIBUTE_UNIX_BLOCKS);
+			} else {
+				alloc_size = 0;
+			}
+
+			append (out iter, parent_iter);
+			set (iter, 0, display_name);
+			set (iter, 1, parse_name);
+			set (iter, 2, 0.0);
+			set (iter, 3, size);
+			set (iter, 4, alloc_size);
+			set (iter, 5, elements);
+
+			try {
+				var children = directory.enumerate_children (ATTRIBUTES, FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
+				FileInfo? child_info;
+				while ((child_info = children.next_file (cancellable)) != null) {
+					if (cancellable.is_cancelled ()) {
+						return;
+					}
+
+					switch (child_info.get_file_type ()) {
+						case FileType.DIRECTORY:
+							var child = directory.get_child (child_info.get_name ());
+							add_directory (child, child_info, iter);
+							elements++;
+							break;
+
+						case FileType.REGULAR:
+							if (child_info.has_attribute (FILE_ATTRIBUTE_UNIX_NLINK)) {
+								if (child_info.get_attribute_uint32 (FILE_ATTRIBUTE_UNIX_NLINK) > 1) {
+									var hl = HardLink (child_info);
+
+									/* check if we've already encountered this file */
+									if (hl in hardlinks) {
+										continue;
+									}
+
+									hardlinks += hl;
+								}
+							}
+
+							if (child_info.has_attribute (FILE_ATTRIBUTE_UNIX_BLOCKS)) {
+								alloc_size += 512 * child_info.get_attribute_uint64 (FILE_ATTRIBUTE_UNIX_BLOCKS);
+							}
+							size += child_info.get_size ();
+							elements++;
+							break;
+
+						default:
+							/* ignore other types (symlinks, sockets, devices, etc) */
+							break;
+					}
+				}
+			} catch (IOError.PERMISSION_DENIED e) {
+			} catch (Error e) {
+				warning ("couldn't iterate %s: %s", parse_name, e.message);
+			}
+
+		}
+
+		void scan (File directory) {
+			try {var info = directory.query_info (ATTRIBUTES, 0, cancellable);
+			add_directory (directory, info);} catch { }
+		}
+
+		public Scanner (File directory) {
+			set_column_types (new Type[] {
+			                  typeof (string), /* DIR_NAME */
+			                  typeof (string), /* PARSE_NAME */
+			                  typeof (double), /* PERCENT */
+			                  typeof (uint64), /* SIZE */
+			                  typeof (uint64), /* ALLOC_SIZE */
+			                  typeof (int)});  /* ELEMENTS */
+			scan (directory);
+		}
+	}
+}
diff --git a/src/baobab-window.vala b/src/baobab-window.vala
new file mode 100644
index 0000000..d879d7f
--- /dev/null
+++ b/src/baobab-window.vala
@@ -0,0 +1,79 @@
+namespace Baobab {
+	public class Window : Gtk.ApplicationWindow {
+		Gtk.TreeModel? model;
+		Gtk.Builder builder;
+
+		public Window (Application app) {
+			Object (application: app);
+
+			// Build ourselves.
+			builder = new Gtk.Builder ();
+			try {
+				builder.add_from_file (Config.PKGDATADIR + "/baobab-main-window.ui");
+			} catch (Error e) {
+				error ("loading main builder file: %s", e.message);
+			}
+
+			var ui_settings = Application.get_ui_settings ();
+
+			// Setup the logic for switching between the chart types.
+			var chart_type_combo = builder.get_object ("chart-type-combo");
+			var charts_notebook = builder.get_object ("chart-notebook");
+			chart_type_combo.bind_property ("active", charts_notebook, "page", BindingFlags.SYNC_CREATE);
+			ui_settings.bind ("active-chart", chart_type_combo, "active-id", SettingsBindFlags.GET_NO_CHANGES);
+
+			// Setup the logic for statusbar visibility.
+			var statusbar = builder.get_object ("statusbar") as Gtk.Widget;
+			statusbar.visible = ui_settings.get_boolean ("statusbar-visible");
+
+			// Go live.
+			add (builder.get_object ("window-contents") as Gtk.Widget);
+			title = _("Disk Usage Analyzer");
+			set_default_size (800, 500);
+			show ();
+		}
+
+
+		void message (string primary_msg, string secondary_msg, Gtk.MessageType type) {
+			var dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.DESTROY_WITH_PARENT, type,
+					Gtk.ButtonsType.OK, "%s", primary_msg);
+			dialog.format_secondary_text ("%s", secondary_msg);
+			dialog.run (); /* XXX kill it with fire */
+			dialog.destroy ();
+		}
+
+		public bool check_dir (File directory) {
+			if (Application.is_excluded_location (directory)) {
+				message("", _("Cannot check an excluded folder!"), Gtk.MessageType.INFO);
+				return false;
+			}
+
+			try {
+				var info = directory.query_info (FILE_ATTRIBUTE_STANDARD_TYPE, FileQueryInfoFlags.NONE, null);
+				if (info.get_file_type () != FileType.DIRECTORY/* || is_virtual_filesystem ()*/) {
+					var primary = _("\"%s\" is not a valid folder").printf (directory.get_parse_name ());
+					message (primary, _("Could not analyze disk usage."), Gtk.MessageType.ERROR);
+					return false;
+				}
+				return true;
+			} catch (Error e) {
+				message ("", e.message, Gtk.MessageType.INFO);
+				return false;
+			}
+		}
+
+		public void scan_directory (File directory) {
+			if (!check_dir (directory)) {
+				return;
+			}
+
+			model = new Scanner (directory);
+			var rings_chart = builder.get_object ("rings-chart") as Chart;
+			var treemap = builder.get_object ("treemap") as Chart;
+			rings_chart.set_model_with_columns (model, 0, 1, 2, 3, 4, null);
+			treemap.set_model_with_columns (model, 0, 1, 2, 3, 4, null);
+			var treeview = builder.get_object ("treeview") as Gtk.TreeView;
+			treeview.model = model;
+		}
+	}
+}
diff --git a/src/baobab.vapi b/src/baobab.vapi
new file mode 100644
index 0000000..91ce737
--- /dev/null
+++ b/src/baobab.vapi
@@ -0,0 +1,34 @@
+namespace Baobab {
+	[CCode (cheader_filename = "baobab-ringschart.h")]
+	public class Ringschart : Chart {
+		public Ringschart ();
+		public void set_subfoldertips_enabled (bool enabled);
+	}
+
+	[CCode (cheader_filename = "baobab-treemap.h")]
+	public class Treemap : Chart {
+		public Treemap ();
+	}
+
+	[CCode (cheader_filename = "baobab-chart.h")]
+	public class Chart : Gtk.Widget {
+		public void set_model_with_columns (Gtk.TreeModel model, uint name_column, uint size_column, uint info_column, uint percentage_column, uint valid_column, Gtk.TreePath? root);
+
+		public Gtk.TreeModel model { get; set; }
+		public Gtk.TreePath root { get; set; }
+		public uint max_depth { get; set; }
+
+		public void set_model (Gtk.TreeModel? model);
+		public unowned Gtk.TreeModel? get_model ();
+
+		public void set_max_depth (uint max_depth);
+		public uint get_max_depth ();
+
+		public void set_root (Gtk.TreePath? path);
+		public unowned Gtk.TreePath? get_root ();
+
+		public void freeze_updates ();
+		public void thaw_updates ();
+		public bool is_frozen ();
+	}
+}
diff --git a/src/config.vapi b/src/config.vapi
new file mode 100644
index 0000000..e895293
--- /dev/null
+++ b/src/config.vapi
@@ -0,0 +1,6 @@
+[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
+namespace Config {
+	public const string PKGDATADIR;
+	public const string VERSION;
+	public const string GETTEXT_PACKAGE;
+}
diff --git a/src/main.vala b/src/main.vala
new file mode 100644
index 0000000..149c6ed
--- /dev/null
+++ b/src/main.vala
@@ -0,0 +1,4 @@
+int main (string[] args) {
+	var baobab = new Baobab.Application ();
+	return baobab.run (args);
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]