~ubuntu-branches/debian/sid/pgadmin3/sid

« back to all changes in this revision

Viewing changes to pgadmin/gqb/gqbView.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2009-07-30 12:27:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730122716-fddbh42on721bbs2
Tags: 1.10.0-1
* New upstream release.
* Adjusted watch file to match release candidates.
* Updated to Standards-Version 3.8.2:
  - Moved to Section: database.
  - Add DEB_BUILD_OPTIONS support for parallel building.
  - Move from findstring to filter suggestion for DEB_BUILD_OPTIONS parsing.
* pgagent got split into its own separate source package by upstream.
* Exclude Docs.vcproj from installation.
* Move doc-base.enus from pgadmin3 to pgadmin3-data package, the files are
  in there too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// pgAdmin III - PostgreSQL Tools
 
4
// RCS-ID:      $Id: gqbView.cpp 7758 2009-03-26 20:49:59Z dpage $
 
5
// Copyright (C) 2002 - 2009, The pgAdmin Development Team
 
6
// This software is released under the BSD Licence
 
7
//
 
8
// gqbView.cpp - View implementation for MVC Pattern of GQB
 
9
//
 
10
//////////////////////////////////////////////////////////////////////////
 
11
 
 
12
 
 
13
// 1. READ MODEL STATE FROM gqbModel TO CREATE THE GRAPHIC REPRESENTATION OF THE QUERY
 
14
// 2. USE THE CONTROLLER TO CHANGE THE MODEL WITH THE USER INPUT
 
15
 
 
16
#include "pgAdmin3.h"
 
17
 
 
18
// wxWindows headers
 
19
#include <wx/wx.h>
 
20
#include <wx/dcbuffer.h>
 
21
#include <wx/generic/gridctrl.h>
 
22
#include <wx/notebook.h>
 
23
#include <wx/choicdlg.h>
 
24
 
 
25
// App headers
 
26
#include "gqb/gqbModel.h"
 
27
#include "gqb/gqbEvents.h"
 
28
#include "gqb/gqbViewController.h"
 
29
#include "gqb/gqbQueryObjs.h"
 
30
#include "gqb/gqbGraphSimple.h"
 
31
#include "gqb/gqbViewPanels.h"
 
32
#include "gqb/gqbObject.h"
 
33
#include "gqb/gqbObjectCollection.h"
 
34
 
 
35
// Image
 
36
#include "images/gqbJoinCursor.xpm"
 
37
 
 
38
BEGIN_EVENT_TABLE(gqbView, wxScrolledWindow)
 
39
EVT_PAINT(gqbView::onPaint)
 
40
EVT_MOTION(gqbView::onMotion)
 
41
EVT_LEFT_DOWN(gqbView::onMotion)
 
42
EVT_RIGHT_DOWN(gqbView::onRightClick)
 
43
EVT_LEFT_UP(gqbView::onMotion)
 
44
EVT_LEFT_DCLICK(gqbView::onDoubleClick)
 
45
EVT_ERASE_BACKGROUND(gqbView::onEraseBackGround)  //This erase flicker create by wxStaticText when erasing background but this is not needed
 
46
EVT_KEY_DOWN(gqbView::OnKeyDown)
 
47
EVT_MENU(GQB_RMJ_DELETE,        gqbView::OnMenuJoinDelete)
 
48
EVT_MENU(GQB_RMT_DELETE,        gqbView::OnMenuTableDelete)
 
49
EVT_MENU(GQB_RMT_SETALIAS,      gqbView::OnMenuTableSetAlias)
 
50
END_EVENT_TABLE()
 
51
 
 
52
gqbView::gqbView(wxWindow *gqbParent, wxNotebook *gridParent, wxSize size, gqbController *controller, gqbModel *model)
 
53
: wxScrolledWindow(gqbParent, wxID_ANY, wxPoint(201,0), size,
 
54
wxHSCROLL | wxVSCROLL | wxBORDER | wxRETAINED)
 
