~bzr/ubuntu/jaunty/bzr-explorer/bzr-ppa

« back to all changes in this revision

Viewing changes to lib/wt_browser.py

  • Committer: Andrew Starr-Bochicchio
  • Date: 2010-02-09 17:07:26 UTC
  • mfrom: (311.1.113 trunk)
  • Revision ID: a.starr.b@gmail.com-20100209170726-sqpqfbfpufcvr9s0
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
except ImportError:
24
24
    from bzrlib.plugins.explorer.lib.helpers import parent_directories
25
25
 
 
26
from bzrlib.plugins.explorer.lib import kinds
26
27
from bzrlib.plugins.explorer.lib.helpers import build_combo_with_labels
27
28
from bzrlib.plugins.explorer.lib.i18n import gettext, N_
28
 
from bzrlib.plugins.explorer.lib.kinds import (
29
 
    CANCEL_ACTION,
30
 
    OPEN_FOLDER_ACTION,
31
 
    EDIT_ACTION,
32
 
    icon_for_kind,
33
 
    )
34
29
from bzrlib.plugins.qbzr.lib import treewidget
35
30
 
36
31
 
76
71
 
77
72
    def refresh(self):
78
73
        """Refresh the browser."""
79
 
        self._browser.refresh()
 
74
        if self._tree is not None:
 
75
            self._browser.refresh()
80
76
 
81
77
    def get_style(self):
82
78
        return self._style
96
92
        self._browser.set_tree(self._tree, self._branch)
97
93
        self._stacked.setCurrentIndex(index)
98
94
 
99
 
 
100
 
class _ActionPanel(QtGui.QDialogButtonBox):
 
95
    def set_default_action(self, default_action):
 
96
        """Set the default action to either 'open' or 'edit'."""
 
97
        self._browser.set_default_action(default_action)
 
98
 
 
99
 
 
100
class _ActionPanel(QtGui.QToolBar):
101
101
 
102
102
    def __init__(self, action_callback, browse_action, *args):
103
103
        self._action_callback = action_callback
105
105
        QtGui.QDialogButtonBox.__init__(self, *args)
106
106
        self._root = None
107
107
        self._selected_fileinfo = None
 
108
        self._button_style = QtCore.Qt.ToolButtonTextUnderIcon
108
109
 
109
110
        # Build the buttons and add them to a panel
110
 
        browse_button = QtGui.QPushButton()
111
 
        browse_button.setText(self._browse_action.iconText())
112
 
        browse_button.setIcon(self._browse_action.icon())
113
 
        open_button = QtGui.QPushButton()
114
 
        open_button.setText(gettext("&Manage"))
115
 
        open_button.setIcon(icon_for_kind(OPEN_FOLDER_ACTION))
116
 
        edit_button = QtGui.QPushButton()
117
 
        edit_button.setText(gettext("&Edit"))
118
 
        edit_button.setIcon(icon_for_kind(EDIT_ACTION))
119
 
        self.addButton(browse_button, QtGui.QDialogButtonBox.ActionRole)
120
 
        self.addButton(open_button, QtGui.QDialogButtonBox.ActionRole)
121
 
        self.addButton(edit_button, QtGui.QDialogButtonBox.AcceptRole)
