COOPY » Guide  version 0.6.5
/home/paulfitz/cvs/coopy_scm/coopy/src/gui/src/ssmerge_gui.cpp
Go to the documentation of this file.
00001 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
00002 
00003 /*
00004  * Copyright (C) 2010 Paul Fitzpatrick
00005  * CopyPolicy: Released under the terms of the GNU GPL v2.0.
00006  *
00007  */
00008 
00009 #include <coopy/CsvFile.h>
00010 #include <coopy/BookCompare.h>
00011 //#include <coopy/MergeOutputAccum.h>
00012 #include <coopy/Options.h>
00013 #include <coopy/Diff.h>
00014 #include <coopy/PolyBook.h>
00015 
00016 using namespace coopy::store;
00017 using namespace coopy::cmp;
00018 using namespace coopy::app;
00019 
00020 // wxwidgets library version issue
00021 #ifdef __APPLE__
00022 #ifdef NDEBUG
00023 #undef NDEBUG
00024 #endif
00025 #endif
00026 
00027 #include <wx/wx.h>
00028 #include <wx/wxprec.h>
00029 #include <wx/dcbuffer.h>
00030 #include <wx/image.h>
00031 #include <wx/cmdline.h>
00032 #include <wx/dirdlg.h>
00033 #include <wx/textdlg.h>
00034 #include <wx/filefn.h>
00035 #include <wx/filename.h>
00036 #include <wx/textctrl.h>
00037 #include <wx/url.h>
00038 #include <wx/filepicker.h>
00039 #include <wx/process.h>
00040 #include <wx/stdpaths.h>
00041 #include <wx/txtstrm.h>
00042 #include <wx/arrstr.h>
00043 #include <wx/dir.h>
00044 #include <wx/config.h>
00045 #include <wx/log.h>
00046 
00047 #include <string>
00048 #include <list>
00049 #include <iostream>
00050 
00051 // hack to remove warning
00052 #define static const
00053 #include "icon/appicon.xpm"
00054 #undef static
00055 
00056 using namespace std;
00057 
00058 static wxString conv_c(const char *s) {
00059     return wxString(s, wxConvUTF8);
00060 }
00061 
00062 static wxString conv(const std::string& s) {
00063     return wxString(s.c_str(), wxConvUTF8);
00064 }
00065 
00066 static std::string conv(const wxString& s) {
00067     return std::string(s.mb_str(wxConvUTF8));
00068 } 
00069 
00070 static void show(const wxString& view) {
00071 #ifndef WIN32
00072     wxString view2 = wxT("file://") + view;
00073     ::wxLaunchDefaultBrowser(view2);
00074 #else
00075     ::wxLaunchDefaultBrowser(view);
00076 #endif
00077 }
00078 
00079 static void show(const std::string& view) {
00080     wxString x = conv(view);
00081     show(x);
00082 }
00083 
00084 
00085 class MergeApp: public wxApp {
00086 private:
00087     bool silent;
00088 public:
00089     MergeApp() {
00090         silent = false;
00091     }
00092 
00093     virtual bool OnInit();
00094 
00095     virtual void OnInitCmdLine(wxCmdLineParser& parser);
00096     virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
00097 };
00098 
00099 static const wxCmdLineEntryDesc g_cmdLineDesc [] = {
00100     { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("displays help on the command line parameters"),
00101       wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
00102     { wxCMD_LINE_SWITCH, wxT("s"), wxT("silent"), wxT("disables the GUI") },
00103     { wxCMD_LINE_OPTION, wxT("r"), wxT("res"), wxT("set resource location"),
00104       wxCMD_LINE_VAL_STRING, 0  },
00105     //{ wxCMD_LINE_PARAM, NULL, NULL, wxT("input file"), wxCMD_LINE_VAL_STRING,
00106     //wxCMD_LINE_PARAM_OPTIONAL },
00107     { wxCMD_LINE_NONE },
00108 };
00109 
00110 
00111 void MergeApp::OnInitCmdLine(wxCmdLineParser& parser) {
00112     parser.SetDesc (g_cmdLineDesc);
00113     // must refuse '/' as parameter starter or cannot use "/path" style paths
00114     parser.SetSwitchChars (wxT("--"));
00115 }
00116  
00117 bool MergeApp::OnCmdLineParsed(wxCmdLineParser& parser) {
00118     silent = parser.Found(wxT("s"));
00119 
00120     wxString location;
00121     if (parser.Found(wxT("r"),&location)) {
00122         string loc = conv(location);
00123         printf("*** should set location to [%s]\n", loc.c_str());
00124     }
00125     
00126     // to get at your unnamed parameters use
00127     wxArrayString files;
00128     for (size_t i = 0; i < parser.GetParamCount(); i++) {
00129         files.Add(parser.GetParam(i));
00130     }
00131 
00132     // and other command line parameters
00133 
00134     // then do what you need with them.
00135     
00136     return true;
00137 }
00138 
00139 #ifdef WIN32
00140 IMPLEMENT_APP_NO_MAIN(MergeApp);
00141 #else
00142 IMPLEMENT_APP(MergeApp);
00143 #endif
00144 
00145 
00146 class MergeFrame: public wxFrame
00147 {
00148     DECLARE_CLASS(MergeFrame)
00149     DECLARE_EVENT_TABLE()
00150 
00151 private:
00152     wxBoxSizer *topsizer;
00153     wxFilePickerCtrl *files[4];
00154 
00155     wxString config_tags[4];
00156 
00157 public:
00158 
00159     MergeFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
00160 
00161     virtual bool OnInit();
00162 
00163     void OnQuit(wxCommandEvent& event);
00164     void OnAbout(wxCommandEvent& event);
00165 
00166     void OnSaveJob(wxCommandEvent& event);
00167     void OnLoadJob(wxCommandEvent& event);
00168 
00169     void OnExit(wxCloseEvent& event) {
00170         Destroy();
00171         printf("Exiting ssmerge\n");
00172     }
00173   
00174     void OnMerge(wxCommandEvent& event);
00175 
00176     enum
00177     {
00178         TEXT_Main = wxID_HIGHEST + 1,
00179         TEXT_Parent,
00180         TEXT_Local,
00181         TEXT_Remote,
00182         TEXT_Output,
00183         TEXT_MORE1,
00184         TEXT_MORE2,
00185         TEXT_MORE3,
00186         ID_Quit,
00187         ID_Merge,
00188         ID_About,
00189         ID_SaveJob,
00190         ID_LoadJob,
00191     };
00192 };
00193 
00194 
00195 bool MergeApp::OnInit()
00196 {
00197     MergeFrame *frame = new MergeFrame( _T("ssmerge"), wxPoint(50,50), wxSize(450,340) );
00198 
00199     if (!wxApp::OnInit()) {
00200         return false;
00201     }
00202 
00203 
00204     SetVendorName(wxT("DataCommonsCoop"));
00205     SetAppName(wxT("ssmerge_gui"));
00206 
00207     wxConfigBase *pConfig = wxConfigBase::Get();
00208 
00209     // uncomment this to force writing back of the defaults for all values
00210     // if they're not present in the config - this can give the user an idea
00211     // of all possible settings for this program
00212     pConfig->SetRecordDefaults();
00213 
00214     if (!silent) {
00215         if (!frame->OnInit()) {
00216             return false;
00217         }
00218         frame->Show(TRUE);
00219         SetTopWindow(frame);
00220         return TRUE;
00221     } else {
00222         return false;
00223     }
00224 };
00225 
00226 
00227 
00228 IMPLEMENT_CLASS(MergeFrame, wxFrame)
00229 
00230 BEGIN_EVENT_TABLE(MergeFrame, wxFrame)
00231     EVT_MENU(ID_Quit, MergeFrame::OnQuit)
00232     EVT_MENU(ID_About, MergeFrame::OnAbout)
00233     EVT_MENU(ID_SaveJob, MergeFrame::OnSaveJob)
00234     EVT_MENU(ID_LoadJob, MergeFrame::OnLoadJob)
00235     EVT_BUTTON(ID_Merge, MergeFrame::OnMerge)
00236     EVT_BUTTON(ID_Quit, MergeFrame::OnQuit)
00237     EVT_CLOSE(MergeFrame::OnExit)
00238 END_EVENT_TABLE()
00239 
00240 
00241 bool MergeFrame::OnInit() {
00242 
00243     SetIcon(wxIcon((char**)appicon_xpm));
00244 
00245     topsizer = new wxBoxSizer( wxVERTICAL );
00246 
00247     wxBoxSizer *dir_bar = new wxBoxSizer( wxHORIZONTAL );
00248 
00249     wxSizerFlags lflags = 
00250         wxSizerFlags(0).Align(wxALIGN_LEFT).Border(wxALL, 10);
00251 
00252     dir_bar->Add(new wxButton( this, ID_Merge, _T("&Merge") ),
00253                     lflags);
00254 
00255     dir_bar->Add(new wxButton( this, ID_Quit, _T("E&xit") ),
00256                  lflags);    
00257     const char *tips[4] = { 
00258         "Select a common ancestor",
00259         "Select local version",
00260         "Select remote version",
00261         "Select output"
00262     };
00263     const char *labels[4] = {
00264         "Ancestor",
00265         "Local version",
00266         "Remote version",
00267         "Output"
00268     };
00269     const char *tags[4] = {
00270         "Ancestor",
00271         "LocalVersion",
00272         "RemoteVersion",
00273         "Output"
00274     };
00275         
00276     wxConfigBase *pConfig = wxConfigBase::Get();
00277     for (int i=0; i<4; i++) {
00278         wxBoxSizer *fbar = new wxBoxSizer( wxHORIZONTAL );
00279         config_tags[i] = conv_c(tags[i]);
00280         //printf("--> %s %s\n", conv(config_tags[i]).c_str(), tags[i]);
00281         wxString path = pConfig->Read(config_tags[i],wxT(""));
00282         //printf("  %s\n", conv(path).c_str());
00283         files[i] = new wxFilePickerCtrl(this,TEXT_Parent+i, 
00284                                         path,
00285                                         conv_c(tips[i]),
00286                                         wxT("*.*"),
00287                                         wxDefaultPosition,
00288                                         wxSize(400,-1),
00289                                         (i==3)?(wxFLP_USE_TEXTCTRL|wxFLP_SAVE|wxFLP_OVERWRITE_PROMPT):(wxFLP_DEFAULT_STYLE|wxFLP_CHANGE_DIR));
00290         files[i]->SetPath(path);
00291         if (files[i]->GetTextCtrl()) {
00292             files[i]->GetTextCtrl()->SetValue(path);
00293         }
00294         fbar->Add(new wxStaticText(this,-1,conv_c(labels[i]),
00295                                    wxDefaultPosition,
00296                                    wxSize(150,-1)),lflags);
00297         fbar->Add(files[i],1,wxGROW|wxALIGN_CENTER_VERTICAL|wxALL);
00298         fbar->SetItemMinSize(files[i],400,50);
00299         topsizer->Add(fbar,1,wxGROW|wxALIGN_CENTER_VERTICAL|wxALL);
00300     }
00301 
00302     topsizer->Add(dir_bar,wxSizerFlags(0).Align(wxALIGN_RIGHT));
00303 
00304     SetSizer(topsizer);
00305     topsizer->SetSizeHints(this);
00306 
00307     return true;
00308 }
00309 
00310 
00311 void MergeFrame::OnMerge(wxCommandEvent& event) {
00312     //printf("Merging...\n");
00313     wxString parent = files[0]->GetPath();
00314     wxString local = files[1]->GetPath();
00315     wxString remote = files[2]->GetPath();
00316     wxString output = files[3]->GetPath();
00317     wxConfigBase *pConfig = wxConfigBase::Get();
00318     //printf("CONFIG %ld\n", (long)pConfig);
00319     for (int i=0; i<4; i++) {
00320         wxString key = config_tags[i];
00321         wxString val = files[i]->GetPath();
00322         //printf("i is %d :  %s -> %s\n", i, conv(key).c_str(), conv(val).c_str());
00323         pConfig->Write(key,val);
00324     }
00325     pConfig->Flush();
00326     Options opt("ssmerge");
00327     vector<string>& core = opt.core;
00328     core.push_back(conv(parent));
00329     core.push_back(conv(local));
00330     core.push_back(conv(remote));
00331     opt.option_string["output"] = conv(output);
00332 
00333     Diff app;
00334     int result = app.apply(opt);
00335 
00336     if (result==0) {
00337         wxMessageDialog msg(NULL, wxT("Merged. View result?"),
00338                             wxT("Merged."),wxYES_NO|wxCANCEL);
00339         if (msg.ShowModal()==wxID_YES) {
00340             show(output);
00341         }
00342     } else {
00343         wxMessageDialog msg(NULL, wxT("That did not work out."),
00344                             wxT("Sorry!"));
00345         msg.ShowModal();
00346     }
00347 
00348     /*
00349     printf("Parent %s\n", conv(parent).c_str());
00350     printf("Local %s\n", conv(local).c_str());
00351     printf("Remote %s\n", conv(remote).c_str());
00352     PolyBook parent_sheet, local_sheet, remote_sheet;
00353     parent_sheet.read(conv(parent).c_str());
00354     local_sheet.read(conv(local).c_str());
00355     remote_sheet.read(conv(remote).c_str());
00356     CompareFlags flags;
00357 
00358 
00359     BookCompare cmp;
00360     MergeOutputAccum accum;
00361     cmp.compare(parent_sheet,local_sheet,remote_sheet,accum,flags);
00362     const DataSheet& result = accum.getSheet();
00363     printf("Result of dimensions %dx%d\n", result.width(), result.height());
00364 
00365     if (result.width()==0||result.height()==0) {
00366         wxMessageDialog msg(NULL, wxT("No merge took place.\nAre all files present and readable?"),
00367                             wxT("Sorry, no merge"));
00368         msg.ShowModal();
00369         return;
00370     }
00371 
00372         wxFileDialog *SaveDialog = new wxFileDialog(this, _("Save Merged Result As _?"), wxEmptyString, wxEmptyString,
00373                 _("*.*"),
00374                                                 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00375  
00376         if (SaveDialog->ShowModal() == wxID_OK) {
00377                 SetTitle(wxString(wxT("Merge - ")) << SaveDialog->GetFilename());
00378         } else {
00379         return;
00380     }
00381 
00382     if (CsvFile::write(result,conv(SaveDialog->GetPath()).c_str())!=0) {
00383         wxMessageDialog msg(NULL, wxT("Could not save file."),
00384                             wxT("Sorry, no save"));
00385         msg.ShowModal();
00386         return;
00387     }
00388     */
00389 }
00390 
00391 
00392 MergeFrame::MergeFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
00393     : wxFrame((wxFrame *)NULL, -1, title, pos, size)
00394 {
00395 
00396     wxMenu *menuFile = new wxMenu;
00397 
00398     //menuFile->Append( ID_LoadJob, _T("&Load Job...") );
00399     //menuFile->Append( ID_SaveJob, _T("&Save Job...") );
00400     menuFile->Append( ID_About, _T("&About...") );
00401     menuFile->AppendSeparator();
00402     menuFile->Append( ID_Quit, _T("D&one") );
00403 
00404     wxMenuBar *menuBar = new wxMenuBar;
00405     menuBar->Append( menuFile, _T("&File") );
00406 
00407     SetMenuBar( menuBar );
00408 
00409     CreateStatusBar();
00410     SetStatusText( _T("Welcome to ssmerge!") );
00411 }
00412 
00413 void MergeFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
00414 {
00415     printf("Quit!\n");
00416     //wxCloseEvent ev;
00417     //wxPostEvent(this,ev);
00418     // Close(TRUE);
00419     Show(false);
00420 }
00421 
00422 void MergeFrame::OnLoadJob(wxCommandEvent& WXUNUSED(event)) 
00423 {
00424     //wxFileInputStream stream("config.ini");
00425     //wxFileConfig config(stream);
00426     //wxString a = config.Read("a", "");
00427 }
00428 
00429 void MergeFrame::OnSaveJob(wxCommandEvent& WXUNUSED(event)) 
00430 {
00431     //wxFileOutputStream stream("config.ini");
00432     //wxFileConfig
00433 }
00434 
00435 void MergeFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
00436 {
00437     wxMessageBox(_T("Welcome to ssmerge!\n\
00438 Now go back to work."),
00439                  _T("About ssmerge"), wxOK | wxICON_INFORMATION, this);
00440 }
00441 
00442 
00443 #ifdef _WIN32
00444 
00445 FILE *FOUT = NULL;
00446 
00447 int WINAPI WinMain(HINSTANCE hInstance,
00448                    HINSTANCE hPrevInstance,
00449                    LPSTR m_lpCmdLine, int nCmdShow) {
00450 
00451     //g_hinstance = (int)(hInstance);    
00452     return wxEntry(hInstance,hPrevInstance,m_lpCmdLine,nCmdShow);
00453 }
00454 
00455 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines