COOPY » Guide
version 0.6.5
|
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