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 // gqbGridProjTable.cpp - Table implementation for Projection 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 #include <wx/regex.h>
21
22 // App headers
23 #include "gqb/gqbGridProjTable.h"
24 #include "gqb/gqbColumn.h"
25 #include "gqb/gqbQueryObjs.h"
26
gqbGridProjTable(gqbObjsArray * position,gqbObjsArray * parent,wxArrayString * alias)27 gqbGridProjTable::gqbGridProjTable(gqbObjsArray *position, gqbObjsArray *parent, wxArrayString *alias):
28 wxGridTableBase()
29 {
30 colsPosition = position;
31 colsParents = parent;
32 columnsAlias = alias;
33 // GQB-TODO: replace above pointers array with local variable if possible or research what it's causing bug in destructor???
34 }
35
36
~gqbGridProjTable()37 gqbGridProjTable::~gqbGridProjTable()
38 {
39 }
40
41
GetNumberRows()42 int gqbGridProjTable::GetNumberRows()
43 {
44 return (colsPosition->GetCount());
45 }
46
47
GetNumberCols()48 int gqbGridProjTable::GetNumberCols()
49 {
50
51 return 3;
52 }
53
54
IsEmptyCell(int row,int col)55 bool gqbGridProjTable::IsEmptyCell( int row, int col )
56 {
57
58 int count = colsParents->GetCount();
59 if(row + 1 <= count)
60 return false;
61 else
62 return true;
63 }
64
65
GetValue(int row,int col)66 wxString gqbGridProjTable::GetValue( int row, int col )
67 {
68 switch(col)
69 {
70 case 0:
71 if(((gqbQueryObject *)colsParents->Item(row))->getAlias().length() > 0)
72 {
73 return ((gqbQueryObject *)colsParents->Item(row))->getAlias();
74 }
75 else
76 {
77 return ((gqbQueryObject *)colsParents->Item(row))->getName();
78 }
79 break;
80 case 1:
81 return ((gqbColumn *)colsPosition->Item(row))->getName();
82 break;
83 case 2:
84 return columnsAlias->Item(row);
85 break;
86 };
87 return wxT("");
88 }
89
90
GetColLabelValue(int col)91 wxString gqbGridProjTable::GetColLabelValue( int col)
92 {
93 switch(col)
94 {
95 case 0:
96 return _("Relation");
97 break;
98 case 1:
99 return _("Column");
100 break;
101 case 2:
102 return _("Alias");
103 break;
104 };
105 return wxT("");
106 }
107
108
SetValue(int row,int col,const wxString & value)109 void gqbGridProjTable::SetValue( int row, int col, const wxString &value )
110 {
111 // Do nothing on values that cannot be edited on this model [Column & Relation Name]
112 switch(col)
113 {
114 case 2:
115 columnsAlias->Item(row) = value;
116 break;
117 };
118 }
119
GetValueAsCustom(int row,int col,const wxString & typeName)120 void *gqbGridProjTable::GetValueAsCustom( int row, int col, const wxString &typeName )
121 {
122 switch(col)
123 {
124 case 0:
125 return (void *)&colsParents->Item(row);
126 break;
127 case 1:
128 return (void *)&colsPosition->Item(row);
129 break;
130 case 2:
131 break;
132 };
133 return NULL;
134 }
135
136
SetValueAsCustom(int row,int col,const wxString & typeName,void * value)137 void gqbGridProjTable::SetValueAsCustom( int row, int col, const wxString &typeName, void *value )
138 {
139 switch(col)
140 {
141 case 0:
142 colsParents->Add(((gqbQueryObject *)value));
143 break;
144 case 1:
145 colsPosition->Add(((gqbColumn *)value));
146 };
147 }
148
149
AppendItem(int col,gqbObject * item)150 void gqbGridProjTable::AppendItem(int col, gqbObject *item)
151 {
152 bool notify = false;
153 switch(col)
154 {
155 case 0:
156 colsParents->Add(item);
157 break;
158 case 1:
159 colsPosition->Add(item);
160 notify = true;
161 break;
162 case 2:
163 columnsAlias->Add(wxT(""));
164 break;
165 };
166
167 if (notify && GetView() )
168 {
169 wxGridTableMessage msg( this,
170 wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
171 (colsParents->GetCount() - 1),
172 1 );
173 GetView()->ProcessTableMessage( msg );
174
175 // Set the cells read-only
176 GetView()->SetReadOnly(GetView()->GetNumberRows() - 1, 0);
177 GetView()->SetReadOnly(GetView()->GetNumberRows() - 1, 1);
178 }
179
180 }
181
182 // Remove a column at the grid
removeRow(gqbObject * itemTable,gqbObject * itemColumn)183 bool gqbGridProjTable::removeRow(gqbObject *itemTable, gqbObject *itemColumn)
184 {
185 bool found = false;
186 int i, size = colsPosition->GetCount();
187
188 for(i = 0; i < size; i++)
189 {
190 if (colsParents->Item(i) == itemTable && colsPosition->Item(i) == itemColumn)
191 {
192 found = true;
193 break;
194 }
195 }
196
197 if(found)
198 {
199 colsParents->RemoveAt(i);
200 colsPosition->RemoveAt(i);
201 columnsAlias->RemoveAt(i);
202
203 if ( GetView() ) // Notify Grid about the change
204 {
205 wxGridTableMessage msg( this,
206 wxGRIDTABLE_NOTIFY_ROWS_DELETED,
207 i + 1,
208 1 );
209 GetView()->ProcessTableMessage( msg );
210 }
211 }
212
213 return found;
214 }
215
216
removeAllRows(gqbObject * itemTable)217 void gqbGridProjTable::removeAllRows(gqbObject *itemTable)
218 {
219
220 int size = colsParents->GetCount();
221 for(int i = (size - 1); i >= 0; i--)
222 {
223 if (colsParents->Item(i) == itemTable)
224 {
225 colsParents->RemoveAt(i);
226 colsPosition->RemoveAt(i);
227 columnsAlias->RemoveAt(i);
228
229 // Notify Grid about the change
230 if ( GetView() )
231 {
232 wxGridTableMessage msg( this,
233 wxGRIDTABLE_NOTIFY_ROWS_DELETED,
234 i + 1,
235 1 );
236 GetView()->ProcessTableMessage( msg );
237 }
238 }
239 }
240 }
241
242
changesPositions(int sPos,int dPos)243 void gqbGridProjTable::changesPositions(int sPos, int dPos)
244 {
245
246 int size = colsPosition->GetCount();
247 gqbObject *tmpTable = NULL, *tmpColumn = NULL;
248 wxString tmpAlias = wxT("");
249
250 if( (sPos >= 0 && sPos < size) && (dPos >= 0 && dPos < size) )
251 {
252 tmpTable = colsParents->Item(sPos);
253 tmpColumn = colsPosition->Item(sPos);
254 tmpAlias = columnsAlias->Item(sPos);
255
256 colsParents->Item(sPos) = colsParents->Item(dPos);
257 colsPosition->Item(sPos) = colsPosition->Item(dPos);
258 columnsAlias->Item(sPos) = columnsAlias->Item(dPos);
259 colsParents->Item(dPos) = tmpTable;
260 colsPosition->Item(dPos) = tmpColumn;
261 columnsAlias->Item(dPos) = tmpAlias;
262 }
263
264 wxGridTableMessage msg( this,
265 wxGRIDTABLE_REQUEST_VIEW_GET_VALUES,
266 sPos,
267 1 );
268 GetView()->ProcessTableMessage( msg );
269
270 }
271
272
273 // GQB-TODO: optimize this functions & related buttons events at gqbView because works but are a mess.
274 // Change a single row or a range to one pos up or down (but no more than one position)
changesRangeOnePos(int topPos,int bottomPos,int newTop)275 void gqbGridProjTable::changesRangeOnePos(int topPos, int bottomPos, int newTop)
276 {
277 // Eliminate side effect of zero base array on calculations, but careful newTop still it's zero based
278 topPos++;
279 bottomPos++;
280 int sizeRange = bottomPos - (topPos - 1), size = GetNumberRows();
281 if(topPos > newTop) // Go Down
282 {
283 // Only if the movement don't create an overflow
284 if( (topPos > 1) && ((newTop + sizeRange) < size) )
285 {
286 for(int i = newTop ; i < (newTop + sizeRange) ; i++)
287 {
288 changesPositions(i, i + 1);
289 }
290 }
291
292 } // Go Up
293 else
294 {
295 // Only if the movement don't create an overflow
296 if( (bottomPos < size) && ((newTop + sizeRange) <= size) )
297 {
298 // Go Up Down
299 for(int i = (newTop + sizeRange - 1) ; i >= newTop ; i--)
300 {
301 changesPositions(i - 1, i);
302 }
303 }
304 }
305 }
306
307
308 // Removes all items from gqbGridProjTable
emptyTableData()309 void gqbGridProjTable::emptyTableData()
310 {
311
312 int count = colsPosition->GetCount();
313 colsPosition->Empty();
314 colsParents->Empty();
315 columnsAlias->Empty();
316
317 // Notify Grid about the change
318 if ( GetView() )
319 {
320 wxGridTableMessage msg( this,
321 wxGRIDTABLE_NOTIFY_ROWS_DELETED,
322 1,
323 count);
324 GetView()->ProcessTableMessage( msg );
325 }
326 }
327
328