A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/doxyhtml/dock__container_8cpp_source.html below:

NCBI C++ ToolKit: src/gui/widgets/wx/dock_container.cpp Source File

51

DEFINE_EVENT_TYPE(USER_EVT_BEGIN_DRAG_OUTSIDE)

67

wxCLIP_CHILDREN,

_

("dock_container")),

68

m_DockManager(manager),

69

m_WindowManager(manager.GetWindowManager()),

72

m_MarkersWindow(

NULL

),

77

SetBackgroundStyle(wxBG_STYLE_CUSTOM);

83

x_InitDefaultTree(create_tab);

130  return

wxWindow::Layout();

136

wxBoxSizer* sizer =

new

wxBoxSizer(wxVERTICAL);

162

GetSizer()->Layout();

180

node->Link(*centralPane);

188  if

(root && root->IsVisible()) {

191

wxWindow* win = root->GetWindow();

221

wxString pname =

_

(

"panel_"

);

265  bool

kill_root =

false

;

266  if

(full_root->IsClient()) {

267

kill_root = full_root->IsHidden();

269

kill_root = ! full_root->HasChildren() &&

273

full_tree.

m_Root

.Reset();

287  for

(

size_t i

= 0;

i

< children.size(); ) {

291  if

(child->IsContainer()) {

296  bool

central_pane = (centralPane == child);

297  if

( ! central_pane) {

298  if

(child->HasOnlyOneChild()) {

300  CRef<TNode>

grand_child = child->GetTheOnlyChild();

301

child->RemoveChild(*grand_child);

304  _ASSERT

(grand_child->GetParent() == &full_node);

307

kill = child->GetChildren().empty();

314  if

(child->IsSplitter())

315

child->SetHidden(

false

);

360

clients.push_back(

client

);

372  return

root->GetWindow() == window;

446

wxWindow* window =

client

.GetWindow();

450  if

(panel ==

NULL

) {

452

wxWindow* parent = window->GetParent();

455  if

(panel ==

NULL

) {

457

wxString pname =

wxT

(

"panel_"

);

459  string

s =

fp

.GetId();

471

wxWindow* window =

client

.GetWindow();

473

wxWindow* parent = window->GetParent();

537

full_node =

f

.m_Node;

541  LogPostTrees

(

"CDockContainer::AddClientToDefaultLocation() start"

);

547

full_layout_node.

Reset

(full_cont);

550  LogPostTrees

(

"CDockContainer::AddClientToDefaultLocation() end"

);

556

full_client->Link(*

new TNode

(*full_client));

558

full_client->SetFingerprint(p);

559

full_client->GetClone()->SetFingerprint(p);

572

wxWindow* client_w =

client

.GetWindow();

584

full_node->SetWindow(panel);

585

full_node->Link(*

new TNode

(*full_node));

587  TNode

* full_cont = full_node->GetParent();

588  TNode

* full_cont_child = full_node;

596  WM_POST

(

"Unhiding a hidden container with one child"

);

604  WM_POST

(

"Add the client to a visible parent container"

);

611

full_cont_child = full_cont;

615  if

(full_cont ==

NULL

) {

616  WM_POST

(

"we did not find an appropriate parent container"

);

619

full_cont = full_cont_child;

623  WM_POST

(

"Unhide root container"

);

626  WM_POST

(

"Create as central component"

);

706  _ASSERT

(full_client->IsClient());

710  if

(full_target->IsTab()) {

711

fullTab = full_target;

717  if

(full_parent->IsTab()) {

718  if

(full_parent->IsHidden()) {

720

tab->Link(*full_parent);

726

fullTab = full_parent;

730

fullNewTab->Link(*

new TNode

(*fullNewTab));

733

full_parent->ReplaceChild(*full_target, *fullNewTab);

734

fullNewTab->AddChild(*full_target);

738

fullTab = fullNewTab;

743

fullNewTab->Link(*

new TNode

(*fullNewTab));

747

fullNewTab->AddChild(*full_target);

751

fullTab = fullNewTab;

758  _ASSERT

(full_client->GetParent());

765

sizes.push_back(split_left ? s1 : s2);

766

sizes.push_back(split_left ? s2 : s1);

783

full_sp_node->Link(*

new TNode

(*full_sp_node));

787  bool

reverse = (dir == wxLEFT) || (dir == wxTOP);

794  CRef<TNode>

full_parent(full_node_to_split->GetParent());

798

full_parent->ReplaceChild(*full_node_to_split, *full_sp_node);

808

wxSize

size

= full_node_to_split->GetWindow()->GetSize();

810  TNode

& cont = *full_sp_node->GetClone();

813

full_sp_node->AddChild(*full_client);

816

full_sp_node->AddChild(*full_node_to_split);

820

full_sp_node->AddChild(*full_node_to_split);

823

full_sp_node->AddChild(*full_client);

855  LogPostTrees

(

"CDockContainer::RemoveWindow() start"

);

857

wxWindow* window =

dynamic_cast<

wxWindow*

>

(&dockable);

868  TNode

* node = full_node->GetClone();

870  CRef<TNode>

full_parent_node(full_node->GetParent());

878  if

( ! central_pane && parent_node) {

879  if

(parent_node->HasOnlyOneChild()) {

885  if

(full_parent_node) {

964

root->DepthFirstForEach(blocker);

978  switch

(full_node.

GetType

()) {

1000  TNode

& full_vis_child,

1001  TNode

& full_new_child)

1007

full_cont.

Link

(*cont);

1013  _ASSERT

(vis_index >= 0 && new_index >= 0);

1023

cont->RemoveAllChildren();

1024  if

(vis_index < new_index) {

1025

cont->AddChild(vis_child);

1026

cont->AddChild(new_child);

1028

cont->AddChild(new_child);

1029

cont->AddChild(vis_child);

1044

wxWindow* node_w = full_node.

GetWindow

();

1049  for

(

size_t i

= 0;

i

< children.size();

i

++) {

1050  TNode

& full_child = *children[

i

];

1071

fingerprint =

client

->GetFingerprint();

1081  bool

keep_node =

false

;

1088  if

( ! fingerprint.

IsEmpty

()) {

1100

full_parent->RemoveChild(full_node);

1136

full_parent->ReplaceChild(full_cont, *full_child);

1138  _ASSERT

(full_child->GetParent() == full_parent);

1162  if

(full_child->IsHidden() && full_cont.

GetClone

() ==

NULL

) {

1169

full_parent->ReplaceChild(full_cont, *full_child);

1171  _ASSERT

(full_child->GetParent() == full_parent);

1194

parent->RemoveChild(node);

1198

wxWindow* parent_w = parent->GetWindow();

1205

GetSizer()->Detach(win);

1217

wxWindow* child_w = child.

GetWindow

();

1225

wxWindow* parent_w = parent->GetWindow();

1231

parent->ReplaceChild(child, cont);

1262

wxWindow* child_w = child.

GetWindow

();

1270  size_t

child_count = splitter->GetChildren().GetCount();

1271  if

(child_count > 0) {

1283  size_t

child_count = splitter->GetChildren().GetCount();

1284  if

(child_count > 0) {

1298

child_w->Reparent(notebook);

1300  size_t

index = notebook->GetPageIndex(child_w);

1301

notebook->SetSelection(index);

1325

wxWindow* child_w = child->GetWindow();

1337

parent->ReplaceChild(cont, *child);

1344  _ASSERT

(child->GetParent() == parent);

1364

wxWindow* window = full_node.

GetWindow

();

1382  if

( ! window && create) {

1390  if

(create && window) {

1447

vector<wxWindow*> child_windows;

1450

child_windows.push_back(child_node.

GetWindow

());

1452  size_t n

= child_windows.size();

1455

wxWindow* window = full_node.

GetWindow

();

1462

splitter->

Split

(0, (

int

)

n

);

1463  for

(

size_t i

= 0;

i

<

n

;

i

++ ) {

1464

wxWindow* child_w = child_windows[

i

];

1476

splitter->

Split

((

int

)

n

, 0);

1477  for

(

size_t i

= 0;

i

<

n

;

i

++ ) {

1478

wxWindow* child_w = child_windows[

i

];

1490  for

(

size_t i

= 0;

i

<

n

;

i

++ ) {

1491

wxWindow* child_w = child_windows[

i

];

1495

child_w->Reparent(notebook);

1499  int

index = notebook->GetPageIndex(child_w);

1500

notebook->SetSelection(index);

1515

wxWindow* win = full_node.

GetWindow

();

1519  for

(wxWindow* w = win; w; w = w->GetParent()) {

1540

vector<wxWindow*> child_windows;

1584  if

(curr_node == &node)

1596

wxWindow* curr_w = curr_node->

GetWindow

();

1600

curr_w = curr_w->GetParent();

1643  for

(

size_t i

= 0;

i

< clients.size();

i

++ ) {

1653

wxWindow* parent = window->GetParent();

1654  while

(parent && parent !=

this

) {

1657  if

(notebook && visited.

find

(notebook) == visited.

end

()) {

1659  int

index = notebook->GetPageIndex(window);

1660

notebook->SetSelection(index);

1661

visited.

insert

(notebook);

1665

parent = parent->GetParent();

1679

clients.push_back(

client

);

1713

wxMouseState ms_state = wxGetMouseState();

1714  bool

split_tab_panes = ms_state.ShiftDown();

1722

wxRect target_rc(0, 0, 0, 0);

1807

wxPoint pt = curr_w->ScreenToClient(screen_pt);

1810

wxWindowList& children = curr_w->GetChildren();

1811

wxWindow* child_w =

NULL

;

1812  for

( wxWindowList::iterator it = children.begin(); it != children.end(); ++it ) {

1815

wxRect rc = w->GetRect();

1816  if

(rc.Contains(pt)) {

1830  bool

split_tab_pane)

1840

wxWindow* top_dock_w =

dynamic_cast<

wxWindow*

>

(top_dock);

1841

effect = top_dock->

DropTest

(screen_pt, target);

1843  if

(effect !=

ePutInTab

&& ! split_tab_pane) {

1845

wxWindow* parent_w = top_dock_w->GetParent();

1847  if

(parent_w &&

dynamic_cast<CDockNotebook

*

>

(parent_w)) {

1849

top_dock_w =

dynamic_cast<

wxWindow*

>

(top_dock);

1851

effect = top_dock->

DropTest

(screen_pt, target);

1858

target = top_dock_w;

1873

rc.width = rc.width / 3;

1877

rc.width = rc.width / 3;

1878

rc.x = root_rc.GetRight() - rc.width;

1882

rc.height = rc.height / 3;

1886

rc.height = rc.height / 3;

1887

rc.y = root_rc.GetBottom() - rc.height;

1897

rc.width = rc.width / 3;

1901

rc.width = rc.width / 3;

1902

rc.x = target_rc.GetRight() - rc.width;

1906

rc.height = rc.height / 3;

1910

rc.height = rc.height / 3;

1911

rc.y = target_rc.GetBottom() - rc.height;

1922

rc.SetSize(wxSize(-1, -1));

1925

rc.SetSize(wxSize(-1, -1));

1937

vector<IWMClient*> clients;

1956

wxPoint sc_mouse_pos = ::wxGetMousePosition();

1969

vector<wxWindow*> pages;

1970  for

(

size_t i

= 0;

i

< notebook.GetPageCount();

i

++ ) {

1971

pages.push_back(notebook.GetPage(

i

));

2003

wxPoint sc_mouse_pos = ::wxGetMousePosition();

2018

wxPoint sc_mouse_pos = ::wxGetMousePosition();

2029

wxPoint sc_mouse_pos = ::wxGetMousePosition();

2065  tree

.GetCentralPane()->SetHidden(

false

);

2075

}

catch

(std::exception&) {

2077  ERR_POST

(

"CDockContainer::ApplyLayout() - error loading layout - "

);

2138  bool

maximized =

false

;

2160  if

(!frame) frame = mainFrame;

static CDockContainerDescr * FromUserObject(const objects::CUser_object &obj)

CDockContainerDescr(wxPoint pos, wxSize size, bool maximized, CRef< CDockLayoutTree > tree)

CRef< CDockLayoutTree > m_Tree

objects::CUser_object * ToUserObject() const

CDockContainer is a window that hosts docked windows.

void x_Full_ReduceContainer(TNode &full_cont)

void x_Full_RemoveNode(TNode &full_node, ERemoveAction action)

bool HasDefaultPositionFor(const TFingerprint &fingerprint)

void OnBeginDragOver(const wxPoint &sc_mouse_pt)

EDockEffect x_HitTest(const wxPoint &screen_pt, wxWindow *&target, bool split_tab_pane)

CDockMarkerWindow * m_MarkersWindow

bool IsRootWindow(wxWindow *window)

void x_Full_ReduceHiddenContainer_IfNeeded(TNode &full_cont)

bool x_IsElastic(TNode &node)

EDockEffect OnEndDragOver(wxWindow *&target)

CDockPanel * x_DockPanelForClient(IWMClient &client)

void OnLeftUp(wxMouseEvent &event)

void x_GetClientsInNode(TNode &node, vector< IWMClient * > &clients)

void x_DestroyEmptyLayout()

Saving and Loading Layouts Loads a full layout tree from the given CUser_object IWMClientFactory is u...

CRef< CDockLayoutTree > m_FullTree

string x_GetPageNameByWindow(wxWindow *window)

CFloatingFrame * m_DockFrame

CRef< CDockLayoutTree > m_VisibleTree

CRef< TNode > RemoveWindow(IDockableWindow &dockable, ERemoveAction action)

void x_Visible_RemoveNode(TNode &node, ERemoveAction action)

Functions updating visible tree and windows based on the full tree.

IDockDropTarget * x_FindDockDropTargetByPos(const wxPoint &screen_pt)

void OnMouseCaptureLost(wxMouseCaptureLostEvent &event)

void OnMouseMove(wxMouseEvent &event)

void OnTabClosePressed(wxWindow *page)

TNode * x_FindNodeByWindow(wxWindow *window)

CDockLayoutTree::CNode TNode

CDockManager & GetDockManager()

CFloatingFrame * GetDockFrame()

returns floating frame hosting this container

wxWindow * x_CreateContainerWindow(CDockLayoutTree::ENodeType type)

void x_SetRootWindow(wxWindow *window)

void x_AddClientInTab(CRef< TNode > full_client, CRef< TNode > full_target)

TWindowToNode m_WindowToNode

void OnLeftDown(wxMouseEvent &event)

Mouse handling functions handle mouse events in case when a tab is dragged from a tab control and the...

void OnTabBeginDragOutside(CBeginDragOutsideEvent &event)

void x_Visible_ReplaceContainerWithChild(TNode &cont)

void x_Full_CleanLayoutTreeBranch(TNode *centralPane, TNode &full_node)

Cleans the given tree starting from the given node.

void x_Full_DisconnectChildren(TNode &full_node)

Disconnect all child nodes from the given node in all 3 trees (Full Tree, Visible Tree and Window Tre...

void ApplyLayout(CDockLayoutTree &tree)

bool NeedToSavePositions()

void OnUpdateTabOrder(CDockNotebook &notebook)

CDockPanel * x_GetDockPanel(IWMClient &client)

void x_AddClientInSplitter(CRef< TNode > full_client, CRef< TNode > full_target, EDockEffect effect)

void x_Full_UnhideContainer_AddChildren(TNode &full_cont, TNode &full_vis_child, TNode &full_new_child)

void AddClientToDefaultLocation(IWMClient &client)

void GetClientsInWindow(wxWindow *window, vector< IWMClient * > &clients)

void x_InstantiateNode_AddChildWindows(TNode &full_node)

Iterates child windows of the given container node and inserts them into the container window.

virtual ~CDockContainer()

wxWindow * GetRootWindow()

returns window representing the root of the layout hosted by the container

void GetAllClients(vector< IWMClient * > &clients)

void x_Visible_ReplaceChildWithContainer(TNode &child, TNode &cont)

void x_DestroyNode(TNode &full_node, ERemoveAction action)

void SetFullTree(CDockLayoutTree &full_tree)

initialize the container with the layout tree

CDockManager & m_DockManager

TNode * x_AddClientToHiddenPos(IWMClient &client, CRef< TNode > full_node)

void OnDragOver(const wxPoint &sc_mouse_pt)

objects::CUser_object * SaveLayout(wxFrame *mainFrame)

wxRect x_CalculateHintRect()

void x_Full_CleanLayoutTree(CDockLayoutTree &full_ree)

This clean-up normalizes the tree, so that it can be instantiated as a layout.

void x_InstantiateNode(TNode &full_node, bool recursive, EInstFlags flags=fAll)

Ensures that a node has a window and this window is properly connected with its child and parent wind...

void AddClient(CRef< TNode > full_client, EDockEffect effect, wxWindow *target_w)

void x_Visible_AddChildToContainer(TNode &cont, TNode &child)

Adds a child to a visible node.

CDockLayoutTree::TNodeVector TNodeVector

void AddClientToCentralPane(CRef< TNode > full_client)

void BlockSplittersLayout(bool block)

Iterates through all splitters and blocks / unblocks layout.

CRef< CDockLayoutTree > DisconnectTrees()

void LogPostTrees(const string &test)

void ActivateClients(vector< IWMClient * > &clients)

IDockableWindow * m_TabDockable

bool HasNoWMClients()

returns true if Dock Container does not have any IWMClients as children

void x_InitDefaultTree(bool create_tab)

CNode - a node in layout tree corresponding to a window.

CRef< CNode > GetTheOnlyChild()

ENodeType GetType() const

const vector< int > & GetSplitterSizes() const

void RemoveChild(CNode &node)

void SetWindow(wxWindow *window)

void AddChild(CNode &node)

CRef< CNode > GetParent()

bool DepthFirstSearch(F &func)

Inline functions.

void EnforceChildOrder(const vector< wxWindow * > &windows)

TNodeVector & GetChildren()

void SetFingerprint(const TFingerprint &p)

TFingerprint GetFingerprint() const

long GetBranchIndex(CNode &grandchild_node) const

bool HasOnlyOneChild() const

size_t ReplaceChild(CNode &old_node, CNode &new_node)

CDockLayoutTree - represents hierarchical layout in a Dock Container as a tree where nodes correspond...

void SaveSplitterLayout()

CDockLayoutTree * CloneTree() const

void Validate(const CNode &node, bool vis_tree) const

vector< CRef< CNode > > TNodeVector

CConstRef< CNode > GetRoot() const

CConstRef< CNode > GetCentralPane() const

objects::CUser_object * ToUserObject() const

static CRef< CDockLayoutTree > FromUserObject(const objects::CUser_object &obj)

bool DepthFirstSearch(F &func)

void DisconnectAllNodes()

CDockManager CDockManager sends requests to Window Manager, Window Manager makes decisions about dele...

wxWindow * GetTopAppWindow()

void OnBeginDrag(IDockableWindow &dockable, const wxPoint &sc_mouse_pos)

CDockContainer * GetMainContainer()

bool OnDrag(IDockableWindow &dockable, const wxPoint &sc_mouse_pos)

void OnTabClosePressed(const vector< IWMClient * > &clients)

void OnEndDrag(IDockableWindow &dockable, EDragResult result, const wxPoint &sc_mouse_pos)

CDockMarkerWindow - top level window with docking markers displayed on top of the application window.

virtual EDockEffect HitTest(const wxPoint &screen_pt)

determines whether a given position is inside one of the 9 markers and returns the corresponding dock...

void SetTargetRect(const wxRect &root_rc, const wxRect &target_rc)

CDockNotebook - an extended version of wxAuiNotebook capable of working with Dock Manager and Window ...

void InsertPageAtHitPoint(wxWindow *page, const wxString &caption)

void MakeSelectionVisible()

CDockPanel - a container with a title bar (caption) hosting a single client window (IWMClient).

virtual void ShowBorder(bool show)

void RemoveClient(wxWindow *new_parent)

disconnect the client and re-parent it to the given window

CDockSplitter = an extended version of CSplitter capable of working with Dock Manager and Window Mana...

void SetResizableCell(int col, int row)

virtual void BlockLayout(bool block=true)

bool InsertToCell(wxWindow *child, int col, int row)

If cell [col, row] exists and vacant - adds widget to the container.

void SetWidths(const TPosVector &widths)

void SetHeights(const TPosVector &heights)

@ eHorizontal

vertical space is splitted

virtual void Split(ESplitType type)

Creates a splitter with a single cell.

int GetColumnsCount() const

CUser_object & AddField(const string &label, const string &value, EParseField parse=eParse_String)

add a data field to the user object that holds a given value

const CUser_field & GetField(const string &str, const string &delim=".", NStr::ECase use_case=NStr::eCase) const

Access a named field in this user object.

FBlockSplitterLayout(bool block)

void operator()(CDockLayoutTree::CNode &node)

FClientCreator(CDockContainer &cont, IWMClientFactory *factory)

CDockContainer & m_DockContainer

IWMClientFactory * m_Factory

void operator()(CDockLayoutTree::CNode &node)

bool operator()(CDockLayoutTree::CNode &node)

IWMClient::CFingerprint m_Print

CRef< CDockLayoutTree::CNode > m_Node

FNodeFingerprintEquals(const IWMClient::CFingerprint &print)

bool operator()(CDockLayoutTree::CNode &node)

IDockContWindow - abstract window container for use with Dock Manager.

virtual void Cont_Replace(wxWindow *old_child, wxWindow *new_child)=0

virtual void Cont_Remove(wxWindow *child)=0

IDockDropTarget - interface representing a component that can serve as a drop target during D&D docki...

virtual EDockEffect DropTest(const wxPoint &screen_pt, wxWindow *&target)=0

IDockableWindow - repersents a window that can be docked in Dock Manager.

virtual void SetDockContainer(CDockContainer *cont)=0

IWMClientFactory - IWMClient factory.

virtual IWMClient * CreateClient(const TFingerprint &fingerprint, wxWindow *parent)=0

creates a client by fingerprint returns NULL if fingerprint is not recognized.

CFingerprint identifies an instance of IWMClient and is used for labeling layout positions.

const string GetId() const

IWClient - abstract Window Manager client.

virtual string GetClientLabel(IWMClient::ELabel ltype=IWMClient::eDefault) const =0

returns the client label (name) to be displayed in UI

container_type::iterator iterator

const_iterator end() const

const_iterator find(const key_type &key) const

iterator_bool insert(const value_type &val)

const_iterator find(const key_type &key) const

const_iterator end() const

void sDockPanel_ShowBorder(wxWindow *w, bool show)

static const char * kYTag

void sRestoreSplitterSizes(CDockLayoutTree::CNode &full_node)

void sGetSplitSizes(int total_size, vector< int > &sizes, bool split_left)

static const char * kHeightTag

static CUser_object * sWindowPosToUserObject(const wxRect &rc, bool maximized)

wxDirection sGetDirectionByEffect(EDockEffect effect)

static const char * kDockContainer

static const char * kMaximizedTag

static const char * kWindowPos

static const char * kTreeTag

static const char * kXTag

static const char * kWidthTag

bool sRootSplit(EDockEffect effect)

static void sWindowPosFromUserObject(const CUser_object &obj, wxRect &rc, bool &maximized)

#define EVT_BEGIN_DRAG_OUTSIDE(fn)

wxWindow * CreateDockHintFrame(wxWindow &parent, CDockManager &manager)

This functions create a platform-dependent Hint Window for Dock Manager.

#define test(a, b, c, d, e)

#define ERR_POST(message)

Error posting with file, line number information but without error codes.

#define LOG_POST(message)

This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...

void Info(CExceptionArgs_Base &args)

TObjectType * ReleaseOrNull(void)

Release a reference to the object and return a pointer to the object.

TObjectType * GetPointer(void) THROWS_NONE

Get pointer,.

void Reset(void)

Reset reference object.

TObjectType * Release(void)

Release a reference to the object and return a pointer to the object.

#define END_NCBI_SCOPE

End previously defined NCBI scope.

#define BEGIN_NCBI_SCOPE

Define ncbi namespace.

static const char label[]

const TData & GetData(void) const

Get the Data member data.

TBool GetBool(void) const

Get the variant data.

TInt GetInt(void) const

Get the variant data.

const TObject & GetObject(void) const

Get the variant data.

void SetType(TType &value)

Assign a value to Type data member.

static void text(MDB_val *v)

const struct ncbi::grid::netcache::search::fields::SIZE size

static sljit_uw total_size

static CNamedPipeClient * client

#define row(bind, expected)

bool operator()(CDockLayoutTree::CNode &node)

CRef< CDockLayoutTree::CNode > m_Node

wxString ToWxString(const string &s)

wxRect GetScreenRect(const wxWindow &win)


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4