NCBI C++ ToolKit
str_url_renderer.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: str_url_renderer.cpp 46003 2021-01-21 12:55:21Z grichenk $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Roman Katargin
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
38 
39 #include "wx/tokenzr.h"
40 #include <wx/dc.h>
41 #include <wx/settings.h>
42 
44 
45 // ----------------------------------------------------------------------------
46 // CStrWithURLRenderer
47 // ----------------------------------------------------------------------------
48 
50  const wxGridCellAttr& attr,
51  wxDC& dc,
52  bool isSelected)
53 {
54  dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT );
55 
56  // TODO some special colours for attr.IsReadOnly() case?
57 
58  // different coloured text when the grid is disabled
59  if ( grid.IsThisEnabled() )
60  {
61  if ( isSelected )
62  {
63  wxColour clr;
64  if ( grid.HasFocus() )
65  clr = grid.GetSelectionBackground();
66  else
67  clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
68  dc.SetTextBackground( clr );
69  dc.SetTextForeground( grid.GetSelectionForeground() );
70  }
71  else
72  {
73  dc.SetTextBackground( attr.GetBackgroundColour() );
74  dc.SetTextForeground( attr.GetTextColour() );
75  }
76  }
77  else
78  {
79  dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
80  dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
81  }
82 
83  dc.SetFont( attr.GetFont() );
84 }
85 
86 static wxSize GetLineSize(const wxGridCellAttr& attr,
87  wxDC& dc,
88  const CStrWithUrlContainer::TLine& line,
89  vector<int>& widths)
90 {
91  wxCoord width = 0, height = 0;
92 
93  wxFont linkFont = attr.GetFont();
94  linkFont.SetUnderlined(true);
95 
97  const CStrWithUrlLink* link = dynamic_cast<const CStrWithUrlLink*>(*it);
98  if (link) {
99  dc.SetFont(linkFont);
100  }
101  else {
102  dc.SetFont(attr.GetFont());
103  }
104  wxCoord x = 0, y = 0;
105  dc.GetTextExtent((*it)->GetText(), &x, &y);
106  width += x;
107  height = wxMax(height, y);
108  widths.push_back(x);
109  }
110 
111  dc.SetFont(attr.GetFont());
112 
113  return wxSize(width, height);
114 }
115 
116 wxSize CStrWithURLRenderer::DoGetBestSize(const wxGridCellAttr& attr,
117  wxDC& dc,
118  const wxString& text)
119 {
120  wxCoord max_x = 0, max_y = 0;
121 
122  CStrWithUrlParser parser;
123  unique_ptr<wxObject> result(parser.Parse(text));
124  CStrWithUrlContainer* container = dynamic_cast<CStrWithUrlContainer*>(result.get());
125 
126  ITERATE(vector<CStrWithUrlContainer::TLine>, it, container->GetLines()) {
127  vector<int> widths;
128  wxSize size = GetLineSize(attr, dc, *it, widths);
129  max_x = wxMax(max_x, size.x);
130  max_y = wxMax(max_y, size.y);
131  }
132 
133  max_y *= container->GetLines().size(); // multiply by the number of lines.
134 
135  return wxSize(max_x, max_y);
136 }
137 
139  wxGridCellAttr& attr,
140  wxDC& dc,
141  int row, int col)
142 {
143  return DoGetBestSize(attr, dc, x_GetHtmlValue(grid, row, col));
144 }
145 
147  wxGridCellAttr& attr,
148  wxDC& dc,
149  const wxRect& rectCell,
150  int row, int col,
151  bool isSelected)
152 {
153  wxRect rect = rectCell;
154  rect.Inflate(-1);
155 
156  // erase only this cells background, overflow cells should have been erased
157  wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
158 
159  wxString value = x_GetHtmlValue(grid, row, col);
160  CStrWithUrlParser parser;
161  unique_ptr<wxObject> result(parser.Parse(value));
162  CStrWithUrlContainer* container = dynamic_cast<CStrWithUrlContainer*>(result.get());
163 
164  int hAlign, vAlign;
165  attr.GetAlignment(&hAlign, &vAlign);
166 
167 
168  // now we only have to draw the text
169  SetTextColoursAndFont(grid, attr, dc, isSelected);
170 
171  wxDCClipper clip(dc, rect);
172 
173  wxFont linkFont = attr.GetFont();
174  linkFont.SetUnderlined(true);
175 
176  wxCoord y = rect.GetTop();
177 
178  CCellHyperlinks* links = new CCellHyperlinks();
179 
180  wxColour textColor = dc.GetTextForeground();
181 
182  ITERATE(vector<CStrWithUrlContainer::TLine>, it, container->GetLines()) {
183  if (y > rect.GetBottom())
184  break;
185 
186  vector<int> widths;
187  wxSize size = GetLineSize(attr, dc, *it, widths);
188  wxCoord x = rect.GetLeft();
189 
190  if (hAlign&wxALIGN_RIGHT) {
191  x = rect.GetRight() - size.x;
192  }
193  else if (hAlign&wxALIGN_CENTER_HORIZONTAL) {
194  x += (rect.GetWidth() - size.x)/2;
195  }
196 
197  int i = 0;
199  if (x > rect.GetRight())
200  break;
201  if (x + widths[i] >= rect.GetLeft()) {
202  const CStrWithUrlLink* link = dynamic_cast<const CStrWithUrlLink*>(*it2);
203 
204  if (link) {
205  dc.SetFont(linkFont);
206  dc.SetTextForeground(*wxBLUE);
207  }
208  else {
209  dc.SetFont(attr.GetFont());
210  dc.SetTextForeground(textColor);
211  }
212 
213  dc.DrawText( (*it2)->GetText(), x, y );
214 
215  if (link) {
216  wxRect linkRect(x, y + 2, widths[i], size.y - 2); // Make hot area little smaller to not interfere with row resize
217  linkRect.Intersect(rect);
218  links->Add(linkRect, link->GetUrl());
219  }
220  }
221  x += widths[i++];
222  }
223 
224  y += size.y;
225  }
226 
227  dc.SetTextForeground(textColor);
228  dc.SetFont(attr.GetFont());
229 
230  CGrid* g = dynamic_cast<CGrid*>(&grid);
231  if (g == 0) {
232  delete links;
233  return;
234  }
235 
236  if (links->Empty()) {
237  delete links;
238  g->GetHyperlinks().SetLink(col, row, 0);
239  } else {
240  g->GetHyperlinks().SetLink(col, row, links);
241  }
242 }
243 
244 wxString CStrWithURLRenderer::x_GetHtmlValue(wxGrid& grid, int row, int col)
245 {
246  CwxGridTableAdapter& adapter = dynamic_cast<CwxGridTableAdapter&>(*grid.GetTable());
247  return adapter.GetHtmlValue(row, col);
248 }
249 
250 
CGrid.
Definition: grid.hpp:50
virtual wxSize GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int row, int col)
void SetTextColoursAndFont(const wxGrid &grid, const wxGridCellAttr &attr, wxDC &dc, bool isSelected)
wxString x_GetHtmlValue(wxGrid &grid, int row, int col)
wxSize DoGetBestSize(const wxGridCellAttr &attr, wxDC &dc, const wxString &text)
virtual void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected)
const vector< TLine > & GetLines() const
vector< CStrWithUrlText * > TLine
wxString GetHtmlValue(int row, int col)
char value[7]
Definition: config.c:431
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
int i
static void text(MDB_val *v)
Definition: mdb_dump.c:62
const struct ncbi::grid::netcache::search::fields::SIZE size
static wxSize GetLineSize(const wxGridCellAttr &attr, wxDC &dc, const CStrWithUrlContainer::TLine &line, vector< int > &widths)
int g(Seg_Gsm *spe, Seq_Mtf *psm, Thd_Gsm *tdg)
Definition: thrddgri.c:44
else result
Definition: token2.c:20
Modified on Fri Mar 01 10:04:53 2024 by modify_doxy.py rev. 669887