~ubuntu-branches/ubuntu/utopic/pgadmin3/utopic-proposed

« back to all changes in this revision

Viewing changes to src/ui/dlgClasses.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Enrici
  • Date: 2004-12-14 23:46:39 UTC
  • Revision ID: james.westby@ubuntu.com-20041214234639-tve0i5l49fq13jli
Tags: upstream-1.2.0
ImportĀ upstreamĀ versionĀ 1.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// pgAdmin III - PostgreSQL Tools
 
4
// RCS-ID:      $Id: dlgClasses.cpp,v 1.17 2004/10/22 14:25:16 andreas Exp $
 
5
// Copyright (C) 2002 - 2004, The pgAdmin Development Team
 
6
// This software is released under the Artistic Licence
 
7
//
 
8
// dlgClasses.cpp - Some dialogue base classes 
 
9
//
 
10
//////////////////////////////////////////////////////////////////////////
 
11
 
 
12
// wxWindows headers
 
13
#include <wx/wx.h>
 
14
#include <wx/settings.h>
 
15
#include <wx/xrc/xmlres.h>
 
16
 
 
17
 
 
18
// App headers
 
19
#include "pgAdmin3.h"
 
20
#include "wx/process.h"
 
21
#include "frmMain.h"
 
22
#include "pgConn.h"
 
23
#include "frmAbout.h"
 
24
 
 
25
#include "menu.h"
 
26
 
 
27
 
 
28
BEGIN_EVENT_TABLE(pgDialog, wxDialog)
 
29
    EVT_BUTTON (wxID_CANCEL,            pgDialog::OnCancel)
 
30
    EVT_CLOSE(                          pgDialog::OnClose)
 
31
END_EVENT_TABLE()
 
32
 
 
33
 
 
34
 
 
35
void pgDialog::PostCreation()
 
36
{
 
37
    wxWindow *statusBarContainer=FindWindow(wxT("unkStatusBar_container"));
 
38
 
 
39
    if (statusBarContainer)
 
40
    {
 
41
        statusBar = new wxStatusBar(this, -1, wxST_SIZEGRIP);
 
42
        wxXmlResource::Get()->AttachUnknownControl(wxT("unkStatusBar"), statusBar);
 
43
    }
 
44
    if (GetWindowStyle() & wxTHICK_FRAME)   // is designed with sizers; don't change
 
45
        return;
 
46
 
 
47
    if (!btnCancel)
 
48
        return;
 
49
 
 
50
    wxSize  size = btnCancel->GetSize();
 
51
    wxPoint pos = btnCancel->GetPosition();
 
52
    int height = pos.y + size.GetHeight() + ConvertDialogToPixels(wxSize(0,3)).y;
 
53
    if (statusBar)
 
54
        height += statusBar->GetSize().GetHeight();
 
55
 
 
56
    int right = pos.x + ConvertDialogToPixels(wxSize(50,0)).x - size.GetWidth();
 
57
    btnCancel->Move(right, pos.y);
 
58
    
 
59
    if (btnOK)
 
60
    {
 
61
        size = btnOK->GetSize();
 
62
        right -= size.GetWidth() + ConvertDialogToPixels(wxSize(3,0)).x;
 
63
        btnOK->Move(right, pos.y);
 
64
    }
 
65
    if (btnApply)
 
66
    {
 
67
        size = btnApply->GetSize();
 
68
        right -= size.GetWidth() - ConvertDialogToPixels(wxSize(3,0)).x;
 
69
        btnApply->Move(right, pos.y);
 
70
    }
 
71
 
 
72
    int w, h;
 
73
    size=GetSize();
 
74
    GetClientSize(&w, &h);
 
75
 
 
76
    SetSize(size.GetWidth(), size.GetHeight() + height - h);
 
77
}
 
78
 
 
79
 
 
80
void pgDialog::RestorePosition(int defaultX, int defaultY, int defaultW, int defaultH, int minW, int minH)
 
