Rev 164: Add a _WTItem class layout that can wrap the WT.walkdirs interface. in http://bazaar.launchpad.net/~jameinel/bzr-explorer/wt_model

John Arbash Meinel john at arbash-meinel.com
Tue Jul 7 21:52:02 BST 2009


At http://bazaar.launchpad.net/~jameinel/bzr-explorer/wt_model

------------------------------------------------------------
revno: 164
revision-id: john at arbash-meinel.com-20090707205158-95ex3vouiczesp4v
parent: john at arbash-meinel.com-20090707194419-lm7utnurj1n15nr6
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: wt_model
timestamp: Tue 2009-07-07 15:51:58 -0500
message:
  Add a _WTItem class layout that can wrap the WT.walkdirs interface.
  
  This gives us access to both versioned objects and unversioned objects.
-------------- next part --------------
=== modified file 'lib/wt_browser.py'
--- a/lib/wt_browser.py	2009-07-07 19:44:19 +0000
+++ b/lib/wt_browser.py	2009-07-07 20:51:58 +0000
@@ -26,35 +26,6 @@
     )
 
 
-class WorkingTreeModel(QtGui.QDirModel):
-    """A model that starts to know information about a given directory.
-    """
-
-    def __init__(self, parent=None):
-        QtGui.QDirModel.__init__(self, parent)
-        self._dir_model_columns = QtGui.QDirModel.columnCount(self)
-        self._extra_data = {}
-
-    def columnCount(self, ignored=None):
-        return self._dir_model_columns + 1
-
-    def data(self, index, role):
-        if not index.isValid():
-            return QtCore.QVariant()
-        column = index.column() - self._dir_model_columns
-        if column < 0:
-            return QtGui.QDirModel.data(self, index, role)
-        if role != QtCore.Qt.DisplayRole:
-            return QtCore.QVariant()
-        return QtCore.QVariant('this is my str')
-
-    def headerData(self, section, orientation, role):
-        column = section - self._dir_model_columns
-        if column < 0:
-            return QtGui.QDirModel.headerData(self, section, orientation, role)
-        return QtCore.QVariant('my section')
-
-
 class WorkingTreeBrowser(QtGui.QDockWidget):
 
     def __init__(self, action_callback, browse_action, *args):

=== added file 'lib/wt_model.py'
--- a/lib/wt_model.py	1970-01-01 00:00:00 +0000
+++ b/lib/wt_model.py	2009-07-07 20:51:58 +0000
@@ -0,0 +1,147 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""Implement a Model defining interactions with a WorkingTree"""
+
+from bzrlib import workingtree
+
+from PyQt4 import QtCore, QtGui
+
+
+# TODO: consider that this is similar to what one would want for an
+#       InventoryModel, except we should have extra attributes like
+#       "is_modified", etc. Also consider that for a working tree, we probably
+#       need to handle files that are unknown and ignored.
+class _WTItem(object):
+    """Encapsulates the display information for a given item.
+
+    :ivar children:
+    :type children: A list of _WTItem objects
+    """
+
+    def __init__(self, path, name, disk_kind, file_id, inv_kind, parent):
+        """Create a new _WTItem
+
+        :type inventory_entry: A bzrlib.inventory.InventoryEntry
+        :type parent: _WTItem
+        """
+        self.path = path
+        self.name = name
+        self.disk_kind = disk_kind
+        self.file_id = file_id
+        self.inv_kind = inv_kind
+        # Note: this creates a cyclical reference, consider using parent_id
+        #       instead
+        self.parent = parent
+        self.children = []
+
+    @staticmethod
+    def create_from_wt(wt):
+        """Create the _WTItem tree structure from an inventory."""
+        wt.lock_read()
+        try:
+            # By file-id
+            dir_items = {}
+            root_wt_item = None
+            for dir_info, dir_block_info in wt.walkdirs():
+                dir_path, dir_file_id = dir_info
+                try:
+                    dir_wt_item = dir_items[dir_file_id]
+                except KeyError:
+                    dir_wt_item = _WTItem(dir_path, '', 'directory',
+                        dir_file_id, 'directory', parent=None)
+                    root_wt_item = dir_wt_item
+                for (f_path, f_name, f_disk_kind, _, f_id,
+                     f_inv_kind) in dir_block_info:
+                    wt_item = _WTItem(f_path, f_name, f_disk_kind, f_id,
+                                      f_inv_kind, parent=dir_wt_item)
+                    dir_wt_item.children.append(wt_item)
+        finally:
+            wt.unlock()
+        return root_wt_item
+
+
+class WorkingTreeModel(QtCore.QAbstractItemModel):
+
+    def __init__(self, path, parent=None):
+        QtCore.QAbstractItemModel.__init__(self, parent)
+        self._wt = workingtree.WorkingTree.open(path)
+
+    def index(self, row, column, parent=None):
+        """Return the QModelIndex for the given item.
+
+        :param row: In this case, the Nth file for the given directory
+        :type row: int
+        :param column: The data attribute for the given file/dir
+        :type column: int
+        :param parent: the containing directory
+        :type parent: QModelIndex
+        :return: The index object to reference the given data
+        :rtype: QModelIndex
+        """
+        # Der broken
+        return None
+
+    # def parent(self, ...):
+
+    # def rowCount(self, ...):
+    # implement def hasChildren(self, ...) if rowCount is expensive
+
+    # def columnCount(self, ...):
+
+    # def data(self, ...):
+
+    # implement def setData(self, ...) if we want to be editable
+
+    # def headerData(self, ...):
+
+    # Interesting Role list:
+    #   QtCore.Qt.DisplayRole, QtCore.Qt.ToolTipRole, QtCore.Qt.WhatsThisRole
+
+    # Do we want to incrementally populate? Perhaps this would be useful for an
+    # IterChangesModel
+    # def fetchMore(self, ...)
+    # def canFetchmore(self, ...)
+
+
+# class WorkingTreeModel(QtGui.QDirModel):
+#     """A model that starts to know information about a given directory.
+#     """
+# 
+#     def __init__(self, parent=None):
+#         QtGui.QDirModel.__init__(self, parent)
+#         self._dir_model_columns = QtGui.QDirModel.columnCount(self)
+#         self._extra_data = {}
+# 
+#     def columnCount(self, ignored=None):
+#         return self._dir_model_columns + 1
+# 
+#     def data(self, index, role):
+#         if not index.isValid():
+#             return QtCore.QVariant()
+#         column = index.column() - self._dir_model_columns
+#         if column < 0:
+#             return QtGui.QDirModel.data(self, index, role)
+#         if role != QtCore.Qt.DisplayRole:
+#             return QtCore.QVariant()
+#         return QtCore.QVariant('this is my str')
+# 
+#     def headerData(self, section, orientation, role):
+#         column = section - self._dir_model_columns
+#         if column < 0:
+#             return QtGui.QDirModel.headerData(self, section, orientation, role)
+#         return QtCore.QVariant('my section')
+# 