122
 
        self.connect(browse_button, QtCore.SIGNAL("clicked(bool)"),
 
111
        self._open_button = self._build_button(
 
112
            kinds.icon_for_kind(kinds.OPEN_ACTION),
 
113
            gettext("&Open"),
 
114
            gettext("Open selected item"),
 
115
            self._do_open_file)
 
116
        self._edit_button = self._build_button(
 
117
            kinds.icon_for_kind(kinds.EDIT_ACTION),
 
118
            gettext("&Edit"),
 
119
            gettext("Edit selected item"),
 
120
            self._do_edit_file)
 
121
        self.addSeparator()
 
122
        self._build_button(
 
123
            kinds.icon_for_kind(kinds.OPEN_FOLDER_ACTION),
 
124
            gettext("&Manage"),
 
125
            gettext("Open file manager on folder"),
 
126
            self._do_open_folder)
 
127
        self._build_button(
 
128
            kinds.icon_for_kind(kinds.NEW_FILE_ACTION),
 
129
            gettext("&New File"),
 
130
            gettext("Create a new file"),
 
131
            self._do_new_file)
 
132
        self._build_button(
 
133
            kinds.icon_for_kind(kinds.NEW_FOLDER_ACTION),
 
134
            gettext("New &Folder"),
 
135
            gettext("Create a new folder"),
 
136
            self._do_new_folder)
 
137
        self.addSeparator()
 
138
        self._build_button(
 
139
            self._browse_action.icon(),
 
140
            self._browse_action.iconText(),
 
141
            self._browse_action.statusTip(),
123
142
            self._do_browse_items)
124
 
        self.connect(open_button, QtCore.SIGNAL("clicked(bool)"),
125
 
            self._do_open_folder)
126
 
        self.connect(edit_button, QtCore.SIGNAL("clicked(bool)"),
127
 
            self._do_edit_file)
128
 
        self._edit_button = edit_button
129
 
 
130
 
    def _do_browse_items(self):
131
 
        self._action_callback("browse", None)
132
 
 
133
 
    def _do_open_folder(self):
 
143
        self.addSeparator()
 
144
        self._build_button(
 
145
            kinds.icon_for_kind(kinds.COLLAPSE_ALL_ACTION),
 
146
            gettext("&Collapse"),
 
147
            gettext("Fully collapse tree"),
 
148
            self._do_collapse_all)
 
149
        self._build_button(
 
150
            kinds.icon_for_kind(kinds.EXPAND_ALL_ACTION),
 
151
            gettext("&Expand"),
 
152
            gettext("Fully expand tree"),
 
153
            self._do_expand_all)
 
154
 
 
155
    def _build_button(self, icon, text, tooltip, callback, arrow=None):
 
156
        button = QtGui.QToolButton()
 
157
        button.setText(text)
 
158
        if arrow:
 
159
            button.setArrowType(arrow)
 
160
        else:
 
161
            button.setIcon(icon)
 
162
        button.setToolTip(tooltip)
 
163
        #button.setToolButtonStyle(self._button_style)
 
164
        button.setAutoRaise(True)
 
165
        #self.addButton(button, QtGui.QDialogButtonBox.ActionRole)
 
166
        self.addWidget(button)
 
167
        self.connect(button, QtCore.SIGNAL("clicked(bool)"), callback)
 
168
        return button
 
169
 
 
170
    def _get_folder(self):
134
171
        fileinfo = self._selected_fileinfo
135
172
        if fileinfo is None:
136
173
            folder = self._root
138
175
            folder = fileinfo.canonicalFilePath()
139
176
        else:
140
177
            folder = fileinfo.canonicalPath()
141
 
        self._action_callback("open", folder)
 
178
        return unicode(folder)
 
179
 
 
180
    def _do_browse_items(self):
 
181
        self._action_callback("browse", None)
 
182
 
 
183
    def _do_open_folder(self):
 
184
        self._action_callback("open", self._get_folder())
 
185
 
 
186
    def _do_open_file(self):
 
187
        fileinfo = self._selected_fileinfo
 
188
        path = fileinfo.canonicalFilePath()
 
189
        self._action_callback("open", unicode(path))
142
190
 
143
191
    def _do_edit_file(self):
144
192
        fileinfo = self._selected_fileinfo
145
193
        path = fileinfo.canonicalFilePath()
146
194
        self._action_callback("edit", unicode(path))
147
195
 
 
196
    def _do_new_file(self):
 
197
        destination = self._get_folder()
 
198
        self._action_callback("new-file", destination)
 
199
        self._tree_viewer.refresh()
 
200
 
 
201
    def _do_new_folder(self):
 
202
        destination = self._get_folder()
 
203
        self._action_callback("new-directory", destination)
 
204
        self._tree_viewer.refresh()
 
205
 
 
206
    def _do_collapse_all(self):
 
207
        self._tree_viewer.collapseAll()
 
208
 
 
209
    def _do_expand_all(self):
 
210
        self._tree_viewer.expandAll()
 
211
 
 
212
    def set_viewer(self, tree_viewer):
 
213
        self._tree_viewer = tree_viewer
 
214
 
148
215
    def set_root(self, path):
149
216
        self._root = path
150
217
 
151
 
    def set_selection(self, fileinfo):
 
218
    def set_selection(self, fileinfo, model_index=None):
152
219
        self._selected_fileinfo = fileinfo
 
220
        self._selected_index = model_index
153
221
        edit_is_enabled = True
154
222
        if fileinfo is None or fileinfo.isDir():
155
223
            edit_is_enabled = False
156
224
        self._edit_button.setEnabled(edit_is_enabled)
 
225
        self._open_button.setEnabled(edit_is_enabled)
157
226
 
158
227
 
159
228
class _FilterPanel(QtGui.QWidget):
161
230
    def __init__(self, *args):
162
231
        QtGui.QWidget.__init__(self, *args)
163
232
        self._tree_viewer = None
164
 
        self._current_filter = ''
 
233
        self._apply_filter_callback = ''
165
234
 
166
235
        # Build the controls
167
236
        filter_label = QtGui.QLabel(gettext("Filter:"))
169
238
        self._filter_cancel_button = QtGui.QToolButton()
170
239
        self._filter_cancel_button.setAutoRaise(True)
171
240
        self._filter_cancel_button.setEnabled(False)
172
 
        self._filter_cancel_button.setIcon(icon_for_kind(CANCEL_ACTION))
 
241
        self._filter_cancel_button.setIcon(kinds.icon_for_kind(
 
242
            kinds.CANCEL_ACTION))
173
243
        self._filter_cancel_button.setToolTip(gettext("Clear the filter"))
174
244
 
175
245
        # Connect up the controls to handlers
187
257
        self.setLayout(layout)
188
258
 
189
259
    def _apply_filter(self, text):
190
 
        self._tree_viewer.invalidate_filter()
 
260
        self._apply_filter_callback(text)
191
261
        if text:
192
262
            self._filter_cancel_button.setEnabled(True)
193
 
            # Filtering active. We want to see all matches and
194
 
            # this mostly works. It seems to struggle though when
195
 
            # the filter gets shorter - maybe a Qt 4.4 bug w.r.t.
196
 
            # propagating exactly what's changed to the view?
197
 
            self._tree_viewer.expandAll()
198
263
        else:
199
 
            # Filtering cleared. Restore the initial view with
200
 
            # everything collapsed. (If the user has selectively
201
 
            # expanded some directories out before filtering,
202
 
            # collapsing all here implies losing that setup. We
203
 
            # could always remember the expanded directories at
204
 
            # the start of filtering and restore them at this
205
 
            # point if it proves a problem in practice.)
206
 
            self._tree_viewer.collapseAll()
207
 
            self._tree_viewer.refresh()
208
264
            self._filter_cancel_button.setEnabled(False)
209
265
        self._current_filter = text
210
266
 
214
270
    def get_filter(self):
215
271
        return unicode(self._filter_field.text())
216
272
 
217
 
    def set_tree_viewer(self, tree_viewer):
218
 
        self._tree_viewer = tree_viewer
 
273
    def set_apply_filter(self, apply_filter_callback):
 
274
        self._apply_filter_callback = apply_filter_callback
219
275
 
220
276
 
221
277
class _TreeViewer(QtGui.QTreeView):
226
282
        self._selection_callback = selection_callback
227
283
        self._filter_callback = filter_callback
228
284
        QtGui.QTreeView.__init__(self, *args)
 
285
        self._default_action = "open"
229
286
 
230
287
        # Use a proxy model so we can filter on the path.
231
288
        self._source_model = _TreeModel()
253
310
        fileinfo = self._get_fileinfo(model_index)
254
311
        if fileinfo is not None and not fileinfo.isDir():
255
312
            path = fileinfo.canonicalFilePath()
256
 
            self._action_callback("open", unicode(path))
 
313
            self._action_callback(self._default_action, unicode(path))
257
314
 
258
315
    def _do_current_changed(self, model_index, prev_model_index):
259
316
        fileinfo = self._get_fileinfo(model_index)
260
 
        self._selection_callback(fileinfo)
 
317
        self._selection_callback(fileinfo, model_index)
261
318
 
262
319
    def _get_fileinfo(self, model_index):
263
320
        model = model_index.model()
284
341
    def invalidate_filter(self):
285
342
        self._model.invalidateFilter()
286
343
 
 
344
    def set_default_action(self, default_action):
 
345
        """Set the default action to either 'open' or 'edit'."""
 
346
        self._default_action = default_action
 
347
 
287
348
 
288
349
class _TreeModel(QtGui.QDirModel):
289
350
 
359
420
        return result
360
421
 
361
422
 
362
 
class _ClassicBrowser(QtGui.QWidget):
 
423
class _AbstractBrowser(QtGui.QWidget):
363
424
 
364
425
    filter_panel_factory = _FilterPanel
365
426
    tree_viewer_factory = _TreeViewer
376
437
        self._filter_panel = self.filter_panel_factory()
377
438
        self._tree_viewer = self.tree_viewer_factory(action_callback,
378
439
            self._action_panel.set_selection, self._filter_panel.get_filter)
379
 
        self._filter_panel.set_tree_viewer(self._tree_viewer)
 
440
        self._action_panel.set_viewer(self._tree_viewer)
 
441
        self._filter_panel.set_apply_filter(self._apply_filter)
380
442
 
381
443
        # Put them together
382
444
        layout = QtGui.QVBoxLayout()
396
458
        """Refresh the browser."""
397
459
        self._tree_viewer.refresh()
398
460
 
 
461
    def set_default_action(self, default_action):
 
462
        """Set the default action to either 'open' or 'edit'."""
 
463
        self._tree_viewer.set_default_action(default_action)
 
464
 
 
465
 
 
466
class _ClassicBrowser(_AbstractBrowser):
 
467
 
 
468
    def _apply_filter(self, text):
 
469
        self._tree_viewer.invalidate_filter()
 
470
        if text:
 
471
            # Filtering active. We want to see all matches and
 
472
            # this mostly works. It seems to struggle though when
 
473
            # the filter gets shorter - maybe a Qt 4.4 bug w.r.t.
 
474
            # propagating exactly what's changed to the view?
 
475
            self._tree_viewer.expandAll()
 
476
        else:
 
477
            # Filtering cleared. Restore the initial view with
 
478
            # everything collapsed. (If the user has selectively
 
479
            # expanded some directories out before filtering,
 
480
            # collapsing all here implies losing that setup. We
 
481
            # could always remember the expanded directories at
 
482
            # the start of filtering and restore them at this
 
483
            # point if it proves a problem in practice.)
 
484
            self._tree_viewer.collapseAll()
 
485
            self._tree_viewer.refresh()
 
486
 
399
487
 
400
488
### QBrowse style browser support ###
401
489
 
402
490
# The map from filter category to filter flags for TreeFilterProxyModels
403
491
_FILTER_FLAGS_MAP = {
404
492
    # The flag order is UNCHANGED, CHANGED, UNVERSIONED, IGNORED
405
 
    'versioned':        [True, True, True, False],
 
493
    'all':              [True, True, True, True],
406
494
    'changed':          [False, True, False, False],
 
495
    'versioned':        [True, True, False, False],
 
496
    'unversioned':      [False, False, True, False],
407
497
    'ignored':          [False, False, True, True],
408
 
    'unversioned':      [False, False, True, False],
409
 
    'all':              [True, True, True, True],
 
498
    'unignored':        [True, True, True, False],
410
499
    }
411
500
 
412
501
class _QBrowseStyleFilterPanel(QtGui.QWidget):
417
506
 
418
507
        # Build the controls
419
508
        self._category_combo = build_combo_with_labels([
 
509
            ('all', gettext("All")),
 
510
            ('changed', gettext("Changed")),
420
511
            ('versioned', gettext("Versioned")),
421
 
            ('changed', gettext("Changed")),
 
512
            ('unversioned', gettext("Unversioned")),
422
513
            ('ignored', gettext("Ignored")),
423
 
            ('unversioned', gettext("Unversioned")),
424
 
            ('all', gettext("All")),
 
514
            ('unignored', gettext("Unignored")),
425
515
            ])
 
516
        self._category_combo.setCurrentIndex(5)
 
517
        self._text_filter = _FilterPanel()
426
518
 
427
519
        # Connect up the controls to handlers
428
520
        QtCore.QObject.connect(self._category_combo,
429
521
            QtCore.SIGNAL("currentIndexChanged(int)"),
430
522
            self._apply_category)
 
523
        self._text_filter.set_apply_filter(self._apply_text)
431
524
 
432
525
        # Put the controls together
433
526
        layout = QtGui.QHBoxLayout()
434
527
        layout.addWidget(self._category_combo)
435
 
        layout.addStretch(1)
 
528
        layout.addWidget(self._text_filter)
436
529
        layout.setContentsMargins(0, 0, 0, 0)
437
530
        self.setLayout(layout)
438
531
 
 
532
    def _flags_for_index(self, index):
 
533
        category = str(self._category_combo.itemData(index).toString())
 
534
        return _FILTER_FLAGS_MAP[category]
 
535
 
439
536
    def _apply_category(self, index):
440
 
        category = str(self._category_combo.itemData(index).toString())
441
 
        filter_flags = _FILTER_FLAGS_MAP[category]
442
 
        #print "category %s mapped to flags %s" % (category, filter_flags)
443
 
        self._tree_viewer.tree_filter_model.setFilters(filter_flags)
 
537
        self._apply_filter_callback(self._flags_for_index(index), True,
 
538
            self._text_filter.get_filter(), False)
 
539
 
 
540
    def _apply_text(self, text):
 
541
        index = self._category_combo.currentIndex()
 
542
        self._apply_filter_callback(self._flags_for_index(index), False,
 
543
            text, True)
444
544
 
445
545
    def clear_filter(self):
446
 
        # do nothing?
447
 
        pass
 
546
        self._text_filter.clear_filter()
448
547
 
449
548
    def get_filter(self):
450
549
        index = self._category_combo.currentIndex()
451
 
        return str(self._category_combo.itemData(index).toString())
452
 
 
453
 
    def set_tree_viewer(self, tree_viewer):
454
 
        self._tree_viewer = tree_viewer
455
 
 
456
 
 
457
 
class _QBrowseStyleTreeViewer(treewidget.TreeWidget):
458
 
 
459
 
    def __init__(self, action_callback, selection_callback,
460
 
            filter_callback, *args):
461
 
        self._selection_callback = selection_callback
 
550
        return self._flags_for_index(index), self._text_filter.get_filter()
 
551
 
 
552
    def set_apply_filter(self, apply_filter_callback):
 
553
        self._apply_filter_callback = apply_filter_callback
 
554
 
 
555
 
 
556
class _QBrowseFilterProxyModel(treewidget.TreeFilterProxyModel):
 
557
    """Filter a working tree by a text string.
 
558
 
 
559
    If the text matches a directory, the directory and all it's contents
 
560
    are shown. If the text matches a file, the parent directories and
 
561
    the item are shown.
 
562
 
 
563
    Note: For efficency, we pre-calculate the interesting entries
 
564
    once each time the text is changed. We then simply look up
 
565
    each path in the set of interesting paths inside the per-row
 
566
    filtering callback.
 
567
    """
 
568
 
 
569
    def __init__(self, *args):
 
570
        treewidget.TreeFilterProxyModel.__init__(self, *args)
 
571
        self.text_to_match = None
 
572
        self._interesting = None
 
573
        self._all_data_loaded = False
 
574
 
 
575
    def setTextToMatch(self, text):
 
576
        self.text_to_match = text
 
577
        self._update_interesting()
 
578
        self.invalidateFilter()
 
579
 
 
580
    def invalidateFilter(self):
 
581
        treewidget.TreeFilterProxyModel.invalidateFilter(self)
 
582
 
 
583
    def _update_interesting(self):
 
584
        if not self.text_to_match:
 
585
            self._interesting = None
 
586
            return
 
587
        text = self.text_to_match
 
588
        interesting = set([''])
 
589
        directories = set()
 
590
        for path in self._iter_paths():
 
591
            if path.find(text) >= 0:
 
592
                interesting.add(path)
 
593
                directories.update(parent_directories(path))
 
594
        interesting.update(directories)
 
595
        #print "\ninteresting for %s ...\n%s\n" % (text,
 
596
        #    "\n".join(sorted(interesting)))
 
597
        self._interesting = interesting
 
598
 
 
599
    def _iter_paths(self):
 
600
        # The source model loads data lazily. We need everything loaded
 
601
        # to find the complete set of paths though
 
602
        self._ensure_all_data_loaded()
 
603
        return iter(self.source_model.inventory_data_by_path.keys())
 
604
 
 
605
    def _ensure_all_data_loaded(self):
 
606
        if self._all_data_loaded:
 
607
            return
 
608
        model = self.source_model
 
609
        for id in range(0, len(model.inventory_data)):
 
610
            self._load_dirs(model, id)
 
611
        self._all_data_loaded = True
 
612
 
 
613
    def _load_dirs(self, model, id):
 
614
        item_data = model.inventory_data[id]
 
615
        if item_data.item.kind == "directory":
 
616
            if item_data.children_ids is None:
 
617
                # This locks and unlocks the tree each time.
 
618
                # I wonder how that impacts performance?
 
619
                model.load_dir(id)
 
620
            for child_id in item_data.children_ids:
 
621
                self._load_dirs(model, child_id)
 
622
 
 
623
    def filterAcceptsRow(self, source_row, source_parent):
 
624
        result = treewidget.TreeFilterProxyModel.filterAcceptsRow(
 
625
            self, source_row, source_parent)
 
626
        if result and self._interesting:
 
627
            # Apply the text filter (matches found earlier)
 
628
            path, kind = self._get_path_info(source_row, source_parent)
 
629
            result = path in self._interesting
 
630
        return result
 
631
 
 
632
    def _get_path_info(self, source_row, source_parent):
 
633
        """Return path, kind for a model item."""
 
634
        model = self.source_model
 
635
        parent_id = source_parent.internalId()
 
636
        children_ids = model.inventory_data[parent_id].children_ids
 
637
        # Why is this check required?
 
638
        if len(children_ids) <= source_row:
 
639
            return None, None
 
640
        id = children_ids[source_row]
 
641
        data = model.inventory_data[id]
 
642
        return data.path, data.item.kind
 
643
 
 
644
 
 
645
class _QBrowseTreeWidget(treewidget.TreeWidget):
 
646
 
 
647
    def __init__(self, *args):
462
648
        treewidget.TreeWidget.__init__(self, *args)
 
649
        # Patch in a custom FilterProxyModel that handles text filtering
 
650
        self.tree_filter_model = _QBrowseFilterProxyModel()
 
651
        self.tree_filter_model.setSourceModel(self.tree_model)
 
652
        self.setModel(self.tree_filter_model)
 
653
 
 
654
 
 
655
class _QBrowseStyleTreeViewer(_QBrowseTreeWidget):
 
656
 
 
657
    def __init__(self, action_callback, selection_callback,
 
658
            filter_callback, *args):
 
659
        self._action_callback = action_callback
 
660
        self._selection_callback = selection_callback
 
661
        _QBrowseTreeWidget.__init__(self, *args)
 
662
        self._default_action = "open"
463
663
 
464
664
        # Track the selection
465
665
        self.connect(self.selectionModel(),
466
666
            QtCore.SIGNAL("currentChanged(QModelIndex,QModelIndex)"),
467
667
            self._do_current_changed)
468
668
 
 
669
    def do_default_action(self, model_index):
 
670
        """Override the handler provided by treewidget.TreeWidget."""
 
671
        item_data = self.get_selection_items([model_index])[0]
 
672
        fileinfo = QtCore.QFileInfo(item_data.path)
 
673
        if fileinfo is not None and not fileinfo.isDir():
 
674
            path = fileinfo.canonicalFilePath()
 
675
            self._action_callback(self._default_action, unicode(path))
 
676
 
469
677
    def _do_current_changed(self, model_index, prev_model_index):
470
678
        item_data = self.get_selection_items([model_index])[0]
471
679
        fileinfo = QtCore.QFileInfo(item_data.path)
472
 
        self._selection_callback(fileinfo)
 
680
        self._selection_callback(fileinfo, model_index)
473
681
 
474
682
    def invalidate_filter(self):
475
683
        self.tree_filter_model.invalidateFilter()
476
684
 
477
 
 
478
 
class _QBrowseStyleBrowser(_ClassicBrowser):
 
685
    def set_default_action(self, default_action):
 
686
        """Set the default action to either 'open' or 'edit'."""
 
687
        self._default_action = default_action
 
688
 
 
689
 
 
690
class _QBrowseStyleBrowser(_AbstractBrowser):
479
691
 
480
692
    filter_panel_factory = _QBrowseStyleFilterPanel
481
693
    tree_viewer_factory = _QBrowseStyleTreeViewer
 
694
 
 
695
    def _apply_filter(self, flags, flags_changed, text, text_changed):
 
696
        if flags_changed:
 
697
            self._tree_viewer.tree_filter_model.setFilters(flags)
 
698
        if text_changed:
 
699
            self._tree_viewer.tree_filter_model.setTextToMatch(text)