diff --git a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp
index ac2917a..9dd0adf 100644
a
|
b
|
|
11 | 11 | #include <new> |
12 | 12 | #include <set> |
13 | 13 | |
| 14 | #include <LayoutBuilder.h> |
| 15 | #include <MessageRunner.h> |
14 | 16 | #include <StringList.h> |
| 17 | #include <TextControl.h> |
15 | 18 | |
16 | 19 | #include <AutoDeleter.h> |
17 | 20 | |
… |
… |
|
25 | 28 | #include "Tracing.h" |
26 | 29 | |
27 | 30 | |
| 31 | static const uint32 MSG_FUNCTION_FILTER_CHANGED = 'mffc'; |
| 32 | static const uint32 MSG_FUNCTION_TYPING_TIMEOUT = 'mftt'; |
| 33 | |
| 34 | static const uint32 kKeypressTimeout = 250000; |
| 35 | |
| 36 | |
28 | 37 | // #pragma mark - SourcePathComponentNode |
29 | 38 | |
30 | 39 | |
… |
… |
public:
|
198 | 207 | |
199 | 208 | LocatableFile* currentFile = NULL; |
200 | 209 | BStringList pathComponents; |
| 210 | bool applyFilter = !fCurrentFilter.IsEmpty(); |
201 | 211 | int32 functionCount = fImageDebugInfo->CountFunctions(); |
202 | 212 | for (int32 i = 0; i < functionCount; i++) { |
203 | 213 | FunctionInstance* instance = fImageDebugInfo->FunctionAt(i); |
… |
… |
public:
|
213 | 223 | } |
214 | 224 | |
215 | 225 | LocatableFile* sourceFile = instance->SourceFile(); |
| 226 | if (applyFilter && !_FilterFunction(instance, sourceFile)) |
| 227 | continue; |
| 228 | |
216 | 229 | if (sourceFile == NULL) { |
217 | 230 | if (!_AddFunctionNode(sourcelessNode, instance, NULL)) |
218 | 231 | return; |
… |
… |
public:
|
351 | 364 | return false; |
352 | 365 | } |
353 | 366 | |
| 367 | void SetFilter(const char* filter) |
| 368 | { |
| 369 | fCurrentFilter = filter; |
| 370 | |
| 371 | SetImageDebugInfo(fImageDebugInfo); |
| 372 | } |
| 373 | |
354 | 374 | private: |
355 | 375 | bool _GetSourcePathComponents(LocatableFile* currentFile, |
356 | 376 | BStringList& pathComponents) |
… |
… |
private:
|
438 | 458 | return true; |
439 | 459 | } |
440 | 460 | |
| 461 | bool _FilterFunction(FunctionInstance* instance, LocatableFile* sourceFile) |
| 462 | { |
| 463 | if (instance->PrettyName().IFindFirst(fCurrentFilter) >= 0) |
| 464 | return true; |
| 465 | else if (sourceFile != NULL) { |
| 466 | BString path; |
| 467 | sourceFile->GetPath(path); |
| 468 | return path.IFindFirst(fCurrentFilter) >= 0; |
| 469 | } |
| 470 | |
| 471 | return false; |
| 472 | } |
| 473 | |
| 474 | |
441 | 475 | private: |
442 | 476 | typedef BObjectList<SourcePathComponentNode> ChildPathComponentList; |
443 | 477 | |
… |
… |
private:
|
445 | 479 | ImageDebugInfo* fImageDebugInfo; |
446 | 480 | ChildPathComponentList fChildPathComponents; |
447 | 481 | SourcePathComponentNode* fSourcelessNode; |
| 482 | BString fCurrentFilter; |
448 | 483 | }; |
449 | 484 | |
450 | 485 | |
… |
… |
ImageFunctionsView::ImageFunctionsView(Listener* listener)
|
455 | 490 | : |
456 | 491 | BGroupView(B_VERTICAL), |
457 | 492 | fImageDebugInfo(NULL), |
| 493 | fFilterField(NULL), |
458 | 494 | fFunctionsTable(NULL), |
459 | 495 | fFunctionsTableModel(NULL), |
460 | | fListener(listener) |
| 496 | fListener(listener), |
| 497 | fLastFilterKeypress(0) |
461 | 498 | { |
462 | 499 | SetName("Functions"); |
463 | 500 | } |
… |
… |
ImageFunctionsView::SetFunction(FunctionInstance* function)
|
545 | 582 | |
546 | 583 | |
547 | 584 | void |
| 585 | ImageFunctionsView::AttachedToWindow() |
| 586 | { |
| 587 | BView::AttachedToWindow(); |
| 588 | |
| 589 | fFilterField->SetTarget(this); |
| 590 | } |
| 591 | |
| 592 | |
| 593 | void |
| 594 | ImageFunctionsView::MessageReceived(BMessage* message) |
| 595 | { |
| 596 | switch (message->what) { |
| 597 | case MSG_FUNCTION_FILTER_CHANGED: |
| 598 | { |
| 599 | fLastFilterKeypress = system_time(); |
| 600 | BMessage keypressMessage(MSG_FUNCTION_TYPING_TIMEOUT); |
| 601 | BMessageRunner::StartSending(BMessenger(this), &keypressMessage, |
| 602 | kKeypressTimeout, 1); |
| 603 | break; |
| 604 | } |
| 605 | |
| 606 | case MSG_FUNCTION_TYPING_TIMEOUT: |
| 607 | { |
| 608 | if (system_time() - fLastFilterKeypress >= kKeypressTimeout) { |
| 609 | fFunctionsTableModel->SetFilter(fFilterField->Text()); |
| 610 | _ExpandFilteredNodes(); |
| 611 | } |
| 612 | } |
| 613 | |
| 614 | default: |
| 615 | BView::MessageReceived(message); |
| 616 | break; |
| 617 | } |
| 618 | } |
| 619 | |
| 620 | |
| 621 | void |
548 | 622 | ImageFunctionsView::LoadSettings(const BMessage& settings) |
549 | 623 | { |
550 | 624 | BMessage tableSettings; |
… |
… |
ImageFunctionsView::_Init()
|
591 | 665 | { |
592 | 666 | fFunctionsTable = new TreeTable("functions", 0, B_FANCY_BORDER); |
593 | 667 | AddChild(fFunctionsTable->ToView()); |
| 668 | AddChild(fFilterField = new BTextControl("filtertext", "Filter:", |
| 669 | NULL, new BMessage(MSG_FUNCTION_FILTER_CHANGED))); |
| 670 | |
| 671 | fFilterField->SetModificationMessage(new BMessage( |
| 672 | MSG_FUNCTION_FILTER_CHANGED)); |
594 | 673 | fFunctionsTable->SetSortingEnabled(false); |
595 | 674 | |
596 | 675 | // columns |
… |
… |
ImageFunctionsView::_Init()
|
605 | 684 | } |
606 | 685 | |
607 | 686 | |
| 687 | void |
| 688 | ImageFunctionsView::_ExpandFilteredNodes() |
| 689 | { |
| 690 | if (fFilterField->TextView()->TextLength() != 0) |
| 691 | _ExpandChildren(fFunctionsTableModel); |
| 692 | } |
| 693 | |
| 694 | |
| 695 | void |
| 696 | ImageFunctionsView::_ExpandChildren(void* parent) |
| 697 | { |
| 698 | for (int32 i = 0; i < fFunctionsTableModel->CountChildren(parent); i++) { |
| 699 | void* child = fFunctionsTableModel->ChildAt(parent, i); |
| 700 | if (fFunctionsTableModel->CountChildren(child) == 0) { |
| 701 | SourcePathComponentNode* node = (SourcePathComponentNode*)child; |
| 702 | TreeTablePath path; |
| 703 | if (fFunctionsTableModel->GetFunctionPath(node->Function(), path)) |
| 704 | fFunctionsTable->SetNodeExpanded(path, true, true); |
| 705 | return; |
| 706 | } else |
| 707 | _ExpandChildren(child); |
| 708 | } |
| 709 | } |
| 710 | |
| 711 | |
608 | 712 | // #pragma mark - Listener |
609 | 713 | |
610 | 714 | |
diff --git a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h
index 55fb959..dfbbac6 100644
a
|
b
|
|
12 | 12 | #include "Team.h" |
13 | 13 | |
14 | 14 | |
| 15 | class BTextControl; |
15 | 16 | class FunctionInstance; |
16 | 17 | |
17 | 18 | |
… |
… |
public:
|
31 | 32 | void SetImageDebugInfo( |
32 | 33 | ImageDebugInfo* imageDebugInfo); |
33 | 34 | void SetFunction(FunctionInstance* function); |
| 35 | virtual void AttachedToWindow(); |
| 36 | virtual void MessageReceived(BMessage* message); |
34 | 37 | |
35 | 38 | void LoadSettings(const BMessage& settings); |
36 | 39 | status_t SaveSettings(BMessage& settings); |
… |
… |
private:
|
45 | 48 | |
46 | 49 | void _Init(); |
47 | 50 | |
| 51 | void _ExpandFilteredNodes(); |
| 52 | void _ExpandChildren(void *parentNode); |
| 53 | |
48 | 54 | private: |
49 | 55 | ImageDebugInfo* fImageDebugInfo; |
| 56 | BTextControl* fFilterField; |
50 | 57 | TreeTable* fFunctionsTable; |
51 | 58 | FunctionsTableModel* fFunctionsTableModel; |
52 | 59 | Listener* fListener; |
| 60 | bigtime_t fLastFilterKeypress; |
53 | 61 | }; |
54 | 62 | |
55 | 63 | |
diff --git a/src/kits/interface/ColumnListView.cpp b/src/kits/interface/ColumnListView.cpp
index ec8b1af..f9b67a0 100644
a
|
b
|
OutlineView::Clear()
|
3070 | 3070 | DeselectAll(); |
3071 | 3071 | // Make sure selection list doesn't point to deleted rows! |
3072 | 3072 | RecursiveDeleteRows(&fRows, false); |
3073 | | Invalidate(); |
3074 | 3073 | fItemsHeight = 0.0; |
3075 | 3074 | FixScrollBar(true); |
| 3075 | Invalidate(); |
3076 | 3076 | } |
3077 | 3077 | |
3078 | 3078 | |
… |
… |
OutlineView::FixScrollBar(bool scrollToFit)
|
4378 | 4378 | vScrollBar->SetRange(0.0, maxScrollBarValue); |
4379 | 4379 | vScrollBar->SetSteps(20.0, fVisibleRect.Height()); |
4380 | 4380 | } |
4381 | | } else if (vScrollBar->Value() == 0.0) |
| 4381 | } else if (vScrollBar->Value() == 0.0 || fItemsHeight == 0.0) |
4382 | 4382 | vScrollBar->SetRange(0.0, 0.0); // disable scroll bar. |
4383 | 4383 | } |
4384 | 4384 | } |