55
{
 
56
    this->controller=controller;
 
57
    this->model=model;
 
58
    pressed=-1;
 
59
    selected=-1;
 
60
    changeTOpressed=false;
 
61
    canvasSize=size;
 
62
    collectionSelected=NULL;
 
63
    joinSelected=NULL;
 
64
    joinSource=NULL;
 
65
    joinDest=NULL;
 
66
    joinSCol=NULL;
 
67
    joinDCol=NULL;
 
68
    refreshRate=3;
 
69
    iterator=NULL;
 
70
    mode=pt_normal;
 
71
    joinCursorImage = wxBitmap(gqbJoinCursor_xpm).ConvertToImage();
 
72
    joinCursor= wxCursor(joinCursorImage);
 
73
    m_rightJoins=NULL;
 
74
    m_rightTables=NULL;
 
75
    jTempSelected=NULL;
 
76
    cTempSelected=NULL;
 
77
 
 
78
    // Assing kind of join Options
 
79
    joinTypeChoices.Add(wxString(wxT(" = ")));
 
80
    joinTypeChoices.Add(wxString(wxT(" > ")));
 
81
    joinTypeChoices.Add(wxString(wxT(" < ")));
 
82
    joinTypeChoices.Add(wxString(wxT(" >= ")));
 
83
    joinTypeChoices.Add(wxString(wxT(" <= ")));
 
84
 
 
85
    // Assign default graphic behavior [skin of forms inside model]
 
86
    this->graphBehavior = new gqbGraphSimple();
 
87
 
 
88
    // Create Projection Panel
 
89
    // GQB-TODO: move model to grid panel constructor
 
90
    this->gridTable = new gqbGridProjTable(this->model->getOrderedColumns(),this->model->getColumnsParents(),this->model->getColumnsAlias());
 
91
    this->projectionPanel = new gqbGridPanel(controller->getTabs(),-1,gridTable);
 
92
 
 
93
    // Create Restrictions Panel
 
94
    this->restrictionsGridTable = new gqbGridRestTable(model->getRestrictions());
 
95
    this->criteriaPanel = new gqbCriteriaPanel(controller->getTabs(),model,restrictionsGridTable);
 
96
 
 
97
    // Create Joins Panel
 
98
    this->joinsGridTable = new gqbGridJoinTable(this->controller);
 
99
    this->joinsPanel = new gqbJoinsPanel(controller->getTabs(), model, joinsGridTable, controller);
 
100
 
 
101
    // Create Order by Panel
 
102
    this->orderByLGridTable = new gqbGridOrderTable(1,model->getOrdByAvailColumns(),model->getOrdByAvailParents(),NULL);
 
103
    this->orderByRGridTable = new gqbGridOrderTable(2,model->getOrdByColumns(), model->getOrdByParents(),model->getOrdByKind());
 
104
    this->orderPanel = new gqbOrderPanel(controller->getTabs(), orderByLGridTable, orderByRGridTable);
 
105
}
 
106
 
 
107
 
 
108
gqbView::~gqbView()
 
109
{
 
110
    if(graphBehavior)
 
111
        delete graphBehavior;
 
112
    if(iterator)
 
113
        delete iterator;
 
114
 
 
115
    if(m_rightTables)
 
116
        delete m_rightTables;
 
117
 
 
118
    if(m_rightJoins)
 
119
        delete m_rightJoins;
 
120
}
 
121
 
 
122
 
 
123
// Overwrite and disable onEraseBackground Event to avoid Flicker
 
124
void gqbView::onEraseBackGround(wxEraseEvent& event)
 
125
{
 
126
}
 
127
 
 
128
 
 
129
// Detect when should be drawn the canvas with the model information
 
130
void gqbView::onPaint(wxPaintEvent& event)
 
131
{
 
132
    wxPaintDC dcc(this);                          // Prepare Context for Buffered Draw
 
133
    wxBufferedDC dc(&dcc, canvasSize);
 
134
    drawAll(dc);                                  // Call Function to draw all
 
135
}
 
136
 
 
137
 
 
138
// GQB-TODO: remove all possible modification to model from here to controller.
 
139
void gqbView::onRightClick(wxMouseEvent& event)
 
