1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // gqbGridRestTable.cpp - Table implementation for Restrictions Panel Grid
9 //
10 //////////////////////////////////////////////////////////////////////////
11 
12 // App headers
13 #include "pgAdmin3.h"
14 
15 // wxWindows headers
16 #include <wx/wx.h>
17 #include <wx/settings.h>
18 #include <wx/utils.h>
19 #include <wx/notebook.h>
20 
21 // App headers
22 #include "gqb/gqbGridRestTable.h"
23 #include "gqb/gqbColumn.h"
24 #include "gqb/gqbQueryObjs.h"
25 #include "gqb/gqbViewPanels.h"
26 
gqbGridRestTable(gqbRestrictions * _restrictions)27 gqbGridRestTable::gqbGridRestTable(gqbRestrictions *_restrictions):
28 	wxGridTableBase()
29 {
30 	restrictions = _restrictions;
31 }
32 
33 
~gqbGridRestTable()34 gqbGridRestTable::~gqbGridRestTable()
35 {
36 }
37 
38 
GetNumberRows()39 int gqbGridRestTable::GetNumberRows()
40 {
41 	return (restrictions->restrictionsCount());
42 }
43 
44 
GetNumberCols()45 int gqbGridRestTable::GetNumberCols()
46 {
47 	return 4;
48 }
49 
50 
IsEmptyCell(int row,int col)51 bool gqbGridRestTable::IsEmptyCell( int row, int col )
52 {
53 
54 	int count = restrictions->restrictionsCount();
55 	if(row + 1 <= count)
56 		return false;
57 	else
58 		return true;
59 }
60 
61 
GetValue(int row,int col)62 wxString gqbGridRestTable::GetValue( int row, int col )
63 {
64 	switch(col)
65 	{
66 		case 0:
67 			return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getLeft();
68 			break;
69 		case 1:
70 			return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getRestriction();
71 			break;
72 		case 2:
73 			return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getValue_s();
74 			break;
75 		case 3:
76 			return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getConnector();
77 			break;
78 	};
79 
80 	return wxT("");
81 }
82 
83 
GetColLabelValue(int col)84 wxString gqbGridRestTable::GetColLabelValue( int col)
85 {
86 	switch(col)
87 	{
88 		case 0:
89 			return _("Restricted Value");
90 			break;
91 		case 1:
92 			return _("Operator");
93 			break;
94 		case 2:
95 			return _("Value");
96 			break;
97 		case 3:
98 			return _("Connector");
99 			break;
100 	};
101 	return wxT("");
102 }
103 
104 
SetValue(int row,int col,const wxString & value)105 void gqbGridRestTable::SetValue( int row, int col, const wxString &value )
106 {
107 	switch(col)
108 	{
109 		case 0:
110 			((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setLeft(value);
111 			break;
112 		case 1:
113 			((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setRestriction(value);
114 			break;
115 		case 2:
116 			((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setValue_s(value);
117 			break;
118 		case 3:
119 			((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setConnector(value);
120 			break;
121 	}
122 }
123 
124 
AppendItem(gqbQueryRestriction * item)125 void gqbGridRestTable::AppendItem(gqbQueryRestriction *item)
126 {
127 	bool notify = true;
128 
129 	restrictions->addRestriction(item);
130 
131 	if (notify && GetView() )
132 	{
133 		wxGridTableMessage msg( this,
134 		                        wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
135 		                        (restrictions->restrictionsCount() - 1),
136 		                        1 );
137 		GetView()->ProcessTableMessage( msg );
138 	}
139 
140 }
141 
142 
DeleteRows(size_t pos=0,size_t numRows=1)143 bool gqbGridRestTable::DeleteRows(size_t pos = 0, size_t numRows = 1)
144 {
145 	if((pos < (size_t)GetNumberRows()) && numRows == 1)
146 	{
147 		gqbQueryRestriction *r = restrictions->getRestrictionAt(pos);
148 		restrictions->removeRestriction(r);
149 
150 		// Notify Grid about the change
151 		if ( GetView() )
152 		{
153 			wxGridTableMessage msg( this,
154 			                        wxGRIDTABLE_NOTIFY_ROWS_DELETED,
155 			                        pos,
156 			                        1 );
157 			GetView()->ProcessTableMessage( msg );
158 		}
159 
160 		delete r;
161 		return true;
162 	}
163 	else
164 		return false;
165 }
166 
167 
168 // Removes all items from gqbGridTable
emptyTableData()169 void gqbGridRestTable::emptyTableData()
170 {
171 
172 	int count = restrictions->restrictionsCount();
173 	restrictions->deleteAllRestrictions();
174 
175 	if ( GetView() )                              //Notify Grid about the change
176 	{
177 		wxGridTableMessage msg( this,
178 		                        wxGRIDTABLE_NOTIFY_ROWS_DELETED,
179 		                        1,
180 		                        count);
181 		GetView()->ProcessTableMessage( msg );
182 	}
183 }
184 
185 
186 //
187 // Cell rendering utilities classes
188 //
189 
Draw(wxGrid & grid,wxGridCellAttr & attr,wxDC & dc,const wxRect & rectCell,int row,int col,bool isSelected)190 void wxGridCellComboBoxRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc,
191                                       const wxRect &rectCell, int row, int col, bool isSelected)
192 {
193 	wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
194 
195 	// first calculate button size
196 	// don't draw outside the cell
197 	int nButtonWidth = 17;
198 	if (rectCell.height < 2) return;
199 	wxRect rectButton;
200 	rectButton.x = rectCell.x + rectCell.width - nButtonWidth;
201 	rectButton.y = rectCell.y + 1;
202 	int cell_rows, cell_cols;
203 	attr.GetSize(&cell_rows, &cell_cols);
204 	rectButton.width = nButtonWidth;
205 	if (cell_rows == 1)
206 		rectButton.height = rectCell.height - 2;
207 	else
208 		rectButton.height = nButtonWidth;
209 
210 	SetTextColoursAndFont(grid, attr, dc, isSelected);
211 	int hAlign, vAlign;
212 	attr.GetAlignment(&hAlign, &vAlign);
213 
214 	// Leave room for button
215 	wxRect rect = rectCell;
216 	rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth() - 2);
217 	rect.Inflate(-1);
218 	grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign);
219 
220 	// Don't bother drawing if the cell is too small
221 	if (rectButton.height < 4 || rectButton.width < 4)
222 		return;
223 
224 	// Draw 3-d button
225 	wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
226 	dc.SetBrush(wxBrush(colourBackGround, wxSOLID));
227 	dc.SetPen(wxPen(colourBackGround, 1, wxSOLID));
228 	dc.DrawRectangle(rectButton);
229 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));
230 	dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(),
231 	            rectButton.GetRight(), rectButton.GetBottom());
232 	dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(),
233 	            rectButton.GetRight(), rectButton.GetTop() - 1);
234 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW),
235 	                1, wxSOLID));
236 	dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetBottom() - 1,
237 	            rectButton.GetRight() - 1, rectButton.GetBottom() - 1);
238 	dc.DrawLine(rectButton.GetRight() - 1, rectButton.GetBottom() - 1,
239 	            rectButton.GetRight() - 1, rectButton.GetTop());
240 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT),
241 	                1, wxSOLID));
242 	dc.DrawLine(rectButton.GetRight() - 2, rectButton.GetTop() + 1,
243 	            rectButton.GetLeft() + 1, rectButton.GetTop() + 1);
244 	dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetTop() + 1,
245 	            rectButton.GetLeft() + 1, rectButton.GetBottom() - 1);
246 
247 	// Draw little triangle
248 	int nTriWidth = 7;
249 	int nTriHeight = 4;
250 	wxPoint point[3];
251 	point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth() - nTriWidth) / 2,
252 	                   rectButton.GetTop() + (rectButton.GetHeight() - nTriHeight) / 2);
253 	point[1] = wxPoint(point[0].x + nTriWidth - 1, point[0].y);
254 	point[2] = wxPoint(point[0].x + 3, point[0].y + nTriHeight - 1);
255 	dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID));
256 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));
257 	dc.DrawPolygon(3, point);
258 	if (m_border == wxLAYOUT_TOP)
259 	{
260 		dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
261 		dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(),
262 		            rectCell.GetLeft(), rectCell.GetTop());
263 	}
264 }
265 
266 
Draw(wxGrid & grid,wxGridCellAttr & attr,wxDC & dc,const wxRect & rectCell,int row,int col,bool isSelected)267 void wxGridCellButtonRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc,
268                                     const wxRect &rectCell, int row, int col, bool isSelected)
269 {
270 	wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
271 
272 	// First calculate button size
273 	// don't draw outside the cell
274 	int nButtonWidth = 17;
275 	if (rectCell.height < 2) return;
276 	wxRect rectButton;
277 	rectButton.x = rectCell.x + rectCell.width - nButtonWidth;
278 	rectButton.y = rectCell.y + 1;
279 	int cell_rows, cell_cols;
280 	attr.GetSize(&cell_rows, &cell_cols);
281 	rectButton.width = nButtonWidth;
282 	if (cell_rows == 1)
283 		rectButton.height = rectCell.height - 2;
284 	else
285 		rectButton.height = nButtonWidth;
286 
287 	SetTextColoursAndFont(grid, attr, dc, isSelected);
288 	int hAlign, vAlign;
289 	attr.GetAlignment(&hAlign, &vAlign);
290 
291 	// Leave room for button
292 	wxRect rect = rectCell;
293 	rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth() - 2);
294 	rect.Inflate(-1);
295 	grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign);
296 
297 
298 	// Don't bother drawing if the cell is too small draw 3-d button
299 	if (rectButton.height < 4 || rectButton.width < 4)
300 		return;
301 
302 	wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
303 	dc.SetBrush(wxBrush(colourBackGround, wxSOLID));
304 	dc.SetPen(wxPen(colourBackGround, 1, wxSOLID));
305 	dc.DrawRectangle(rectButton);
306 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));
307 	dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(),
308 	            rectButton.GetRight(), rectButton.GetBottom());
309 	dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(),
310 	            rectButton.GetRight(), rectButton.GetTop() - 1);
311 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW),
312 	                1, wxSOLID));
313 	dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetBottom() - 1,
314 	            rectButton.GetRight() - 1, rectButton.GetBottom() - 1);
315 	dc.DrawLine(rectButton.GetRight() - 1, rectButton.GetBottom() - 1,
316 	            rectButton.GetRight() - 1, rectButton.GetTop());
317 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT),
318 	                1, wxSOLID));
319 	dc.DrawLine(rectButton.GetRight() - 2, rectButton.GetTop() + 1,
320 	            rectButton.GetLeft() + 1, rectButton.GetTop() + 1);
321 	dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetTop() + 1,
322 	            rectButton.GetLeft() + 1, rectButton.GetBottom() - 1);
323 
324 	// Draw little plus symbol
325 	dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID));
326 	dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));
327 	int nPlusWidth = 7;
328 	int nPlusHeight = 7;
329 	wxPoint point[4];
330 	point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth() - nPlusWidth) / 2, rectButton.GetTop() + (rectButton.GetHeight() / 2) - 1);
331 	point[1] = wxPoint(point[0].x + nPlusWidth, point[0].y);
332 	point[2] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth()) / 2, rectButton.GetTop() + (rectButton.GetHeight() - nPlusHeight) / 2);
333 	point[3] = wxPoint(point[2].x, point[2].y + nPlusHeight);
334 	dc.DrawLine(point[0], point[1]);
335 	dc.DrawLine(point[2], point[3]);
336 
337 	if (m_border == wxLAYOUT_TOP)
338 	{
339 		dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
340 		dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(),
341 		            rectCell.GetLeft(), rectCell.GetTop());
342 	}
343 }
344 
345 
346 //
347 // Cell editing utilities classes
348 //
dxGridCellSizedChoiceEditor(const wxArrayString & choices,bool allowOthers)349 dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(const wxArrayString &choices, bool allowOthers)
350 	: wxGridCellChoiceEditor(choices, allowOthers)
351 {
352 }
353 
354 
dxGridCellSizedChoiceEditor(size_t count,const wxString choices[],bool allowOthers)355 dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(size_t count, const wxString choices[], bool allowOthers)
356 	: wxGridCellChoiceEditor(count, choices, allowOthers)
357 {
358 }
359 
360 
Clone() const361 wxGridCellEditor *dxGridCellSizedChoiceEditor::Clone() const
362 {
363 	dxGridCellSizedChoiceEditor *editor = new
364 	dxGridCellSizedChoiceEditor();
365 	return editor;
366 }
367 
368 
Show(bool show,wxGridCellAttr * attr)369 void dxGridCellSizedChoiceEditor::Show(bool show, wxGridCellAttr *attr)
370 {
371 	wxGridCellEditor::Show(show, attr);
372 }
373