=== modified file 'tests/__init__.py'
--- a/tests/__init__.py	2009-07-07 19:39:48 +0000
+++ b/tests/__init__.py	2009-07-07 20:51:58 +0000
@@ -28,7 +28,8 @@
     suite.addTests(basic_tests)
 
     mod_names = [__name__ + '.' + x for x in [
-        'test_welcome_model'
+        'test_welcome_model',
+        'test_wt_model',
     ]]
     suite.addTests(loader.loadTestsFromModuleNames(mod_names))
     return suite

=== added file 'tests/test_wt_model.py'
--- a/tests/test_wt_model.py	1970-01-01 00:00:00 +0000
+++ b/tests/test_wt_model.py	2009-07-07 20:51:58 +0000
@@ -0,0 +1,86 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""tests for the WorkingTreeModel class"""
+
+from bzrlib import (
+    errors,
+    inventory,
+    tests,
+    )
+
+from bzrlib.plugins.explorer.lib import wt_model
+
+
+class TestWTModel(tests.TestCaseWithTransport):
+
+    def test__init__(self):
+        self.make_branch_and_tree('.')
+        model = wt_model.WorkingTreeModel('.')
+
+
+class Test_WTItem(tests.TestCaseWithTransport):
+
+    def test_from_wt_simple(self):
+        wt = self.make_branch_and_tree('.')
+        self.build_tree(['a_file'])
+        wt.add(['a_file'], ['file-id'])
+        wt.set_root_id('root-id')
+        root_item = wt_model._WTItem.create_from_wt(wt)
+        self.assertIsInstance(root_item, wt_model._WTItem)
+        self.assertEqual('', root_item.path)
+        self.assertEqual('', root_item.name)
+        self.assertEqual('directory', root_item.disk_kind)
+        self.assertEqual('root-id', root_item.file_id)
+        self.assertEqual('directory', root_item.inv_kind)
+        self.assertIs(None, root_item.parent)
+        self.assertEqual(1, len(root_item.children))
+        child = root_item.children[0]
+        self.assertEqual('a_file', child.path)
+        self.assertEqual('a_file', child.name)
+        self.assertEqual('file', child.disk_kind)
+        self.assertEqual('file-id', child.file_id)
+        self.assertEqual('file', child.inv_kind)
+        self.assertIs(root_item, child.parent)
+
+    def test_unversioned_from_wt(self):
+        wt = self.make_branch_and_tree('.')
+        self.build_tree(['a_file', 'unversioned-file'])
+        wt.add(['a_file'], ['file-id'])
+        wt.set_root_id('root-id')
+        root_item = wt_model._WTItem.create_from_wt(wt)
+        self.assertIsInstance(root_item, wt_model._WTItem)
+        self.assertEqual('', root_item.path)
+        self.assertEqual('', root_item.name)
+        self.assertEqual('directory', root_item.disk_kind)
+        self.assertEqual('root-id', root_item.file_id)
+        self.assertEqual('directory', root_item.inv_kind)
+        self.assertIs(None, root_item.parent)
+        self.assertEqual(2, len(root_item.children))
+        child = root_item.children[0]
+        self.assertEqual('a_file', child.path)
+        self.assertEqual('a_file', child.name)
+        self.assertEqual('file', child.disk_kind)
+        self.assertEqual('file-id', child.file_id)
+        self.assertEqual('file', child.inv_kind)
+        self.assertIs(root_item, child.parent)
+        child = root_item.children[1]
+        self.assertEqual('unversioned-file', child.path)
+        self.assertEqual('unversioned-file', child.name)
+        self.assertEqual('file', child.disk_kind)
+        self.assertEqual(None, child.file_id)
+        self.assertEqual(None, child.inv_kind)
+        self.assertIs(root_item, child.parent)



More information about the bazaar-commits mailing list