140
{
 
141
// GQB-TODO: Validate Alias
 
142
    gqbObject *anySelected=NULL;
 
143
    wxPoint pdc=event.GetPosition();
 
144
    pdc.x=event.GetPosition().x;
 
145
    pdc.y=event.GetPosition().y;
 
146
    this->CalcUnscrolledPosition(pdc.x,pdc.y,&pdc.x,&pdc.y);
 
147
    anySelected=controller->getModelSelected(pdc,cTempSelected, jTempSelected, false);
 
148
    if(anySelected)
 
149
    {
 
150
        if(anySelected->getType()==GQB_QUERYOBJ)
 
151
        {
 
152
            if(!m_rightTables)
 
153
            {
 
154
                m_rightTables = new wxMenu;
 
155
                m_rightTables->Append(GQB_RMT_SETALIAS, _("&Set Alias for table"));
 
156
                m_rightTables->Append(GQB_RMT_DELETE, _("&Delete Table"));
 
157
            }
 
158
            cTempSelected=(gqbQueryObject *) (gqbObjectCollection *) anySelected;
 
159
            jTempSelected=NULL;
 
160
            PopupMenu(m_rightTables, event.GetPosition());
 
161
        }
 
162
 
 
163
        if(anySelected->getType()==GQB_JOIN)
 
164
        {
 
165
            if(!m_rightJoins)
 
166
            {
 
167
                m_rightJoins = new wxMenu;
 
168
                m_rightJoins->Append(GQB_RMJ_DELETE, _("&Delete Join"));
 
169
            }
 
170
            cTempSelected=NULL;
 
171
            jTempSelected=(gqbQueryJoin *) anySelected;;
 
172
            PopupMenu(m_rightJoins, event.GetPosition());
 
173
        }
 
174
    }
 
175
}
 
176
 
 
177
 
 
178
void gqbView::OnMenuJoinDelete(wxCommandEvent& WXUNUSED(event))
 
179
{
 
180
    if(jTempSelected)
 
181
    {
 
182
        this->joinsGridTable->removeJoin(joinSelected);
 
183
        controller->removeJoin(jTempSelected);
 
184
        jTempSelected=NULL;
 
185
        this->Refresh();
 
186
    }
 
187
}
 
188
 
 
189
 
 
190
void gqbView::OnMenuTableDelete(wxCommandEvent& WXUNUSED(event))
 
191
{
 
192
    if(cTempSelected)
 
193
    {
 
194
        joinsGridTable->removeJoins(cTempSelected);
 
195
        controller->removeTableFromModel(cTempSelected, gridTable, orderByLGridTable, orderByRGridTable);
 
196
        cTempSelected=NULL;
 
197
        this->Refresh();
 
198
    }
 
199
}
 
200
 
 
201
 
 
202
void gqbView::OnMenuTableSetAlias(wxCommandEvent& event)
 
203
{
 
204
    if(cTempSelected)
 
205
    {
 
206
        // Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign
 
207
        // as his parent the main container of the view, and void the bug
 
208
        wxTextEntryDialog dialog(controller->getDialogParent(),
 
209
                        wxString::Format(_("Enter an alias for table %s"), cTempSelected->getName().c_str()),
 
210
            _("Please enter an alias for the table."),
 
211
            wxT(""),
 
212
            wxOK | wxCANCEL| wxCENTRE);
 
213
        dialog.SetValue(cTempSelected->getAlias());
 
214
        if (dialog.ShowModal() == wxID_OK)
 
215
        {
 
216
            cTempSelected->setAlias(dialog.GetValue());
 
217
            joinsPanel->Refresh();
 
218
        }
 
219
        cTempSelected=NULL;
 
220
        this->Refresh();
 
221
    }
 
222
}
 
223
 
 
224
 
 
225
void gqbView::onDoubleClick(wxMouseEvent& event)
 