81
{
 
82
    wxPoint pos(settings->Read(dlgName, wxPoint(defaultX, defaultY)));
 
83
    wxSize size;
 
84
    if (defaultW < 0)
 
85
        size = GetSize();
 
86
    else
 
87
        size = settings->Read(dlgName, wxSize(defaultW, defaultH));
 
88
 
 
89
    bool posDefault = (pos.x == -1 && pos.y == -1);
 
90
 
 
91
    CheckOnScreen(pos, size, minW, minH);
 
92
    SetSize(pos.x, pos.y, size.x, size.y);
 
93
    if (posDefault)
 
94
        CenterOnParent();
 
95
}
 
96
 
 
97
void pgDialog::SavePosition()
 
98
{
 
99
        settings->Write(dlgName, GetSize(), GetPosition());
 
100
}
 
101
 
 
102
void pgDialog::LoadResource(wxWindow *parent, const wxChar *name)
 
103
{
 
104
    if (name)
 
105
        dlgName = name;
 
106
    wxXmlResource::Get()->LoadDialog(this, parent, dlgName); 
 
107
    PostCreation();
 
108
}
 
109
 
 
110
 
 
111
 
 
112
void pgDialog::OnClose(wxCloseEvent& event)
 
113
{
 
114
    if (IsModal())
 
115
        EndModal(-1);
 
116
    else
 
117
        Destroy();
 
118
}
 
119
 
 
120
 
 
121
void pgDialog::OnCancel(wxCommandEvent& ev)
 
122
{
 
123
    if (IsModal())
 
124
        EndModal(-1);
 
125
    else
 
126
        Destroy();
 
127
}
 
128
 
 
129
 
 
130
///////////////////////////////////////////////////////////////////////////////////////
 
131
 
 
132
 
 
133
BEGIN_EVENT_TABLE(pgFrame, wxFrame)
 
134
    EVT_MENU(MNU_EXIT,                  pgFrame::OnExit)
 
135
    EVT_MENU(MNU_RECENT+1,              pgFrame::OnRecent)
 
136
    EVT_MENU(MNU_RECENT+2,              pgFrame::OnRecent)
 
137
    EVT_MENU(MNU_RECENT+3,              pgFrame::OnRecent)
 
138
    EVT_MENU(MNU_RECENT+4,              pgFrame::OnRecent)
 
139
    EVT_MENU(MNU_RECENT+5,              pgFrame::OnRecent)
 
140
    EVT_MENU(MNU_RECENT+6,              pgFrame::OnRecent)
 
141
    EVT_MENU(MNU_RECENT+7,              pgFrame::OnRecent)
 
142
    EVT_MENU(MNU_RECENT+8,              pgFrame::OnRecent)
 
143
    EVT_MENU(MNU_RECENT+9,              pgFrame::OnRecent)
 
144
    EVT_MENU(MNU_BUGREPORT,             pgFrame::OnBugreport)
 
145
    EVT_MENU(MNU_HELP,                  pgFrame::OnHelp)
 
146
    EVT_MENU(MNU_ABOUT,                 pgFrame::OnAbout)
 
147
#ifdef __WXGTK__
 
148
    EVT_KEY_DOWN(                       pgFrame::OnKeyDown)
 
149
#endif
 
150
END_EVENT_TABLE()
 
151
 
 
152
 
 
153
pgFrame::~pgFrame()
 
154
{
 
155
    if (!dlgName.IsEmpty())
 
156
        SavePosition();
 
157
}
 
158
 
 
159
// Event handlers
 
160
void pgFrame::OnKeyDown(wxKeyEvent& event)
 
161
{
 
162
    event.m_metaDown=false;
 
163
    event.Skip();
 
164
}
 
165
 
 
166
 
 
167
void pgFrame::OnExit(wxCommandEvent& event)
 
168
{
 
169
    Close();
 
170
}
 
171
 
 
172
 
 
173
void pgFrame::OnHelp(wxCommandEvent& WXUNUSED(event))
 
174
{
 
175
    wxString page=GetHelpPage();
 
176
    DisplayHelp(this, page);
 
177
}
 
178
 
 
179
 
 
180
void pgFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 
181
{
 
182
    frmAbout *winAbout = new frmAbout(this);
 
183
    winAbout->Show(TRUE);
 
184
}
 
