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

Go to the SVN repository for this file.

1 /* $Id: text_select_item.cpp 47479 2023-05-02 13:24:02Z ucko $
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 
40 
41 #include <wx/dcclient.h>
42 #include <wx/txtstrm.h>
43 
45 
46 void CTextSelectItem::MouseEvent(wxMouseEvent& event, CTextPanelContext& context)
47 {
48  CTextItem::MouseEvent(event, context);
49  if (!event.GetSkipped())
50  return;
51 
52  if (event.Moving() || event.Dragging())
53  MouseMove(event);
54  else if (event.LeftDown())
55  MouseLeftDown(event);
56  else if (event.LeftUp())
57  MouseLeftUp(event);
58  else if (event.LeftDClick())
59  MouseLeftDClick(event);
60 }
61 
62 void CTextSelectItem::MouseMove(wxMouseEvent& event)
63 {
64  CTextItemPanel* panel = static_cast<CTextItemPanel*>(event.GetEventObject());
65 
66  if (panel->Selecting()) {
67  CTextPanelContext* context = panel->GetContext();
68  int textX, textY, caretX, caretY;
69  x_CalcTextPos(context, event.m_x, event.m_y, textX, textY, caretX, caretY);
70 
71  panel->SelMove(GetStartLine() + textY, textX);
72  panel->SetCursor(wxCursor(wxCURSOR_IBEAM));
73  wxPoint pos = GetPosition();
74  panel->SetCaretPos(pos.x + caretX, pos.y + caretY);
75  }
76  else
77  panel->SetCursor(wxCursor(wxCURSOR_IBEAM));
78 }
79 
80 
81 
82 void CTextSelectItem::MouseLeftDown(wxMouseEvent& event)
83 {
84  CTextItemPanel* panel = static_cast<CTextItemPanel*>(event.GetEventObject());
85  CTextPanelContext* context = panel->GetContext();
86 
87  if (!panel->Selecting()) {
88  if (!event.HasAnyModifiers())
89  context->SelectItem(0, false, false);
90 
91  int textX, textY, caretX, caretY;
92  x_CalcTextPos(context, event.m_x, event.m_y, textX, textY, caretX, caretY);
93 
94  if (textY < numeric_limits<int>::max()) {
95  panel->SelStart(GetStartLine() + textY, textX, event.ShiftDown());
96  wxPoint pos = GetPosition();
97  panel->SetCaretPos(pos.x + caretX, pos.y + caretY);
98  }
99  }
100 }
101 
102 void CTextSelectItem::MouseLeftUp(wxMouseEvent& event)
103 {
104  CTextItemPanel* panel = static_cast<CTextItemPanel*>(event.GetEventObject());
105  CTextPanelContext* context = panel->GetContext();
106 
107  if (panel->Selecting()) {
108  int textX, textY, caretX, caretY;
109  x_CalcTextPos(context, event.m_x, event.m_y, textX, textY, caretX, caretY);
110  panel->SelEnd(GetStartLine() + textY, textX);
111  wxPoint pos = GetPosition();
112  panel->SetCaretPos(pos.x + caretX, pos.y + caretY);
113  }
114 }
115 
116 namespace // anonymous namespace
117 {
118 static bool IsAlpha(char ch)
119 {
120  return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_';
121 }
122 } // anonymous namespace
123 
124 void CTextSelectItem::MouseLeftDClick(wxMouseEvent& event)
125 {
126  CTextItemPanel* panel = static_cast<CTextItemPanel*>(event.GetEventObject());
127  CTextPanelContext* context = panel->GetContext();
128 
129  wxClientDC dc(panel);
130  panel->InitDC(dc);
131  CCalcTextPosOStream ostream(dc, context->GetLeftMargin(), 0,
132  dc.GetCharHeight(), context->GetIndentWidth(), event.m_x, event.m_y);
133  x_RenderText(ostream, context);
134 
135  int textX, textY, caretX, caretY;
136  ostream.GetTextPos(textX, textY);
137 
138  string line = ostream.GetCurrentLine();
139  if (line.empty())
140  return;
141 
142  if (textX >= line.length())
143  textX = static_cast<int>(line.length() - 1);
144 
145  int selStart = textX, selEnd = textX + 1;
146  if (line[selStart] == ' ') {
147  while (selStart > 0 && line[selStart - 1] == ' ')
148  --selStart;
149  while (selEnd < line.length() && line[selEnd] == ' ')
150  ++selEnd;
151  }
152  else if (IsAlpha(line[selStart])) {
153  while (selStart > 0 && IsAlpha(line[selStart - 1]))
154  --selStart;
155  while (selEnd < line.length() && IsAlpha(line[selEnd]))
156  ++selEnd;
157  }
158 
159  panel->SelStart(GetStartLine() + textY, selStart, false);
160  panel->SelEnd(GetStartLine() + textY, selEnd);
161 
162 
163  CCalcCaretPosOStream caretStrm(dc, context->GetLeftMargin(), 0,
164  dc.GetCharHeight(), context->GetIndentWidth(),
165  selEnd, textY);
166  x_RenderText(caretStrm, context);
167  caretStrm.GetCaretPos(caretX, caretY);
168  wxPoint pos = GetPosition();
169  panel->SetCaretPos(pos.x + caretX, pos.y + caretY);
170 }
171 
173  int x, int y,
174  int& textX, int& textY,
175  int& caretX, int& caretY)
176 {
177  CTextItemPanel* textPanel = context->GetPanel();
178  wxClientDC dc(textPanel);
179  textPanel->InitDC(dc);
180  CCalcTextPosOStream ostream(dc, context->GetLeftMargin(), 0,
181  dc.GetCharHeight(), context->GetIndentWidth(), x, y);
182  x_RenderText(ostream, context);
183  ostream.GetTextPos(textX, textY);
184 
185  CCalcCaretPosOStream caretStrm(dc, context->GetLeftMargin(), 0,
186  dc.GetCharHeight(), context->GetIndentWidth(),
187  textX, textY);
188  x_RenderText(caretStrm, context);
189  caretStrm.GetCaretPos(caretX, caretY);
190 
191  CTextPosition pos(textY, textX);
192  this->TextPosToExpanded(pos, context);
193  textY = pos.GetRow();
194  textX = pos.GetCol();
195 }
196 
197 namespace // anonymous namespace
198 {
199 
200 class CCopyText : public CStyledTextOStream
201 {
202 public:
203  CCopyText(wxTextOutputStream& os,
204  int startRow, int startCol,
205  int endRow, int endCol) :
206  m_OS(os),
207  m_StartRow(startRow), m_StartCol(startCol),
208  m_EndRow(endRow), m_EndCol(endCol), m_CurRow(0),
209  m_CurrentLineLength(0) {}
210 
211  virtual StreamHint GetHint() const { return kCopyText; }
212  virtual wxTextOutputStream* GetTextStream() const { return &m_OS; }
213  virtual bool IsVisible() const;
214  virtual void UpdatePosition(int shift) { m_CurrentLineLength += shift; }
215 
216  virtual CStyledTextOStream& operator<< (const string& text);
217 
218  virtual int CurrentRowLength() const { return m_CurrentLineLength; }
219 
220  virtual void SetStyle(const CTextStyle* /*style*/) {}
221  virtual void SetDefaultStyle() {}
222  virtual void Indent (size_t steps);
223  virtual void NewLine();
224 
225 private:
226  wxTextOutputStream& m_OS;
227  int m_StartRow;
228  int m_StartCol;
229  int m_EndRow;
230  int m_EndCol;
231  int m_CurRow;
232  int m_CurrentLineLength;
233 };
234 
235 bool CCopyText::IsVisible() const
236 {
237  if (m_CurRow > m_StartRow && m_CurRow < m_EndRow)
238  return true;
239 
240  if (m_CurRow == m_StartRow) {
241  if (m_CurrentLineLength < m_StartCol)
242  return false;
243  if (m_CurRow == m_EndRow)
244  return m_CurrentLineLength < m_EndCol;
245  return true;
246  }
247 
248  if (m_CurRow == m_EndRow)
249  return m_CurrentLineLength < m_EndCol;
250 
251  return false;
252 }
253 
254 void CCopyText::Indent (size_t steps)
255 {
256  if (steps == 0)
257  return;
258 
259  this->operator<<(string(steps, ' '));
260 }
261 
262 void CCopyText::NewLine()
263 {
264  if (m_CurRow >= m_StartRow && m_CurRow < m_EndRow)
265  m_OS << endl;
266 
267  ++m_CurRow;
268  m_CurrentLineLength = 0;
269 }
270 
272 {
273  int length = static_cast<int>(text.length());
274  int selStart = length, selEnd = length;
275 
276  if (m_CurRow == m_EndRow) {
277  selStart = 0;
278  selEnd = m_EndCol-m_CurrentLineLength;
279  }
280  if (m_CurRow == m_StartRow)
281  selStart = m_StartCol-m_CurrentLineLength;
282 
283  if (m_CurRow > m_StartRow && m_CurRow < m_EndRow) {
284  selStart = 0;
285  selEnd = length;
286  }
287 
288  if (selEnd < selStart)
289  swap(selStart, selEnd);
290 
291  if (selStart < selEnd && selStart < length && selEnd > 0) {
292  selStart = max(selStart, 0);
293  selEnd = min(selEnd, length);
294  m_OS << ToWxString(text.substr(selStart, selEnd - selStart));
295  }
296 
297  m_CurrentLineLength += length;
298  return *this;
299 }
300 
301 } // anonymous namespace
302 
303 void CTextSelectItem::GetText(wxTextOutputStream& os,
304  const CTextBlock& block,
305  CTextPanelContext* context)
306 {
307  CTextBlock b(block);
308  b.ShiftRow(-GetStartLine());
309  CCopyText ostream(os, b.GetStart().GetRow(), b.GetStart().GetCol(),
310  b.GetEnd().GetRow(), b.GetEnd().GetCol());
311  x_RenderText(ostream, context);
312 }
313 
static void Indent(FILE *output_stream, int indent_depth, const char *indent)
Definition: util.cpp:659
void GetCaretPos(int &caretPosX, int &caretPosY) const
void GetTextPos(int &textPosX, int &textPosY) const
void InitDC(wxDC &dc)
bool Selecting() const
void SelStart(int row, int col, bool shift)
CTextPanelContext * GetContext()
void SetCaretPos(int x, int y)
void SelMove(int row, int col)
void SelEnd(int row, int col)
virtual wxPoint GetPosition() const
Definition: text_item.hpp:137
virtual int GetStartLine() const
Definition: text_item.hpp:145
virtual void TextPosToExpanded(CTextPosition &WXUNUSED(pos), CTextPanelContext *WXUNUSED(context)) const
Definition: text_item.hpp:161
virtual void x_RenderText(CStyledTextOStream &WXUNUSED(ostream), CTextPanelContext *WXUNUSED(context)) const
Definition: text_item.hpp:169
virtual void MouseEvent(wxMouseEvent &event, CTextPanelContext &context)
Definition: text_item.cpp:171
int GetIndentWidth() const
CTextItemPanel * GetPanel()
virtual int GetLeftMargin() const
void SelectItem(ITextItem *item, bool controlDown, bool shiftDown)
int GetRow() const
int GetCol() const
virtual void GetText(wxTextOutputStream &os, const CTextBlock &block, CTextPanelContext *context)
virtual void x_CalcTextPos(CTextPanelContext *context, int x, int y, int &textX, int &textY, int &caretX, int &caretY)
void MouseMove(wxMouseEvent &event)
void MouseLeftUp(wxMouseEvent &event)
void MouseLeftDown(wxMouseEvent &event)
void MouseLeftDClick(wxMouseEvent &event)
virtual void MouseEvent(wxMouseEvent &event, CTextPanelContext &context)
CNcbiOstream & operator<<(CNcbiOstream &out, const CEquivRange &range)
Definition: equiv_range.cpp:96
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static void text(MDB_val *v)
Definition: mdb_dump.c:62
T max(T x_, T y_)
T min(T x_, T y_)
wxString ToWxString(const string &s)
Definition: wx_utils.hpp:173
Modified on Mon Mar 04 05:13:47 2024 by modify_doxy.py rev. 669887