226
{
 
227
    // GQB-TODO: Validate Alias
 
228
    gqbObject *anySelected=NULL;
 
229
    wxPoint pdc=event.GetPosition();
 
230
    pdc.x=event.GetPosition().x;
 
231
    pdc.y=event.GetPosition().y;
 
232
    this->CalcUnscrolledPosition(pdc.x,pdc.y,&pdc.x,&pdc.y);
 
233
 
 
234
    anySelected=controller->getModelSelected(pdc,cTempSelected, jTempSelected, false);
 
235
    if(anySelected)
 
236
    {
 
237
        if(anySelected->getType()==GQB_QUERYOBJ)
 
238
        {
 
239
            gqbQueryObject *t = (gqbQueryObject *) (gqbObjectCollection *) anySelected;
 
240
 
 
241
            // Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign
 
242
            // as his parent the main container of the view, and void the bug
 
243
            wxTextEntryDialog dialog(controller->getDialogParent(),
 
244
                        wxString::Format(_("Enter an alias for table %s"), t->getName().c_str()),
 
245
            _("Please enter an alias for the table."),
 
246
                wxT(""),
 
247
                wxOK | wxCANCEL| wxCENTRE);
 
248
            dialog.SetValue(t->getAlias());
 
249
            if (dialog.ShowModal() == wxID_OK)
 
250
            {
 
251
                t->setAlias(dialog.GetValue());
 
252
                joinsPanel->Refresh();
 
253
 
 
254
                // hack to avoid misplaced joins anchors after insert an alias that trigger a table graph resize (bigger)
 
255
                this->Refresh();
 
256
                this->Update(); //force refresh
 
257
                graphBehavior->UpdatePosObject(t,t->position.x,t->position.y,0);
 
258
            }
 
259
        }
 
260
        else if(anySelected->getType()==GQB_JOIN)
 
261
        {
 
262
            gqbQueryJoin *j = (gqbQueryJoin *) anySelected;
 
263
 
 
264
            controller->getTabs()->ChangeSelection(ti_joinsPanel);
 
265
            gqbJoinsPanel *jPanel = wxDynamicCast( joinsPanel, gqbJoinsPanel );
 
266
            jPanel->selectJoin(j);
 
267
        }
 
268
    }
 
269
    this->Refresh();
 
270
}
 
271
 
 
272
 
 
273
// Manages user input [Mouse click, drag & drop] over the Canvas
 
274
void gqbView::onMotion(wxMouseEvent& event)
 
275
{
 
276
    static int refresh=1;                         // refresh counter, everytime this values reaches 
 
277
                                                      // "refreshRate" value then Refresh while dragging
 
278
    // Discover area where event ocurrs
 
279
    pos.x=event.GetPosition().x;
 
280
    pos.y=event.GetPosition().y;
 
281
    this->CalcUnscrolledPosition(pos.x,pos.y,&pos.x,&pos.y);
 
282
    gqbObject *anySelected=NULL;
 
283
 
 
284
    // Button Down Event is triggered
 
285
    if(event.ButtonDown()&& !changeTOpressed)
 
286
    {
 
287
        this->SetFocus();
 
288
 
 
289
        // Which kind of button down was? join creation [click on any column at the 
 
290
                // right of checkbox and drag & drop] or table moving [click on title and drag & drop]
 
291
        anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, false);
 
292
        if(anySelected)
 
293
        {
 
294
            // Anything before just forget about it
 
295
            changeTOpressed=false;
 
296
            joinSource=NULL;
 
297
            joinSCol=NULL;
 
298
            joinDCol=NULL;
 
299
            joinDest=NULL;
 
300
            jpos.x=0;
 
301
            jpos.y=0;
 
302
 
 
303
            if(anySelected->getType()==GQB_QUERYOBJ)
 
304
            {
 
305
                gqbQueryObject* t = (gqbQueryObject *) (gqbObjectCollection *) anySelected;
 
306
 
 
307
                // If click on the title area AND don't click on the columns selection checkbox
 
308
                if( (pos.y-t->position.y <= graphBehavior->getTitleRowHeight()))
 
309
                    controller->setPointerMode(pt_normal);
 
310
                else
 
311
                if(pos.x - t->position.x <= 17)
 
312
                    controller->setPointerMode(pt_normal);
 
313
                else
 
314
                    controller->setPointerMode(pt_join);
 
315
            }
 
316
        }
 
317
        else
 
318
        {
 
319
            anySelected=false;
 
320
            mode=pt_normal;
 
321
        }
 
322
 
 
323
        if(mode==pt_normal)                       // pointer is used to move tables & select/unselect columns
 
324
        {
 
325
            // getSelected Item [Mark it as selected if possible]
 
326
            anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, true);
 
327
            changeTOpressed=true;
 
328
 
 
329
            // Do conversion of type object if any found
 
330
            if(anySelected)
 
331
            {
 
332
                if(anySelected->getType()==GQB_QUERYOBJ)
 
333
                {
 
334
                    collectionSelected = (gqbQueryObject *) (gqbObjectCollection *) anySelected;
 
335
                    joinSelected = NULL;
 
336
                }
 
337
                else if(anySelected->getType()==GQB_JOIN)
 
338
                {
 
339
                    joinSelected = (gqbQueryJoin *) anySelected;
 
340
                    collectionSelected = NULL;
 
341
                }
 
342
            }
 
343
            else
 
344
            {
 
345
                collectionSelected = NULL;
 
346
                joinSelected = NULL;
 
347
            }
 
348
 
 
349
            if(!collectionSelected)               
 
350
            {
 
351
                                // none selected temp unselect all items
 
352
                controller->unsetModelSelected(true);
 
353
            }
 
354
            else
 
355
            {
 
356
                gqbColumn *col=graphBehavior->getColumnAtPosition(&pos,collectionSelected);
 
357
                if(col)
 
358
                {   
 
359
                                        // Add or remove column from model & observers (ex: Grid) (projection part of SQL sentence)
 
360
                    controller->processColumnInModel(collectionSelected,col,gridTable);
 
361
                }
 
362
            }
 
363
 
 
364
            if(!joinSelected)
 
365
            {
 
366
                controller->unsetModelSelected(false);
 
367
            }
 
368
 
 
369
        }   
 