185
 
 
186
 
 
187
void pgFrame::OnBugreport(wxCommandEvent& event)
 
188
{
 
189
    DisplayHelp(this, wxT("bugreport"));
 
190
}
 
191
 
 
192
 
 
193
void pgFrame::OnRecent(wxCommandEvent& event)
 
194
{
 
195
    int fileNo=event.GetId() - MNU_RECENT;
 
196
    lastPath = settings->Read(recentKey + wxString::Format(wxT("/%d"), fileNo), wxT(""));
 
197
 
 
198
    if (!lastPath.IsNull())
 
199
    {
 
200
        int dirsep;
 
201
        dirsep = lastPath.Find(wxFILE_SEP_PATH, true);
 
202
        lastDir = lastPath.Mid(0, dirsep);
 
203
        lastFilename = lastPath.Mid(dirsep+1);
 
204
        OpenLastFile();
 
205
    }
 
206
}
 
207
 
 
208
 
 
209
 
 
210
void pgFrame::UpdateRecentFiles()
 
211
{
 
212
    if (!recentFileMenu)
 
213
        return;
 
214
 
 
215
    if (recentKey.IsEmpty())
 
216
        recentKey = dlgName + wxT("/RecentFiles");
 
217
 
 
218
    wxString lastFiles[10]; // 0 will be unused for convenience
 
219
    int i, maxFiles=9;
 
220
    int recentIndex=maxFiles;
 
221
 
 
222
    for (i=1 ; i <= maxFiles ; i++)
 
223
    {
 
224
        lastFiles[i] = settings->Read(recentKey + wxString::Format(wxT("/%d"), i), wxT(""));
 
225
        if (!lastPath.IsNull() && lastPath.IsSameAs(lastFiles[i], wxARE_FILENAMES_CASE_SENSITIVE))
 
226
            recentIndex=i;
 
227
    }
 
228
    while (i <= maxFiles)
 
229
        lastFiles[i++] = wxT("");
 
230
 
 
231
    if (recentIndex > 1 && !lastPath.IsNull())
 
232
    {
 
233
        for (i=recentIndex ; i > 1 ; i--)
 
234
            lastFiles[i] = lastFiles[i-1];
 
235
        lastFiles[1] = lastPath;
 
236
    }
 
237
 
 
238
    i=recentFileMenu->GetMenuItemCount();
 
239
    while (i)
 
240
    {
 
241
        wxMenuItem *item = recentFileMenu->Remove(MNU_RECENT+i);
 
242
        if (item)
 
243
            delete item;
 
244
        i--;
 
245
    }
 
246
 
 
247
    for (i=1 ; i <= maxFiles ; i++)
 
248
    {
 
249
        settings->Write(recentKey + wxString::Format(wxT("/%d"), i), lastFiles[i]);
 
250
 
 
251
        if (!lastFiles[i].IsNull())
 
252
            recentFileMenu->Append(MNU_RECENT+i, wxT("&") + wxString::Format(wxT("%d"), i) + wxT("  ") + lastFiles[i]);
 
253
    }
 
254
}
 
255
 
 
256
 
 
257
void pgFrame::RestorePosition(int defaultX, int defaultY, int defaultW, int defaultH, int minW, int minH)
 
258
{
 
259
    wxPoint pos(settings->Read(dlgName, wxPoint(defaultX, defaultY)));
 
260
    wxSize size;
 
261
    if (defaultW < 0)
 
262
        size = GetSize();
 
263
    else
 
264
        size = settings->Read(dlgName, wxSize(defaultW, defaultH));
 
265
 
 
266
    bool posDefault = (pos.x == -1 && pos.y == -1);
 
267
 
 
268
    CheckOnScreen(pos, size, minW, minH);
 
269
    SetSize(pos.x, pos.y, size.x, size.y);
 
270
    if (posDefault)
 
271
        CenterOnParent();
 
272
}
 
273
 
 
274
 
 
275
void pgFrame::SavePosition()
 
276
{
 
277
        settings->Write(dlgName, GetSize(), GetPosition());
 
278
}
 
279
 
 
280
 
 
281
 
 
282
//////////////////////////////////////////////////////
 
