SparkleShare/SparkleDiff/SparkleDiffWindow.cs
2010-07-04 11:50:27 +01:00

242 lines
7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SparkleShare, an instant update workflow to Git.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using Gtk;
using Mono.Unix;
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace SparkleShare {
// The main window of SparkleDiff
public class SparkleDiffWindow : Window
{
// Short alias for the translations
public static string _ (string s)
{
return Catalog.GetString (s);
}
private RevisionView ViewLeft;
private RevisionView ViewRight;
private string [] Revisions;
public SparkleDiffWindow (string file_path) : base ("")
{
string file_name = System.IO.Path.GetFileName (file_path);
SetSizeRequest (800, 540);
SetPosition (WindowPosition.Center);
BorderWidth = 12;
DeleteEvent += Quit;
IconName = "image-x-generic";
// TRANSLATORS: The parameter is a filename
Title = String.Format(_("Comparing Revisions of {0}"), file_name);
Revisions = GetRevisionsForFilePath (file_path);
VBox layout_vertical = new VBox (false, 12);
HBox layout_horizontal = new HBox (false, 12);
Process process = new Process ();
process.EnableRaisingEvents = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName (file_path);
process.StartInfo.FileName = "git";
process.StartInfo.Arguments = "log --format=\"%ct\t%an\" " + file_name;
process.Start ();
string output = process.StandardOutput.ReadToEnd ();
string [] revisions_info = Regex.Split (output.Trim (), "\n");
int i = 0;
foreach (string revision_info in revisions_info) {
string [] parts = Regex.Split (revision_info.Trim (), "\t");
int timestamp = int.Parse (parts [0]);
string author = parts [1];
if (i == 0)
revisions_info [i] = _("Current Revision") + "\t" + author;
else
// TRANSLATORS: This is a format specifier according to System.Globalization.DateTimeFormatInfo
revisions_info [i] = UnixTimestampToDateTime (timestamp).ToString (_("d MMM\tH:mm")) +
"\t" + author;
i++;
}
ViewLeft = new LeftRevisionView (revisions_info);
ViewRight = new RightRevisionView (revisions_info);
ViewLeft.SetImage (new RevisionImage (file_path, Revisions [1]));
ViewRight.SetImage (new RevisionImage (file_path, Revisions [0]));
ViewLeft.ComboBox.Changed += delegate {
RevisionImage revision_image;
revision_image = new RevisionImage (file_path, Revisions [ViewLeft.ComboBox.Active]);
ViewLeft.SetImage (revision_image);
HookUpViews ();
ViewLeft.ScrolledWindow.Hadjustment = ViewRight.ScrolledWindow.Hadjustment;
ViewLeft.ScrolledWindow.Vadjustment = ViewRight.ScrolledWindow.Vadjustment;
ViewLeft.UpdateControls ();
};
ViewRight.ComboBox.Changed += delegate {
RevisionImage revision_image;
revision_image = new RevisionImage (file_path, Revisions [ViewRight.ComboBox.Active]);
ViewRight.SetImage (revision_image);
HookUpViews ();
ViewRight.ScrolledWindow.Hadjustment = ViewLeft.ScrolledWindow.Hadjustment;
ViewRight.ScrolledWindow.Vadjustment = ViewLeft.ScrolledWindow.Vadjustment;
ViewRight.UpdateControls ();
};
layout_horizontal.PackStart (ViewLeft);
layout_horizontal.PackStart (ViewRight);
// Order time view according to the user's reading direction
if (Direction == Gtk.TextDirection.Rtl) // See Deejay1? I can do i18n too! :P
layout_horizontal.ReorderChild (ViewLeft, 1);
HookUpViews ();
HButtonBox dialog_buttons = new HButtonBox ();
dialog_buttons.Layout = ButtonBoxStyle.End;
dialog_buttons.BorderWidth = 0;
Button CloseButton = new Button (Stock.Close);
CloseButton.Clicked += delegate (object o, EventArgs args) {
Environment.Exit (0);
};
dialog_buttons.Add (CloseButton);
layout_vertical.PackStart (layout_horizontal, true, true, 0);
layout_vertical.PackStart (dialog_buttons, false, false, 0);
Add (layout_vertical);
}
// Hooks up two views so their scrollbars will be kept in sync
private void HookUpViews () {
ViewLeft.ScrolledWindow.Hadjustment.ValueChanged += SyncViewsHorizontally;
ViewLeft.ScrolledWindow.Vadjustment.ValueChanged += SyncViewsVertically;
ViewRight.ScrolledWindow.Hadjustment.ValueChanged += SyncViewsHorizontally;
ViewRight.ScrolledWindow.Vadjustment.ValueChanged += SyncViewsVertically;
}
// Keeps the two image views in sync horizontally
private void SyncViewsHorizontally (object o, EventArgs args) {
Adjustment source_adjustment = (Adjustment) o;
if (source_adjustment == ViewLeft.ScrolledWindow.Hadjustment)
ViewRight.ScrolledWindow.Hadjustment = source_adjustment;
else
ViewLeft.ScrolledWindow.Hadjustment = source_adjustment;
}
// Keeps the two image views in sync vertically
private void SyncViewsVertically (object o, EventArgs args) {
Adjustment source_adjustment = (Adjustment) o;
if (source_adjustment == ViewLeft.ScrolledWindow.Vadjustment)
ViewRight.ScrolledWindow.Vadjustment = source_adjustment;
else
ViewLeft.ScrolledWindow.Vadjustment = source_adjustment;
}
// Gets a list of all earlier revisions of this file
private string [] GetRevisionsForFilePath (string file_path)
{
string file_name = System.IO.Path.GetFileName (file_path);
Process process = new Process ();
process.EnableRaisingEvents = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
// TODO: Nice commit summary and "Current Revision"
process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName (file_path);
process.StartInfo.FileName = "git";
process.StartInfo.Arguments = "log --format=\"%H\" " + file_name;
process.Start ();
string output = process.StandardOutput.ReadToEnd ();
string [] revisions = Regex.Split (output.Trim (), "\n");
return revisions;
}
// Converts a UNIX timestamp to a more usable time object
public DateTime UnixTimestampToDateTime (int timestamp)
{
DateTime unix_epoch = new DateTime (1970, 1, 1, 0, 0, 0, 0);
return unix_epoch.AddSeconds (timestamp);
}
// Quits the program
private void Quit (object o, EventArgs args) {
Environment.Exit (0);
}
}
}