370
                // Pointer is used to add joins
 
371
        else if(mode==pt_join)
 
372
        {
 
373
            anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, false);
 
374
 
 
375
            // Even if I get an object check that it isn't a join
 
376
            if( (anySelected) && anySelected->getType()==GQB_QUERYOBJ)
 
377
                joinSource = (gqbQueryObject *)(gqbObjectCollection *) anySelected;
 
378
            else
 
379
                joinSource = NULL;
 
380
 
 
381
            if(!joinSource)               
 
382
            {
 
383
                                // creation of join starts
 
384
                joinSCol=NULL;
 
385
                joinDCol=NULL;
 
386
                jpos.x=0;
 
387
                jpos.y=0;
 
388
            }
 
389
            else
 
390
            {
 
391
                joinSCol=graphBehavior->getColumnAtPosition(&pos,joinSource,joinSource->getWidth());
 
392
                jpos=pos;
 
393
 
 
394
                // GQB-TODO then draw line between column & pointer
 
395
            }
 
396
        }
 
397
 
 
398
        this->Refresh();
 
399
    }
 
400
 
 
401
    // Button Up Event is triggered
 
402
    if(event.ButtonUp())
 
403
    {
 
404
                // Pointer is used to move tables & select/unselect columns
 
405
                if(mode==pt_normal)
 
406
        {
 
407
            changeTOpressed=false;
 
408
            anySelected=controller->getModelSelected(pos, collectionSelected, joinSelected, false);
 
409
            if (anySelected && anySelected->getType() == GQB_JOIN)
 
410
            {
 
411
                gqbJoinsPanel *jPanel = wxDynamicCast( joinsPanel, gqbJoinsPanel );
 
412
                jPanel->selectJoin((gqbQueryJoin *)anySelected);
 
413
            }
 
414
        }                                         
 
415
        // Pointer is used to add joins
 
416
                else if(mode==pt_join)
 
417
        {
 
418
            anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, false);
 
419
 
 
420
            // Even if I get an object check that it isn't a join
 
421
            if( (anySelected) && anySelected->getType()==GQB_QUERYOBJ)
 
422
            {
 
423
                joinDest = (gqbQueryObject *)(gqbObjectCollection *) anySelected;
 
424
                // Validate not self joins [in this version tables can be duplicated to create same effect]
 
425
                if(joinDest==joinSource)
 
426
                {
 
427
                    joinDest=NULL;
 
428
                }
 
429
            }else
 
430
            joinDest = NULL;
 
431
 
 
432
                        // Creation of join starts
 
433
            if(!joinDest)                         
 
434
            {
 
435
                joinSource=NULL;
 
436
                joinSCol=NULL;
 
437
                joinDCol=NULL;
 
438
                joinDest=NULL;
 
439
                jpos.x=0;
 
440
                jpos.y=0;
 
441
            }
 
442
            else
 
443
            {
 
444
                joinDCol=graphBehavior->getColumnAtPosition(&pos,joinDest,joinDest->getWidth());
 
445
                if(joinDCol)
 
446
                {
 
447
                    // GQB-TODO: Allow other type of joins
 
448
                    gqbQueryJoin *qj=controller->addJoin(joinSource,joinSCol,joinDest,joinDCol,_equally);
 
449
                    graphBehavior->calcAnchorPoint(qj);
 
450
                    this->joinsGridTable->AppendJoin(qj);
 
451
                }
 
452
                // Let the temporary join line to be draw again [Don't destroy anything because all object where own by other objects this are just pointers]
 
453
                joinSource=NULL;
 
454
                joinSCol=NULL;
 
455
                joinDest=NULL;
 
456
                joinDCol=NULL;
 
457
                jpos.x=0;
 
458
                jpos.y=0;
 
459
            }
 
460
        }
 