283
 
 
284
BEGIN_EVENT_TABLE(DialogWithHelp, pgDialog)
 
285
    EVT_MENU(MNU_HELP,                  DialogWithHelp::OnHelp)
 
286
    EVT_BUTTON(wxID_HELP,               DialogWithHelp::OnHelp)
 
287
END_EVENT_TABLE();
 
288
 
 
289
 
 
290
DialogWithHelp::DialogWithHelp(frmMain *frame) : pgDialog()
 
291
{
 
292
    mainForm = frame;
 
293
 
 
294
    wxAcceleratorEntry entries[2];
 
295
    entries[0].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP);
 
296
// this is for GTK because Meta (usually Numlock) is interpreted like Alt
 
297
// there are too many controls to reset m_Meta in all of them
 
298
    entries[1].Set(wxACCEL_ALT, WXK_F1, MNU_HELP);
 
299
    wxAcceleratorTable accel(2, entries);
 
300
 
 
301
    SetAcceleratorTable(accel);
 
302
}
 
303
 
 
304
 
 
305
void DialogWithHelp::OnHelp(wxCommandEvent& ev)
 
306
{
 
307
    wxString page=GetHelpPage();
 
308
 
 
309
    if (!page.IsEmpty())
 
310
        DisplaySqlHelp(this, page);
 
311
}
 
312
 
 
313
 
 
314
 
 
315
////////////////////////////////////////////////////////////////77
 
316
 
 
317
 
 
318
BEGIN_EVENT_TABLE(ExecutionDialog, DialogWithHelp)
 
319
    EVT_BUTTON (wxID_OK,                ExecutionDialog::OnOK)
 
320
    EVT_BUTTON (wxID_CANCEL,            ExecutionDialog::OnCancel)
 
321
    EVT_CLOSE(                          ExecutionDialog::OnClose)
 
322
END_EVENT_TABLE()
 
323
 
 
324
 
 
325
ExecutionDialog::ExecutionDialog(frmMain *frame, pgObject *_object) : DialogWithHelp(frame)
 
326
{
 
327
    thread=0;
 
328
    object = _object;
 
329
    txtMessages = 0;
 
330
}
 
331
 
 
332
 
 
333
void ExecutionDialog::OnClose(wxCloseEvent& event)
 
334
{
 
335
    Abort();
 
336
    if (IsModal())
 
337
        EndModal(-1);
 
338
    else
 
339
        Destroy();
 
340
}
 
341
 
 
342
 
 
343
void ExecutionDialog::OnCancel(wxCommandEvent& ev)
 
344
{
 
345
    if (thread)
 
346
    {
 
347
        btnCancel->Disable();
 
348
        Abort();
 
349
        btnCancel->Enable();
 
350
        btnOK->Enable();
 
351
        wxButton *btn=btnApply;
 
352
        if (btn)
 
353
            btn->Enable();
 
354
    }
 
355
    else
 
356
    {
 
357
        if (IsModal())
 
358
            EndModal(-1);
 
359
        else
 
360
            Destroy();
 
361
    }
 
362
}
 
363
 
 
364
 
 
365
void ExecutionDialog::Abort()
 
366
{
 
367
    if (thread)
 
368
    {
 
369
        if (thread->IsRunning())
 
370
            thread->Delete();
 
371
        delete thread;
 
372
        thread=0;
 
373
    }
 
374
}
 
375
 
 
376
 
 
377
void ExecutionDialog::OnOK(wxCommandEvent& ev)
 
