From e9d495fb34eb2c69a060ce144d3abeb13afff98e Mon Sep 17 00:00:00 2001 From: Oscar Lesta Date: Sun, 25 Dec 2022 22:02:40 -0300 Subject: [PATCH 1/2] Implement support for calling different diff tools. This is a first, rough attempt. Options are: - Internal - Pe "diff mode" (pending Pe's PR #85) - kdiff3 (untested) - vimdiff (untested) Defaults to Internal for now, until saving/restore settings gets implemented. --- source/OpenFilesDialog.cpp | 104 ++++++++++++++++++++++++++++++++++--- source/OpenFilesDialog.h | 14 ++++- 2 files changed, 110 insertions(+), 8 deletions(-) diff --git a/source/OpenFilesDialog.cpp b/source/OpenFilesDialog.cpp index 36d2e54..a39a3b3 100644 --- a/source/OpenFilesDialog.cpp +++ b/source/OpenFilesDialog.cpp @@ -32,8 +32,12 @@ #include "OpenFilesDialog.h" +#include #include +#include #include +#include +#include #include #include @@ -53,6 +57,12 @@ static const char NAME_RIGHT_BROWSE_BUTTON[] = "RightBrowseButton"; static const char NAME_DIFF_THEM_BUTTON[] = "DiffThemButton"; static const char NAME_CANCEL_BUTTON[] = "CancelButton"; +static const uint32 kMsgDiffToolSelected = 'dtsl'; + +static const char* kPeSignature = "application/x-vnd.beunited.pe"; +static const char* kTerminalSignature = "application/x-vnd.Haiku-Terminal"; + + /** * @brief コンストラクタ * @param[in] topLeft ダイアログの左上位置 @@ -62,7 +72,8 @@ OpenFilesDialog::OpenFilesDialog(BPoint topLeft) RT(IDS_TITLE_OPEN_FILES), B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, - B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_MINIMIZABLE) + B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_MINIMIZABLE), + fDiffToolMenuField(NULL) { int index; for (index = 0; index < FileMAX; index++) @@ -120,7 +131,14 @@ void OpenFilesDialog::Initialize() BButton* cancelButton = new BButton(BRect(282, 84, 362, 108), NAME_CANCEL_BUTTON, RT(IDS_LABEL_CANCEL), new BMessage(ID_CANCEL)); baseView->AddChild(cancelButton); - + + BPopUpMenu* menu = new BPopUpMenu("diff tool menu"); + fDiffToolMenuField = new BMenuField( + BRect(12, 84, 212, 108), + "diff tool menu field", "Diff Tool:", menu); + populateDiffToolMenu(); + baseView->AddChild(fDiffToolMenuField); + Show(); } @@ -286,13 +304,85 @@ void OpenFilesDialog::doDiffThem() return; } BPath rightPath(text); - - PonpokoDiffApp* app = static_cast(be_app); - TextDiffWnd* newDiffWnd = app->NewTextDiffWnd(); - newDiffWnd->ExecuteDiff(leftPath, rightPath, NULL, NULL); - PostMessage(B_QUIT_REQUESTED); + + int diffTool = getSelectedDiffTool(); + switch (diffTool) { + case dtInternal: + { + PonpokoDiffApp* app = static_cast(be_app); + TextDiffWnd* newDiffWnd = app->NewTextDiffWnd(); + newDiffWnd->ExecuteDiff(leftPath, rightPath, NULL, NULL); + PostMessage(B_QUIT_REQUESTED); + break; + } + case dtPe: + { + const char* argv[] = {"--diff", leftPath.Path(), rightPath.Path(), NULL}; + be_roster->Launch(kPeSignature, 3, argv); + PostMessage(B_QUIT_REQUESTED); + break; + } + case dtKdiff3: + { + // ToDo: use be_roster->Launch() with an entry_ref to the kdiff3 binary. + BString cmd; + cmd.SetToFormat("kdiff3 %s %s", leftPath.Path(), rightPath.Path()); + system(cmd.String()); + PostMessage(B_QUIT_REQUESTED); + break; + } + case dtVimDiff: + { + const char* argv[] = {"-t", "Differences", "vimdiff", leftPath.Path(), rightPath.Path(), NULL}; + be_roster->Launch(kTerminalSignature, 5, argv); + PostMessage(B_QUIT_REQUESTED); + break; + } + default: + BAlert* alert = new BAlert("PonpokoDiff", "Unkown diff tool option!", "Ok"); + alert->Go(); + } +} + + +void OpenFilesDialog::populateDiffToolMenu() +{ + // ToDo: + // - save/restore the selected menu item to/from a settings file. + // - Either only add external tools if they're installed, or show an error + // when trying to use them if they are not. + + BMenuItem* internalDiffTool = new BMenuItem("Internal", new BMessage(kMsgDiffToolSelected)); + internalDiffTool->SetMarked(true); + fDiffToolMenuField->Menu()->AddItem(internalDiffTool); + + BMenuItem* peDiffTool = new BMenuItem("Pe diff", new BMessage(kMsgDiffToolSelected)); + peDiffTool->SetMarked(false); + fDiffToolMenuField->Menu()->AddItem(peDiffTool); + + BMenuItem* kdiff3DiffTool = new BMenuItem("kdiff3", new BMessage(kMsgDiffToolSelected)); + kdiff3DiffTool->SetMarked(false); + fDiffToolMenuField->Menu()->AddItem(kdiff3DiffTool); + + BMenuItem* vimDiffDiffTool = new BMenuItem("vimdiff", new BMessage(kMsgDiffToolSelected)); + vimDiffDiffTool->SetMarked(false); + fDiffToolMenuField->Menu()->AddItem(vimDiffDiffTool); } + +int OpenFilesDialog::getSelectedDiffTool() +{ + BMenuItem* item = NULL; + int32 count = fDiffToolMenuField->Menu()->CountItems(); + for (int i = 0; i < count; i++) { + item = (BMenuItem*)fDiffToolMenuField->Menu()->ItemAt(i); + if (item->IsMarked()) + return i; + } + return dtInternal; +} + + /** * @brief ウィンドウが閉じるときに呼び出されます。 */ diff --git a/source/OpenFilesDialog.h b/source/OpenFilesDialog.h index 59d9508..4f060a5 100644 --- a/source/OpenFilesDialog.h +++ b/source/OpenFilesDialog.h @@ -35,6 +35,7 @@ #include #include +#include /** * @brief 比較するファイルを選択するダイアログ @@ -59,14 +60,25 @@ class OpenFilesDialog : public BWindow FileMAX /// ファイル最大数 }; + + enum DiffTool + { + dtInternal = 0, + dtPe, + dtKdiff3, + dtVimDiff + }; private: void doBrowseFile(OpenFilesDialog::FileIndex fileIndex); void doFileSelected(OpenFilesDialog::FileIndex fileIndex, BMessage* message); void doDiffThem(); - + void populateDiffToolMenu(); + int getSelectedDiffTool(); + private: BFilePanel* filePanels[FileMAX]; ///< ファイルを選択するためのファイルパネル + BMenuField* fDiffToolMenuField; }; #endif // OPENFILESDIALOG_H__INCLUDED From f28fb78b2c31041b19a00a2ac5b73f43e2b91c68 Mon Sep 17 00:00:00 2001 From: Oscar Lesta Date: Sun, 14 May 2023 15:38:49 -0300 Subject: [PATCH 2/2] Added support for mcdiff, and saving/loading of the last used diff tool. --- source/OpenFilesDialog.cpp | 66 +++++++++++++++++++++++++++++++++++++- source/OpenFilesDialog.h | 4 +++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/source/OpenFilesDialog.cpp b/source/OpenFilesDialog.cpp index a39a3b3..eaaf50a 100644 --- a/source/OpenFilesDialog.cpp +++ b/source/OpenFilesDialog.cpp @@ -32,8 +32,12 @@ #include "OpenFilesDialog.h" +#include + #include #include +#include +#include #include #include #include @@ -61,7 +65,7 @@ static const uint32 kMsgDiffToolSelected = 'dtsl'; static const char* kPeSignature = "application/x-vnd.beunited.pe"; static const char* kTerminalSignature = "application/x-vnd.Haiku-Terminal"; - +static const char* const kPonpokoDiffSettings = "PonpokoDiff_settings"; /** * @brief コンストラクタ @@ -87,6 +91,8 @@ OpenFilesDialog::OpenFilesDialog(BPoint topLeft) */ OpenFilesDialog::~OpenFilesDialog() { + writeSettings(); + int index; for (index = 0; index < FileMAX; index++) { @@ -139,6 +145,8 @@ void OpenFilesDialog::Initialize() populateDiffToolMenu(); baseView->AddChild(fDiffToolMenuField); + readSettings(); + Show(); } @@ -322,6 +330,13 @@ void OpenFilesDialog::doDiffThem() PostMessage(B_QUIT_REQUESTED); break; } + case dtMcDiff: + { + const char* argv[] = {"-t", "Differences", "mcdiff", leftPath.Path(), rightPath.Path(), NULL}; + be_roster->Launch(kTerminalSignature, 5, argv); + PostMessage(B_QUIT_REQUESTED); + break; + } case dtKdiff3: { // ToDo: use be_roster->Launch() with an entry_ref to the kdiff3 binary. @@ -360,6 +375,10 @@ void OpenFilesDialog::populateDiffToolMenu() peDiffTool->SetMarked(false); fDiffToolMenuField->Menu()->AddItem(peDiffTool); + BMenuItem* mcDiffTool = new BMenuItem("mcdiff", new BMessage(kMsgDiffToolSelected)); + mcDiffTool->SetMarked(false); + fDiffToolMenuField->Menu()->AddItem(mcDiffTool); + BMenuItem* kdiff3DiffTool = new BMenuItem("kdiff3", new BMessage(kMsgDiffToolSelected)); kdiff3DiffTool->SetMarked(false); fDiffToolMenuField->Menu()->AddItem(kdiff3DiffTool); @@ -383,6 +402,51 @@ int OpenFilesDialog::getSelectedDiffTool() } +void OpenFilesDialog::setSelectedDiffTool(int diffTool) +{ + BMenuItem* item = (BMenuItem*) fDiffToolMenuField->Menu()->ItemAt(diffTool); + item->SetMarked(true); +} + + +void OpenFilesDialog::readSettings() +{ + int diffTool = 0; + + BPath path; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { + path.Append(kPonpokoDiffSettings); + + BFile file; + if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK) { + char buffer[20]; + file.Read(&buffer, 20); + int i; + if (sscanf(buffer, "diff_tool = %d\n", &i) == 1) + diffTool = i; + } + } + setSelectedDiffTool(diffTool); +} + +status_t OpenFilesDialog::writeSettings() +{ + BPath path; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) + return B_ERROR; + + path.Append(kPonpokoDiffSettings); + + BFile file; + if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) != B_OK) + return B_ERROR; + + BString string; + string.SetToFormat("diff_tool = %d\n", getSelectedDiffTool()); + file.Write(string.String(), strlen(string)); + return B_OK; +} + /** * @brief ウィンドウが閉じるときに呼び出されます。 */ diff --git a/source/OpenFilesDialog.h b/source/OpenFilesDialog.h index 4f060a5..91dfdbd 100644 --- a/source/OpenFilesDialog.h +++ b/source/OpenFilesDialog.h @@ -65,6 +65,7 @@ class OpenFilesDialog : public BWindow { dtInternal = 0, dtPe, + dtMcDiff, dtKdiff3, dtVimDiff }; @@ -75,6 +76,9 @@ class OpenFilesDialog : public BWindow void doDiffThem(); void populateDiffToolMenu(); int getSelectedDiffTool(); + void setSelectedDiffTool(int diffTool); + void readSettings(); + status_t writeSettings(); private: BFilePanel* filePanels[FileMAX]; ///< ファイルを選択するためのファイルパネル