461
 
 
462
        controller->setPointerMode(pt_normal);    //when button is up, pointer mode should be only normal
 
463
        this->Refresh();
 
464
    }
 
465
 
 
466
    // Mouse is Dragged while mouse button is down
 
467
    if (event.Dragging()&&pressed)
 
468
    {
 
469
        if(mode==pt_normal)
 
470
        {
 
471
            if(collectionSelected)
 
472
            {
 
473
                // GQB-TODO: same as gqbGraphBehavior.h [find a way to not hard code the 17 default value]
 
474
                if((pos.x > collectionSelected->position.x+17) || (pos.x < collectionSelected->position.x) )
 
475
                {
 
476
                    graphBehavior->UpdatePosObject(collectionSelected,pos.x,pos.y,40);
 
477
                }
 
478
 
 
479
                // Don't draw too much when dragging table around canvas [lower cpu use]
 
480
                                if(refresh%refreshRate==0)
 
481
                {
 
482
                    this->Refresh();
 
483
                    refresh=1;
 
484
                }else
 
485
                refresh++;
 
486
 
 
487
            }
 
488
        }
 
489
        else if(mode==pt_join)
 
490
        {
 
491
            if(joinSource && !joinDest)
 
492
            {
 
493
                this->Refresh();
 
494
            }
 
495
 
 
496
        }
 
497
    }
 
498
}
 
499
 
 
500
 
 
501
void gqbView::OnKeyDown(wxKeyEvent& event)
 
502
{
 
503
    if(event.GetKeyCode() == WXK_DELETE)
 
504
    {
 
505
        if(collectionSelected)
 
506
        {
 
507
            this->joinsGridTable->removeJoins(collectionSelected);
 
508
            controller->removeTableFromModel(collectionSelected,gridTable,orderByLGridTable,orderByRGridTable);
 
509
            collectionSelected=NULL;
 
510
            this->Refresh();
 
511
        }
 
512
 
 
513
        if(joinSelected)
 
514
        {
 
515
            this->joinsGridTable->removeJoin(joinSelected);
 
516
            controller->removeJoin(joinSelected);
 
517
            joinSelected=NULL;
 
518
            this->Refresh();
 
519
        }
 
520
    }
 
521
}
 
522
 
 
523
 
 
524
void gqbView::drawAll(wxBufferedDC& bdc)
 