378
{
 
379
    if (!thread)
 
380
    {
 
381
        wxString sql=GetSql();
 
382
        if (sql.IsEmpty())
 
383
            return;
 
384
 
 
385
        btnOK->Disable();
 
386
 
 
387
        thread=new pgQueryThread(object->GetConnection(), sql);
 
388
        if (thread->Create() != wxTHREAD_NO_ERROR)
 
389
        {
 
390
            Abort();
 
391
            return;
 
392
        }
 
393
 
 
394
        wxLongLong startTime=wxGetLocalTimeMillis();
 
395
        thread->Run();
 
396
        wxNotebook *nb=CTRL_NOTEBOOK("nbNotebook");
 
397
        if (nb)
 
398
            nb->SetSelection(nb->GetPageCount()-1);
 
399
 
 
400
        while (thread && thread->IsRunning())
 
401
        {
 
402
            wxMilliSleep(10);
 
403
            // here could be the animation
 
404
            if (txtMessages)
 
405
                txtMessages->AppendText(thread->GetMessagesAndClear());
 
406
            wxYield();
 
407
        }
 
408
 
 
409
        if (thread)
 
410
        {
 
411
            bool isOk = (thread->ReturnCode() == PGRES_COMMAND_OK || thread->ReturnCode() == PGRES_TUPLES_OK);
 
412
 
 
413
            if (txtMessages)
 
414
                txtMessages->AppendText(thread->GetMessagesAndClear());
 
415
 
 
416
            if (thread->DataSet() != NULL)
 
417
                wxLogDebug(wxString::Format(_("%d rows."), thread->DataSet()->NumRows()));
 
418
 
 
419
            if (isOk)
 
420
            {
 
421
                if (txtMessages)
 
422
                    txtMessages->AppendText(_("Total query runtime: ") 
 
423
                        + (wxGetLocalTimeMillis()-startTime).ToString() + wxT(" ms."));
 
424
 
 
425
                btnOK->SetLabel(_("Done"));
 
426
                btnCancel->Disable();
 
427
            }
 
428
            else
 
429
            {
 
430
                if (txtMessages)
 
431
                    txtMessages->AppendText(object->GetConnection()->GetLastError());
 
432
                Abort();
 
433
            }
 
434
        }
 
435
        else
 
436
            if (txtMessages)
 
437
                txtMessages->AppendText(_("\nCancelled.\n"));
 
438
 
 
439
        btnOK->Enable();
 
440
        wxButton *btn=btnApply;
 
441
        if (btn)
 
442
            btn->Enable();
 
443
    }
 
444
    else
 
445
    {
 
446
        Abort();
 
447
        Destroy();
 
448
    }
 
449
}
 
450
 
 
451
 
 
452
 
 
453
#define TIMER_ID 4442
 
454
 
 
455
BEGIN_EVENT_TABLE(ExternProcessDialog, DialogWithHelp)
 
456
    EVT_BUTTON(wxID_OK,                     ExternProcessDialog::OnOK)
 
457
    EVT_BUTTON(wxID_CANCEL,                 ExternProcessDialog::OnCancel)
 
458
    EVT_CLOSE(                              ExternProcessDialog::OnClose)
 
459
    EVT_END_PROCESS(-1,                     ExternProcessDialog::OnEndProcess)
 
460
    EVT_TIMER(TIMER_ID,                     ExternProcessDialog::OnPollProcess)
 
461
END_EVENT_TABLE()
 
462
 
 
463
 
 
464
 
 
465
ExternProcessDialog::ExternProcessDialog(frmMain *frame) : DialogWithHelp(frame)
 
466
{
 
467
    txtMessages = 0;
 
468
    process = 0;
 
469
    done = false;
 
470
 
 
471
    timer=new wxTimer(this, TIMER_ID);
 
472
}
 
473
 
 
474
 
 
475
 
 
476
ExternProcessDialog::~ExternProcessDialog()
 
477
{
 
478
    Abort();
 
479
    delete timer;
 
480
}
 
481
 
 
482
 
 
483
void ExternProcessDialog::OnOK(wxCommandEvent& ev)
 
484
{
 
485
    if (!done)
 
486
        Execute(0);
 
487
    else
 
488
    {
 
489
        Abort();
 
490
        pgDialog::OnCancel(ev);
 
491
    }
 
492
}
 
493
 
 
494
 
 
495
bool ExternProcessDialog::Execute(int step, bool finalStep)
 
