Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for calling different diff tools. #10

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 161 additions & 7 deletions source/OpenFilesDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,16 @@

#include "OpenFilesDialog.h"

#include <cstdio>

#include <Alert.h>
#include <Button.h>
#include <File.h>
#include <FindDirectory.h>
#include <MenuItem.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <Roster.h>
#include <String.h>
#include <TextControl.h>

Expand All @@ -53,6 +61,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";
static const char* const kPonpokoDiffSettings = "PonpokoDiff_settings";

/**
* @brief コンストラクタ
* @param[in] topLeft ダイアログの左上位置
Expand All @@ -62,7 +76,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++)
Expand All @@ -76,6 +91,8 @@ OpenFilesDialog::OpenFilesDialog(BPoint topLeft)
*/
OpenFilesDialog::~OpenFilesDialog()
{
writeSettings();

int index;
for (index = 0; index < FileMAX; index++)
{
Expand Down Expand Up @@ -120,7 +137,16 @@ 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);

readSettings();

Show();
}

Expand Down Expand Up @@ -286,11 +312,139 @@ void OpenFilesDialog::doDiffThem()
return;
}
BPath rightPath(text);

PonpokoDiffApp* app = static_cast<PonpokoDiffApp*>(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<PonpokoDiffApp*>(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 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.
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* 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);

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;
}


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;
}

/**
Expand Down
18 changes: 17 additions & 1 deletion source/OpenFilesDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include <Window.h>
#include <FilePanel.h>
#include <MenuField.h>

/**
* @brief 比較するファイルを選択するダイアログ
Expand All @@ -59,14 +60,29 @@ class OpenFilesDialog : public BWindow

FileMAX /// ファイル最大数
};

enum DiffTool
{
dtInternal = 0,
dtPe,
dtMcDiff,
dtKdiff3,
dtVimDiff
};

private:
void doBrowseFile(OpenFilesDialog::FileIndex fileIndex);
void doFileSelected(OpenFilesDialog::FileIndex fileIndex, BMessage* message);
void doDiffThem();

void populateDiffToolMenu();
int getSelectedDiffTool();
void setSelectedDiffTool(int diffTool);
void readSettings();
status_t writeSettings();

private:
BFilePanel* filePanels[FileMAX]; ///< ファイルを選択するためのファイルパネル
BMenuField* fDiffToolMenuField;
};

#endif // OPENFILESDIALOG_H__INCLUDED