From afc72ae949266e359a79693a67bff390761b06cc Mon Sep 17 00:00:00 2001 From: Vinicius Santos Date: Tue, 14 Aug 2012 12:34:59 -0300 Subject: [PATCH 31/31] Implemeting auto save feature in the SQL Editor. --- pgadmin/frm/frmOptions.cpp | 4 + pgadmin/frm/frmQuery.cpp | 129 +++++++++++++++++++++++++++++++++- pgadmin/include/frm/frmQuery.h | 36 +++++++++- pgadmin/include/utils/sysSettings.h | 10 +++ pgadmin/pgAdmin3.cpp | 1 + pgadmin/ui/frmOptions.xrc | 12 +++ 6 files changed, 184 insertions(+), 8 deletions(-) diff --git a/pgadmin/frm/frmOptions.cpp b/pgadmin/frm/frmOptions.cpp index 1ad00ad..6083c69 100644 --- a/pgadmin/frm/frmOptions.cpp +++ b/pgadmin/frm/frmOptions.cpp @@ -81,6 +81,7 @@ #define chkShowUsersForPrivileges CTRL_CHECKBOX("chkShowUsersForPrivileges") #define txtAutoRowCount CTRL_TEXT("txtAutoRowCount") #define txtIndent CTRL_TEXT("txtIndent") +#define txtAutoSave CTRL_TEXT("txtAutoSave") #define chkSpacesForTabs CTRL_CHECKBOX("chkSpacesForTabs") #define cbCopyQuote CTRL_COMBOBOX("cbCopyQuote") #define cbCopyQuoteChar CTRL_COMBOBOX("cbCopyQuoteChar") @@ -278,6 +279,7 @@ frmOptions::frmOptions(frmMain *parent) txtMaxColSize->SetValidator(numval); txtAutoRowCount->SetValidator(numval); txtIndent->SetValidator(numval); + txtAutoSave->SetValidator(numval); txtHistoryMaxQueries->SetValidator(numval); txtHistoryMaxQuerySize->SetValidator(numval); @@ -290,6 +292,7 @@ frmOptions::frmOptions(frmMain *parent) chkShowUsersForPrivileges->SetValue(settings->GetShowUsersForPrivileges()); txtAutoRowCount->SetValue(NumToStr(settings->GetAutoRowCountThreshold())); txtIndent->SetValue(NumToStr(settings->GetIndentSpaces())); + txtAutoSave->SetValue(NumToStr(settings->GetMinAutoSave())); chkSpacesForTabs->SetValue(settings->GetSpacesForTabs()); cbCopyQuote->SetSelection(settings->GetCopyQuoting()); cbCopyQuoteChar->SetValue(settings->GetCopyQuoteChar()); @@ -654,6 +657,7 @@ void frmOptions::OnOK(wxCommandEvent &ev) settings->SetShowUsersForPrivileges(chkShowUsersForPrivileges->GetValue()); settings->SetAutoRowCountThreshold(StrToLong(txtAutoRowCount->GetValue())); settings->SetIndentSpaces(StrToLong(txtIndent->GetValue())); + settings->SetMinAutoSave(StrToLong(txtAutoSave->GetValue())); settings->SetSpacesForTabs(chkSpacesForTabs->GetValue()); settings->SetCopyQuoting(cbCopyQuote->GetCurrentSelection()); settings->SetCopyQuoteChar(cbCopyQuoteChar->GetValue()); diff --git a/pgadmin/frm/frmQuery.cpp b/pgadmin/frm/frmQuery.cpp index 2626240..06c4ff5 100644 --- a/pgadmin/frm/frmQuery.cpp +++ b/pgadmin/frm/frmQuery.cpp @@ -91,6 +91,7 @@ // a simple flag will suffice. // Required because the pgScript parser isn't currently thread-safe :-( bool frmQuery::ms_pgScriptRunning = false; +wxString frmQuery::openLostFiles; BEGIN_EVENT_TABLE(frmQuery, pgFrame) EVT_ERASE_BACKGROUND( frmQuery::OnEraseBackground) @@ -158,6 +159,7 @@ BEGIN_EVENT_TABLE(frmQuery, pgFrame) EVT_AUI_PANE_CLOSE( frmQuery::OnAuiUpdate) EVT_TIMER(CTL_TIMERSIZES, frmQuery::OnAdjustSizesTimer) EVT_TIMER(CTL_TIMERFRM, frmQuery::OnTimer) + EVT_TIMER(CTL_TIMERAUTOSAVE, frmQuery::OnTimerAutoSave) // These fire when the queries complete EVT_MENU(QUERY_COMPLETE, frmQuery::OnQueryComplete) EVT_MENU(PGSCRIPT_COMPLETE, frmQuery::OnScriptComplete) @@ -210,21 +212,23 @@ private: }; -frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const wxString &query, const wxString &file) +frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const wxString &query, const wxString &file, const wxString &autoSaveQuery) : pgFrame(NULL, _title), timer(this, CTL_TIMERFRM), + timerAutoSave(this, CTL_TIMERAUTOSAVE), pgScript(new pgsApplication(_conn)), pgsStringOutput(&pgsOutputString), pgsOutput(pgsStringOutput, wxEOL_UNIX), pgsTimer(new pgScriptTimer(this)) { pgScript->SetCaller(this, PGSCRIPT_COMPLETE); - + mainForm = form; conn = _conn; loading = true; closing = false; + userAnswer = UNDEFINED; dlgName = wxT("frmQuery"); recentKey = wxT("RecentFiles"); @@ -599,7 +603,70 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); viewMenu->Check(MNU_SHOWLINENUMBER, bVal); - if (!file.IsEmpty() && wxFileName::FileExists(file)) + if (!wxFileName::DirExists(AUTOSAVE_DIR)) + wxFileName::Mkdir(AUTOSAVE_DIR); + + wxDateTime autoSaveDateTime = wxDateTime::Now(); + if (autoSaveQuery == wxEmptyString) + { + autoSaveFileName.SetPath(AUTOSAVE_DIR); + autoSaveFileName.SetFullName(autoSaveDateTime.Format(wxT("%Y-%m-%d %H-%M-%S")) + AUTOSAVE_EXT); + } + else if (file != wxEmptyString) + autoSaveFileName = file; + + wxString f = wxFindFirstFile(AUTOSAVE_DIR + wxT("*") + AUTOSAVE_EXT); + wxString lastOpenFile; + + if (!f.IsEmpty() && autoSaveQuery == wxEmptyString) + { + wxString line, database, user, host; + long port; + bool isOK; + + while (!f.IsEmpty() && f != lastOpenFile && openLostFiles.Find(f) == wxNOT_FOUND) + { + isOK = false; + // Analyzing file-by-file. + wxTextFile lostFile(f); + + lostFile.Open(); + // retrieving the metadatas of file + database = lostFile.GetLine(AUTOSAVE_LINE_DATABASE); + user = lostFile.GetLine(AUTOSAVE_LINE_USER); + host = lostFile.GetLine(AUTOSAVE_LINE_HOST); + lostFile.GetLine(AUTOSAVE_LINE_PORT).ToLong(&port); + + if ((conn->GetDbname() == database) && (conn->GetUser() == user) && (conn->GetHost() == host) && (conn->GetPort() == port)) + { + isOK = true; + + if (userAnswer == UNDEFINED) + { + if (wxMessageBox(wxT("The pgAdmin found one or more files that was lost by some problem. Do you want to retrieve all of them?"), wxT("Warning"), wxYES_NO | wxICON_QUESTION ) == wxYES) + userAnswer = ANSWER_YES; + else + userAnswer = ANSWER_NO; + } + } + + lostFile.Close(); + + if (userAnswer == ANSWER_YES && isOK) + { + lastOpenFile = f; + openLostFile(f); + openLostFiles += f + wxT(" "); + } + else if (userAnswer == ANSWER_NO && isOK) + removeAutoSaveFile(f); + + f = wxFindNextFile(); + } + + sqlQuery->SetText(query); + } + else if (autoSaveQuery == wxEmptyString && !file.IsEmpty() && wxFileName::FileExists(file)) { wxFileName fn = file; lastFilename = fn.GetFullName(); @@ -608,7 +675,7 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w OpenLastFile(); } else - sqlQuery->SetText(query); + sqlQuery->SetText(autoSaveQuery != wxEmptyString ? autoSaveQuery : query); sqlQuery->Colourise(0, query.Length()); @@ -620,6 +687,10 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w queryMenu->Enable(MNU_CLEARHISTORY, false); setTools(false); lastFileFormat = settings->GetUnicodeFile(); + if (autoSaveQuery == wxEmptyString) + openLostFiles += autoSaveFileName.GetFullPath() + wxT(" "); + // Start the autosave. + timerAutoSave.Start(settings->GetMinAutoSave() * 60000); // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) @@ -684,6 +755,9 @@ frmQuery::~frmQuery() delete pgScript; pgScript = NULL; } + + // Delete autosave file + removeAutoSaveFile(autoSaveFileName.GetFullPath()); if (mainForm) mainForm->RemoveFrame(this); @@ -907,6 +981,35 @@ void frmQuery::Go() loading = false; } +void frmQuery::openLostFile(wxString fileName) +{ + wxString line, query; + int firstLine = AUTOSAVE_LINE_PORT + 1; + wxTextFile lostFile(fileName); + + lostFile.Open(); + + lostFile.GoToLine(firstLine); + for (line = lostFile.GetLine(firstLine); !lostFile.Eof(); line = lostFile.GetNextLine()) + query += line + wxT("\n"); + + frmQuery *fq = new frmQuery(mainForm, wxEmptyString, conn->Duplicate(), wxEmptyString , fileName, query); + if (mainForm) + mainForm->AddFrame(fq); + fq->Go(); + + lostFile.Close(); +} + +void frmQuery::removeAutoSaveFile(wxString fileName) +{ + if (wxFileName::FileExists(fileName)) + wxRemoveFile(fileName); + + if (openLostFiles.Find(fileName) != wxNOT_FOUND) + openLostFiles.erase(openLostFiles.Find(fileName), fileName.Len() + 1); + +} typedef struct __sqltokenhelp { @@ -2797,6 +2900,24 @@ void frmQuery::OnTimer(wxTimerEvent &event) } } + +void frmQuery::OnTimerAutoSave(wxTimerEvent &event) +{ + if (wxFileName::DirExists(AUTOSAVE_DIR)) + { + wxTextFile fileAutoSave(autoSaveFileName.GetFullPath()); + // Saving metadatas. + fileAutoSave.InsertLine(conn->GetDbname(), AUTOSAVE_LINE_DATABASE); + fileAutoSave.InsertLine(conn->GetUser(), AUTOSAVE_LINE_USER); + fileAutoSave.InsertLine(conn->GetHost(), AUTOSAVE_LINE_HOST); + fileAutoSave.InsertLine(wxString() << conn->GetPort(), AUTOSAVE_LINE_PORT); + // saving the query automatically. + fileAutoSave.AddLine(sqlQuery->GetText()); + fileAutoSave.Write(); + fileAutoSave.Close(); + } + +} // Adjust sizes of GQB components, Located here because need to // avoid some issues when implementing inside controller/view Classes void frmQuery::adjustGQBSizes() diff --git a/pgadmin/include/frm/frmQuery.h b/pgadmin/include/frm/frmQuery.h index e9de7f6..93998ff 100644 --- a/pgadmin/include/frm/frmQuery.h +++ b/pgadmin/include/frm/frmQuery.h @@ -36,6 +36,10 @@ // #define FRMQUERY_PERSPECTIVE_VER wxT("8317") +// used in the autosave feature +const wxString AUTOSAVE_DIR = wxT("autosave/"); +const wxString AUTOSAVE_EXT = wxT(".pga"); + #ifdef __WXMAC__ #define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=415;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|") #else @@ -74,7 +78,7 @@ public: class frmQuery : public pgFrame { public: - frmQuery(frmMain *form, const wxString &_title, pgConn *conn, const wxString &qry, const wxString &file = wxEmptyString); + frmQuery(frmMain *form, const wxString &_title, pgConn *conn, const wxString &qry, const wxString &file = wxEmptyString, const wxString &autoSaveQuery = wxEmptyString); ~frmQuery(); void Go(); @@ -106,8 +110,8 @@ public: void UpdateAllRecentFiles(); void UpdateAllFavouritesList(); void UpdateAllMacrosList(); - private: + frmMain *mainForm; wxAuiManager manager; ctlSQLBox *sqlQuery; @@ -126,6 +130,13 @@ private: wxTimer timer; wxLongLong elapsedQuery, startTimeQuery; + //Auto save related + wxTimer timerAutoSave; + wxFileName autoSaveFileName; + void openLostFile(wxString fileName); + void removeAutoSaveFile(wxString fileName); + int userAnswer; + // pgScript interface pgsApplication *pgScript; wxString pgsOutputString; @@ -218,6 +229,7 @@ private: void OnDeleteAll(wxCommandEvent &event); void OnTimer(wxTimerEvent &event); + void OnTimerAutoSave(wxTimerEvent &event); void OpenLastFile(); void updateMenu(wxObject *obj = 0); @@ -262,7 +274,7 @@ private: // A simple mutex-like flag to prevent concurrent script execution. // Required because the pgScript parser isn't currently thread-safe :-( static bool ms_pgScriptRunning; - + static wxString openLostFiles; DECLARE_EVENT_TABLE() }; @@ -291,7 +303,23 @@ enum CTL_SQLQUERYCBOX, CTL_DELETECURRENTBTN, CTL_DELETEALLBTN, - CTL_SCRATCHPAD + CTL_SCRATCHPAD, + CTL_TIMERAUTOSAVE +}; + +enum +{ + AUTOSAVE_LINE_DATABASE, + AUTOSAVE_LINE_USER, + AUTOSAVE_LINE_HOST, + AUTOSAVE_LINE_PORT +}; + +enum +{ + UNDEFINED, + ANSWER_YES, + ANSWER_NO }; /////////////////////////////////////////////////////// diff --git a/pgadmin/include/utils/sysSettings.h b/pgadmin/include/utils/sysSettings.h index 69ecdd4..d8bde35 100644 --- a/pgadmin/include/utils/sysSettings.h +++ b/pgadmin/include/utils/sysSettings.h @@ -339,6 +339,16 @@ public: { WriteLong(wxT("IndentSpaces"), newval); } + long GetMinAutoSave() const + { + long l; + Read(wxT("MinAutoSave"), &l, 10L); + return l; + } + void SetMinAutoSave(const long newval) + { + WriteLong(wxT("MinAutoSave"), newval); + } bool GetIndicateNull() const { bool b; diff --git a/pgadmin/pgAdmin3.cpp b/pgadmin/pgAdmin3.cpp index 2e2cbc5..0cfc345 100644 --- a/pgadmin/pgAdmin3.cpp +++ b/pgadmin/pgAdmin3.cpp @@ -80,6 +80,7 @@ #define PLUGINS_DIR wxT("/plugins.d") #define SETTINGS_INI wxT("/settings.ini") + // Globals frmMain *winMain = 0; wxThread *updateThread = 0; diff --git a/pgadmin/ui/frmOptions.xrc b/pgadmin/ui/frmOptions.xrc index cf136c6..67050a6 100644 --- a/pgadmin/ui/frmOptions.xrc +++ b/pgadmin/ui/frmOptions.xrc @@ -445,6 +445,18 @@ 4 + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + -- 1.7.4.msysgit.0