496
{
 
497
    btnOK->Disable();
 
498
    final=finalStep;
 
499
 
 
500
    if (txtMessages)
 
501
        txtMessages->AppendText(GetDisplayCmd(step) + END_OF_LINE);
 
502
 
 
503
    if (process)
 
504
        delete process;
 
505
 
 
506
    process = new wxProcess(this);
 
507
    size_t i;
 
508
    for (i=0 ; i < environment.GetCount() ; i++)
 
509
    {
 
510
        wxString str=environment.Item(i);
 
511
        wxSetEnv(str.BeforeFirst('='), str.AfterFirst('='));
 
512
    }
 
513
    process->Redirect();
 
514
    pid = wxExecute(GetCmd(step), wxEXEC_ASYNC, process);
 
515
    if (pid)
 
516
    {
 
517
        wxNotebook *nb=CTRL_NOTEBOOK("nbNotebook");
 
518
        if (nb)
 
519
            nb->SetSelection(nb->GetPageCount()-1);
 
520
        if (txtMessages)
 
521
        {
 
522
            checkStreams();
 
523
            timer->Start(100L);
 
524
        }
 
525
        return true;
 
526
    }
 
527
    else
 
528
    {
 
529
        delete process;
 
530
        return false;
 
531
    }
 
532
}
 
533
 
 
534
 
 
535
void ExternProcessDialog::OnCancel(wxCommandEvent &ev)
 
536
{
 
537
    if (process)
 
538
    {
 
539
        btnCancel->Disable();
 
540
        Abort();
 
541
    }
 
542
    else
 
543
        pgDialog::OnCancel(ev);
 
544
}
 
545
 
 
546
 
 
547
void ExternProcessDialog::OnClose(wxCloseEvent &ev)
 
548
{
 
549
    btnCancel->Disable();
 
550
    Abort();
 
551
    pgDialog::OnClose(ev);
 
552
}
 
553
 
 
554
 
 
555
void ExternProcessDialog::OnPollProcess(wxTimerEvent& event)
 
556
{
 
557
    checkStreams();
 
558
}
 
559
 
 
560
 
 
561
void ExternProcessDialog::checkStreams()
 
562
{
 
563
    if (txtMessages && process)
 
564
    {
 
565
        if (process->IsErrorAvailable())
 
566
            readStream(process->GetErrorStream());
 
567
        if (process->IsInputAvailable())
 
568
            readStream(process->GetInputStream());
 
569
    }
 
570
}
 
571
 
 
572
 
 
573
void ExternProcessDialog::readStream(wxInputStream *input)
 
574
{
 
575
    if (input)
 
576
    {
 
577
        char buffer[1000+1];
 
578
        size_t size=1;
 
579
        while (size && !input->Eof())
 
580
        {
 
581
            input->Read(buffer, sizeof(buffer)-1);
 
582
            size=input->LastRead();
 
583
            if (size)
 
584
            {
 
585
                buffer[size]=0;
 
586
                txtMessages->AppendText(wxString::FromAscii(buffer));
 
587
            }
 
588
        }
 
589
    }
 
590
}
 
591
 
 
592
 
 
593
void ExternProcessDialog::OnEndProcess(wxProcessEvent &ev)
 
594
{
 
595
    if (process)
 
596
    {
 
597
        if (final)
 
598
            btnOK->SetLabel(_("Done"));
 
599
        done=true;
 
600
    }
 
601
    timer->Stop();
 
602
 
 
603
    if (txtMessages)
 
604
    {
 
605
        checkStreams();
 
606
        txtMessages->AppendText(END_OF_LINE
 
607
                              + wxString::Format(_("Process returned exit code %d."), ev.GetExitCode())
 
608
                              + END_OF_LINE);
 
609
    }
 
610
 
 
611
    if (process)
 
612
    {
 
613
        wxKill(ev.GetPid(), wxSIGTERM);
 
614
        delete process;
 
615
        process=0;
 
616
        pid=0;
 
617
    }
 
618
    btnOK->Enable();
 
619
    btnCancel->Enable();
 
620
}
 
621
 
 
622
 
 
623
void ExternProcessDialog::Abort()
 
624
{
 
625
    timer->Stop();
 
626
    if (process)
 
627
    {
 
628
        done=false;
 
629
        wxProcess *tmpProcess=process;
 
630
        process=0;
 
631
        wxKill(pid, wxSIGTERM);
 
632
        pid=0;
 
633
        delete tmpProcess;
 
634
    }
 
635
}