525
{
 
526
    bdc.Clear();
 
527
    if(!iterator)
 
528
        // Get an iterator for the objects (tables/views) in the model.
 
529
        iterator = this->model->createQueryIterator();
 
530
    else
 
531
        iterator->ResetIterator();
 
532
 
 
533
    // First Draw Tables
 
534
    while(iterator->HasNext())
 
535
    {
 
536
        gqbQueryObject *tmp= (gqbQueryObject *)iterator->Next();
 
537
        wxPoint pt = wxPoint(tmp->position);      // Use a copy because I don't want to store the modified 
 
538
                                                          // version of point after CalcScrolledPosition was called
 
539
 
 
540
                // adjust coordinates
 
541
        this->CalcScrolledPosition(pt.x,pt.y,&pt.x,&pt.y);
 
542
        graphBehavior->drawTable(bdc,&pt,tmp);    // graph table
 
543
    }
 
544
 
 
545
    // Later Draw Joins over Tables
 
546
    iterator->ResetIterator();
 
547
    while(iterator->HasNext())
 
548
    {
 
549
        gqbQueryObject *tmp= (gqbQueryObject *)iterator->Next();
 
550
 
 
551
        if(tmp->getHaveJoins())
 
552
        {
 
553
            gqbIteratorBase *joinsIterator = tmp->createJoinsIterator();
 
554
            while(joinsIterator->HasNext())
 
555
            {
 
556
                gqbQueryJoin *join = (gqbQueryJoin *) joinsIterator->Next();
 
557
                wxPoint o = join->getSourceAnchor();
 
558
                wxPoint d = join->getDestAnchor();
 
559
 
 
560
                // adjust coordinates origin
 
561
                this->CalcScrolledPosition(o.x,o.y,&o.x,&o.y);
 
562
 
 
563
                // adjust coordinates destination
 
564
                this->CalcScrolledPosition(d.x,d.y,&d.x,&d.y);
 
565
                graphBehavior->drawJoin(bdc,o,d,join->getAnchorsUsed(), join->getSelected(), join->getKindofJoin());
 
566
            }
 
567
            delete joinsIterator;
 
568
        }
 
569
 
 
570
    }
 
571
 
 
572
    // This iterator is delete at destroyer for reuse purposes
 
573
    if(joinSource)
 
574
    {
 
575
        // Draw temporary line while creating a join
 
576
        wxPoint source=jpos;
 
577
        wxPoint destination=pos;
 
578
        this->CalcScrolledPosition(source.x,source.y,&source.x,&source.y);
 
579
        this->CalcScrolledPosition(destination.x,destination.y,&destination.x,&destination.y);
 
580
        graphBehavior->drawTempJoinLine(bdc,source,destination);
 
581
    }
 
582
}
 
583
 
 
584
 
 
585
void gqbView::setPointerMode(pointerMode pm)
 
586
{
 
587
    mode=pm;
 
588
    if(mode==pt_join)
 
589
        this->SetCursor(joinCursor);
 
590
    else
 
591
        this->SetCursor(wxNullCursor);
 
592
}
 
593
 
 
594
 
 
595
bool gqbView::clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest)
 
596
{
 
597
    return graphBehavior->clickOnJoin(join,pt,origin,dest);
 
598
}
 
599
 
 
600
 
 
601
void gqbView::emptyPanelsData()
 
602
{
 
603
    gridTable->emptyTableData();
 
604
    this->joinsGridTable->emptyTableData();
 
605
}
 
606
 
 
607
 
 
608
void gqbView::newTableAdded(gqbQueryObject *item)
 
609
{
 
610
    // Refresh Order By Panel's Left Grid
 
611
    if (orderByLGridTable->GetView() )
 
612
    {
 
613
        wxGridTableMessage msg( orderByLGridTable,
 
614
            wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
 
615
            orderByLGridTable->GetNumberRows()-1,
 
616
            item->parent->countCols() );
 
617
        orderByLGridTable->GetView()->ProcessTableMessage( msg );
 
618
    }
 
619
}
 
620
 
 
621
void gqbView::updateTable(gqbQueryObject *queryTable)
 
622
{
 
623
    if (queryTable->getHaveJoins())
 
624
    {
 
625
        gqbIteratorBase *j=queryTable->createJoinsIterator();
 
626
        while (j->HasNext())
 
627
        {
 
628
            gqbQueryJoin *tmp= (gqbQueryJoin *)j->Next();
 
629
            graphBehavior->calcAnchorPoint(tmp);
 
630
        }
 
631
        delete j;
 
632
    }
 
633
 
 
634
    // Update position of anchor points of Joins that come from others tables
 
635
    if (queryTable->getHaveRegJoins())
 
636
    {
 
637
        gqbIteratorBase *r=queryTable->createRegJoinsIterator();
 
638
        while (r->HasNext())
 
639
        {
 
640
            gqbQueryJoin *tmp= (gqbQueryJoin *)r->Next();
 
641
            graphBehavior->calcAnchorPoint(tmp);
 
642
        }
 
643
        delete r;
 
644
    }
 
645
    this->Refresh();
 
646
}
 
647