summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2009-03-19 22:52:58 +0100
committerGravatar Martin Szulecki2009-03-19 22:52:58 +0100
commit2a7a82094d50b75380b9858eae5eb41ed169378d (patch)
tree48e84c870df9a5211de593911d36524cf5913821 /src
downloadgfax-2a7a82094d50b75380b9858eae5eb41ed169378d.tar.gz
gfax-2a7a82094d50b75380b9858eae5eb41ed169378d.tar.bz2
Initial import of gfax 0.7.7
Diffstat (limited to 'src')
-rwxr-xr-xsrc/Defines.cs.in12
-rwxr-xr-xsrc/Makefile.am69
-rwxr-xr-xsrc/efax.cs605
-rwxr-xr-xsrc/evolution.cs134
-rwxr-xr-xsrc/fax.cs501
-rwxr-xr-xsrc/gfaxphonebook.cs498
-rwxr-xr-xsrc/gfaxprefs.cs302
-rw-r--r--src/gfaxsend.cs364
-rwxr-xr-xsrc/gui.cs1137
-rwxr-xr-xsrc/guitools.cs540
-rwxr-xr-xsrc/hylafax.cs950
-rw-r--r--src/main.cs243
-rwxr-xr-xsrc/newphonebook.cs187
-rwxr-xr-xsrc/phonebook.cs386
-rwxr-xr-xsrc/sendphonebook.cs242
15 files changed, 6170 insertions, 0 deletions
diff --git a/src/Defines.cs.in b/src/Defines.cs.in
new file mode 100755
index 0000000..fab15cc
--- /dev/null
+++ b/src/Defines.cs.in
@@ -0,0 +1,12 @@
+
+using System;
+
+namespace gfax
+{
+ public class Defines
+ {
+ public static string VERSION = "@version@";
+ public static string DATADIR = "@datadir@";
+ public static string GNOME_LOCALE_DIR = DATADIR + "/locale";
+ }
+}
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100755
index 0000000..e71dd90
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,69 @@
+# 0169 - Don't warn about unused functions, they are called from libglade
+# 0219 - Constructs like Gtk.TreeIter iter = new Gtk.TreeIter();
+CSC = mcs -nowarn:0169,0219 -debug
+
+TARGET = gfax.exe
+WRAPPER = gfax
+SCHEMA = $(top_srcdir)/gfax.schemas.in
+
+#CSFLAGS = -define:DEBUGEFAX
+#CSFLAGS = -define:DEBUGHYLAFAX
+#CSFLAGS =
+
+ASSEMBLIES = -r:Mono.Posix
+
+RESOURCES = \
+ -resource:$(top_srcdir)/glade/gfax.glade,gfax.glade \
+ -resource:$(top_srcdir)/glade/send-druid.glade,send-druid.glade \
+ -resource:$(top_srcdir)/pixmaps/gfax.png,gfax.png \
+ -resource:$(top_srcdir)/pixmaps/send.png,send.png
+
+
+CSFILES = efax.cs \
+ fax.cs \
+ gui.cs \
+ gfaxprefs.cs \
+ gfaxsend.cs \
+ gfaxphonebook.cs \
+ newphonebook.cs \
+ guitools.cs \
+ hylafax.cs \
+ main.cs \
+ phonebook.cs \
+ evolution.cs \
+ sendphonebook.cs
+
+
+GENERATED_CSFILES = Defines.cs Settings.cs
+
+Defines.cs: Defines.cs.in ../config.log
+ sed -e "s|\@version\@|$(VERSION)|" \
+ -e "s|\@datadir\@|$(datadir)|" \
+ -e "s|\@eprefix\@|$(eprefix)|" \
+ < Defines.cs.in > Defines.cs
+
+Settings.cs: Settings.cs
+ env GCONF_CONFIG_SOURCE="" gconftool-2 --makefile-install-rule $(SCHEMA); \
+ gconfsharp2-schemagen gfax $(SCHEMA) > $(srcdir)/Settings.cs
+
+gfax.exe: $(CSFILES) $(GENERATED_CSFILES)
+ $(CSC) $(CSFLAGS) $(GFAX_LIBS) $(ASSEMBLIES) $(RESOURCES) $(CSFILES) $(GENERATED_CSFILES) -o $@
+
+all: gfax.exe
+
+install-data-local: $(TARGET)
+ $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
+ $(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(pkglibdir)/$(TARGET)
+
+uninstall-local:
+ rm -f $(DESTDIR)$(pkglibdir)/$(TARGET)
+
+EXTRA_DIST = \
+ $(srcdir)/Defines.cs.in \
+ $(CSFILES)
+
+
+CLEANFILES = \
+ gfax.exe \
+ Defines.cs \
+ Settings.cs
diff --git a/src/efax.cs b/src/efax.cs
new file mode 100755
index 0000000..d9df4dc
--- /dev/null
+++ b/src/efax.cs
@@ -0,0 +1,605 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ // Sequence to send a file is:
+ // 1) Make sure we're connected
+ // 2) Store the filename on the server [storefile_open]
+ // 3) Send the file line by line
+ // 4) Close the stream for sending the file
+ // 5) For all the phone numbers do:
+ // a) job_new [job_new]
+ // b) set all job parms [job_parm_set]
+ // c) submit the job [submit_job]
+ // 6) Close the connection.
+
+// Properties
+// string Hostname, Username, Password
+// int IPPort
+
+//#define DEBUGEFAX
+
+namespace gfax {
+ using Gtk;
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using System.Text; //Encoding.ASCII.GetBytes
+ using System.Collections;
+ using System.Net;
+ using System.Threading;
+ using System.Net.Sockets;
+ using System.Diagnostics;
+
+
+ public class Efax
+ {
+ private static System.Threading.Thread thread;
+ string user;
+
+
+ //Speaker Volume
+ string[] speakerVolume = {"L0","L1","L2","L3"};
+ const int VERY_LOW = 0;
+ const int LOW = 1;
+ const int MEDIUM = 2;
+ const int HIGH = 3;
+
+ // Speaker modes
+ string[] speakerMode = {"M0","M1","M2","M3"};
+ const int NEVER = 0;
+ const int UNTIL_CARRIER = 1;
+ const int ALWAYS_ON = 2;
+ const int ON_RECEIVE_ONLY = 3;
+
+ string[] modemType = {@"-j\Q4",@"-j\Q1",@"-j*F1",@"-j&H2&I0&R1&D3I4",@"-or"};
+
+
+ /*
+ # FCINIT='-j\Q4' # AT&T (Dataport, Paradyne)
+ # FCINIT='-j\Q1' # Motorola (Power Modem, 3400 Pro,...)
+ # FCINIT='-j*F1' # QuickComm (Spirit II)
+ # FCINIT='-j&H2&I0&R1&D3I4' # USR (Courier, Sportster)
+ # FCINIT='-or' # Multi-Tech (for bit reversal)
+ */
+
+ // Don't need this anymore
+ //TextWriter statusfile = null;
+
+ public Efax ()
+ {
+
+ // Set initial modem settings, gconfsharp-schemagen doesn't like "&"
+ // so can't set a default in gfax.schemas
+ if ( Settings.EfaxModemInit == "" )
+ Settings.EfaxModemInit = "-iZ -i&FE0&D2S7=120 -i&C0";
+ if ( Settings.EfaxModemFcinit == "" )
+ Settings.EfaxModemFcinit = "-j&H2&I0&R1&D3I4";
+ if ( Settings.EfaxModemReset == "" )
+ Settings.EfaxModemReset = "-kZ";
+
+ //Don't need this anymore
+ //statusfile = TextWriter.Synchronized(File.CreateText(gfax.Procfile));
+ }
+
+ public void close ()
+ {
+ }
+
+ // Method status(queue)
+ //
+ // queue is the queue fax system it can be one of:
+ // 'sendq', 'doneq' or 'recvq'
+ //
+ // Return a string containing lines formatted like so
+ // "jobid=number=status=owner=pages=dials=error=sendat\n"
+ // such as:
+ // "2=5551212=S=george=2=1=error message=2004/03/09 18.01.51\n"
+ public string status (string queue)
+ {
+ StreamReader infile = null;
+ string[] sts = new string[11];
+ string path;
+ string buf;
+
+
+ if (queue == "sendq")
+ path = gfax.SpoolDirectory;
+ else if (queue == "doneq")
+ path = gfax.SpoolDirectory + "/doneq";
+ else
+ path = gfax.SpoolDirectory + "/recq";
+
+ string[] control_files = Directory.GetFiles(path, "C_*");
+ string[] lines = new string[control_files.Length];
+ int num_lines = 0;
+
+ foreach (string s in control_files) {
+ try {
+ infile = File.OpenText(s);
+
+ for (int i=0; (buf = infile.ReadLine()) != null; i++) {
+ string[] sa = buf.Split('=');
+ if ( sa[1].Length != 0 )
+ sts[i] = sa[1];
+ else
+ sts[i] = "-";
+ }
+ infile.Close();
+ // Purge doneq files if older than 5 days.
+ if ( queue == "doneq" )
+ if ( (DateTime.Now).Subtract(File.GetCreationTime(s)).Days > 5 )
+ File.Delete(s);
+
+ lines[num_lines++] = String.Format("{0}={1}={2}={3}={4}={5}={6}={7}\n",
+ sts[0],sts[2],sts[3],sts[4],sts[5],sts[6],sts[10],sts[7]);
+ }
+ catch (Exception e) {
+ //return;
+ }
+ }
+
+ return String.Concat(lines);
+ }
+
+ // send_init (string filename)
+ //
+ // Here we should convert the file with ghostscript and return a directory
+ // that points to the converted files to send, one per page. There should
+ // be some status messages passed to the user to let them know whats going on.
+ // Maybe a dialog box.
+ //
+ // We also setup the status message system.
+ public string send_init (string fname)
+ {
+ StreamReader fp = null;
+ double lines = 0;
+ string resolution = "204x98"; // normal res
+
+ // Get new directory name and make it
+ Random rand = new Random();
+ string rand_file = rand.Next().ToString();
+ string dir_name = String.Format("{0}/D_{1}",gfax.SpoolDirectory, rand_file);
+ // TODO proper checks here, this is nasty
+ Directory.CreateDirectory(dir_name);
+
+
+ // get the fax options
+ if (gfax.sendWizardResolution) {
+ resolution = "204x196";
+ }else {
+ if (Settings.HiResolution)
+ resolution = "204x196";
+ }
+
+ string papersize = Settings.EfaxPapersize;
+
+
+ //figure out how many lines in the file for progress bar
+ // TODO progress bar and error
+ try { fp = File.OpenText(fname); }
+ catch (Exception e) { }
+
+ while ( (fp.ReadLine()) != null ) {
+ lines = lines + 1;
+ }
+ fp.Close();
+
+
+ try { fp = File.OpenText(fname); }
+ catch (Exception e) { }
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Efax.send_init] File :{0} is open and has {1} lines", fname,lines);
+ }
+
+ fp.Close();
+
+
+ // TODO need random temp file name
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Efax.send_init] Converting file with gs");
+ Console.WriteLine(" Filename -> {0}",fname);
+ Console.WriteLine(" Resolution -> {0}",resolution);
+ Console.WriteLine(" Directory -> {0}",dir_name);
+ Console.WriteLine(" Papersize -> {0}\n",papersize);
+ }
+
+ ProcessStartInfo pidInfo = new ProcessStartInfo();
+ pidInfo.FileName = "gs";
+
+ pidInfo.Arguments = String.Concat(
+ "-q -sDEVICE=tiffg3 -r",
+ resolution,
+ " -dNOPAUSE -dSAFER -dBATCH",
+ " -sOutputFile=",
+ dir_name,
+ "/tmp.%03d -sPAPERSIZE=",
+ papersize, " ",fname);
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Efax.send_init]\n {0}", pidInfo.Arguments);
+ }
+
+ Process pid = Process.Start(pidInfo);
+ pid.WaitForExit();
+
+ return dir_name;
+ }
+
+ // Method send(string directory, contact)
+ //
+ // Sequence to send a file is:
+ public void send (string directory, GfaxContact contact)
+ {
+ StreamWriter outfile;
+ int pages;
+
+
+ string emailAddress = Settings.EmailAddress;
+ string emailNotify = "none";
+
+ // Get advanced options
+ if (gfax.fromSendWizard) {
+ if (gfax.sendWizardEmailNotify) {
+ emailNotify = "done";
+ emailAddress = gfax.sendWizardEmailAddress;
+ }
+ } else {
+ if (Settings.EmailNotify)
+ emailNotify = "done";
+ }
+
+ //2004/03/09 18.01.51
+ // Format time to send
+ DateTime st = DateTime.Now;
+ string tts = String.Format("{0}/{1:00}/{2:00} {3:00}.{4:00}.00",
+ st.Year, st.Month, st.Day, st.Hour, st.Minute);
+
+ // get next jobid
+ if ( Settings.EfaxNextJobid > 998 )
+ Settings.EfaxNextJobid = 1;
+ else
+ Settings.EfaxNextJobid++;
+
+ // open directory and count files, that will be the number of pages.
+ pages = Directory.GetFiles(directory).Length;
+
+ // build filename
+ Random rand = new Random();
+ string rand_file = rand.Next().ToString();
+ string tfname = String.Format("{0}/C_{1}.{2}",gfax.SpoolDirectory, contact.PhoneNumber, rand_file);
+
+ // TODO error stuff
+ //Open new status file
+ try { outfile = File.CreateText(tfname); }
+ catch (Exception e) { return; }
+ outfile.Write("Jobid=");
+ outfile.WriteLine(Settings.EfaxNextJobid);
+ outfile.Write("JobDirectory=");
+ outfile.WriteLine(directory);
+ outfile.Write("PhoneNumber=");
+ outfile.WriteLine(contact.PhoneNumber);
+ outfile.Write("Status=");
+ outfile.WriteLine("P");
+ outfile.Write("Owner=");
+ outfile.WriteLine(Environment.GetEnvironmentVariable("USERNAME"));
+ outfile.Write("Pages=");
+ outfile.WriteLine(pages.ToString());
+ outfile.Write("Dials=");
+ outfile.WriteLine(0);
+ outfile.Write("Sendat=");
+ outfile.WriteLine(tts);
+ outfile.Write("Notification=");
+ outfile.WriteLine(emailNotify);
+ outfile.Write("Email=");
+ outfile.WriteLine(emailAddress);
+ outfile.Write("ErrorMessage=");
+ outfile.WriteLine("");
+ outfile.Close();
+
+ // jobid might need to be Convert.ToInt32
+
+ }
+
+ public void job_delete (string jobid)
+ {
+ StreamReader infile = null;
+ string[] sts = new string[11];
+ string buf;
+
+ string[] controlFiles = Directory.GetFiles(gfax.SpoolDirectory, "C_*");
+
+ foreach (string controlFile in controlFiles) {
+ try {
+ infile = File.OpenText(controlFile);
+
+ for (int i=0; (buf = infile.ReadLine()) != null; i++) {
+ string[] sa = buf.Split('=');
+ if ( sa[1].Length != 0 )
+ sts[i] = sa[1];
+ else
+ sts[i] = "-";
+ }
+ infile.Close();
+
+ if ( sts[0] == jobid ) {
+ File.Delete(controlFile);
+ Directory.Delete(sts[1], true);
+ break;
+ }
+ }
+ catch (Exception e) {continue; }
+ }
+
+ // end up here with control file name
+ return;
+ }
+
+ public string job_kill (string jobid)
+ {
+ return null;
+ }
+
+ public void run_efaxd ()
+ {
+ // Create the thread object, passing in the efaxd method
+ WaitCallback callback = new WaitCallback(efaxd);
+ ThreadPool.QueueUserWorkItem(callback);
+ }
+
+ /* efaxd
+ * For now just cycle through the control files and send the fax
+ *
+ */
+ private void efaxd (object state)
+ {
+ thread = System.Threading.Thread.CurrentThread;
+
+ StreamReader infile = null;
+ string[] sts = new string[11];
+ string buf;
+ //bool fatalError = false;
+ int retries;
+ string speakerModeVolume;
+
+ //string jobid, number, status, owner, pages, dials, error, sendat;
+ System.Threading.Thread.Sleep(15000); // Don't start immediately
+
+ while (true) {
+ Application.Invoke (delegate {gfax.GAppbar.ClearStack();});
+ Application.Invoke (delegate {gfax.GAppbar.Push(Catalog.GetString("Scanning control files."));});
+
+ // while there are job files in the folder
+ while (Directory.GetFiles(gfax.SpoolDirectory, "C_*").Length > 0) {
+
+ string[] controlFiles = Directory.GetFiles(gfax.SpoolDirectory, "C_*");
+ // for each job try send it
+ foreach (string controlFile in controlFiles) {
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("Control files are ----> {0}", controlFile);
+ }
+
+ //Application.Invoke (delegate {gfax.GAppbar.ClearStack();});
+ Application.Invoke (delegate {gfax.GStatusTextBuffer.InsertAtCursor(
+ Catalog.GetString("Running job " + controlFile));});
+
+ try {
+ infile = File.OpenText(controlFile);
+
+ for (int i=0; (buf = infile.ReadLine()) != null; i++) {
+ string[] sa = buf.Split('=');
+ if ( sa[1].Length != 0 )
+ sts[i] = sa[1];
+ else
+ sts[i] = "-";
+ }
+ infile.Close();
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Efaxd] Buffer is {0}", buf);
+ }
+ }
+ catch (Exception e) {continue; }
+
+ //lines[num_lines++] = String.Format("{0}={1}={2}={3}={4}={5}={6}={7}\n",
+ // sts[0],sts[2],sts[3],sts[4],sts[5],sts[6],sts[10],sts[7]);
+
+ // If we aborted for some reason check the retries
+ if (Convert.ToInt32(sts[6]) >= Settings.EfaxRetries) {
+ sts[10] = Catalog.GetString("Busy retries exceeded");
+ update_status_code(sts, controlFile, "F");
+ continue;
+ }
+
+ sts[10] = ""; // clear error message
+ update_status_code(sts, controlFile, "R");
+
+ // default "-iM1L0"
+ speakerModeVolume = String.Concat("-i",
+ speakerMode[Settings.EfaxModemSpeakerMode],
+ speakerVolume[Settings.EfaxModemSpeakerVolume]);
+
+ string [] tifFiles = Directory.GetFiles(sts[1], "tmp.*");
+ StringBuilder filesToSend = new StringBuilder();
+ foreach (string f in tifFiles) {
+ filesToSend.Append(f);
+ filesToSend.Append(" ");
+ }
+
+
+ ProcessStartInfo pidInfo = new ProcessStartInfo();
+ pidInfo.FileName = "efax";
+ pidInfo.RedirectStandardError = true;
+ pidInfo.UseShellExecute = false;
+ //used for testing
+ //Thread.Sleep(5000);
+ //pidInfo.FileName = "echo";
+ //pidInfo.FileName = "sleep 5";
+
+ pidInfo.Arguments = String.Concat(
+ "-d /dev/", Settings.EfaxModemDevice, //modem port
+ " -x ", Settings.EfaxLockfile, Settings.EfaxModemDevice, // lockfile
+ " \"", Settings.EfaxModemInit, "\"", // init sequence
+ " \"", speakerModeVolume, "\"", // speaker enable / mode
+ " -l \"", Settings.FaxNumber, "\"", // Our fax number
+ " \"", Settings.EfaxModemReset, "\"", // how to reset modem
+ " -f /usr/bin/efaxfont",
+ " -h \'%d/%d\'", // should be name number and date
+ " -v i", // session progress information
+ " -t T", sts[2], // should make sure there are no bad chars
+ " ", filesToSend); // files to send
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Efax.send]\n {0}", pidInfo.Arguments);
+ }
+ Application.Invoke (delegate {gfax.GAppbar.ClearStack();});
+ Application.Invoke (delegate {gfax.GAppbar.Push(Catalog.GetString("Sending facsimile..."));});
+ Process pid = Process.Start(pidInfo);
+ StreamReader myStreamReader = pid.StandardError;
+
+ //start the pulser
+ Application.Invoke (delegate {gfax.Pulser.StartPulse();});
+ Application.Invoke (delegate {gfax.Status.Append("");});
+
+ while (!pid.HasExited) {
+ string str = myStreamReader.ReadLine();
+ Application.Invoke (delegate {gfax.Status.Append(str);});
+ System.Threading.Thread.Sleep(200);
+ }
+ //stop the pulser.
+ Application.Invoke (delegate {gfax.Pulser.EndPulse();});
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Efax.efaxd] Exit code - {0}", pid.ExitCode);
+ }
+
+ switch (pid.ExitCode) {
+ case 0:
+ // If successful then mv the control file to the done queue and flag
+ // a date for it's removal.
+ sts[10] = Catalog.GetString("Success");
+ update_status_code(sts, controlFile, "D");
+ // remove directory path
+ string basefilename = controlFile.Remove(0, gfax.SpoolDirectory.Length + 1);
+ string newfilename = String.Concat(gfax.SpoolDirectory,"/doneq/", basefilename);
+ File.Move(controlFile, newfilename);
+ break;
+ case 1:
+ // busy number, continue after timeout
+ // update listview as well
+ retries = Convert.ToInt32(sts[6]);
+ if (retries++ < Settings.EfaxRetries) {
+ sts[6] = retries.ToString();
+ update_status_code(sts, controlFile, "W");
+ }
+ else {
+ sts[10] = Catalog.GetString("Busy retries exceeded");
+ update_status_code(sts, controlFile, "F");
+ }
+ break;
+ case 2:
+ // fatal errors - no retry
+ //fatalError = true;
+ // change code in file
+ sts[10] = Catalog.GetString("Fatal error");
+ update_status_code(sts, controlFile, "F");
+ break;
+ case 3:
+ // Modem error - no retry
+ //fatalError = true;
+ sts[10] = Catalog.GetString("Fatal modem error");
+ update_status_code(sts, controlFile, "F");
+ break;
+ case 4:
+ // Modem not responding
+ //fatalError = true;
+ sts[10] = Catalog.GetString("Modem not responding");
+ update_status_code(sts, controlFile, "B");
+ break;
+ case 5:
+ // Program terminated
+ //fatalError = true;
+ sts[10] = Catalog.GetString("Program terminated");
+ update_status_code(sts, controlFile, "F");
+ break;
+ }// end of switch
+
+ //sleep between each fax for the modem to stablize
+ System.Threading.Thread.Sleep(3000);
+ } // end of foreach
+ // This basically sleeps between busy numbers.
+ System.Threading.Thread.Sleep(30000);
+ }
+ System.Threading.Thread.Sleep(30000); // sleep 30 seconds
+ // Moved this from case 0 above
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("Deleting --->{0}", sts[1]);
+ }
+ //Directory.Delete(sts[1], true);
+ }// end of while
+ }
+
+
+ // Updates the status code in the control file and writes it back to disk
+ public void update_status_code (string[] job, string file, string status)
+ {
+ string fname = file;
+
+ if ( status == "F" ) {
+ string filename = file.Remove(0, gfax.SpoolDirectory.Length + 1);
+ fname = String.Concat(gfax.SpoolDirectory,"/doneq/", filename);
+ File.Delete(file);
+ Directory.Delete(job[1], true);
+ }
+
+
+ // Thread safe
+ TextWriter outfile = TextWriter.Synchronized(File.CreateText(fname));
+
+ // TODO change this to string.concat and just issue one write
+ try {
+ //outfile = File.CreateText(file);
+
+ outfile.Write("Jobid=");
+ outfile.WriteLine(job[0]);
+ outfile.Write("JobDirectory=");
+ outfile.WriteLine(job[1]);
+ outfile.Write("PhoneNumber=");
+ outfile.WriteLine(job[2]);
+ outfile.Write("Status=");
+ outfile.WriteLine(status);
+ outfile.Write("Owner=");
+ outfile.WriteLine(job[4]);
+ outfile.Write("Pages=");
+ outfile.WriteLine(job[5]);
+ outfile.Write("Dials=");
+ outfile.WriteLine(job[6]);
+ outfile.Write("Sendat=");
+ outfile.WriteLine(job[7]);
+ outfile.Write("Notification=");
+ outfile.WriteLine(job[8]);
+ outfile.Write("Email=");
+ outfile.WriteLine(job[9]);
+ outfile.Write("ErrorMessage=");
+ outfile.WriteLine(job[10]);
+
+ outfile.Close();
+ }
+ catch (Exception e) {}
+ }
+
+ }
+}
diff --git a/src/evolution.cs b/src/evolution.cs
new file mode 100755
index 0000000..5622a69
--- /dev/null
+++ b/src/evolution.cs
@@ -0,0 +1,134 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace gfax {
+ using System;
+ using System.IO;
+ using GLib;
+ using Gtk;
+ using GtkSharp;
+ using System.Collections;
+ using System.Reflection;
+ using Evolution;
+
+ //************************************************************************
+ //
+ //
+ //
+ public class EdsPhoneBooks
+ {
+
+ private void OnContactsAdded (object o, Evolution.ContactsAddedArgs args)
+ {
+ Console.WriteLine ("Contacts added:");
+ foreach (Evolution.Contact contact in args.Contacts) {
+ Console.WriteLine ("\nId: {0}", contact.Id);
+ Console.WriteLine ("Fullname: {0}", contact.FullName);
+ }
+ }
+
+ private void OnContactsChanged (object o, Evolution.ContactsChangedArgs args)
+ {
+ }
+
+ private void OnContactsRemoved (object o, Evolution.ContactsRemovedArgs args)
+ {
+
+ }
+
+ public ArrayList GetPhoneBooks ()
+ {
+ ArrayList ebooks = new ArrayList();
+
+ SourceList slist = new SourceList ("/apps/evolution/addressbook/sources");
+ if (slist != null) {
+ SList group_list = slist.Groups;
+ //Console.WriteLine ("Group count: {0}", group_list.Count);
+
+ foreach (SourceGroup group in group_list) {
+ //Only get phone books on this machine.
+ if (group.Name == "On This Computer") {
+ SList src_list = group.Sources;
+
+ foreach (Evolution.Source src in src_list) {
+ ebooks.Add(src.Name);
+ }
+ }
+ }
+ }
+ return ebooks;
+ }
+
+
+ public ArrayList GetContacts (string bookName)
+ {
+ string contact_fax = null;
+ ArrayList ebooks = new ArrayList();
+ ArrayList records = new ArrayList();
+
+ SourceList slist = new SourceList ("/apps/evolution/addressbook/sources");
+ if (slist != null) {
+ SList group_list = slist.Groups;
+ foreach (SourceGroup group in group_list) {
+ //Only get phone books on this machine.
+ if (group.Name == "On This Computer") {
+ SList src_list = group.Sources;
+
+ foreach (Evolution.Source src in src_list) {
+ if (src.Name == bookName) {
+ //Book bk = Book.NewSystemAddressbook ();
+ Book bk = new Book(src);
+ bk.Open (true);
+
+ BookQuery q = BookQuery.AnyFieldContains ("");
+ Contact[] contactlist = bk.GetContacts (q);
+ //Console.WriteLine ("Contact count (range) : {0}", contactlist.Length);
+
+ if (contactlist != null) {
+
+ foreach (Contact comp in contactlist) {
+ contact_fax = null;
+
+ if (comp.BusinessFax != null && comp.BusinessFax != String.Empty) {
+ contact_fax = comp.BusinessFax;
+ }
+ else if (comp.OtherFax != null && comp.OtherFax != String.Empty) {
+ contact_fax = comp.OtherFax;
+ }
+ else if (comp.HomeFax != null && comp.HomeFax != String.Empty) {
+ contact_fax = comp.HomeFax;
+ }
+
+ if (contact_fax != null) {
+ GfaxContact gc = new GfaxContact();
+ //Console.WriteLine ("Id: {0}", comp.Id);
+ gc.PhoneNumber = contact_fax;
+ gc.ContactPerson = comp.FullName;
+ gc.Organization = comp.Org;
+ records.Add(gc);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return records;
+ }
+ }
+}
diff --git a/src/fax.cs b/src/fax.cs
new file mode 100755
index 0000000..91d0f0f
--- /dev/null
+++ b/src/fax.cs
@@ -0,0 +1,501 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+//#define DEBUGHYLAFAX
+
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.Collections;
+
+ public enum FaxStatus: int {
+ Sent,
+ Fail,
+ New,
+ Busy,
+ Block,
+ Sleep,
+ Run,
+ Receiving,
+ Received
+ };
+
+ public class Fax
+ {
+ static Hylafax hfax;
+ static Efax efax;
+ static bool firstRun = true;
+
+ public class FaxQueue
+ {
+ public string Jobid;
+ public string Number;
+ public string Status;
+ public FaxStatus StatusType;
+ public string Owner;
+ public string Pages;
+ public string Dials;
+ public string Error;
+ public object Sendat;
+ }
+
+ public class FaxRecQueue
+ {
+ public string Pages;
+ public string Status;
+ public FaxStatus StatusType;
+ public string Sender;
+ public object TimeReceived;
+ public string Filename;
+ }
+
+ public static string async_get_server_status ()
+ {
+
+ if (Settings.TransmitAgent == "hylafax") {
+ hfax = new Hylafax();
+
+ if ( !hfax.connect() )
+ return (Catalog.GetString("No Connection"));
+ hfax.asyncstatus("status");
+ hfax.close();
+ hfax = null;
+ return ("");
+ }
+
+ if (Settings.TransmitAgent == "efax") {
+ //TODO put modem ready status here
+ if (firstRun) {
+ firstRun = false;
+ return (Catalog.GetString("Efax transmit process running...\nScanning job files every 30 seconds."));
+ }
+ else
+ return (null);
+ }
+
+ return (Catalog.GetString("Error transport agent not specified!"));
+ }
+
+ public static ArrayList async_get_queue_status (string queue)
+ {
+ if (Settings.TransmitAgent == "hylafax") {
+ hfax = new Hylafax();
+
+ if ( hfax.connect() )
+ hfax.asyncstatus(queue);
+ hfax.close();
+ hfax = null;
+ }
+
+ if (Settings.TransmitAgent == "efax") {
+ string reply = gfax.efax.status(queue);
+
+ if (queue == "doneq" || queue == "sendq")
+ return (parse_senddone(reply));
+ else // (queue == "recvq")
+ return (parse_receive(reply));
+ }
+ return (null);
+ }
+
+ // parse the send or done queue
+ public static ArrayList parse_senddone (string reply)
+ {
+ ArrayList list = new ArrayList();
+
+ if (reply.Length > 0) {
+ foreach (string s in reply.Split('\n')) {
+ FaxQueue hq = new FaxQueue();
+ //Console.WriteLine("s length equals --> {0}", s.Length);
+ if (s.Length == 0 )
+ break;
+
+ string[] sa = s.Split('=');
+
+ // TODO put error here about bad network comms
+ if (sa.Length != 8) {
+ break;
+ }
+
+ if ( sa[0].Length != 0 )
+ hq.Jobid = sa[0].Trim();
+ else
+ hq.Jobid = "";
+ if ( sa[1].Length != 0 )
+ hq.Number = sa[1].Trim();
+ else
+ hq.Number = "";
+ if ( sa[2].Length != 0 ) {
+ switch (sa[2]) {
+ case "R":
+ hq.Status = Catalog.GetString("Run");
+ hq.StatusType = FaxStatus.Run;
+ break;
+ case "S":
+ hq.Status = Catalog.GetString("Sleep");
+ hq.StatusType = FaxStatus.Sleep;
+ break;
+ case "B":
+ hq.Status = Catalog.GetString("Block");
+ hq.StatusType = FaxStatus.Block;
+ break;
+ case "W":
+ hq.Status = Catalog.GetString("Busy");
+ hq.StatusType = FaxStatus.Busy;
+ break;
+ case "D":
+ hq.Status = Catalog.GetString("Done");
+ hq.StatusType = FaxStatus.Sent;
+ break;
+ case "F":
+ hq.Status = Catalog.GetString("Fail");
+ hq.StatusType = FaxStatus.Fail;
+ break;
+ case "P":
+ hq.Status = Catalog.GetString("New");
+ hq.StatusType = FaxStatus.New;
+ break;
+ }
+ }
+ else
+ hq.Status = "";
+ if ( sa[3].Length != 0 )
+ hq.Owner = sa[3].Trim();
+ else
+ hq.Owner = "";
+ if ( sa[4].Length != 0 )
+ hq.Pages = sa[4].Trim();
+ else
+ hq.Pages = "";
+ if ( sa[5].Length != 0 )
+ hq.Dials = sa[5].Trim();
+ else
+ hq.Dials = "";
+ if ( sa[6].Length != 0 )
+ hq.Error = sa[6];
+ else
+ hq.Error = "";
+
+ if ( sa[7].Length != 0 ) { // 2004/03/09 18.01.51
+ try {
+ hq.Sendat = (DateTime)System.DateTime.ParseExact(sa[7].Replace(".", ":").Trim(), "yyyy/MM/dd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
+ }
+ catch(FormatException e)
+ {
+ hq.Sendat = null;
+ }
+ } else {
+ hq.Sendat = null;
+ }
+
+ list.Add(hq);
+ }
+
+ } else { // no status
+
+ FaxQueue hq = new FaxQueue();
+ hq.Jobid = "";
+ hq.Number = "";
+ hq.Status = "";
+ hq.Owner = "";
+ hq.Pages = "";
+ hq.Dials = "";
+ hq.Error = "";
+ hq.Sendat = null;
+
+ list.Add(hq);
+ }
+
+ return (list);
+ }
+
+ // parse the receive queue
+ //
+ //Page S Sender/TSI Recvd@ Filename
+ //1 +49 30 7865224 10Nov04 fax00004.tif
+ // should come back as
+ //1= =+49 30 7865224=10Nov04=fax00004.tif
+ public static ArrayList parse_receive (string reply)
+ {
+ ArrayList list = new ArrayList();
+
+
+ if (reply.Length > 0) {
+ foreach (string s in reply.Split('\n')) {
+ FaxRecQueue hq = new FaxRecQueue();
+ if (s.Length == 0 )
+ break;
+
+ string[] sa = s.Split('=');
+ if (sa.Length != 5) {
+ break;
+ }
+
+ if ( sa[0].Length != 0 )
+ hq.Pages = sa[0].Trim();
+ else
+ hq.Pages = "";
+ if ( sa[1].Length != 0 )
+ switch (sa[1]) {
+ case "N*":
+ hq.Status = Catalog.GetString("Receiving");
+ hq.StatusType = FaxStatus.Receiving;
+ break;
+ case "N ":
+ hq.Status = Catalog.GetString("Done");
+ hq.StatusType = FaxStatus.Received;
+ break;
+ }
+ if ( sa[2].Length != 0 )
+ hq.Sender = sa[2].Trim();
+ else
+ hq.Sender = "";
+ if ( sa[3].Length != 0 )
+ {
+ try {
+ hq.TimeReceived = (DateTime)System.DateTime.ParseExact(sa[3], "ddMMMyy", System.Globalization.CultureInfo.InvariantCulture);
+ }
+ catch(FormatException e )
+ {
+ hq.TimeReceived = null;
+ }
+ }
+ else
+ hq.TimeReceived = null;
+ if ( sa[4].Length != 0 )
+ hq.Filename = sa[4].Trim();
+ else
+ hq.Filename = "";
+
+ list.Add(hq);
+ }
+
+ } else { // no status
+
+ FaxRecQueue hq = new FaxRecQueue();
+ hq.Pages = "";
+ hq.Status = "";
+ hq.Sender = "";
+ hq.TimeReceived = null;
+ hq.Filename = "";
+
+ list.Add(hq);
+ }
+
+ return (list);
+ }
+
+
+
+ public static void sendfax (string fname)
+ {
+ string remote_fname;
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Fax.sendfax] File name is : {0}", fname);
+ }
+
+ if (Settings.TransmitAgent == "hylafax") {
+ Hylafax hfaxsf = new Hylafax();
+ // hylafax actually stores the file to the server
+ hfaxsf.connect();
+ remote_fname = hfaxsf.send_init(fname);
+
+ // if "Cancel" button pressed on progess bar
+ if (remote_fname == "cancelled")
+ return;
+
+ if (Settings.Faxtracing == true) {
+ if (Settings.TransmitAgent == "hylafax") {
+ Console.WriteLine("[Fax.sendfax] Remote file name is : {0}", remote_fname);
+ }
+ }
+
+ //System.Threading.Thread.Sleep(2000);
+
+ IEnumerator enu = gfax.Destinations.GetEnumerator();
+
+ if (Settings.Faxtracing == true) {
+ if (Settings.TransmitAgent == "hylafax") {
+ Console.WriteLine("[Fax.sendfax] Destinations has a count of : {0}", gfax.Destinations.Count);
+ }
+ }
+
+ while ( enu.MoveNext() ) {
+ // TODO try catch exception here
+ GfaxContact c = (GfaxContact)enu.Current;
+
+ if (Settings.Faxtracing == true) {
+ if (Settings.TransmitAgent == "hylafax") {
+ Console.WriteLine("[Fax.sendfax] In while loop contact is -----> {0}", c.PhoneNumber);
+ }
+ }
+
+ hfaxsf.send(remote_fname, c);
+
+ if (Settings.Faxtracing == true) {
+ if (Settings.TransmitAgent == "hylafax") {
+ Console.WriteLine("[Fax.sendfax] In while loop bottom... ");
+ }
+ }
+
+ //System.Threading.Thread.Sleep(1000);
+ // open the log and log out going fax to server
+ // Date Time PhoneNumber Organization ContactPerson
+ // log file is in ~/.etc/gfax
+ //if (Settings.LogEnabled)
+ //log_it((GfaxContact)enu.Current);
+ }
+
+ if (Settings.Faxtracing == true) {
+ if (Settings.TransmitAgent == "hylafax") {
+ Console.WriteLine("[Fax.sendfax] End of send contact loop...");
+ }
+ }
+
+ hfaxsf = null;
+ }
+
+
+ //Efax transport
+ if (Settings.TransmitAgent == "efax") {
+
+ // Convert the file with ghostscript
+ string directory = gfax.efax.send_init(fname);
+ if (directory == "cancelled")
+ return;
+
+ IEnumerator enu = gfax.Destinations.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ gfax.efax.send(directory, (GfaxContact)enu.Current);
+ if (Settings.LogEnabled)
+ log_it((GfaxContact)enu.Current);
+ }
+ }
+ }
+
+ public static bool recvfax (string fname)
+ {
+
+ // Hylafax support
+ if (Settings.TransmitAgent == "hylafax") {
+ hfax = new Hylafax();
+ // hylafax actually stores the file to the server
+ hfax.connect();
+ return(hfax.getfile(fname));
+ }
+
+ // Efax transport
+ if (Settings.TransmitAgent == "efax") {
+ return false;
+ }
+
+ return false;
+ }
+
+
+ public static void log_it (GfaxContact contact)
+ {
+
+ }
+
+
+ public static void modify_job (string jobid, string number, string sendat, string dials)
+ {
+ if (Settings.TransmitAgent == "hylafax") {
+ hfax = new Hylafax();
+ hfax.connect();
+ hfax.job_select(jobid);
+ hfax.job_suspend();
+ hfax.job_param_set("SENDTIME", sendat);
+ hfax.job_param_set("EXTERNAL", number);
+ hfax.job_param_set("DIALSTRING", number);
+ hfax.job_param_set("MAXDIALS", dials);
+ hfax.job_submit();
+ hfax = null;
+ }
+
+ /*
+ if (Settings.TransmitAgent == "efax") {
+ gfax.efax.job_kill(jobid);
+ gfax.efax.job_delete(jobid);
+ }
+ */
+
+ }
+
+ public static void resubmit_job (string jobid, string number, string sendat, string dials)
+ {
+ // will have to query the job, get the file name
+ // possibly retrieve the file and then re-submit the job
+
+ if (Settings.TransmitAgent == "hylafax") {
+ hfax = new Hylafax();
+ hfax.connect();
+ hfax.job_select(jobid);
+
+ /*
+ hfax.job_reset("P");
+ hfax.job_suspend();
+ hfax.job_param_set("SENDTIME", sendat);
+ hfax.job_param_set("EXTERNAL", number);
+ hfax.job_param_set("DIALSTRING", number);
+ hfax.job_param_set("MAXDIALS", dials);
+ hfax.job_submit();
+ hfax = null;
+ */
+ }
+
+ }
+
+
+ public static void delete_job (string jobid)
+ {
+ if (Settings.TransmitAgent == "hylafax") {
+ hfax = new Hylafax();
+ hfax.connect();
+ hfax.job_select(jobid);
+ hfax.job_kill();
+ hfax.job_delete();
+ hfax = null;
+ }
+
+ if (Settings.TransmitAgent == "efax") {
+ gfax.efax.job_kill(jobid);
+ gfax.efax.job_delete(jobid);
+ }
+
+ }
+
+ public static int delete_file (string fname)
+ {
+ if (Settings.TransmitAgent == "hylafax") {
+ hfax = new Hylafax();
+ hfax.connect();
+ int reply = hfax.deletefile(fname);
+ hfax = null;
+ return (reply);
+ }
+
+ if (Settings.TransmitAgent == "efax") {
+ return(0);
+ }
+ return(0);
+ }
+ }
+}
diff --git a/src/gfaxphonebook.cs b/src/gfaxphonebook.cs
new file mode 100755
index 0000000..be922c0
--- /dev/null
+++ b/src/gfaxphonebook.cs
@@ -0,0 +1,498 @@
+// 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 2 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, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using GLib;
+ using Gtk;
+ using Gnome;
+ using Glade;
+ using GConf.PropertyEditors;
+ using GtkSharp;
+ using System.Runtime.InteropServices;
+ using System.Collections;
+ using System.Diagnostics;
+ using System.Reflection;
+
+ //************************************************************************
+ // GfaxPhonebook class
+ //
+
+ public class GfaxPhonebook
+ {
+ const string APPNAME = "Gfax";
+
+ const int COLUMN_0 = 0;
+ const int COLUMN_1 = 1;
+ const int COLUMN_2 = 2;
+ const int COLUMN_3 = 3;
+ const int ALL_COLUMNS = -1;
+
+ string tempName;
+ string tempNumber;
+ string tempCompany;
+
+ bool eventsEnabled = true;
+
+ [Glade.Widget] Gtk.Window PhbookWindow;
+ [Glade.Widget] Gtk.ComboBox PhonebookComboBox;
+ [Glade.Widget] Gtk.TreeView ItemTreeview;
+ [Glade.Widget] Gtk.Entry PhonebookComboEntry;
+ [Glade.Widget] Gtk.Entry EditPhbNumberEntry;
+ [Glade.Widget] Gtk.Entry EditPhbNameEntry;
+ [Glade.Widget] Gtk.Entry EditPhbCompanyEntry;
+ [Glade.Widget] Gtk.ToolButton SaveCloseButton;
+ [Glade.Widget] Gtk.ToolButton DeletePhonebookButton;
+ [Glade.Widget] Gtk.Button AddButton;
+ [Glade.Widget] Gtk.Button UpdateButton;
+ [Glade.Widget] Gtk.Button ClearButton;
+ [Glade.Widget] Gtk.Statusbar Statusbar;
+
+ Gtk.ListStore ItemStore; //phonebook item store
+ G_ListView ItemView;
+
+ GConf.PropertyEditors.EditorShell shell;
+ Phonebook[] myPhoneBooks;
+ Glade.XML gxml;
+ const int id = 1;
+ bool pbIsReadOnly = false; //wether current phone book is no editable.
+
+ public GfaxPhonebook ()
+ {
+ myPhoneBooks = Phonetools.get_phonebooks();
+
+ Application.Init ();
+ gxml = new Glade.XML (null, "send-druid.glade","PhbookWindow",null);
+ gxml.Autoconnect (this);
+
+ ItemStore = new ListStore(typeof (string), typeof (string), typeof (string));
+ ItemView = new G_ListView(ItemTreeview, ItemStore);
+ ItemView.AddColumnTitle(Catalog.GetString("Organization"), 0, COLUMN_0);
+ ItemView.AddColumnTitle(Catalog.GetString("Phone Number"), 1, COLUMN_1);
+ ItemView.AddColumnTitle(Catalog.GetString("Contact"), 2, COLUMN_2);
+ ItemTreeview.HeadersVisible = true;
+ //ItemTreeview.Selection.Mode = SelectionMode.Multiple;
+ ItemTreeview.Selection.Changed +=
+ new EventHandler(on_ItemTreeview_selection);
+
+ // Populate the drop down combo box with phonebooks and populate
+ // the list with the first phonebook.
+ // TODO sort these alphabetically
+ if ( myPhoneBooks.Length > 0) {
+ string[] list = new string[myPhoneBooks.Length];
+
+ if ( myPhoneBooks != null ) {
+ // populate the list
+ int i = 0;
+ PhonebookComboBox.RemoveText(0);
+ foreach (Phonebook p in myPhoneBooks) {
+ list[i++] = p.Name;
+ PhonebookComboBox.AppendText(p.Name);
+ }
+ PhonebookComboBox.Active = 0;
+ }
+
+ //Console.WriteLine(list[PhonebookComboBox.Active]);
+ DeletePhonebookButton.Sensitive = true;
+ } else {
+ DeletePhonebookButton.Sensitive = false;
+ }
+
+ SaveCloseButton.Sensitive = false;
+ UpdateButton.Sensitive = false;
+ ClearButton.Sensitive = false;
+ AddButton.Sensitive = false;
+
+ Application.Run ();
+ }
+
+
+ private void on_PhbookWindow_delete_event (object o, DeleteEventArgs args)
+ {
+ PhbookWindow.Destroy();
+ Application.Quit ();
+ }
+
+ // Menu signals
+ private void on_New_activate (object o, EventArgs args)
+ {
+ on_NewPhonebookButton_clicked(null, null);
+ }
+
+ private void on_SaveAndClose_activate (object o, EventArgs args)
+ {
+ on_SaveCloseButton_clicked(null, null);
+ }
+
+ private void on_Delete_activate (object o, EventArgs args)
+ {
+ on_DeletePhonebookButton_clicked(null, null);
+ }
+
+ private void on_Close_activate (object o, EventArgs args)
+ {
+ on_CloseButton_clicked(null, null);
+ }
+ //--------- end of menu -----------------
+
+
+ private void on_NewPhonebookButton_clicked (object o, EventArgs args)
+ {
+ // Unselect any phone book otherwise we get gtk errors.
+ ItemTreeview.Selection.UnselectAll();
+
+ // run the wizard
+ NewPhoneBook nphb = new NewPhoneBook ();
+ nphb.Run();
+
+ if ( nphb.PhoneBookNames.Count > 0 ) { // don't do this if cancelled
+ IEnumerator enu = nphb.PhoneBookNames.GetEnumerator();
+
+ while ( enu.MoveNext() ) {
+ Phonebook ph = new Phonebook();
+ if (nphb.PhoneBookType == "gfax")
+ ph.Path = gfax.ConfigDirectory + "/" + (string)enu.Current;
+ else
+ ph.Path = "";
+
+ ph.Name = (string)enu.Current; // get the new book name
+ ph.Type = nphb.PhoneBookType;
+ Phonetools.add_book(ph);
+ PhonebookComboBox.AppendText(ph.Name);
+ }
+ // Reload the phone books
+ myPhoneBooks = Phonetools.get_phonebooks();
+
+ if ( myPhoneBooks.Length > 0) {
+ //PhonebookComboBox.AppendText(ph.Name);
+ PhonebookComboBox.Active = 0;
+ DeletePhonebookButton.Sensitive = true;
+ }
+ }
+
+ nphb = null;
+ }
+
+ private void on_DeletePhonebookButton_clicked (object o, EventArgs args)
+ {
+
+ if ( myPhoneBooks.Length > 0) {
+ string[] list = new string[myPhoneBooks.Length];
+
+ if ( myPhoneBooks != null ) {
+ // populate the list
+ int i = 0;
+ foreach (Phonebook pb in myPhoneBooks) {
+ list[i++] = pb.Name;
+ }
+ }
+ string book = list[PhonebookComboBox.Active];
+
+ MessageDialog md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Question,
+ ButtonsType.YesNo,
+ Catalog.GetString("Are you sure you want to delete the phone book?")
+ );
+
+ ResponseType result = (ResponseType)md.Run ();
+
+ if (result == ResponseType.Yes) {
+ md.Destroy();
+
+ if (book == null)
+ return;
+ Phonetools.delete_book(book);
+
+ PhonebookComboBox.RemoveText(PhonebookComboBox.Active);
+ ItemStore.Clear();
+
+ myPhoneBooks = Phonetools.get_phonebooks();
+
+ if (myPhoneBooks.Length > 0) {
+ // now reload
+ PhonebookComboBox.Active = 0;
+ on_PhonebookComboBox_changed(null, null);
+ } else {
+ DeletePhonebookButton.Sensitive = false;
+ PhonebookComboBox.InsertText(0," ");
+ }
+ PhonebookComboBox.Active = 0;
+
+ } else {
+ md.Destroy();
+ }
+ }
+ }
+
+ private void on_SaveCloseButton_clicked (object o, EventArgs args)
+ {
+ ArrayList rows;
+ ArrayList contacts = new ArrayList();
+ string book;
+
+ if ( myPhoneBooks.Length > 0) {
+ string[] list = new string[myPhoneBooks.Length];
+
+ if ( myPhoneBooks != null ) {
+ // populate the list
+ int i = 0;
+ foreach (Phonebook pb in myPhoneBooks)
+ list[i++] = pb.Name;
+ }
+ book = list[PhonebookComboBox.Active];
+
+ // just get all items and save
+ SaveCloseButton.Sensitive = false;
+ //eventsEnabled = false;
+ EditPhbCompanyEntry.Text = "";
+ EditPhbNumberEntry.Text = "";
+ EditPhbNameEntry.Text = "";
+
+ rows = ItemView.GetAllRows();
+
+ IEnumerator enu = rows.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ GfaxContact c = new GfaxContact();
+ c.Organization = ((string[])enu.Current)[0];
+ c.PhoneNumber = ((string[])enu.Current)[1];
+ c.ContactPerson = ((string[])enu.Current)[2];
+ contacts.Add(c);
+ }
+
+ Phonetools.save_phonebook_items(book, contacts);
+ //EditPhbList.Selection.UnselectAll();
+ }
+
+ PhbookWindow.Destroy();
+ Application.Quit ();
+ }
+
+ private void on_CloseButton_clicked (object o, EventArgs args)
+ {
+ if (SaveCloseButton.Sensitive) {
+ MessageDialog md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Question,
+ ButtonsType.YesNo,
+ Catalog.GetString("You have unsaved phone book entries.\n Are you sure you want to Quit?")
+ );
+
+ ResponseType result = (ResponseType)md.Run ();
+
+ if (result == ResponseType.Yes) {
+ md.Destroy();
+ PhbookWindow.Destroy();
+ Application.Quit ();
+ } else {
+ md.Destroy();
+ }
+ } else {
+ PhbookWindow.Destroy();
+ Application.Quit ();
+ }
+ }
+
+
+ private void on_PhonebookComboBox_changed (object o, EventArgs args)
+ {
+ ArrayList contacts = null;
+ Phonebook p;
+
+ // get the first book in the list and load the liststore
+ if ( myPhoneBooks.Length > 0) {
+ string[] list = new string[myPhoneBooks.Length];
+
+ if ( myPhoneBooks != null ) {
+ // populate the list
+ int i = 0;
+ foreach (Phonebook pb in myPhoneBooks) {
+ list[i++] = pb.Name;
+ }
+ }
+
+ p = Phonetools.get_book_from_name(list[PhonebookComboBox.Active]);
+ if (p == null)
+ return;
+
+ // Clear the list_store
+ ItemStore.Clear();
+
+ contacts = Phonetools.get_contacts(p);
+
+ if (contacts != null) {
+ IEnumerator enu = contacts.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ GfaxContact c = new GfaxContact();
+ c = (GfaxContact)enu.Current;
+ ItemView.AddTextToRow(c.Organization, c.PhoneNumber, c.ContactPerson);
+ }
+ if (p.Type == "evolution") {
+ pbIsReadOnly = true;
+ EditPhbCompanyEntry.Sensitive = false;
+ EditPhbNumberEntry.Sensitive = false;
+ EditPhbNameEntry.Sensitive = false;
+
+ } else {
+ pbIsReadOnly = false;
+ EditPhbCompanyEntry.Sensitive = true;
+ EditPhbNumberEntry.Sensitive = true;
+ EditPhbNameEntry.Sensitive = true;
+ eventsEnabled = true;
+ }
+ }
+ }
+ }
+
+ private void on_EditPhbNumberEntry_changed (object o, EventArgs args)
+ {
+ if (eventsEnabled) {
+ ArrayList al = ItemView.GetSelections(ALL_COLUMNS);
+ // if single contact selected
+ if (al.Count > 0) {
+ UpdateButton.Sensitive = true;
+ } else {
+ AddButton.Sensitive = true;
+ ClearButton.Sensitive = true;
+ }
+ }
+ }
+ private void on_EditPhbNameEntry_changed (object o, EventArgs args)
+ {
+ if (eventsEnabled) {
+ ArrayList al = ItemView.GetSelections(ALL_COLUMNS);
+ // if single contact selected
+ if (al.Count > 0) {
+ UpdateButton.Sensitive = true;
+ } else {
+ AddButton.Sensitive = true;
+ ClearButton.Sensitive = true;
+ }
+ }
+ }
+ private void on_EditPhbCompanyEntry_changed (object o, EventArgs args)
+ {
+ if (eventsEnabled) {
+ ArrayList al = ItemView.GetSelections(ALL_COLUMNS);
+ // if single contact selected
+ if (al.Count > 0) {
+ UpdateButton.Sensitive = true;
+ } else {
+ AddButton.Sensitive = true;
+ ClearButton.Sensitive = true;
+ }
+ }
+ }
+
+ private void on_ClearButton_clicked (object o, EventArgs args)
+ {
+ eventsEnabled = false;
+ EditPhbCompanyEntry.Text = "";
+ EditPhbNumberEntry.Text = "";
+ EditPhbNameEntry.Text = "";
+ UpdateButton.Sensitive = false;
+ ItemTreeview.Selection.UnselectAll();
+ ClearButton.Sensitive = false;
+ AddButton.Sensitive = false;
+ Statusbar.Pop(id);
+ Statusbar.Push(id, " ");
+ }
+
+ private void on_AddButton_clicked (object o, EventArgs args)
+ {
+ ItemView.AddTextToRow(EditPhbCompanyEntry.Text,
+ EditPhbNumberEntry.Text,
+ EditPhbNameEntry.Text);
+
+ eventsEnabled = false; // no updates till selected
+ EditPhbCompanyEntry.Text = "";
+ EditPhbNumberEntry.Text = "";
+ EditPhbNameEntry.Text = "";
+ EditPhbNumberEntry.HasFocus = true;
+ SaveCloseButton.Sensitive = true;
+ ClearButton.Sensitive = false;
+ AddButton.Sensitive = false;
+ eventsEnabled = true;
+ }
+
+ private void on_UpdateButton_clicked (object o, EventArgs args)
+ {
+ ItemView.UpdateColumnText(tempNumber, EditPhbNumberEntry.Text, COLUMN_1);
+ ItemView.UpdateColumnText(tempName, EditPhbNameEntry.Text, COLUMN_2);
+ ItemView.UpdateColumnText(tempCompany, EditPhbCompanyEntry.Text, COLUMN_0);
+ EditPhbCompanyEntry.Text = "";
+ EditPhbNumberEntry.Text = "";
+ EditPhbNameEntry.Text = "";
+ UpdateButton.Sensitive = false;
+ ItemTreeview.Selection.UnselectAll();
+ ClearButton.Sensitive = false;
+ SaveCloseButton.Sensitive = true;
+ Statusbar.Pop(id);
+ Statusbar.Push(id, " ");
+ }
+
+ private void on_ItemTreeview_selection (object o, EventArgs args)
+ {
+ ArrayList al;
+
+ eventsEnabled = false; // no updates
+ if (!pbIsReadOnly) {
+ al = ItemView.GetSelections(ALL_COLUMNS);
+ Statusbar.Push(id,Catalog.GetString("Press the <DELETE> key to delete an entry."));
+
+ // if single contact selected
+ if (al.Count == 3) {
+ IEnumerator enu = al.GetEnumerator();
+ enu.MoveNext();
+ EditPhbCompanyEntry.Text = (string)enu.Current;
+ tempCompany = (string)enu.Current;
+ enu.MoveNext();
+ EditPhbNumberEntry.Text = (string)enu.Current;
+ tempNumber = (string)enu.Current;
+ enu.MoveNext();
+ EditPhbNameEntry.Text = (string)enu.Current;
+ tempName = (string)enu.Current;
+ }
+ AddButton.Sensitive = false;
+ ClearButton.Sensitive = true;
+ eventsEnabled = true;
+ }
+ }
+
+ private void on_ItemTreeview_key_press_event (object o, KeyPressEventArgs args)
+ {
+ if (args.Event.Key == Gdk.Key.Delete ) {
+
+ //eventsEnabled = false; // no updates
+ ArrayList al = ItemView.GetSelections(ALL_COLUMNS);
+
+ // if single contact selected
+ //if (al.Count == 3) {
+ ItemView.RemoveSelectedRow();
+ EditPhbCompanyEntry.Text = "";
+ EditPhbNumberEntry.Text = "";
+ EditPhbNameEntry.Text = "";
+ //}
+ AddButton.Sensitive = false;
+ ClearButton.Sensitive = false;
+ SaveCloseButton.Sensitive = true;
+ //eventsEnabled = true;
+ }
+ }
+ }
+}
diff --git a/src/gfaxprefs.cs b/src/gfaxprefs.cs
new file mode 100755
index 0000000..0ff9e6d
--- /dev/null
+++ b/src/gfaxprefs.cs
@@ -0,0 +1,302 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using GLib;
+ using Gtk;
+ using Gnome;
+ using Glade;
+ using GConf.PropertyEditors;
+ using GtkSharp;
+ using System.Runtime.InteropServices;
+ using System.Collections;
+ using System.Diagnostics;
+ using System.Reflection;
+
+ //************************************************************************
+ // GfaxPrefs class
+ //
+ // This is the preferences window.
+ public class GfaxPrefs
+ {
+ Glade.XML gxml;
+ [Glade.Widget] Gtk.Dialog PrefsDialog;
+ [Glade.Widget] Gtk.Notebook PrefsNotebook;
+ //System Tab
+ [Glade.Widget] Gtk.RadioButton HylafaxRadioButton;
+ [Glade.Widget] Gtk.RadioButton EfaxRadioButton;
+ [Glade.Widget] Gtk.Entry FaxNumberEntry;
+ [Glade.Widget] Gtk.Entry DialPrefixEntry;
+ [Glade.Widget] Gtk.Entry ModemEntry;
+ [Glade.Widget] Gtk.Entry FaxViewerEntry;
+
+ //Hylafax Tab
+ [Glade.Widget] Gtk.Entry HylafaxHostnameEntry;
+ [Glade.Widget] Gtk.Entry HylafaxPortEntry;
+ [Glade.Widget] Gtk.Entry HylafaxUsernameEntry;
+
+ //Efax Tab
+ [Glade.Widget] Gtk.Entry EfaxModemDeviceEntry;
+ [Glade.Widget] Gtk.ComboBox EfaxPapersizeComboBox;
+ [Glade.Widget] Gtk.ComboBox EfaxModemTypeComboBox;
+ [Glade.Widget] Gtk.ComboBox EfaxModemSpeakerVolumeComboBox;
+
+ //User Tab
+ [Glade.Widget] Gtk.CheckButton EmailNotifyCheckButton;
+ [Glade.Widget] Gtk.Entry EmailAddressEntry;
+ [Glade.Widget] Gtk.CheckButton SendNowCheckButton;
+ [Glade.Widget] Gtk.CheckButton FaxLogCheckButton;
+ [Glade.Widget] Gtk.CheckButton CoverPageCheckButton;
+ [Glade.Widget] Gtk.CheckButton HiResCheckButton;
+
+ // we set this otherwise setting inital values will wipe
+ // out all the other settings.
+ bool eventsEnabled = false;
+
+ bool taChanged = false;
+
+ const int HYLAFAX_PAGE = 1;
+ const int EFAX_PAGE = 2;
+
+ string[] papersize = {"letter", "legal", "a4"};
+
+ string[] modemType = {@"-j\Q4",@"-j\Q1",@"-j*F1",@"-j&H2&I0&R1&D3I4",@"-or"};
+ /*
+ # FCINIT='-j\Q4' # AT&T (Dataport, Paradyne)
+ # FCINIT='-j\Q1' # Motorola (Power Modem, 3400 Pro,...)
+ # FCINIT='-j*F1' # QuickComm (Spirit II)
+ # FCINIT='-j&H2&I0&R1&D3I4' # USR (Courier, Sportster)
+ # FCINIT='-or' # Multi-Tech (for bit reversal)
+ */
+
+
+ public GfaxPrefs ()
+ {
+ gxml = new Glade.XML (null, "gfax.glade","PrefsDialog",null);
+ //GConf.PropertEditors
+ EditorShell shell = new EditorShell (gxml);
+ gxml.Autoconnect(this);
+
+
+ // System Tab
+ if (Settings.TransmitAgent == "hylafax") {
+ HylafaxRadioButton.Active = true;
+ CoverPageCheckButton.Visible = false;
+ PrefsNotebook.GetNthPage(EFAX_PAGE).Hide();
+ }
+ else if (Settings.TransmitAgent == "efax") {
+ EfaxRadioButton.Active = true;
+ EmailNotifyCheckButton.Sensitive = false;
+ EmailAddressEntry.Sensitive = false;
+ Settings.SendNow = SendNowCheckButton.Active;
+ FaxLogCheckButton.Visible = false;
+ CoverPageCheckButton.Visible = false;
+ Settings.HiResolution = HiResCheckButton.Active;
+
+ PrefsNotebook.GetNthPage(HYLAFAX_PAGE).Hide();
+ }
+
+ // Set these regardless so they are set if we need them
+ switch (Settings.EfaxPapersize) {
+ case "letter":
+ EfaxPapersizeComboBox.Active = 0;
+ break;
+ case "legal":
+ EfaxPapersizeComboBox.Active = 1;
+ break;
+ case "a4":
+ EfaxPapersizeComboBox.Active = 2;
+ break;
+ default:
+ EfaxPapersizeComboBox.Active = 0;
+ break;
+ }
+ //"-j\\Q4","-j\\Q1","-j*F1","-j&H2&I0&R1&D3I4","-or"
+ switch (Settings.EfaxModemFcinit) {
+ case @"-j\Q4":
+ EfaxModemTypeComboBox.Active = 0;
+ break;
+ case @"-j\Q1":
+ EfaxModemTypeComboBox.Active = 1;
+ break;
+ case @"-j*F1":
+ EfaxModemTypeComboBox.Active = 2;
+ break;
+ case @"-j&H2&I0&R1&D3I4":
+ EfaxModemTypeComboBox.Active = 3;
+ break;
+ case @"-or":
+ EfaxModemTypeComboBox.Active = 4;
+ break;
+ default:
+ EfaxModemTypeComboBox.Active = 5;
+ break;
+ }
+
+ EfaxModemSpeakerVolumeComboBox.Active = Settings.EfaxModemSpeakerVolume;
+
+
+
+ // changes that happen automagically
+ shell.Add(SettingKeys.FaxNumber, "FaxNumberEntry");
+ shell.Add(SettingKeys.PhonePrefix, "DialPrefixEntry");
+ shell.Add(SettingKeys.FaxViewer, "FaxViewerEntry");
+
+ // Hylafax Tab
+ shell.Add(SettingKeys.Hostname, "HylafaxHostnameEntry");
+ shell.Add(SettingKeys.Port, "HylafaxPortEntry");
+ shell.Add(SettingKeys.Username, "HylafaxUsernameEntry");
+
+ // Efax Tab
+ shell.Add(SettingKeys.EfaxModemDevice, "EfaxModemDeviceEntry");
+
+
+ // User tab
+ shell.Add(SettingKeys.EmailNotify, "EmailNotifyCheckButton");
+ shell.Add(SettingKeys.EmailAddress, "EmailAddressEntry");
+ shell.Add(SettingKeys.SendNow, "SendNowCheckButton");
+ shell.Add(SettingKeys.LogEnabled, "FaxLogCheckButton");
+ shell.Add(SettingKeys.CoverPage, "CoverPageCheckButton");
+ shell.Add(SettingKeys.HiResolution, "HiResCheckButton");
+
+ eventsEnabled = true;
+
+ }
+
+
+ private void on_PrefsDialog_delete_event (object o, DeleteEventArgs args)
+ {
+ MessageDialog md;
+ if (taChanged) {
+ md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Warning,
+ ButtonsType.Ok,
+ Catalog.GetString("You need to exit Gfax and restart it when you change transport agents")
+ );
+ md.Run ();
+ md.Destroy();
+ }
+ PrefsDialog.Destroy();
+ args.RetVal = true;
+ }
+
+ private void on_CloseButton_clicked (object o, EventArgs args)
+ {
+ MessageDialog md;
+ if (taChanged) {
+ md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Warning,
+ ButtonsType.Ok,
+ Catalog.GetString("You need to exit Gfax and restart it when you change transport agents")
+ );
+ md.Run ();
+ md.Destroy();
+ }
+ PrefsDialog.Destroy();
+ }
+
+ private void on_HelpButton_clicked (object o, EventArgs args)
+ {
+
+ }
+
+ private void system_tab_changed (object o, EventArgs args)
+ {
+ if (eventsEnabled) {
+ //eventsEnabled = false;
+ if (HylafaxRadioButton.Active) {
+ Settings.TransmitAgent = "hylafax";
+ Settings.RefreshQueueInterval = 30;
+ Settings.RefreshQueueEnabled = false;
+ PrefsNotebook.GetNthPage(HYLAFAX_PAGE).Show();
+ PrefsNotebook.GetNthPage(EFAX_PAGE).Hide();
+ }
+ else if (EfaxRadioButton.Active) {
+ Settings.TransmitAgent = "efax";
+ Settings.RefreshQueueInterval = 15;
+ Settings.RefreshQueueEnabled = true;
+ PrefsNotebook.GetNthPage(EFAX_PAGE).Show();
+ PrefsNotebook.GetNthPage(HYLAFAX_PAGE).Hide();
+
+ }
+
+ Settings.FaxNumber = FaxNumberEntry.Text;
+ Settings.PhonePrefix = DialPrefixEntry.Text;
+ Settings.FaxViewer = FaxViewerEntry.Text;
+ }
+ }
+
+ private void user_tab_changed (object o, EventArgs args)
+ {
+ if (eventsEnabled) {
+ Settings.EmailNotify = EmailNotifyCheckButton.Active;
+ Settings.EmailAddress = EmailAddressEntry.Text;
+ Settings.SendNow = SendNowCheckButton.Active;
+ Settings.LogEnabled = FaxLogCheckButton.Active;
+ Settings.CoverPage = CoverPageCheckButton.Active;
+ Settings.HiResolution = HiResCheckButton.Active;
+ }
+ }
+
+ private void radio_button_toggled (object o, EventArgs args)
+ {
+ if (eventsEnabled)
+ taChanged = true;
+ }
+
+
+ private void efax_setup_changed (object o, EventArgs args)
+ {
+
+ if (eventsEnabled) {
+ // Option 5 is custom define so we don't change anything
+ if (EfaxModemTypeComboBox.Active != 5) {
+ switch (EfaxModemTypeComboBox.Active) {
+ case 0:
+ Settings.EfaxModemFcinit = @"-j\Q4";
+ break;
+ case 1:
+ Settings.EfaxModemFcinit = @"-j\Q1";
+ break;
+ case 2:
+ Settings.EfaxModemFcinit = @"-j*F1";
+ break;
+ case 3:
+ Settings.EfaxModemFcinit = @"-j&H2&I0&R1&D3I4";
+ break;
+ case 4:
+ Settings.EfaxModemFcinit = @"-or";
+ break;
+ default:
+ Settings.EfaxModemFcinit = @"-j&H2&I0&R1&D3I4";
+ break;
+ }
+ }
+
+ Settings.EfaxPapersize = EfaxPapersizeComboBox.ActiveText;
+ Settings.EfaxModemSpeakerVolume = EfaxModemSpeakerVolumeComboBox.Active;
+ }
+ }
+ }
+}
diff --git a/src/gfaxsend.cs b/src/gfaxsend.cs
new file mode 100644
index 0000000..444ed91
--- /dev/null
+++ b/src/gfaxsend.cs
@@ -0,0 +1,364 @@
+// 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 2 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, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+//************************************************************************
+// GfaxSend class
+//
+// This is a the send window for sending of a facsimile.
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using GLib;
+ using Gtk;
+ using Gnome;
+ using Glade;
+ using GConf.PropertyEditors;
+ using GtkSharp;
+ using System.Runtime.InteropServices;
+ using System.Collections;
+ using System.Diagnostics;
+ using System.Reflection;
+
+
+ public class GfaxSend // : Program
+ {
+ const string APPNAME = "Gfax";
+
+ const int COLUMN_0 = 0;
+ const int COLUMN_1 = 1;
+ const int COLUMN_2 = 2;
+ const int COLUMN_3 = 3;
+ const int ALL_COLUMNS = -1;
+
+ [Glade.Widget] Gtk.Window NewFaxDialog;
+ [Glade.Widget] Gtk.Button BrowseButton;
+ [Glade.Widget] Gtk.Button PhoneButton;
+ [Glade.Widget] Gtk.Entry NumberEntry;
+ [Glade.Widget] Gtk.Entry EmailEntry;
+ [Glade.Widget] Gtk.Entry FilenameEntry;
+ [Glade.Widget] Gtk.CheckButton ResolutionCheckbutton;
+ [Glade.Widget] Gtk.CheckButton EmailCheckbutton;
+ [Glade.Widget] Gtk.CheckButton SendCheckbutton;
+ [Glade.Widget] Gtk.TreeView ItemTreeview;
+ [Glade.Widget] Gnome.DateEdit SendDateedit;
+ //[Glade.Widget] Gnome.FileEntry PSFileEntry;
+
+
+ Gtk.ListStore ItemStore;
+ G_ListView ItemListview;
+
+ GConf.PropertyEditors.EditorShell shell;
+
+ Glade.XML gxml;
+ string filename, includeFilename;
+ bool dosend;
+
+ public GfaxSend (string fname, string[] args)
+ {
+
+ filename = fname;
+ includeFilename = args[0];
+
+ Application.Init ();
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[GfaxSend] File name is : {0}", fname);
+ }
+
+ // check to see if we've run before, if so gfax will be there
+ if ( Settings.RunSetupAtStart ) {
+ Settings.RunSetupAtStart = false;
+ MessageDialog md;
+ md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Info,
+ ButtonsType.Ok,
+ Catalog.GetString(
+ @"
+This is the first time you have run Gfax.
+Please run Gfax from the menu or command line and set your
+MODEM TYPE, PORT and Fax number under preferences.
+
+Gfax is initially setup to use Efax, you may change it use
+Hylafax if you prefer or require connection to a network
+facsimile server.")
+ );
+ md.Run ();
+ md.Destroy();
+ Application.Quit();
+ dosend = false;
+ Environment.Exit(0);
+ }
+/*
+ if ( Settings.FaxNumber.Length <= 4 ) {
+ MessageDialog md;
+ md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Info,
+ ButtonsType.Ok,
+ Catalog.GetString(
+ @"
+You must have a Fax number set in your preferences under
+Phone Information.")
+ );
+ md.Run ();
+ md.Destroy();
+ //Application.Quit();
+ dosend = false;
+ return;
+ }
+*/
+ gxml = new Glade.XML (null, "send-druid.glade","NewFaxDialog",null);
+ gxml.Autoconnect (this);
+
+ // Set the program icon
+ //Gdk.Pixbuf Icon = new Gdk.Pixbuf(null, "gfax.png");
+ //((Gtk.Window) gxml["NewFaxDialog"]).Icon = Icon;
+ //NewFaxDialog.Icon = Icon;
+
+ ItemStore = new ListStore(
+ typeof (Boolean),
+ typeof (string),
+ typeof (string),
+ typeof (string));
+
+ ItemListview = new G_ListView(ItemTreeview, ItemStore);
+
+ ItemListview.AddColumnTitleToggle(Catalog.GetString("Send"), 0, COLUMN_0);
+ ItemListview.AddColumnTitle(Catalog.GetString("Phone Number"), 0, COLUMN_1);
+ ItemListview.AddColumnTitle(Catalog.GetString("Organization"), 0, COLUMN_2);
+ ItemListview.AddColumnTitle(Catalog.GetString("Contact"), 0, COLUMN_3);
+
+ ItemTreeview.HeadersVisible = true;
+
+ //ItemTreeview.Selection.Mode = SelectionMode.Multiple;
+
+ ResolutionCheckbutton.Active = Settings.HiResolution;
+ EmailCheckbutton.Active = Settings.EmailNotify;
+ EmailEntry.Text = Settings.EmailAddress;
+
+ if (Settings.TransmitAgent == "efax") {
+ EmailCheckbutton.Visible = false;
+ EmailEntry.Visible = false;
+ SendCheckbutton.Visible = false;
+ SendDateedit.Visible = false;
+ }
+
+ if (SendCheckbutton.Active)
+ SendDateedit.Sensitive = false;
+
+ // If we have a file name from the gnome print dialog
+ if (includeFilename != "do_filename") {
+ FilenameEntry.Text = Catalog.GetString("Spooled from print job");
+ FilenameEntry.Sensitive = false;
+ BrowseButton.Sensitive = false;
+ }
+
+ Application.Run ();
+ }
+
+ public bool DoSend
+ {
+ get { return dosend; }
+ }
+
+ public string Filename
+ {
+ get { return filename; }
+ }
+
+
+ private void on_window1_delete_event (object o, DeleteEventArgs args)
+ {
+ dosend = false;
+ //((Gtk.Window) gxml["NewFaxDialog"]).Destroy();
+ NewFaxDialog.Destroy();
+ Application.Quit ();
+ args.RetVal = true;
+ }
+
+ private void on_CancelButton_clicked (object o, EventArgs args)
+ {
+ dosend = false;
+ //((Gtk.Window) gxml["NewFaxDialog"]).Destroy();
+ NewFaxDialog.Destroy();
+ Application.Quit ();
+ }
+
+ private void on_NumberEntry_changed (object o, EventArgs args)
+ {
+ //if (NumberEntry.Text == "\t")
+ //((Gnome.Druid) gxml["send_druid"]).HasFocus = true;
+ }
+
+ private void on_SendCheckButton_toggled (object o, EventArgs args)
+ {
+ SendDateedit.Sensitive = ! SendDateedit.Sensitive;
+ }
+
+ private void on_NumberEntry_activate (object o, EventArgs args)
+ {
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+
+ iter = ItemStore.AppendValues(true, NumberEntry.Text, "", "");
+ ItemTreeview.Model = ItemStore;
+ NumberEntry.Text = "";
+ }
+
+
+ private void on_BrowseButton_clicked (object o, EventArgs args)
+ {
+ FileChooserDialog fc = new FileChooserDialog("Choose postscript file", null, FileChooserAction.Open);
+ fc.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+ fc.AddButton (Gtk.Stock.Open, Gtk.ResponseType.Ok);
+
+ ResponseType result = (ResponseType)fc.Run ();
+
+ if (result == ResponseType.Ok) {
+ FilenameEntry.Text = fc.Filename;
+ fc.Destroy();
+ } else {
+ fc.Destroy();
+ }
+ }
+
+
+ private void on_PhoneButton_clicked (object o, EventArgs args)
+ {
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+ // display the phone book, when we return gfax.Destinations
+ // will be set with contacts.
+ GfaxSendPhoneBook gfs = new GfaxSendPhoneBook(gxml, "gfaxsend");
+
+ ItemStore.Clear();
+
+ if (gfax.Destinations.Count > 0) {
+ IEnumerator enu = gfax.Destinations.GetEnumerator();
+
+ while ( enu.MoveNext() ) {
+ iter = ItemStore.AppendValues(true,
+ ((GfaxContact)enu.Current).PhoneNumber,
+ ((GfaxContact)enu.Current).Organization,
+ ((GfaxContact)enu.Current).ContactPerson);
+ ItemTreeview.Model = ItemStore;
+ }
+ }
+ }
+
+
+ // When finished gfax.Destinations will contain a list of contacts
+ // of Phonebook.Contact type.
+ private void on_SendfaxButton_clicked (object o, EventArgs args)
+ {
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+ ArrayList rows = new ArrayList();
+
+ if (includeFilename == "do_filename")
+ filename = FilenameEntry.Text;
+
+ if (!File.Exists(filename)) {
+ MessageDialog md;
+ md = new MessageDialog (null, DialogFlags.DestroyWithParent,
+ MessageType.Info, ButtonsType.Ok,
+ Catalog.GetString(
+ @"
+The file you have entered does not exist.
+Please check the name and try again.")
+ );
+ md.Run ();
+ md.Destroy();
+ return;
+ }
+
+ // clear all the distinations, it's a little wierd yup
+ gfax.Destinations.Clear();
+
+ // Get the first row.
+ ItemStore.GetIterFirst(out iter);
+
+ try {
+ if ( (bool)ItemStore.GetValue(iter, 0) ) { // if send is true (toggle set)
+
+ GfaxContact c = new GfaxContact();
+ c.PhoneNumber = (string)ItemStore.GetValue(iter, 1); // number
+ c.Organization = (string)ItemStore.GetValue(iter, 2); // organization
+ c.ContactPerson = (string)ItemStore.GetValue(iter, 3); // contact
+
+ rows.Add(c);
+ }
+ }
+ catch (Exception e) {
+ MessageDialog md;
+ md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Info,
+ ButtonsType.Ok,
+ Catalog.GetString(
+ @"
+You have not entered a facsimile number!
+Please enter a number and press the <i><b>Enter</b></i> key or
+click the <i><b>Phone Book</b></i> button to select numbers or
+entire phone books.")
+ );
+ md.Run ();
+ md.Destroy();
+ return;
+ }
+
+ // get the rest of the rows
+ while (ItemStore.IterNext(ref iter)) {
+
+ try {
+ if ( (bool)ItemStore.GetValue(iter, 0) ) { // if send is true (toggle set)
+
+ GfaxContact c = new GfaxContact();
+ c.PhoneNumber = (string)ItemStore.GetValue(iter, 1); // number
+ c.Organization = (string)ItemStore.GetValue(iter, 2); // organization
+ c.ContactPerson = (string)ItemStore.GetValue(iter, 3); // contact
+
+ rows.Add(c);
+ }
+ }
+ catch (Exception e) {}
+ }
+
+
+ if (SendCheckbutton.Active) {
+ gfax.timeToSend = DateTime.UtcNow;
+ } else {
+ // Convert to UTC for Hylafax
+ gfax.timeToSend = (SendDateedit.Time).ToUniversalTime();
+ }
+
+ gfax.Destinations = rows;
+
+ //get the fine resolution status
+ gfax.sendWizardResolution = ResolutionCheckbutton.Active;
+ //get the email flag and email address
+ gfax.sendWizardEmailNotify = EmailCheckbutton.Active;
+ gfax.sendWizardEmailAddress = EmailEntry.Text;
+
+ if ( gfax.Destinations.Count > 0 )
+ dosend = true; // yes send the fax
+
+ //((Gtk.Window) gxml["NewFaxDialog"]).Hide();
+ NewFaxDialog.Hide();
+ Application.Quit();
+ }
+ }
+}
diff --git a/src/gui.cs b/src/gui.cs
new file mode 100755
index 0000000..b5ab51a
--- /dev/null
+++ b/src/gui.cs
@@ -0,0 +1,1137 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+//#define DEBUG
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using GLib;
+ using Gdk;
+ using Gtk;
+ using Gnome;
+ using Glade;
+ using GConf.PropertyEditors;
+ using GtkSharp;
+ using System.Runtime.InteropServices;
+ using System.Collections;
+ using System.Diagnostics;
+ using System.Reflection;
+
+
+ //************************************************************************
+ // Gfax class
+ //
+ // This is the main application window
+
+ public class Gfax : Program
+ {
+ const string VERSION = "0.7.7";
+ const string NAME = "Gfax";
+ const string APPNAME = "Gfax";
+
+ // Notebook pages
+ const int SENDQ_PAGE = 0;
+ const int DONEQ_PAGE = 1;
+ const int RECEIVEQ_PAGE = 2;
+
+ const int COLUMN_0 = 0;
+ const int COLUMN_1 = 1;
+ const int COLUMN_2 = 2;
+ const int COLUMN_3 = 3;
+ const int COLUMN_4 = 4;
+ const int COLUMN_5 = 5;
+ const int ALL_COLUMNS = -1;
+
+ // Strings to hold old contact info temporarily
+ string tempName;
+ string tempNumber;
+ string tempCompany;
+
+ ArrayList oldSendQueue = null; // hold old queue results
+
+ bool restart = true;
+ bool eventsEnabled = true;
+ bool queueBusy = false;
+
+ enum ActiveQ { done, send, receive };
+ ActiveQ activeQ;
+
+
+ Glade.XML gxml;
+
+ [Glade.Widget] Gtk.Window GfaxWindow;
+ [Glade.Widget] Gnome.AppBar Appbar;
+
+ [Glade.Widget] Gtk.TreeView StatusList;
+ [Glade.Widget] Gtk.TreeView JobsCompleteList;
+ [Glade.Widget] Gtk.TreeView JobsReceivedList;
+ [Glade.Widget] Gtk.Notebook StatusNotebook;
+ [Glade.Widget] Gtk.Button DeleteJobButton;
+ [Glade.Widget] Gtk.Button ModifyJobButton;
+ [Glade.Widget] Gtk.Button ViewPrintButton;
+ [Glade.Widget] Gtk.Button RecvfaxDeleteButton;
+ [Glade.Widget] Gtk.TextView StatusText;
+
+
+ // Menu items
+ [Glade.Widget] Gtk.CheckMenuItem AutoQRefreshCheckMenuItem;
+ [Glade.Widget] Gtk.CheckMenuItem EmailNotificationCheckMenuItem;
+ [Glade.Widget] Gtk.CheckMenuItem HiResolutionModeCheckMenuItem;
+ [Glade.Widget] Gtk.CheckMenuItem LogEnabledCheckMenuItem;
+ [Glade.Widget] Gtk.CheckMenuItem FaxTracingCheckMenuItem;
+
+ //Gtk.Window MainWindow;
+
+ Gtk.ListStore StatusStore;
+ Gtk.ListStore RecvStore;
+ Gtk.TreeModel StatusModel;
+ G_ListView lv, jobsCompletedView, jobsReceivedView;
+
+ // text buffer for status text area
+ TextBuffer StatusTextBuffer = new TextBuffer(new TextTagTable());
+
+ Phonebook[] myPhoneBooks;
+
+ GConf.PropertyEditors.EditorShell shell;
+
+ long filePos = 0;
+ static bool iconified = true; // gfax starts iconified
+
+ static long lastMaxOffset;
+
+
+
+ public Gfax (string fname, string[] args)
+ : base (APPNAME, VERSION, Modules.UI, args, new object [0])
+ {
+ //Phonebook[] pb; delete me
+
+ // Set the program icon
+ Gtk.Window.DefaultIconName = "gfax";
+
+ Application.Init ();
+
+ // check to see if we've run before, if so gfax will be there
+ if ( Settings.RunSetupAtStart ) {
+ Settings.RunSetupAtStart = false;
+
+ MessageDialog md;
+ md = new MessageDialog (
+ null,
+ DialogFlags.DestroyWithParent,
+ MessageType.Info,
+ ButtonsType.Ok,
+ Catalog.GetString(
+ @"
+This is the first time you have run Gfax.
+You should set your MODEM TYPE and PORT under preferences.
+
+Gfax is initially setup to use Efax, you may change it use
+Hylafax if you prefer or require connection to a network
+facsimile server.")
+ );
+ md.Run ();
+ md.Destroy();
+ }
+
+ if (!Directory.Exists(gfax.SpoolDirectory)) {
+ G_Message gm = new G_Message(Catalog.GetString(
+ @"Your spool directory is missing!
+
+Please login as the root user and create the "
++ gfax.SpoolDirectory +
+" directory.\n\nAll users should be able to write to it.\n"));
+ return;
+ }
+ if (!Directory.Exists(gfax.SpoolDirectory + "/doneq")) {
+ G_Message gm = new G_Message(Catalog.GetString(
+ @"The doneq directory is missing in your spool directory!
+
+Please login as the root user and create the "
++ gfax.SpoolDirectory + "/doneq" +
+" directory.\n\nAll users should be able to write to it.\n"));
+ return;
+ }
+ if (!Directory.Exists(gfax.SpoolDirectory + "/recq")) {
+ G_Message gm = new G_Message(Catalog.GetString(
+ @"The recq directory is missing in your spool directory!
+
+Please login as the root user and create the "
++ gfax.SpoolDirectory + "/recq" +
+" directory.\n\nAll users should be able to write to it.\n"));
+ return;
+ }
+
+
+ gxml = new Glade.XML (null, "gfax.glade", "GfaxWindow", null);
+ gxml.Autoconnect (this);
+
+
+ // Set initial gui state as per preferences
+ // GConf.PropertyEditors.EditorShell doesn't handle
+ // checkmenuitems;
+ eventsEnabled = false;
+ if (Settings.TransmitAgent == "hylafax") {
+ AutoQRefreshCheckMenuItem.Active = Settings.RefreshQueueEnabled;
+ EmailNotificationCheckMenuItem.Active = Settings.EmailNotify;
+ HiResolutionModeCheckMenuItem.Active = Settings.HiResolution;
+ LogEnabledCheckMenuItem.Active = Settings.LogEnabled;
+ }
+ if (Settings.TransmitAgent == "efax") {
+ AutoQRefreshCheckMenuItem.Active = Settings.RefreshQueueEnabled;
+ AutoQRefreshCheckMenuItem.Sensitive = false;
+ EmailNotificationCheckMenuItem.Active = false;
+ EmailNotificationCheckMenuItem.Sensitive = false;
+ HiResolutionModeCheckMenuItem.Active = Settings.HiResolution;
+ LogEnabledCheckMenuItem.Visible = false;
+ }
+ eventsEnabled = true;
+
+ StatusText.Editable = false;
+ StatusText.CanFocus = false;
+ StatusText.Buffer = StatusTextBuffer;
+
+ // Set the program icon
+ Gdk.Pixbuf Icon = new Gdk.Pixbuf(null, "gfax.png");
+
+ gfax.MainWindow = GfaxWindow;
+
+ // Setup listview icons
+ InitListViewIcons();
+
+ StatusStore = new ListStore(
+ typeof (Gdk.Pixbuf),
+ typeof (string),
+ typeof (string),
+ typeof (string),
+ typeof (string),
+ typeof (string),
+ typeof (string),
+ typeof (DateTime),
+ typeof (string));
+
+ RecvStore = new ListStore(
+ typeof (Gdk.Pixbuf),
+ typeof (string),
+ typeof (string),
+ typeof (string),
+ typeof (DateTime),
+ typeof (string));
+
+
+ lv = new G_ListView(StatusList, StatusStore);
+ lv.AddColumnIcon(Gtk.Stock.Info, 0);
+ lv.AddColumnTitle(Catalog.GetString("Jobid"), 1, 1);
+ lv.AddColumnTitle(Catalog.GetString("Number"), 2, 2);
+ lv.AddColumnTitle(Catalog.GetString("Status"), 3, 3);
+ lv.AddColumnTitle(Catalog.GetString("Owner"), 4, 4);
+ lv.AddColumnTitle(Catalog.GetString("Pages"), 5, 5);
+ lv.AddColumnTitle(Catalog.GetString("Dials"), 6, 6);
+ lv.AddColumnDateTime(Catalog.GetString("Send At"), "G", 7, 7);
+ lv.AddColumnTitle(Catalog.GetString("Information"), 8, 8);
+
+ // List view for completed jobs tab
+ jobsCompletedView = new G_ListView(JobsCompleteList, StatusStore);
+ jobsCompletedView.AddColumnIcon(Gtk.Stock.Info, 0);
+ jobsCompletedView.AddColumnTitle(Catalog.GetString("Jobid"), 1, 1);
+ jobsCompletedView.AddColumnTitle(Catalog.GetString("Number"), 2, 2);
+ jobsCompletedView.AddColumnTitle(Catalog.GetString("Status"), 3, 3);
+ jobsCompletedView.AddColumnTitle(Catalog.GetString("Owner"), 4, 4);
+ jobsCompletedView.AddColumnTitle(Catalog.GetString("Pages"), 5, 5);
+ jobsCompletedView.AddColumnTitle(Catalog.GetString("Dials"), 6, 6);
+ jobsCompletedView.AddColumnDateTime(Catalog.GetString("Send At"), "G", 7, 7);
+ jobsCompletedView.AddColumnTitle(Catalog.GetString("Information"), 8, 8);
+
+ jobsReceivedView = new G_ListView(JobsReceivedList, RecvStore);
+ jobsReceivedView.AddColumnIcon(Gtk.Stock.Info, 0);
+ jobsReceivedView.AddColumnTitle(Catalog.GetString("Sender"), 1, 1);
+ jobsReceivedView.AddColumnTitle(Catalog.GetString("Status"), 2, 2);
+ jobsReceivedView.AddColumnTitle(Catalog.GetString("Pages "), 3, 3);
+ jobsReceivedView.AddColumnDateTime(Catalog.GetString("Arrived"), "d", 4, 4);
+ jobsReceivedView.AddColumnTitle(Catalog.GetString("Filename"), 5, 5);
+
+ StatusList.Selection.Changed +=
+ new EventHandler(on_StatusList_selection);
+ StatusList.Selection.Mode = SelectionMode.Multiple;
+ StatusList.HeadersVisible = true;
+
+ JobsCompleteList.Selection.Changed +=
+ new EventHandler(on_JobsCompleteList_selection);
+ JobsCompleteList.Selection.Mode = SelectionMode.Multiple;
+ JobsCompleteList.HeadersVisible = true;
+
+ JobsReceivedList.Selection.Changed +=
+ new EventHandler(on_JobsReceivedList_selection);
+ JobsReceivedList.Selection.Mode = SelectionMode.Multiple;
+ JobsReceivedList.HeadersVisible = true;
+
+ // Make sure headers are visible
+ lv.AddTextToRow(null,"","","","","","",null,"");
+ jobsCompletedView.AddTextToRow(null,"","","","","","",null,"");
+ jobsReceivedView.AddTextToRow(null,"","","",null,"");
+ StatusStore.Clear();
+ RecvStore.Clear();
+
+ DeleteJobButton.Sensitive = false;
+ if (Settings.TransmitAgent == "hylafax")
+ ModifyJobButton.Sensitive = false;
+ else
+ ModifyJobButton.Visible = false;
+ ViewPrintButton.Sensitive = false;
+
+ // Setup some global variables
+ gfax.MainProgressBar = Appbar.Progress;
+ gfax.GStatusTextBuffer = StatusTextBuffer;
+ gfax.GAppbar = Appbar;
+
+ gfax.Pulser = new Pulser();
+ gfax.Status = new Status(StatusText, StatusTextBuffer);
+
+ if (Settings.RefreshQueueEnabled)
+ GLib.Timeout.Add((uint)(Settings.RefreshQueueInterval * 1000),
+ new TimeoutHandler (queue_refresh));
+
+ async_update_status();
+
+ if (Settings.TransmitAgent == "hylafax" ) {
+ while (gfax.activeNetwork)
+ System.Threading.Thread.Sleep(100);
+
+ async_net_read_finished();
+ }
+
+ activeQ = ActiveQ.send;
+ async_update_queue_status("sendq");
+
+ StatusIcon sicon = new StatusIcon(Icon);
+ sicon.Activate += new EventHandler (OnImageClick);
+ sicon.Tooltip = "Gfax Facsimile Sender";
+ // showing the trayicon
+ sicon.Visible = true;
+ // setup system tray icon
+ gfax.MainWindow.SkipTaskbarHint = true;
+ gfax.MainWindow.Iconify();
+
+ Application.Run ();
+ }
+
+ // end up here if we click the icon in the notifier
+ private static void OnImageClick(object o, EventArgs arg)
+ {
+ if (iconified) {
+ gfax.MainWindow.Deiconify();
+ iconified = false;
+ gfax.MainWindow.SkipTaskbarHint = false;
+ } else {
+ gfax.MainWindow.Iconify();
+ gfax.MainWindow.SkipTaskbarHint = true;
+ iconified = true;
+ }
+ }
+
+ // End up here if we iconify with the window manager
+ private static void on_mainWindow_window_state_event(object o, WindowStateEventArgs args)
+ {
+ //Console.WriteLine ("state event: type=" + args.Event.Type +
+ // "; new_window_state=" + args.Event.NewWindowState);
+
+ if (args.Event.NewWindowState == Gdk.WindowState.Iconified) {
+ iconified = true;
+ gfax.MainWindow.SkipTaskbarHint = true;
+ } else {
+ gfax.MainWindow.SkipTaskbarHint = false;
+ iconified = false;
+ }
+
+ }
+ //************************************************************************
+ // queue_refresh
+ // returns true to continue timeout functioning
+ //
+ // Queue_refresh connects to the hylafax server and retrieves
+ // updated queue information on regular intervals. This is called
+ // from a GLib.TimeoutHandler
+ public bool queue_refresh ()
+ {
+ if (!Settings.RefreshQueueEnabled)
+ return false;
+
+ // always do main status
+ //update_status(Fax.get_server_status());
+
+ // TODO do all this stuff with Delegates and events
+ async_update_status();
+ while (gfax.activeNetwork)
+ System.Threading.Thread.Sleep(100);
+ // now do queue
+
+ switch (activeQ) {
+ case ActiveQ.done :
+ async_update_queue_status("doneq");
+ break;
+ case ActiveQ.send :
+ async_update_queue_status("sendq");
+ break;
+ case ActiveQ.receive :
+ async_update_queue_status("recvq");
+ break;
+ }
+
+ return true; // must return true from timeout to keep it active
+ }
+
+ // Set to true if we need to restart for changed transport agent
+ public bool Restart
+ {
+ get { return restart; }
+ set { restart = value; }
+ }
+
+
+//========================= PRIVATE METHODS ====================================
+ private void on_StatusList_selection (object o, EventArgs args)
+ {
+ if (StatusList.Selection.CountSelectedRows() > 0) {
+ DeleteJobButton.Sensitive = true;
+ ModifyJobButton.Sensitive = true;
+ } else {
+ DeleteJobButton.Sensitive = false;
+ ModifyJobButton.Sensitive = false;
+ }
+ }
+
+
+ private void on_JobsCompleteList_selection (object o, EventArgs args)
+ {
+ DeleteJobButton.Sensitive = true;
+ }
+
+ private void on_JobsReceivedList_selection (object o, EventArgs args)
+ {
+ if (JobsReceivedList.Selection.CountSelectedRows() > 0) {
+ ViewPrintButton.Sensitive = true;
+ RecvfaxDeleteButton.Sensitive = true;
+ } else {
+ ViewPrintButton.Sensitive = false;
+ RecvfaxDeleteButton.Sensitive = false;
+ }
+ }
+
+ // Double click (Send tab)
+ private void on_StatusList_row_activated (object o, RowActivatedArgs args)
+ {
+ modify_job(lv.GetSelections(ALL_COLUMNS), "sendq");
+ }
+
+
+ private void on_JobsCompleteList_row_activated (object o, RowActivatedArgs args)
+ {
+ //modify_job(jobsCompletedView.GetSelections(ALL_COLUMNS), "doneq");
+ }
+
+
+ private void on_JobsReceivedList_row_activated (object o, RowActivatedArgs args)
+ {
+ // get the selected jobs
+ ArrayList al;
+ string hfaxfile = null;
+
+ // COLUMN_5 is the filename
+ al = jobsReceivedView.GetSelections(COLUMN_5);
+
+ IEnumerator enu = al.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ hfaxfile = (string)enu.Current;
+ }
+ //Console.WriteLine("File to receive is {0}", hfaxfile);
+
+ view_received_fax( hfaxfile );
+ }
+
+ private void on_exitButton_clicked (object o, EventArgs args)
+ {
+ Application.Quit();
+ }
+
+ private void on_mainWindow_delete_event (object o, DeleteEventArgs args)
+ {
+ Application.Quit();
+ args.RetVal = true;
+ }
+
+ private void on_exit1_activate (object o, EventArgs args)
+ {
+ Application.Quit();
+ restart = true;
+ }
+
+
+//Status list notebook signal, switch pages to show different queues
+ private void on_StatusNotebook_switch_page (object o, SwitchPageArgs args)
+ {
+ async_update_status();
+ while (gfax.activeNetwork)
+ System.Threading.Thread.Sleep(100);
+
+ switch (StatusNotebook.CurrentPage) {
+ case SENDQ_PAGE:
+ activeQ = ActiveQ.send;
+ //if (update_queue_status("sendq") > 0)
+ // DeleteJobButton.Sensitive = true;
+ //else {
+ DeleteJobButton.Sensitive = false;
+ //}
+ async_update_queue_status("sendq");
+ break;
+ case DONEQ_PAGE:
+ DeleteJobButton.Sensitive = false;
+ activeQ = ActiveQ.done;
+ async_update_queue_status("doneq");
+ break;
+ case RECEIVEQ_PAGE:
+ DeleteJobButton.Sensitive = false;
+ RecvfaxDeleteButton.Sensitive = false;
+ activeQ = ActiveQ.receive;
+ async_update_queue_status("recvq");
+ break;
+ }
+
+ }
+
+//Main toolbar buttons
+//=======================================================================
+ private void on_NewFaxButton_clicked (object o, EventArgs args)
+ {
+ send_new_fax();
+ }
+
+
+ private void on_PhonebookButton_clicked (object o, EventArgs args)
+ {
+ GfaxPhonebook gpb = new GfaxPhonebook();
+ }
+
+
+ private void on_ModifyJobButton_clicked (object o, EventArgs args)
+ {
+ modify_job(lv.GetSelections(ALL_COLUMNS), "sendq");
+ }
+
+ private void modify_job (ArrayList al, string id)
+ {
+
+ string jobid = null;
+ string number = null;
+ string status = null;
+ string user = null;
+ string pages = null;
+ string dials = null;
+ object sendat = null;
+ string error = null;
+
+ IEnumerator enu = al.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ enu.MoveNext();
+ jobid = (string)enu.Current;
+ enu.MoveNext();
+ number = (string)enu.Current;
+ enu.MoveNext();
+ status = (string)enu.Current;
+ enu.MoveNext();
+ user = (string)enu.Current;
+ enu.MoveNext();
+ pages = (string)enu.Current;
+ enu.MoveNext();
+ int idx = ((string)enu.Current).LastIndexOf(':');
+ dials = ((string)enu.Current).Substring(idx + 1);
+ enu.MoveNext();
+ sendat = (object)enu.Current;
+ enu.MoveNext();
+ error = (string)enu.Current;
+ }
+
+ #if DEBUG
+ Console.WriteLine("[ModifyJob] Date is {0}", sendat);
+ #endif
+
+ Glade.XML xml = new Glade.XML (null, "gfax.glade","vbox74",null);
+ Dialog mjd = new Dialog();
+ mjd.VBox.Add(xml.GetWidget("vbox74"));
+ Gtk.Entry mje = (Gtk.Entry)xml.GetWidget("ModifyJobNumberEntry");
+ Gnome.DateEdit mjde = (Gnome.DateEdit)xml.GetWidget("ModifyJobDate");
+ Gtk.SpinButton mjmd = (Gtk.SpinButton)xml.GetWidget("MaxDialsSpinbutton");
+
+ mjd.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+ mjd.AddButton (Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+
+ // this is to re-enable the entry for editing so it won't be selected
+ // to begin with??? Maybe something to do with re-parenting or something.
+ mje.FocusInEvent +=
+ new FocusInEventHandler (on_ModifyJobNumberEntry_focus_in_event);
+
+ mje.IsEditable = false;
+ mje.Text = number.Trim();
+
+ mjde.Time = sendat == null ? new DateTime(): (DateTime)sendat;
+
+ mjmd.Value = Convert.ToDouble(dials.Trim());
+
+ ResponseType result = (ResponseType)mjd.Run ();
+
+ if (result == ResponseType.Ok) {
+ DateTime newsend = (mjde.Time).ToUniversalTime();
+
+ // Format time to send - timezone is in UTC format.
+ string tts = String.Format("{0}{1:00}{2:00}{3:00}{4:00}",
+ newsend.Year,
+ newsend.Month,
+ newsend.Day,
+ newsend.Hour,
+ newsend.Minute);
+
+ if (id == "sendq" )
+ Fax.modify_job(jobid, mje.Text, tts, (mjmd.ValueAsInt).ToString());
+ else // "doneq"
+ Fax.resubmit_job(jobid, mje.Text, tts, (mjmd.ValueAsInt).ToString());
+
+ mjd.Destroy();
+ } else {
+ mjd.Destroy();
+ }
+
+ async_update_queue_status("sendq");
+ ModifyJobButton.Sensitive = false;
+ DeleteJobButton.Sensitive = false;
+ }
+
+ public void on_ModifyJobNumberEntry_focus_in_event (object o, EventArgs args)
+ {
+ Gtk.Entry e = o as Gtk.Entry;
+ e.IsEditable = true;
+ }
+
+ private void on_DeleteJobButton_clicked (object o, EventArgs args)
+ {
+ // get the selected jobs
+ ArrayList al;
+
+ // get a list of jobids to kill
+ al = lv.GetSelections(COLUMN_1);
+
+ IEnumerator enu = al.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ Fax.delete_job((string)enu.Current);
+ }
+
+ switch (activeQ) {
+ case ActiveQ.done :
+ async_update_queue_status("doneq");
+ break;
+ case ActiveQ.send :
+ async_update_queue_status("sendq");
+ break;
+ case ActiveQ.receive :
+ async_update_queue_status("recvq");
+ break;
+ }
+
+ DeleteJobButton.Sensitive = false;
+ ModifyJobButton.Sensitive = false;
+ }
+
+ private void on_ViewPrintButton_clicked (object o, EventArgs args)
+ {
+ // get the selected jobs
+ ArrayList al;
+ string hfaxfile = null;
+
+ // COLUMN_5 is the filename
+ al = jobsReceivedView.GetSelections(COLUMN_5);
+
+ IEnumerator enu = al.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ hfaxfile = (string)enu.Current;
+ }
+
+ view_received_fax (hfaxfile);
+ }
+
+ private void view_received_fax (string s)
+ {
+ // TODO get proper Gnome mime type and use that first if running Gnome
+ try {
+ if (Fax.recvfax(s)) {
+ ProcessStartInfo pidInfo = new ProcessStartInfo();
+ pidInfo.FileName = Settings.FaxViewer;
+ pidInfo.Arguments = String.Concat(gfax.SpoolDirectory, "/tif/", s);
+ System.Diagnostics.Process pid = System.Diagnostics.Process.Start(pidInfo);
+ } else {
+ G_Message gm = new G_Message(Catalog.GetString(
+@"Cannot read the facsimile file from the server. You most likely do not
+have permission to read the file. Check the settings on your fax server." ));
+ return;
+ }
+
+ } catch (Exception e) {
+ G_Message gm = new G_Message(Catalog.GetString(
+@"Cannot start your faxviewer program.
+Please check your settings. It is currently set to " + Settings.FaxViewer + "." ));
+ }
+
+ switch (activeQ) {
+ case ActiveQ.done :
+ async_update_queue_status("doneq");
+ break;
+ case ActiveQ.send :
+ async_update_queue_status("sendq");
+ break;
+ case ActiveQ.receive :
+ async_update_queue_status("recvq");
+ break;
+ }
+
+ // Reset progressbar
+ gfax.MainProgressBar.Fraction = 0;
+ }
+
+ private void on_RecvfaxDeleteButton_clicked (object o, EventArgs args)
+ {
+ // get the selected jobs
+ ArrayList al;
+ string hfaxfile = null;
+
+ // COLUMN_5 is the filename
+ al = jobsReceivedView.GetSelections(COLUMN_5);
+
+ IEnumerator enu = al.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ hfaxfile = (string)enu.Current;
+
+ try {
+ if (Fax.delete_file(hfaxfile) == 1) {
+ G_Message gm = new G_Message(Catalog.GetString(
+@"Cannot delete the facsimile file from the server. You most likely do not
+have permission to delete the file. Check the settings on your fax server." ));
+ return;
+ }
+ } catch (Exception e) {
+ G_Message gm = new G_Message(Catalog.GetString(
+@"Cannot delete the file on the Hylafax server.
+Please check your settings or contact your system Administrator"));
+ }
+
+ switch (activeQ) {
+ case ActiveQ.done :
+ async_update_queue_status("doneq");
+ break;
+ case ActiveQ.send :
+ async_update_queue_status("sendq");
+ break;
+ case ActiveQ.receive :
+ async_update_queue_status("recvq");
+ break;
+ }
+ }
+ }
+
+
+
+// Menu items selected =============================================
+ private void on_newfax_activate (object o, EventArgs args)
+ {
+ send_new_fax();
+ }
+
+ private void on_preferences_activate (object o, EventArgs args)
+ {
+ GfaxPrefs gp = new GfaxPrefs();
+ }
+
+ private void on_jobs1_activate (object o, EventArgs args)
+ {
+
+ }
+
+ private void on_auto_queue_refresh_check_menu_item_activate (object o, EventArgs args)
+ {
+ if (eventsEnabled) {
+ Settings.RefreshQueueEnabled = !Settings.RefreshQueueEnabled;
+ if (Settings.RefreshQueueEnabled)
+ GLib.Timeout.Add((uint)(Settings.RefreshQueueInterval * 1000),
+ new TimeoutHandler(queue_refresh));
+ }
+ }
+
+ private void on_log_enabled_check_menu_item_activate (object o, EventArgs args)
+ {
+ if (eventsEnabled)
+ Settings.LogEnabled = !Settings.LogEnabled;
+ }
+
+ private void on_email_notification_check_menu_item_activate (object o, EventArgs args)
+ {
+ if (eventsEnabled)
+ Settings.EmailNotify = !Settings.EmailNotify;
+ }
+
+ private void on_hi_resolution_mode_check_menu_item_activate (object o, EventArgs args)
+ {
+ if (eventsEnabled)
+ Settings.HiResolution = !Settings.HiResolution;
+ }
+
+ private void on_fax_tracing_check_menuItem_activate (object o, EventArgs args)
+ {
+ if (eventsEnabled)
+ Settings.Faxtracing = !Settings.Faxtracing;
+ }
+
+
+ private static AboutDialog about = null;
+ private static void on_about_activate (object sender, EventArgs args)
+ {
+ if (about == null)
+ about = new AboutDialog();
+
+ about.Name = NAME;
+ about.Version = VERSION;
+ about.LogoIconName = "gfax";
+ about.Authors = new string[] { "George Farris <farrisg@shaw.ca>" };
+ about.Documenters = new string[] {};
+ about.Copyright = Catalog.GetString("Copyright (C) 2003 George Farris <farrisg@shaw.ca>");
+ about.Comments = Catalog.GetString("A Facsimile application for GNOME");
+ about.TranslatorCredits = (
+ "Johannes Rohr <johannes@rohr.org> - German\n" +
+ "Maris Dembovskis <marisdembovskis@gmail.com> - Latvian\n" +
+ "Sasa Ostrouska <saxa@droplinegnome.org> Italian\n" +
+ "Bart Verstraete <bartverstraete@telenet.be> - Dutch");
+ about.Run();
+ about.Hide();
+ }
+
+
+//--------------------------- SUPPORT FUNCTIONS -------------------------------
+ Gdk.Pixbuf fax_fail;
+ Gdk.Pixbuf fax_sent;
+ Gdk.Pixbuf fax_sleep;
+ Gdk.Pixbuf fax_block;
+ Gdk.Pixbuf fax_run;
+ Gdk.Pixbuf fax_receiving;
+ Gdk.Pixbuf fax_received;
+
+ public void InitListViewIcons()
+ {
+ fax_receiving = Gtk.IconTheme.Default.LoadIcon ("document-save", 16, 0);
+ fax_fail = Gtk.IconTheme.Default.LoadIcon ("gtk-cancel", 16, 0);
+ fax_sent = Gtk.IconTheme.Default.LoadIcon ("gtk-apply", 16, 0);
+ fax_run = Gtk.IconTheme.Default.LoadIcon ("printer-printing", 16, 0);
+ fax_block = Gtk.IconTheme.Default.LoadIcon ("printer-error", 16, 0);
+ fax_sleep = Gtk.IconTheme.Default.LoadIcon ("appointment-soon", 16, 0);
+ fax_received = Gtk.IconTheme.Default.LoadIcon ("text-x-generic", 16, 0);
+ }
+
+ public Gdk.Pixbuf GetFaxStatusIcon (FaxStatus status)
+ {
+ switch (status)
+ {
+ case FaxStatus.Fail:
+ return fax_fail;
+ case FaxStatus.New:
+ return fax_run;
+ case FaxStatus.Busy:
+ return fax_block;
+ case FaxStatus.Block:
+ return fax_block;
+ case FaxStatus.Sleep:
+ return fax_sleep;
+ case FaxStatus.Run:
+ return fax_run;
+ case FaxStatus.Receiving:
+ return fax_receiving;
+ case FaxStatus.Received:
+ return fax_received;
+ }
+
+ return fax_sent;
+ }
+
+ // Updates the status text widget
+ // only used for Efax
+ public void update_status (string s)
+ {
+ if (s == null)
+ return;
+
+ if (Settings.TransmitAgent == "efax") {
+ TextMark tm = StatusTextBuffer.GetMark("insert");
+ StatusTextBuffer.InsertAtCursor(String.Concat(s, "\n"));
+ StatusText.ScrollMarkOnscreen(tm);
+ }
+ }
+
+ public void async_update_status ()
+ {
+ string s;
+
+ if (Settings.TransmitAgent == "efax") {
+ s = Fax.async_get_server_status();
+ if (s != null ) {
+ TextMark tm = StatusTextBuffer.GetMark("insert");
+ StatusTextBuffer.InsertAtCursor(String.Concat(s, "\n"));
+ StatusText.ScrollMarkOnscreen(tm);
+ }
+ }
+
+ if (Settings.TransmitAgent == "hylafax") {
+ // Progressbar pulser - add this when we have async comms
+ GLib.Timeout.Add((uint)(100), new TimeoutHandler (queue_progress));
+
+ // update status bar
+ Appbar.ClearStack();
+ Appbar.Push(Catalog.GetString("Refreshing server status..."));
+ Appbar.Refresh();
+ //GLib.MainContext.Iteration ();
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+
+ s = Fax.async_get_server_status();
+ }
+ }
+
+
+ private void async_update_queue_status(string queue)
+ {
+ G_ListView view;
+ Fax.FaxQueue q = null;
+ Fax.FaxRecQueue rq = null;
+
+ view = lv;
+
+ switch (queue) {
+ case "sendq":
+ view = lv;
+ break;
+ case "doneq":
+ view = jobsCompletedView;
+ break;
+ case "recvq":
+ view = jobsReceivedView;
+ break;
+ }
+
+ if (Settings.TransmitAgent == "hylafax") {
+ // Progressbar pulser - add this when we have async comms
+ GLib.Timeout.Add((uint)(100), new TimeoutHandler (queue_progress));
+
+ // update status bar
+ Appbar.ClearStack();
+ Appbar.Push(Catalog.GetString("Refreshing queue..."));
+ Appbar.Refresh();
+ //GLib.MainContext.Iteration ();
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+
+ Fax.async_get_queue_status(queue);
+ }
+ if (Settings.TransmitAgent == "efax") {
+ async_update_listview(Fax.async_get_queue_status(queue), queue);
+ }
+ }
+
+ // We end up here when an async network read is finished
+ private void async_net_read_finished ()
+ {
+ switch (gfax.asyncReadType) {
+ case "doneq" :
+ async_update_listview(Fax.parse_senddone(gfax.asyncFolderMessageBuffer), "doneq");
+ break;
+ case "sendq" :
+ async_update_listview(Fax.parse_senddone(gfax.asyncFolderMessageBuffer), "sendq");
+ break;
+ case "recvq" :
+ async_update_listview(Fax.parse_receive(gfax.asyncFolderMessageBuffer), "recvq");
+ break;
+ case "status" :
+ StatusTextBuffer.Text = gfax.asyncServerMessageBuffer;
+ break;
+ }
+ }
+
+ private void async_update_listview(ArrayList reply, string queue)
+ {
+ G_ListView view;
+ Fax.FaxQueue q = null;
+ Fax.FaxRecQueue rq = null;
+
+ view = lv;
+
+ switch (queue) {
+ case "sendq":
+ view = lv;
+ break;
+ case "doneq":
+ view = jobsCompletedView;
+ break;
+ case "recvq":
+ view = jobsReceivedView;
+ break;
+ }
+
+ if (reply.Count > 0) {
+ StatusStore.Clear();
+ RecvStore.Clear();
+ IEnumerator enu = reply.GetEnumerator();
+
+ if (queue == "sendq" || queue == "doneq") {
+ while ( enu.MoveNext() ) {
+ q = (Fax.FaxQueue)enu.Current;
+ view.AddTextToRow(GetFaxStatusIcon(q.StatusType), q.Jobid, q.Number, q.Status, q.Owner, q.Pages, q.Dials, q.Sendat, q.Error);
+ }
+
+ Appbar.ClearStack();
+
+ if (q.Jobid != "") {
+ Appbar.Push(Catalog.GetString("There are " + reply.Count + " jobs in the queue"));
+ Appbar.Refresh();
+ //((Gtk.Window) gxml["Gfax"]).Title = "Gfax (" + reply.Count + ")";
+ GfaxWindow.Title = "Gfax (" + reply.Count + ")";
+ //return reply.Count;
+ return;
+ } else {
+ Appbar.Push(Catalog.GetString("There are 0 jobs in the queue"));
+ Appbar.Refresh();
+ //((Gtk.Window) gxml["Gfax"]).Title = "Gfax";
+ GfaxWindow.Title = "Gfax";
+ }
+ } else { //receive queue
+ while ( enu.MoveNext() ) {
+ rq = (Fax.FaxRecQueue)enu.Current;
+ view.AddTextToRow(GetFaxStatusIcon(rq.StatusType), rq.Sender, rq.Status, rq.Pages, rq.TimeReceived, rq.Filename);
+ }
+
+ if (rq.Sender != "") {
+ Appbar.Push(Catalog.GetString("There are " + reply.Count + " jobs in the queue"));
+ Appbar.Refresh();
+ //((Gtk.Window) gxml["Gfax"]).Title = "Gfax (" + reply.Count + ")";
+ GfaxWindow.Title = "Gfax (" + reply.Count + ")";
+ //return reply.Count;
+ return;
+ } else {
+ Appbar.Push(Catalog.GetString("There are 0 jobs in the queue"));
+ Appbar.Refresh();
+ //((Gtk.Window) gxml["Gfax"]).Title = "Gfax";
+ GfaxWindow.Title = "Gfax";
+ }
+ }
+
+ oldSendQueue = reply; // else save queue
+ }
+
+
+ StatusStore.Clear();
+ RecvStore.Clear();
+ }
+
+
+ private bool queue_progress ()
+ {
+ if (gfax.activeNetwork) {
+ Appbar.Progress.Pulse();
+ return (true);
+ }
+ else {
+ async_net_read_finished();
+ Appbar.Progress.Fraction = 0;
+ return (false);
+ }
+ }
+
+ // This is where we end up if the New Fax button or the menu item
+ // has been selected.
+ private void send_new_fax ()
+ {
+
+ string [] largs = {"do_filename"};
+ GfaxSend sd = new GfaxSend ("", largs);
+
+ // send the faxes
+ if (sd.DoSend) {
+ Fax.sendfax(sd.Filename);
+ // if file is temp data (/var/spool/gfax/D.*) then delete it
+ FileInfo f = new FileInfo(sd.Filename);
+ if (File.Exists(String.Concat(gfax.SpoolDirectory, "/", f.Name)))
+ File.Delete(String.Concat(gfax.SpoolDirectory, "/", f.Name));
+ }
+ activeQ = ActiveQ.send;
+ async_update_queue_status("sendq");
+ sd = null;
+ largs = null;
+ }
+
+ }
+
+ public class Status
+ {
+ TextBuffer stb;
+ TextView stv;
+
+ public Status (Gtk.TextView StatusText, TextBuffer StatusTextBuffer)
+ {
+ stv = StatusText;
+ stb = StatusTextBuffer;
+ }
+
+ public void Append (string s)
+ {
+ TextMark tm = stb.GetMark("insert");
+ stb.InsertAtCursor(String.Concat(s, "\n"));
+ stv.ScrollMarkOnscreen(tm);
+ }
+ }
+
+ // pulse the main window progressbar
+ public class Pulser
+ {
+ public bool endPulse;
+
+ public void StartPulse ()
+ {
+ endPulse = true;
+ GLib.Timeout.Add((uint)(200),
+ new TimeoutHandler (PulseIt));
+ }
+
+ public void EndPulse ()
+ {
+ endPulse = false;
+ }
+
+ private bool PulseIt ()
+ {
+ gfax.MainProgressBar.Pulse();
+ if (endPulse)
+ return(true);
+ else {
+ gfax.MainProgressBar.Fraction = 0;
+ return(false);
+ }
+ }
+ }
+
+}
diff --git a/src/guitools.cs b/src/guitools.cs
new file mode 100755
index 0000000..8828941
--- /dev/null
+++ b/src/guitools.cs
@@ -0,0 +1,540 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace gfax {
+ using System;
+ using System.IO;
+ using System.Collections;
+ using System.Reflection;
+ using GLib;
+ using Gtk;
+ using Gdk;
+ using Gnome;
+ using Glade;
+ using GtkSharp;
+
+ // G_ProgressBar
+ public class G_ProgressBar
+ {
+ [Glade.Widget] Gtk.Dialog HylafaxProgressDialog;
+ [Glade.Widget] ProgressBar HylafaxProgressbar;
+ [Glade.Widget] Gtk.Notebook HylafaxProgressNotebook;
+ [Glade.Widget] Gtk.Button HylafaxProgressCancelButton;
+ [Glade.Widget] Gtk.Button HylafaxProgressCloseButton;
+
+ bool close = true;
+ bool cancel = false; // Cancel all jobs
+
+ public G_ProgressBar ()
+ {
+ Glade.XML xml = new Glade.XML (null, "gfax.glade","HylafaxProgressDialog",null);
+ xml.Autoconnect (this);
+
+ HylafaxProgressNotebook.CurrentPage = 0;
+ HylafaxProgressCloseButton.Hide();
+ HylafaxProgressDialog.Show();
+ }
+
+ public bool Cancel
+ {
+ get { return cancel; }
+ }
+
+ private void on_HylafaxProgressCancelButton_clicked(object o, EventArgs args)
+ {
+ cancel = true;
+ }
+
+ private void on_HylafaxProgressCloseButton_clicked(object o, EventArgs args)
+ {
+ close = false;
+ HylafaxProgressDialog.Destroy();
+ }
+
+ public void Close()
+ {
+ //close = false;
+ //HylafaxProgressDialog.Hide();
+ //HylafaxProgressDialog.Dispose();
+ HylafaxProgressDialog.Destroy();
+ }
+
+ //public void Run ()
+ //{
+ // HylafaxProgressDialog.Run();
+ //}
+
+ public double Fraction
+ {
+ set { HylafaxProgressbar.Fraction = value; }
+ }
+
+ public void Finished()
+ {
+ HylafaxProgressNotebook.CurrentPage = 1;
+ HylafaxProgressCancelButton.Hide();
+ HylafaxProgressCloseButton.Show();
+ // TODO Bad, bad, slap your wrist boy, do timer function
+ // or fix this somehow. Can I say 100% processor useage.
+ //while (close) {
+ // while (Gtk.Application.EventsPending ())
+ // Gtk.Application.RunIteration ();
+ //}
+ }
+ }
+
+ // G_Message class
+ //
+ // A simple message dialog
+ public class G_Message
+ {
+ public G_Message (string s)
+ {
+ MessageDialog d = new MessageDialog (
+ null, DialogFlags.DestroyWithParent, MessageType.Error, ButtonsType.Ok, s);
+ d.Run ();
+ d.Destroy ();
+ }
+
+ public G_Message (string s, bool toplevel)
+ {
+ Application.Init();
+ MessageDialog d = new MessageDialog (
+ null, DialogFlags.DestroyWithParent, MessageType.Error, ButtonsType.Ok, s);
+ d.Run ();
+ d.Destroy ();
+ Application.Quit();
+ }
+ }
+
+ public class G_Password
+ {
+ [Glade.Widget] Gtk.Dialog PasswordDialog;
+ [Glade.Widget] Gtk.Entry PasswordEntry;
+
+ string pass; // the password entered
+ bool cancel = false; // Cancel the connection
+ bool remember = false; // Remember the password
+
+ public G_Password ()
+ {
+ Glade.XML xml = new Glade.XML (null, "gfax.glade","PasswordDialog",null);
+ xml.Autoconnect (this);
+
+ PasswordDialog.Show();
+ }
+
+ public bool Cancel
+ {
+ get { return cancel; }
+ }
+
+ public bool RememberPassword
+ {
+ get { return remember; }
+ }
+
+ public string Password
+ {
+ get { return pass; }
+ }
+
+ public void Run ()
+ {
+ PasswordDialog.Run();
+ }
+
+ private void on_PasswordCheckbutton_toggled(object o, EventArgs args)
+ {
+ remember = true;
+ }
+
+ private void on_cancelbutton_clicked(object o, EventArgs args)
+ {
+ cancel = true;
+ PasswordDialog.Hide();
+ }
+
+ private void on_PasswordEntry_activate(object o, EventArgs args)
+ {
+ pass = PasswordEntry.Text;
+ PasswordDialog.Hide();
+ }
+
+ private void on_okbutton_clicked(object o, EventArgs args)
+ {
+ pass = PasswordEntry.Text;
+ PasswordDialog.Hide();
+ }
+
+ public void Close()
+ {
+ PasswordDialog.Destroy();
+ }
+ }
+
+
+ // ***********************************************************************
+ //
+ // G_GetFilename class
+ //
+ // Implements a GTK+ fileselector with signal handler for Ok and Cancel
+ // Arguments:
+ // string title : Title open file selection dialog
+ // string dir : Starting directory
+
+ public class G_GetFilename
+ {
+ string fname;
+ public Gtk.FileSelection fs;
+
+ public G_GetFilename (string title, string dir)
+ {
+ fs = new FileSelection(title);
+ fs.Filename = dir;
+ fs.Modal = true;
+ fs.HideFileopButtons ();
+ fs.OkButton.Clicked += new EventHandler (ok);
+ fs.CancelButton.Clicked += new EventHandler (cancel);
+
+/*
+ check_button = new CheckButton ("Show Fileops");
+ check_button.Toggled += new EventHandler (show_fileops);
+ fs.ActionArea.PackStart (check_button, false, false, 0);
+
+ toggle_button = new ToggleButton ("Select Multiple");
+ toggle_button.Clicked += new EventHandler (select_multiple);
+ fs.ActionArea.PackStart (toggle_button, false, false, 0);
+*/
+ fs.ShowAll();
+ fs.Run ();
+ }
+
+ public void Destroy ()
+ {
+ fs.Destroy();
+ }
+
+ private void cancel (object o, EventArgs args)
+ {
+ //Console.WriteLine("[Cancel] file selection cancel");
+ fs.Hide ();
+ }
+
+ private void ok (object o, EventArgs args)
+ {
+ //Console.WriteLine(fs.Filename);
+ fname = fs.Filename;
+ fs.Hide ();
+ }
+
+ public string Fname
+ {
+ get {return fname;}
+ set {fname = value;}
+ }
+
+
+ }
+
+ public class CellRendererDateTime: CellRendererText
+ {
+ public string Format;
+ }
+
+ public class G_ListView
+ {
+ Gtk.ListStore store;
+ Gtk.TreeView tree;
+ Gtk.TreeViewColumn column;
+ Gtk.CellRendererText textrenderer;
+ CellRendererDateTime datetimerenderer;
+ Gtk.CellRendererPixbuf iconrenderer;
+ Gtk.TreeIter iter;
+ Value valnot = new Value(false);
+ Value valone = new Value(true);
+
+ const int COLUMN_0 = 0;
+ const int COLUMN_1 = 1;
+ const int COLUMN_2 = 2;
+ const int ALL_COLUMNS = -1;
+
+ public G_ListView (Gtk.TreeView tr, Gtk.ListStore st)
+ {
+ store = st;
+ tree = tr;
+ iter = new Gtk.TreeIter();
+ }
+
+ public void AddColumnIcon (string iconname, int col)
+ {
+ column = new TreeViewColumn ();
+ iconrenderer = new Gtk.CellRendererPixbuf ();
+ column.Expand = false;
+ column.Resizable = false;
+ column.Clickable = false;
+ column.Reorderable = false;
+ column.Alignment = 0.5f;
+ column.Widget = new Gtk.Image(
+ Gtk.IconTheme.Default.LoadIcon (iconname, 16, 0)
+ );
+ column.Widget.Show();
+ column.PackStart (iconrenderer, true);
+ column.AddAttribute (iconrenderer, "pixbuf", col);
+ tree.AppendColumn(column);
+ }
+
+ protected int DateTimeTreeIterCompareFunc (TreeModel model, TreeIter a, TreeIter b)
+ {
+ int col = -1;
+ SortType sort;
+
+ bool is_sorted = ((Gtk.ListStore)model).GetSortColumnId (out col, out sort);
+ if(!is_sorted)
+ return 0;
+
+ DateTime dateA = (DateTime)model.GetValue (a, col);
+ DateTime dateB = (DateTime)model.GetValue (b, col);
+
+ return dateA.CompareTo(dateB);
+ }
+
+ protected void DateTimeColumnDataHandler (TreeViewColumn column,
+ CellRenderer cell, TreeModel model, TreeIter iter)
+ {
+ DateTime date = (DateTime)model.GetValue (iter, column.SortColumnId);
+ CellRendererDateTime renderer = (CellRendererDateTime)cell;
+ renderer.Text = date.ToString(renderer.Format);
+ }
+
+ public void AddColumnDateTime (string title, string format, int sortid, int col)
+ {
+ store.SetSortFunc(col, new TreeIterCompareFunc(DateTimeTreeIterCompareFunc));
+
+ column = new TreeViewColumn ();
+ datetimerenderer = new CellRendererDateTime ();
+ datetimerenderer.Format = format == null ? "G" : format;
+ column.Title = title;
+ column.SortColumnId = sortid;
+ column.Sizing = TreeViewColumnSizing.Autosize;
+ column.Reorderable = true;
+ column.Resizable = true;
+ column.Expand = false;
+ column.Alignment = 0.0f;
+ column.PackStart (datetimerenderer, true);
+ column.SetCellDataFunc (datetimerenderer, new TreeCellDataFunc(DateTimeColumnDataHandler));
+ tree.AppendColumn(column);
+ }
+
+ public void AddColumnTitle (string title, int sortid, int col)
+ {
+ column = new TreeViewColumn ();
+ textrenderer = new CellRendererText ();
+ //text.Editable = true;object
+ column.Title = title;
+ column.SortColumnId = sortid;
+ column.Sizing = TreeViewColumnSizing.Autosize;
+ column.Reorderable = true;
+ column.Resizable = true;
+ column.Expand = false;
+ column.Alignment = 0.0f;
+ column.PackStart (textrenderer, true);
+ column.AddAttribute (textrenderer, "text", col);
+ tree.AppendColumn(column);
+ }
+
+// TODO move this to GfaxSend in gui.cs
+ public void AddColumnTitleToggle (string title, int sortid, int col)
+ {
+ column = new TreeViewColumn ();
+ CellRendererToggle toggle = new CellRendererToggle ();
+ toggle.Activatable = true;
+ toggle.Toggled += new ToggledHandler (toggle_it);
+ column.Title = title;
+ column.PackStart (toggle, false);
+ column.AddAttribute (toggle, "active", col);
+ tree.AppendColumn(column);
+ }
+
+ // we need to manually set the toggle when selected otherwise
+ // it won't show in the gui.
+ public void toggle_it (object o, Gtk.ToggledArgs args)
+ {
+ store.GetIterFromString(out iter, args.Path);
+ bool tog = (bool)store.GetValue(iter, 0);
+ store.SetValue(iter, 0, !tog);
+ }
+// end of move
+
+ // Each arg is a new column
+ public void AddTextToRow (params object[] args)
+ {
+ iter = store.AppendValues(args);
+ tree.Model = store;
+ }
+
+ // returns a list of arrays of columns size
+ public ArrayList GetAllRows()
+ {
+ ArrayList rows = new ArrayList();
+
+ // Really get the whole row.
+ string[] col = new string[store.NColumns];
+ store.GetIterFirst(out iter);
+
+ for ( int i = 0; i < store.NColumns; i++) {
+ try {
+ col[i] = (string)store.GetValue(iter, i);
+ //Console.WriteLine("Column {0}",col[i]);
+ }
+ catch (Exception e) { }
+ }
+ rows.Add(col);
+
+ #if DEBUG
+ Console.WriteLine("got colums");
+ #endif
+
+ while (store.IterNext(ref iter)) {
+ string[] coln = new string[store.NColumns];
+ for ( int i = 0; i < store.NColumns; i++) {
+ coln[i] = (string)store.GetValue(iter, i);
+ }
+ rows.Add(coln);
+ }
+ return rows;
+ }
+
+ // get multiple selections, return a list of objects
+ public ArrayList GetSelections(int column)
+ {
+ ArrayList selects = new ArrayList();
+
+ // Really get the whole row.
+ if (column == ALL_COLUMNS) {
+ store.GetIterFirst(out iter);
+ if ( tree.Selection.IterIsSelected(iter)) {
+ for ( int i = 0; i < store.NColumns; i++) {
+ selects.Add(store.GetValue(iter, i));
+ }
+ }
+
+ while (store.IterNext(ref iter)) {
+ if ( tree.Selection.IterIsSelected(iter)) {
+ for ( int i = 0; i < store.NColumns; i++) {
+ selects.Add(store.GetValue(iter, i));
+ }
+ }
+ }
+ }
+ else
+ {
+ store.GetIterFirst(out iter);
+ if ( tree.Selection.IterIsSelected(iter)) {
+ selects.Add(store.GetValue(iter, column));
+ }
+
+ while (store.IterNext(ref iter)) {
+ if ( tree.Selection.IterIsSelected(iter)) {
+ selects.Add(store.GetValue(iter, column));
+ }
+ }
+ }
+ return selects;
+ }
+
+ // get single selection
+ public object GetSingleSelection ()
+ {
+ object sel = null;
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+
+ store.GetIterFirst(out iter);
+ if ( tree.Selection.IterIsSelected(iter)) {
+ sel = store.GetValue(iter, 0);
+ }
+
+ while (store.IterNext(ref iter)) {
+ if ( tree.Selection.IterIsSelected(iter)) {
+ sel = store.GetValue(iter, 0);
+ }
+ }
+ return sel;
+ }
+
+ public void RemoveSelectedRow ()
+ {
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+
+ store.GetIterFirst(out iter);
+ if ( tree.Selection.IterIsSelected(iter)) {
+ store.Remove(ref iter);
+ return;
+ }
+
+ while (store.IterNext(ref iter)) {
+ if ( tree.Selection.IterIsSelected(iter)) {
+ store.Remove(ref iter);
+ break;
+ }
+ }
+ return;
+ }
+
+ //TODO get this to work
+ public void RemoveSelectedRows ()
+ {
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+
+ store.GetIterFirst(out iter);
+ if ( tree.Selection.IterIsSelected(iter)) {
+ store.Remove(ref iter);
+ }
+
+ while (store.IterNext(ref iter)) {
+ if ( tree.Selection.IterIsSelected(iter)) {
+ store.Remove(ref iter);
+ }
+ }
+ return;
+ }
+
+
+ public void UpdateColumnText (string oldString, string newString, int column)
+ {
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+
+ store.GetIterFirst(out iter);
+ // Check for a null Stamp (no initial entry in the list)
+ if (iter.Stamp == 0)
+ return;
+
+ if ( oldString == (string)store.GetValue(iter, column)) {
+ GLib.Value val = new GLib.Value(newString);
+ store.SetValue (iter, column, val);
+ }
+
+ while (store.IterNext(ref iter)) {
+ if ( oldString == (string)store.GetValue(iter, column)) {
+ GLib.Value val1 = new GLib.Value(newString);
+ store.SetValue (iter, column, val1);
+ }
+ }
+
+ }
+ }
+}
diff --git a/src/hylafax.cs b/src/hylafax.cs
new file mode 100755
index 0000000..54ab63f
--- /dev/null
+++ b/src/hylafax.cs
@@ -0,0 +1,950 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ // Sequence to send a file is:
+ // 1) Make sure we're connected
+ // 2) Store the filename on the server [storefile_open]
+ // 3) Send the file line by line
+ // 4) Close the stream for sending the file
+ // 5) For all the phone numbers do:
+ // a) job_new [job_new]
+ // b) set all job parms [job_parm_set]
+ // c) submit the job [submit_job]
+ // 6) Close the connection.
+
+// Properties
+// string Hostname, Username, Password
+// int IPPort
+
+//#define DEBUGHYLAFAX
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using System.Text; //Encoding.ASCII.GetBytes
+ using System.Collections;
+ using System.Threading;
+ using System.Net;
+ using System.Net.Sockets;
+
+
+ public class Hylafax
+ {
+ TcpClient mainclient = new TcpClient();
+ NetworkStream mainstream;
+ string host, user, pass;
+ int port;
+ bool permission;
+
+
+ public class StateObject
+ {
+ public TcpClient client = null;
+ public int totalBytesRead = 0;
+ public const int BufferSize = 256;
+ public string readType = null;
+ public byte[] buffer = new byte[BufferSize];
+ public StringBuilder messageBuffer = new StringBuilder();
+ }
+
+
+ // connect
+ // return false on sucess or true on cancel
+ public bool connect ()
+ {
+ host = Settings.Hostname;
+ port = Convert.ToInt32(Settings.Port);
+ user = Settings.Username;
+ if (gfax.hylafaxPassword == null) // if we already entered a pass but
+ if (Settings.Password != "") // don't want to remember it it won't be null
+ gfax.hylafaxPassword = Settings.Password;
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine ("Initializing hylafax class .......");
+ }
+
+ try {
+ mainclient.Connect(host, port);
+ mainstream = mainclient.GetStream();
+ string s = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine ("[hylafax.connect] on connect : {0}", s);
+ }
+
+
+ if(mainstream.CanWrite && mainstream.CanRead){
+ // Write username
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine ("[hylafax.connect] Sending USER : {0}", user);
+ }
+
+ //If the username is null then hylafax doesn't need usernames
+ // TODO check the hylafax protocol about this
+ if (user == "")
+ user = "anonymous";
+
+ write (mainstream, "USER " + user + "\n");
+ // Read result
+ // If the result is ("230 User <username> logged in.")
+ // I don't need to send a password
+ // Else if the result is ("331 Password required for <username>.")
+ // I must send a password.
+ string returndata = read(mainstream, mainclient);
+
+ if (returndata.Substring(0,3) == "331") {
+ //Console.WriteLine("Password is {0}", gfax.hylafaxPassword);
+ for (int i = 0; i < 3; i++) {
+
+ if (gfax.hylafaxPassword == null) {
+ G_Password gpass = new G_Password();
+ gpass.Run();
+
+ if (gpass.Cancel) {
+ return false; // connection cancelled
+ }
+ gfax.hylafaxPassword = gpass.Password;
+ if (gpass.RememberPassword)
+ Settings.Password = gpass.Password;
+ gpass.Close();
+ }
+ // 530 Login incorrect. result from bad password
+ //prompt for password
+ write (mainstream, "PASS " + gfax.hylafaxPassword + "\n");
+
+ string rtn = read(mainstream, mainclient);
+ //Console.WriteLine("Return is {0}", rtn);
+ if (rtn.Substring(0,3) == "230") // user is logged in
+ break;
+ else {
+ gfax.hylafaxPassword = null;
+ write (mainstream, "USER " + user + "\n");
+ string rtndata = read(mainstream, mainclient);
+ }
+ }
+ }
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.connect] USER returned : {0}", returndata);
+ }
+ }
+ else if (!mainstream.CanRead) {
+ Console.WriteLine(Catalog.GetString("You can not write data to this stream"));
+ mainclient.Close();
+ }
+ else if (!mainstream.CanWrite) {
+ Console.WriteLine(Catalog.GetString("You can not read data from this stream"));
+ mainclient.Close();
+ }
+
+ return true;
+ }
+ catch (Exception e ) {
+ Console.WriteLine(e.ToString());
+ G_Message m = new G_Message(Catalog.GetString("Could not connect to your Hylafax server.\n" +
+ "Check console messages for further information\n\n" +
+ "You might need to set a value for username."));
+ return false;
+ }
+ }
+
+ public void close ()
+ {
+ mainclient.Close();
+ }
+
+ // Method status(queue)
+ //
+ // queue is the queue directory of the hylafax server it can be one of:
+ // 'status', 'sendq', 'doneq' or 'recvq'
+ //
+ // Return a list containing lines
+/*
+ public string status (string queue)
+ {
+ #if DEBUGHYLAFAX
+ Console.WriteLine ("[hylafax.status] queue is : {0}", queue);
+ #endif
+ // try
+ return getfolder(queue);
+ }
+*/
+ public void asyncstatus (string queue)
+ {
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine ("[hylafax.status] queue is : {0}", queue);
+ }
+ asyncgetfolder(queue);
+ }
+
+ // send_init (string filename)
+ //
+ // 2) Store the filename on the server [storefile_open]
+ // 3) Send the file line by line
+ // 4) Close the stream for sending the file
+ public string send_init (string fname)
+ {
+ G_ProgressBar pbar;
+ TcpClient myclient;
+ NetworkStream mystream;
+ StreamReader fp = null;
+ string buf;
+ string remote_fname;
+ double lines = 0;
+ double lines_sent = 0;
+ double percent = 0;
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.send_init] Filename : {0}", fname);
+ }
+
+ //timezone("LOCAL");
+ // Setup the server and return a passive connection
+ // PASV, STOT
+ myclient = storefile_open();
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.send_init] Got tcpclient");
+ }
+
+ mystream = myclient.GetStream();
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.send_init] Stream is open");
+ }
+ //figure out how many lines in the file for progress bar
+ // TODO progress bar and error
+ try { fp = File.OpenText(fname); }
+ catch (Exception e) { }
+
+ while ( (buf = fp.ReadLine()) != null ) {
+ lines = lines + 1;
+ }
+ fp.Close();
+
+ try { fp = File.OpenText(fname); }
+ catch (Exception e) { }
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.send_init] File :{0} is open and has {1} lines", fname,lines);
+ }
+
+ pbar = new G_ProgressBar();
+ //pbar.Text = "File xmit";
+ lines_sent = 1;
+ while ( (buf = fp.ReadLine()) != null ) {
+ write(mystream, buf);
+ write(mystream, "\n");
+ lines_sent = lines_sent + 1;
+ percent = lines_sent / lines;
+ if (percent <= 1.0)
+ pbar.Fraction = percent;
+ //GLib.MainContext.Iteration ();
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+ if (pbar.Cancel)
+ break;
+ }
+ fp.Close();
+ remote_fname = storefile_close(myclient);
+
+ if (pbar.Cancel) { //If the transfer was cancelled
+ deletefile(remote_fname);
+ remote_fname = "cancelled";
+ pbar.Close();
+ } else {
+ pbar.Finished();
+ }
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.send_init] Stream is closed, sent {0} lines",lines_sent);
+ }
+ return remote_fname;
+ }
+
+ // Method send(string filename_on_server, Contact contact)
+ //
+ // Sequence to send a file is:
+ // a) job_new [job_new]
+ // b) set all job parms [job_parm_set]
+ // c) submit the job [submit_job]
+ // format send time - should be as such:
+ // yyyymmddhhmm
+ //-> JPARM SENDTIME 200403100509
+ //213 SENDTIME set to 20040310050900.
+ public void send (string remote_fname, GfaxContact contact)
+ {
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("Hylafax.send] top of method...");
+ }
+
+ string emailAddress = Settings.EmailAddress;
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("Hylafax.send] email address {0}", emailAddress);
+ }
+
+ string resolution = "98";
+ string emailNotify = "none";
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.send] gfax.timeToSend : {0}", gfax.timeToSend);
+ Console.WriteLine("[Hylafax.send] Remote file name is : {0}", remote_fname);
+ }
+
+ // if this is sent from GfaxSend wizard
+ if (gfax.fromSendWizard) {
+ if (gfax.sendWizardResolution)
+ resolution = "196";
+
+ if (gfax.sendWizardEmailNotify) {
+ emailNotify = "done";
+ emailAddress = gfax.sendWizardEmailAddress;
+ }
+ } else {
+ if (Settings.EmailNotify)
+ emailNotify = "done";
+
+ if (Settings.HiResolution)
+ resolution = "196";
+ }
+
+ // Format time to send - timezone is in UTC format.
+ string tts = String.Format("{0}{1:00}{2:00}{3:00}{4:00}",
+ gfax.timeToSend.Year,
+ gfax.timeToSend.Month,
+ gfax.timeToSend.Day,
+ gfax.timeToSend.Hour,
+ gfax.timeToSend.Minute);
+
+ string jid = job_new();
+ //TODO try catch exception here
+ //#item[1] is the name #item[2] is the company
+
+ job_param_set("FROMUSER", Environment.UserName);
+ job_param_set("LASTTIME", "000259");
+ job_param_set("SENDTIME", tts);
+ job_param_set("MAXDIALS", "12");
+ job_param_set("MAXTRIES", "3");
+ job_param_set("SCHEDPRI", "127");
+ job_param_set("DIALSTRING", contact.PhoneNumber);
+ job_param_set("NOTIFYADDR", emailAddress);
+ job_param_set("VRES", resolution);
+ job_param_set("PAGEWIDTH", "215");
+ job_param_set("PAGELENGTH", "279");
+ job_param_set("NOTIFY", emailNotify); //can be "none" or "done"
+ job_param_set("PAGECHOP", "default");
+ job_param_set("CHOPTHRESHOLD", "3");
+ job_param_set("DOCUMENT", remote_fname);
+ job_submit();
+ }
+
+ public bool getfile (string fname)
+ {
+ G_ProgressBar pbar;
+ TcpClient myclient;
+ NetworkStream mystream;
+ FileStream fp;
+ string data;
+ double fsize = 0;
+ double totalBytes = 0;
+ double percent = 0;
+
+ // get the file size for the receive progress bar
+ write(mainstream, String.Concat("SIZE recvq/", fname, "\n"));
+ data = read(mainstream, mainclient);
+ try {
+ string[] s = data.Split();
+ fsize = Convert.ToDouble(s[1]);
+ } catch (Exception e) {
+ Console.WriteLine("Couldn't get file size");
+ Console.WriteLine("Hylafax exception {0}", e);
+ return (false);
+ }
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.getfile] \"File size is : {0}", fsize);
+ }
+
+ // assume we have permission to open file
+ permission = true;
+ // PASV, RETR
+ myclient = recvfile_open(fname);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.getfile] Got tcpclient");
+ }
+
+ mystream = myclient.GetStream();
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[Hylafax.getfile] Stream is open");
+ }
+
+ if (!permission) {
+ return (false);
+ }
+
+ try {
+ fp = new FileStream(String.Concat(gfax.SpoolDirectory,"/tif/",fname), FileMode.Create);
+ } catch (Exception e) {
+ Console.WriteLine(e.ToString());
+ return(false);
+ }
+
+ byte[] bytes = new byte[256];
+
+ do {
+ try {
+ gfax.MainProgressBar.Fraction = percent;
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+
+ int len = mystream.Read(bytes, 0, bytes.Length);
+ if (len > 0 ) {
+ totalBytes = totalBytes + len;
+ percent = totalBytes / fsize;
+ if (percent <= 1.0)
+ gfax.MainProgressBar.Fraction = percent;
+ //GLib.MainContext.Iteration ();
+ while (Gtk.Application.EventsPending ())
+ Gtk.Application.RunIteration ();
+ fp.Write(bytes,0,len);
+ }
+ } catch ( Exception e ) {
+ Console.WriteLine(e.ToString());
+ return(false);
+ }
+ // Seems if we don't sleep here for a bit, we never read
+ // all the data??? Maybe a Hylafax thing.
+ System.Threading.Thread.Sleep(1);
+
+ } while (mystream.DataAvailable);
+
+ fp.Close();
+ recvfile_close(myclient);
+
+ // valid file received
+ return(true);
+ }
+
+
+
+ private string job_new ()
+ {
+ string data;
+ string[] tmp;
+ //string jobid;
+
+ try {
+ write(mainstream, "JOB default\n");
+ data = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.job_new] \"JOB default\" data returned : {0}", data);
+ }
+
+ write(mainstream, "JNEW\n");
+ data = read(mainstream, mainclient);
+ // data = 200 New job created: jobid: 14433 groupid: 14433.
+ tmp = data.Split(' ');
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.job_new] \"JNEW\" data returned : {0}", data);
+ }
+
+ } catch (Exception e) {
+ Console.WriteLine("Hylafax exception {0}", e);
+ return ("");
+ }
+
+ // jobid might need to be Convert.ToInt32
+ return tmp[5];
+ }
+
+ public void job_param_set (string pname, string pvalue)
+ {
+ string data;
+
+ write(mainstream, "JPARM " + pname + " " + pvalue +"\n");
+ data = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.Write("[hylafax.job_param_set] \"JPARM\" data returned : {0}", data);
+ }
+ }
+
+ public void job_submit ()
+ {
+ string data;
+
+ write(mainstream, "JSUBM\n");
+ data = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.job_submit] \"JSUBM\" data returned : {0}", data);
+ }
+ }
+
+ private TcpClient storefile_open ()
+ {
+ TcpClient myclient = new TcpClient();
+ NetworkStream mystream;
+ IPAddress ipaddr;
+ int ipport;
+ string data;
+
+ write(mainstream, "PASV\n");
+ data = read(mainstream, mainclient);
+
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.storefile_open] data returned : {0}", data);
+ }
+
+ // dig out ip address and port for new connection
+ ipaddr = get_ip_addr(data);
+ ipport = get_ip_port(data);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.storefile_open] ipaddr, port : {0}, {1}", ipaddr, ipport);
+ }
+
+ try {
+ myclient.Connect(ipaddr, ipport);
+ }
+ catch (Exception e ) {
+ Console.WriteLine(e.ToString());
+ // handle error here
+ }
+
+ mystream = myclient.GetStream();
+ write(mainstream, "STOT\n");
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.storefile_open] wrote STOT");
+ }
+ data = read(mainstream, mainclient);
+ //data = 150 FILE: /tmp/doc1097.ps (Opening new data connection).
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.storefile_open] returned from STOT : {0}", data);
+ }
+ return myclient;
+ }
+
+ private string storefile_close(TcpClient tc)
+ {
+ string data;
+ string[] s;
+ string fn;
+
+ tc.Close();
+ data = read(mainstream, mainclient);
+ // data = 226 Transfer complete (FILE: /tmp/doc1101.ps).
+ // TODO error checking
+
+ // remove white space first, Arrgggh!
+ fn = data.Trim();
+ s = fn.Split(' ');
+
+ return(s[4].TrimEnd(')','.'));
+ }
+
+ private TcpClient recvfile_open (string fname)
+ {
+ TcpClient myclient = new TcpClient();
+ NetworkStream mystream;
+ IPAddress ipaddr;
+ int ipport;
+ string data;
+
+ write(mainstream, "PASV\n");
+ data = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.recvfile_open] data returned : {0}", data);
+ }
+
+ // dig out ip address and port for new connection
+ ipaddr = get_ip_addr(data);
+ ipport = get_ip_port(data);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.recvfile_open] ipaddr, port : {0}, {1}", ipaddr, ipport);
+ }
+
+ try {
+ myclient.Connect(ipaddr, ipport);
+ }
+ catch (Exception e ) {
+ Console.WriteLine(e.ToString());
+ // handle error here
+ }
+
+ mystream = myclient.GetStream();
+ write(mainstream, "TYPE I\n");
+ data = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.recvfile_open] data returned : {0}", data);
+ }
+
+ write(mainstream, String.Concat("RETR recvq/", fname, "\n"));
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.recvfile_open] wrote RETR");
+ }
+ data = read(mainstream, mainclient);
+
+ if (data.Substring(0,3) == "550")
+ permission = false;
+ //data = returned from RETR : 550 recvq/fax000000018.tif: Operation not permitted.
+ //data = returned from RETR : 150 Opening new data connection for recvq/fax000000018.tif (2793 bytes).
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.recvfile_open] returned from RETR : {0}", data);
+ }
+ return myclient;
+ }
+
+ private string recvfile_close(TcpClient tc)
+ {
+ string data;
+ string[] s;
+ string fn;
+
+ tc.Close();
+ data = read(mainstream, mainclient);
+ // data = 226 Transfer complete (FILE: /tmp/doc1101.ps).
+ // TODO error checking
+
+ // remove white space first, Arrgggh!
+ //fn = data.Trim();
+ //s = fn.Split(' ');
+
+ //return(s[4].TrimEnd(')','.'));
+ return "";
+ }
+
+/*
+ private string getfolder (string folder)
+ {
+ TcpClient myclient = new TcpClient();
+ NetworkStream mystream;
+ IPAddress ipaddr;
+ int ipport;
+ string jobfmt;
+
+ write(mainstream, "PASV\n");
+ string data = read(mainstream, mainclient);
+
+ // dig out ip address and port for new connection
+ ipaddr = get_ip_addr(data);
+ ipport = get_ip_port(data);
+
+ try {
+ myclient.Connect(ipaddr, ipport);
+ }
+ catch (Exception e ) {
+ Console.WriteLine(e.ToString());
+ // handle error here
+ }
+
+ mystream = myclient.GetStream();
+ /*
+ RCVFMT (receive)
+ %4p%1z %14.14s %7t %f
+ p - number of pages
+ z - * if still receiving, <space> otherwise
+ s - sender (TIS)
+ t - time received
+ f - filename
+
+ 1= =Malaspina Univ=16Oct06=fax000000018.tif
+
+ JOBFMT (send, done)
+ j - Job identifier
+ e - Phone number
+ a - Job state (one-character symbol)
+ o - Job owner
+ P - # pages transmitted/total # pages to transmit
+ D - Total # dials/maximum # dials
+ s - Job status information from last failure
+ Y - Scheduled date and time
+ */
+/* // set the job format string
+ if (folder == "doneq" || folder == "sendq") {
+ jobfmt = "\"%-4j=%-14e=%1a=%-12o=%-5P=%-5D=%.35s=%-19Y\"";
+ write(mainstream, "JOBFMT "+jobfmt+"\n");
+ data = read(mainstream, mainclient);
+ }
+ if (folder == "recvq") {
+ jobfmt = "\"%4p=N%1z=%14.14s=%7t=%f\"";
+ write(mainstream, "RCVFMT "+jobfmt+"\n");
+ data = read(mainstream, mainclient);
+ }
+ write(mainstream, "LIST "+folder+"\n");
+ data = read(mystream, myclient);
+
+
+ #if DEBUGHYLAFAX
+ Console.WriteLine("[hylafax.getfolder] list folder data : {0}", data);
+ Console.WriteLine("[hylafax.getfolder] data length : {0}", data.Length);
+ #endif
+
+ myclient.Close();
+ return data;
+ }
+*/
+
+ private void asyncgetfolder (string folder)
+ {
+ TcpClient myclient = new TcpClient();
+ IPAddress ipaddr;
+ int ipport;
+ string jobfmt;
+
+ write(mainstream, "PASV\n");
+ string data = read(mainstream, mainclient);
+
+ // dig out ip address and port for new connection
+ ipaddr = get_ip_addr(data);
+ ipport = get_ip_port(data);
+
+ try {
+ myclient.Connect(ipaddr, ipport);
+ }
+ catch (Exception e ) {
+ Console.WriteLine(e.ToString());
+ // handle error here
+ }
+
+ /*
+ RCVFMT (receive)
+ %4p%1z %14.14s %7t %f
+ p - number of pages
+ z - * if still receiving, <space> otherwise
+ s - sender (TIS)
+ t - time received
+ f - filename
+
+ 1= =Malaspina Univ=16Oct06=fax000000018.tif
+
+ JOBFMT (send, done)
+ j - Job identifier
+ e - Phone number
+ a - Job state (one-character symbol)
+ o - Job owner
+ P - # pages transmitted/total # pages to transmit
+ D - Total # dials/maximum # dials
+ s - Job status information from last failure
+ Y - Scheduled date and time
+ */
+ // set the job format string
+ if (folder == "doneq" || folder == "sendq") {
+ jobfmt = "\"%-4j=%-14e=%1a=%-12o=%-5P=%-5D=%.35s=%-19Y\"";
+ write(mainstream, "JOBFMT "+jobfmt+"\n");
+ data = read(mainstream, mainclient);
+ }
+ if (folder == "recvq") {
+ jobfmt = "\"%4p=N%1z=%28.28s=%7t=%f\"";
+ write(mainstream, "RCVFMT "+jobfmt+"\n");
+ data = read(mainstream, mainclient);
+ }
+ write(mainstream, "LIST "+folder+"\n");
+ //data = read(mystream, myclient);
+ asyncread(myclient, folder);
+ }
+
+ private IPAddress get_ip_addr (string ipdata)
+ {
+ int index = ipdata.IndexOf("(");
+ int len = ipdata.IndexOf(")") - index;
+ string s = ipdata.Substring(index + 1, len - 1 );
+ char[] splitter = {','};
+ string[] sa = s.Split(splitter);
+ string sipaddr = String.Concat(sa[0],".",sa[1],".",sa[2],".",sa[3]);
+ return IPAddress.Parse(sipaddr);
+ }
+
+ private int get_ip_port (string ipdata)
+ {
+ // find port returned
+ int index = ipdata.IndexOf("(");
+ int len = ipdata.IndexOf(")") - index;
+ string s = ipdata.Substring(index + 1, len - 1 );
+ char[] splitter = {','};
+ string[] sa = s.Split(splitter);
+ return (Convert.ToInt32(sa[4]) * 256 + Convert.ToInt32(sa[5]));
+ }
+
+
+ private void write (NetworkStream sock, string s)
+ {
+ byte[] bytes = Encoding.ASCII.GetBytes(s);
+ sock.Write(bytes, 0, bytes.Length);
+ }
+
+
+ private string read (NetworkStream str, TcpClient c)
+ {
+ StringBuilder buf = new StringBuilder();
+ byte[] bytes = new byte[256];
+
+ do {
+ try {
+ int len = str.Read(bytes, 0, bytes.Length);
+ if (len > 0 ) {
+ buf.Append(Encoding.ASCII.GetString(bytes,0,len));
+ }
+ } catch ( Exception e ) {
+ Console.WriteLine("Network IO problem " + e.ToString());
+ }
+ // Seems if we don't sleep here for a bit, we never read
+ // all the data??? Maybe a Hylafax thing.
+ System.Threading.Thread.Sleep(5);
+
+ } while (str.DataAvailable);
+ return (buf.ToString());
+ }
+
+
+ //public void asyncread (TcpClient sock, string readType)
+ private void asyncread (TcpClient sock, string readType)
+ {
+ gfax.activeNetwork = true;
+ if (readType == "status") {
+ gfax.asyncServerMessageBuffer = "";
+ } else {
+ gfax.asyncFolderMessageBuffer = "";
+ }
+
+ StateObject state = new StateObject();
+ state.client = sock;
+ state.readType = readType;
+ NetworkStream stream = sock.GetStream();
+
+ if (stream.CanRead) {
+ try {
+ IAsyncResult ar = stream.BeginRead (state.buffer, 0, StateObject.BufferSize,
+ new AsyncCallback(myReadCallBack), state);
+ } catch ( Exception e ) {
+ Console.WriteLine("Network IO problem " + e.ToString());
+ }
+ }
+ }
+
+
+ //========================================================
+ //public static void myReadCallBack(IAsyncResult ar )
+ private static void myReadCallBack(IAsyncResult ar )
+ {
+ int numberOfBytesRead;
+ StateObject state = (StateObject) ar.AsyncState;
+ NetworkStream mas = state.client.GetStream();
+ string type = null;
+
+ numberOfBytesRead = mas.EndRead(ar);
+ state.totalBytesRead += numberOfBytesRead;
+
+ //Console.WriteLine("Byes read ---------------> {0}", numberOfBytesRead);
+ if ( numberOfBytesRead > 0) {
+ state.messageBuffer.Append(Encoding.ASCII.GetString(state.buffer, 0, numberOfBytesRead));
+ mas.BeginRead(state.buffer, 0, StateObject.BufferSize,
+ new AsyncCallback(myReadCallBack), state);
+ } else {
+ mas.Close();
+ state.client.Close();
+ //Console.WriteLine("Byes read ---------------> {0}", state.totalBytesRead);
+ //Console.WriteLine("You received the following message : {0} " + state.messageBuffer);
+ if (state.readType == "status") {
+ gfax.asyncServerMessageBuffer = state.messageBuffer.ToString();
+ } else {
+ gfax.asyncFolderMessageBuffer = state.messageBuffer.ToString();
+ }
+ gfax.asyncReadType = state.readType;
+ mas = null;
+ state = null;
+ gfax.activeNetwork = false;
+ }
+ }
+
+ public void job_select (string jobid)
+ {
+ write(mainstream, "JOB " + jobid + "\n");
+ string s = read(mainstream, mainclient);
+ #if DEBUGHYLAFAX
+ Console.WriteLine("[hylafax.select] returned: {0}", s);
+ #endif
+ }
+
+ public void job_kill ()
+ {
+ write (mainstream, "JKILL\n");
+ string s = read(mainstream, mainclient);
+ #if DEBUGHYLAFAX
+ Console.WriteLine("[hylafax.kill] returned: {0}", s);
+ #endif
+ }
+
+ public void job_delete ()
+ {
+ write (mainstream, "JDELE\n");
+ string s = read(mainstream, mainclient);
+ #if DEBUGHYLAFAX
+ Console.WriteLine("[hylafax.delete] returned: {0}", s);
+ #endif
+ }
+
+ public void job_suspend ()
+ {
+ write (mainstream, "JSUSP\n");
+ string s = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.suspend] returned: {0}", s);
+ }
+ }
+
+ // Returns
+ // 550 fax000000019.tif: Operation not permitted.
+ //
+ public int deletefile (string name)
+ {
+ write (mainstream, String.Concat("DELE ", "recvq/", name, "\n"));
+ string s = read(mainstream, mainclient);
+ if (s.Substring(0,3) == "550")
+ return(1);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.deletefile] returned: {0}", s);
+ }
+ return (0);
+ }
+
+
+ private void job_param (string parms)
+ {
+ write (mainstream, "JPARM " + parms + "\n");
+ string s = read(mainstream, mainclient);
+ #if DEBUGHYLAFAX
+ Console.WriteLine("[hylafax.param] returned: {0}", s);
+ #endif
+ }
+
+ public void job_reset (string parms)
+ {
+ write (mainstream, "JREST " + parms + "\n");
+ string s = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.reset] returned: {0}", s);
+ }
+
+ }
+
+
+ private void timezone (string name) // can be "LOCAL" or "GMT"
+ {
+ write (mainstream, "TZONE " + name + "\n");
+ string s = read(mainstream, mainclient);
+ if (Settings.Faxtracing == true) {
+ Console.WriteLine("[hylafax.timezone] returned: {0}", s);
+ }
+ }
+ }
+}
diff --git a/src/main.cs b/src/main.cs
new file mode 100644
index 0000000..e44b897
--- /dev/null
+++ b/src/main.cs
@@ -0,0 +1,243 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace gfax {
+ using GLib;
+ using Gtk;
+ using GtkSharp;
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using System.Collections;
+ using System.Text; //Encoding.ASCII.GetBytes
+ using System.Threading;
+ using System.Diagnostics;
+
+
+
+ public class gfax
+ {
+ // Gfax Global variables ( ya, ya I know)
+ //
+ // list of contacts of type Contact to xmit, we use this everywhere so it is
+ // simpler to make it public and global.
+ public static ArrayList Destinations = new ArrayList();
+ public static DateTime timeToSend;
+ public static bool quitAfterSend = false;
+ public static bool fromSendWizard = false;
+ public static bool sendWizardResolution = false;
+ public static bool sendWizardEmailNotify = false;
+ public static string sendWizardEmailAddress = null;
+ public static string hylafaxPassword = null;
+ public static string ConfigDirectory = null;
+ public static string SpoolDirectory = null;
+ public static bool activeNetwork = false;
+ public static Gnome.AppBar GAppbar = null;
+ public static Gtk.ProgressBar MainProgressBar = null;
+ public static Gtk.TextBuffer GStatusTextBuffer = null;
+ public static Gtk.Window MainWindow = null;
+ public static string asyncFolderMessageBuffer = "";
+ public static string asyncServerMessageBuffer = "";
+ public static string asyncReadType = "";
+
+ public static Efax efax;
+ public static Status Status;
+ public static Pulser Pulser;
+
+ public static string filename = null;
+ public static string[] pargs;
+
+ const bool TOPLEVEL = true;
+
+
+ public static void Main (string[] args)
+ {
+
+ string HOMEDIR = Environment.GetEnvironmentVariable("HOME");
+ string USER = Environment.GetEnvironmentVariable("USER");
+ ConfigDirectory = HOMEDIR + "/.config/gfax";
+ SpoolDirectory = HOMEDIR + "/.local/share/gfax/spool";
+ pargs = args;
+
+ // TODO put this is try/catch
+ if ( !Directory.Exists(ConfigDirectory)) {
+ if ( !Directory.Exists(HOMEDIR + "/.config")) {
+ Directory.CreateDirectory(HOMEDIR + "/.config");
+ }
+ // Move data from old ~/.etc directory
+ if ( Directory.Exists(HOMEDIR + "/.etc/gfax")) {
+ Directory.Move(HOMEDIR + "/.etc/gfax", ConfigDirectory);
+ } else {
+ Directory.CreateDirectory(ConfigDirectory);
+ }
+ }
+ if ( !Directory.Exists(HOMEDIR + "/.local/share/gfax/spool") ) {
+ if ( !Directory.Exists(HOMEDIR + "/.local/share/gfax") ) {
+ if ( !Directory.Exists(HOMEDIR + "/.local/share") ) {
+ if ( !Directory.Exists(HOMEDIR + "/.local") )
+ Directory.CreateDirectory(HOMEDIR + "/.local");
+ Directory.CreateDirectory(HOMEDIR + "/.local/share");
+ }
+ Directory.CreateDirectory(HOMEDIR + "/.local/share/gfax");
+ }
+ Directory.CreateDirectory(HOMEDIR + "/.local/share/gfax/spool");
+ Directory.CreateDirectory(HOMEDIR + "/.local/share/gfax/spool/doneq");
+ Directory.CreateDirectory(HOMEDIR + "/.local/share/gfax/spool/recq");
+ }
+
+ // Clean out the spool/tif directory - incoming faxes
+ if ( !Directory.Exists(HOMEDIR + "/.local/share/gfax/spool/tif")) {
+ Directory.CreateDirectory(HOMEDIR + "/.local/share/gfax/spool/tif");
+ } else {
+ Directory.Delete(HOMEDIR + "/.local/share/gfax/spool/tif/", true);
+ Directory.CreateDirectory(HOMEDIR + "/.local/share/gfax/spool/tif");
+ }
+
+
+
+ // Initialize GETTEXT
+ Catalog.Init ("gfax", Defines.GNOME_LOCALE_DIR);
+
+ // handle command line args ourselves
+ for (int i=0; i < args.Length; i++ ) {
+ //Console.WriteLine("{0} {1}", i, args[i]);
+ switch (args[i])
+ {
+ case "--help" :
+ Console.WriteLine (Catalog.GetString("Gfax help..."));
+ Console.WriteLine ("Gfax spool dir -> {0}", SpoolDirectory);
+ break;
+ case "-f" : // file name is present
+ filename = args[i+1];
+ break;
+ //case "-q" : // immediately quit after sending fax
+ // filename = args[i+1];
+ // break;
+ default:
+ if (File.Exists(args[i]))
+ filename = args[i];
+ break;
+ }
+ }
+
+ try {
+ if ( Settings.RunSetupAtStart ) {
+ // Set some default preferences.
+ Settings.TransmitAgent = "efax";
+ Settings.SendNow = true;
+ Settings.EfaxModemDevice = "ttyS0";
+ Settings.RefreshQueueInterval = 15;
+ Settings.RefreshQueueEnabled = true;
+ }
+ } catch (Exception e) {
+ //TODO HIG love required
+ G_Message gm = new G_Message(
+ Catalog.GetString(
+@"Gconfd cannot find your settings.
+If you are running Gfax immediately
+after an installation, you may have
+to log out and log back in again."), TOPLEVEL);
+ Console.WriteLine("Exception in main.cs {0}", e);
+ Environment.Exit(0);
+ }
+
+ // If we have a file name run the send dialog
+ if (filename != null) {
+ GfaxSend sd = new GfaxSend (filename, args);
+ FileInfo f = new FileInfo(filename);
+
+ // send the faxes
+ if (sd.DoSend) {
+ fromSendWizard = true;
+
+ // Start the fax daemon if efax
+ if (Settings.TransmitAgent == "efax") {
+ efax = new Efax();
+ efax.run_efaxd();
+ }
+
+ Fax.sendfax(filename);
+ // delete the spool file (~.local/share/gfax/spool/D.*)
+ if (File.Exists(String.Concat(SpoolDirectory, "/", f.Name)))
+ File.Delete(String.Concat(SpoolDirectory, "/", f.Name));
+
+ //if (!quitAfterSend) {
+ //Gfax gf = new Gfax (filename, args);
+ //}
+ }
+
+ // delete the spool file that gfaxlpr created if it exists
+ if (File.Exists(String.Concat("/var/spool/gfax/", USER, "/", f.Name)))
+ File.Delete(String.Concat("/var/spool/gfax/", USER, "/", f.Name));
+
+ }else {
+ // check to see if we've run before, if so gfax will be there
+
+ if ( !Directory.Exists("/var/spool/gfax/" + USER)) {
+ Directory.CreateDirectory("/var/spool/gfax/" + USER);
+ }
+
+ FileSystemWatcher watcher = new FileSystemWatcher();
+ watcher.Path = "/var/spool/gfax/" + USER;
+
+ watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
+ | NotifyFilters.FileName | NotifyFilters.DirectoryName;
+ // Only watch text files.
+ watcher.Filter = "*";
+ watcher.Created += new FileSystemEventHandler(TIOnChanged);
+ // Begin watching.
+ watcher.EnableRaisingEvents = true;
+
+ // Start the fax daemon if efax
+ if (Settings.TransmitAgent == "efax") {
+ efax = new Efax();
+ efax.run_efaxd();
+ }
+
+ Gfax gf = new Gfax (filename, args);
+ }
+
+ }
+
+ // Define the event handlers.
+ private static void TIOnChanged(object source, FileSystemEventArgs e)
+ {
+ // Specify what is done when a file is changed, created, or deleted.
+ Console.WriteLine("File---: " + e.FullPath + " " + e.ChangeType);
+ //GfaxSend sd = new GfaxSend ("/home/george/log.txt", pargs);
+
+ quitAfterSend = true;
+
+ ProcessStartInfo pidInfo = new ProcessStartInfo();
+ pidInfo.FileName = "gfax";
+
+ pidInfo.Arguments = String.Concat("-f ",e.FullPath + " " + e.ChangeType);
+
+ if (Settings.Faxtracing == true) {
+ if (Settings.TransmitAgent == "efax") {
+ Console.WriteLine("[Efax.send_init]\n {0}", pidInfo.Arguments);
+ }
+ }
+
+ System.Diagnostics.Process pid = System.Diagnostics.Process.Start(pidInfo);
+ pid.WaitForExit();
+
+
+ }
+
+ }
+}
diff --git a/src/newphonebook.cs b/src/newphonebook.cs
new file mode 100755
index 0000000..1424977
--- /dev/null
+++ b/src/newphonebook.cs
@@ -0,0 +1,187 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+//************************************************************************
+// NewPhoneBook class
+//
+// A new phone book druid, should make it easier for people to create
+// new phone books. The old way was a little confusing.
+//
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using GLib;
+ using Gtk;
+ using Gnome;
+ using Glade;
+ using GConf.PropertyEditors;
+ using GtkSharp;
+ using System.Runtime.InteropServices;
+ using System.Collections;
+ using System.Diagnostics;
+ using System.Reflection;
+
+ public class NewPhoneBook
+ {
+ [Glade.Widget] Gtk.Dialog NewPhoneBookDialog;
+ [Glade.Widget] Gnome.Druid NewPhoneBookDruid;
+ [Glade.Widget] Gnome.DruidPage EvoDruidPageStandard;
+ [Glade.Widget] Gnome.DruidPage druidpagestandard12;
+ [Glade.Widget] Gtk.RadioButton GfaxRadioButton;
+ [Glade.Widget] Gtk.RadioButton EvolutionRadioButton;
+ [Glade.Widget] Gtk.RadioButton DatabaseRadioButton;
+ [Glade.Widget] Gtk.RadioButton LDAPRadioButton;
+ [Glade.Widget] Gtk.Entry NewPhoneBookNameEntry;
+ [Glade.Widget] Gtk.TreeView EvolutionTreeView;
+
+ // Properties
+ ArrayList booknames;
+ string phonebooktype;
+
+ Gtk.ListStore store;
+ G_ListView view;
+
+ const int COLUMN_0 = 0;
+ const int COLUMN_1 = 1;
+
+ public NewPhoneBook ()
+ {
+ booknames = new ArrayList();
+
+ Glade.XML xml = new Glade.XML (null, "gfax.glade","NewPhoneBookDialog",null);
+ xml.Autoconnect (this);
+
+ GfaxRadioButton.Active = true;
+
+ EvolutionRadioButton.Sensitive = true;
+ // turn these off until somewhere near supported
+ DatabaseRadioButton.Visible = false;
+ LDAPRadioButton.Visible = false;
+
+ store = new ListStore(
+ typeof (Boolean),
+ typeof (string));
+
+ view = new G_ListView(EvolutionTreeView, store);
+
+ view.AddColumnTitleToggle(Catalog.GetString("Use"), 0, COLUMN_0);
+ view.AddColumnTitle(Catalog.GetString("Phone Book"), 0, COLUMN_1);
+
+ EvolutionTreeView.HeadersVisible = true;
+
+ NewPhoneBookDruid.ShowAll();
+ }
+
+ public ArrayList PhoneBookNames
+ {
+ get { return booknames; }
+ }
+
+ public string PhoneBookType
+ {
+ get { return phonebooktype; }
+ }
+
+ public void Run()
+ {
+ NewPhoneBookDialog.Run();
+ }
+
+ private void on_NewPhoneBookDialog_delete_event (object o, DeleteEventArgs args)
+ {
+ NewPhoneBookDialog.Hide();
+ NewPhoneBookDialog.Dispose();
+ args.RetVal = true;
+ }
+
+ private void on_NewPhoneBookDruidEdge_finish (object o, Gnome.FinishClickedArgs args)
+ {
+
+ if (GfaxRadioButton.Active) {
+ phonebooktype = "gfax";
+ booknames.Add( NewPhoneBookNameEntry.Text );
+ } else if (EvolutionRadioButton.Active) {
+ phonebooktype = "evolution";
+
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+
+ // Get the first row.
+ store.GetIterFirst(out iter);
+
+ try {
+ if ( (bool)store.GetValue(iter, 0) ) { // if use is true (toggle set)
+ booknames.Add( (string)store.GetValue(iter, 1) );
+ }
+ } catch (Exception e) {}
+
+ // get the rest of the rows
+ while (store.IterNext(ref iter)) {
+
+ try {
+ if ( (bool)store.GetValue(iter, 0) ) {
+ booknames.Add( (string)store.GetValue(iter, 1) );
+ }
+ }
+ catch (Exception e) {}
+ }
+ }
+ else if (DatabaseRadioButton.Active)
+ phonebooktype = "sql";
+ else if (LDAPRadioButton.Active)
+ phonebooktype = "ldap";
+
+ NewPhoneBookDialog.Hide();
+ NewPhoneBookDialog.Dispose();
+ }
+
+ private void on_NewPhoneBookDruid_cancel (object o, EventArgs args)
+ {
+ NewPhoneBookDialog.Hide();
+ NewPhoneBookDialog.Dispose();
+ }
+
+ private void on_druidpagestandard12_next (object o, Gnome.NextClickedArgs args)
+ {
+ // we're on the gfax phone book enter name pages
+ // skip to finish on next signal
+ NewPhoneBookDruid.Page = EvoDruidPageStandard;
+ }
+
+
+ private void on_BookDruidPageStandard_next (object o, Gnome.NextClickedArgs args)
+ {
+ // skip next page if active
+ if (EvolutionRadioButton.Active) {
+ NewPhoneBookDruid.Page = druidpagestandard12;
+
+ EdsPhoneBooks eds = new EdsPhoneBooks();
+ ArrayList ebooks = new ArrayList();
+ ebooks = eds.GetPhoneBooks();
+
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+
+ IEnumerator enu = ebooks.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ iter = store.AppendValues(false, enu.Current);
+ EvolutionTreeView.Model = store;
+ }
+ }
+ }
+ }
+}
diff --git a/src/phonebook.cs b/src/phonebook.cs
new file mode 100755
index 0000000..fbb8621
--- /dev/null
+++ b/src/phonebook.cs
@@ -0,0 +1,386 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using System.Text;
+ using System.Collections;
+
+ // Phone book that holds multiple numbers
+ public class Phonebook
+ {
+ public string Name; //Name book is called by
+ public string Path; //Filename including path
+ public string Type; // Type of phone book (gfax,gcard etc)
+ }
+
+ // Individual contact in phone book
+ public class GfaxContact
+ {
+ public string Organization;
+ public string PhoneNumber;
+ public string ContactPerson;
+ }
+
+ public class Phonetools
+ {
+ public static Phonebook[] get_phonebooks ()
+ {
+ StreamReader infile = null;
+ string buf;
+ bool migrate = false;
+
+ Phonebook[] pbooks = null;
+
+ // TODO get location from gconf
+ string HOMEDIR = Environment.GetEnvironmentVariable("HOME");
+ string PHONEBOOKS = gfax.ConfigDirectory + "/phonebooks";
+
+ #if DEBUG
+ Console.WriteLine("[Phonebook] Reading phonebook file");
+ #endif
+
+ int numberOfBooks = get_number_of_books();
+ pbooks = new Phonebook[numberOfBooks];
+
+ if (numberOfBooks == 0) {
+ return (pbooks);
+ }
+
+
+ try {
+ infile = File.OpenText(PHONEBOOKS);
+ int i = 0;
+
+ while ( (buf = infile.ReadLine()) != null ) {
+ switch (buf.Trim()) {
+ case "<book>" :
+ // TODO more robust file reading
+ Phonebook c = new Phonebook();
+ c.Name = strip_tag(infile.ReadLine(), "name");
+ c.Type = strip_tag(infile.ReadLine(), "type");
+ c.Path = strip_tag(infile.ReadLine(), "path");
+
+ // Migrate from old location
+ if (c.Type == "gfax") {
+ if (Path.GetDirectoryName(c.Path) == HOMEDIR + "/.etc/gfax") {
+ c.Path = gfax.ConfigDirectory + "/" + Path.GetFileName(c.Path);
+ migrate = true;
+ }
+ }
+
+ pbooks[i++] = c;
+ continue;
+ }
+ }
+
+ infile.Close();
+ if (migrate)
+ save_phonebooks(pbooks);
+ return pbooks;
+ }
+ catch (Exception e) {
+ Console.WriteLine("get_phonebooks - Exception in phonebook.cs {0}", e);
+ return pbooks;
+ }
+
+ }
+
+ // save or create phonebooks files
+ public static void save_phonebooks (Phonebook[] pbooks)
+ {
+ StreamWriter outfile;
+
+ // TODO get location from gconf
+ string PHONEBOOKS = gfax.ConfigDirectory + "/phonebooks";
+
+ try {
+ outfile = File.CreateText(PHONEBOOKS);
+ } catch (Exception e) {
+ Console.WriteLine("Exception in phonebook.cs {0}", e);
+ return;
+ }
+
+ outfile.WriteLine("<gfax>");
+ Console.WriteLine("Len :{0}", pbooks.Length);
+ foreach (Phonebook p in pbooks) {
+ outfile.WriteLine(" <book>");
+ outfile.WriteLine(" <name>" + p.Name + "</name>");
+ outfile.WriteLine(" <type>" + p.Type + "</type>");
+ outfile.WriteLine(" <path>" + p.Path + "</path>");
+ outfile.WriteLine(" </book>");
+ }
+ outfile.WriteLine("</gfax>");
+ outfile.Close();
+ }
+
+ public static void delete_book (string book)
+ {
+ StreamReader infile = null;
+ string buf;
+ string deleteme = null;
+ Phonebook[] pbooks = null;
+
+ // make array size less 1 because we're deleting 1
+ pbooks = new Phonebook[get_number_of_books() - 1];
+
+ // TODO get location from gconf
+ string PHONEBOOKS = gfax.ConfigDirectory + "/phonebooks";
+ string type = "";
+ try {
+ infile = File.OpenText(PHONEBOOKS);
+ int i = 0;
+
+ // iterate through the phonebook file and skip past book to delete
+ while ( (buf = infile.ReadLine()) != null ) {
+ switch (buf.Trim()) {
+ case "<book>" :
+ // TODO more robust file reading
+ Phonebook c = new Phonebook();
+ c.Name = strip_tag(infile.ReadLine(), "name");
+ c.Type = strip_tag(infile.ReadLine(), "type");
+ c.Path = strip_tag(infile.ReadLine(), "path");
+
+ if (c.Name != book)
+ pbooks[i++] = c;
+ else {
+ deleteme = c.Path;
+ type = "gfax";
+ }
+ continue;
+ }
+ }
+ infile.Close();
+ save_phonebooks(pbooks);
+
+ if (type == "gfax")
+ if (File.Exists(deleteme))
+ File.Delete(deleteme);
+ }
+ catch (Exception e) {
+ Console.WriteLine("delete_book - Exception in phonebook.cs {0}", e);
+ return;
+ }
+ }
+
+ // Create or add the new phone book to the "phonebooks" file.
+ public static void add_book (Phonebook p)
+ {
+ StreamReader infile = null;
+ string buf;
+ Phonebook[] pbooks = null;
+
+ // make array plus 1 because we're adding 1
+ pbooks = new Phonebook[get_number_of_books() + 1];
+
+ // TODO get location from gconf
+ string PHONEBOOKS = gfax.ConfigDirectory + "/phonebooks";
+
+ if (p.Type == "gfax") {
+ // add default path if not specified
+ if (Path.GetDirectoryName(p.Path) == "")
+ p.Path = gfax.ConfigDirectory + p.Path;
+ }
+ // Create the file.
+ if (!File.Exists(PHONEBOOKS)) {
+ FileStream fs = File.Create(PHONEBOOKS);
+ fs.Close();
+ }
+
+ int i = 0;
+ try {
+ infile = File.OpenText(PHONEBOOKS);
+
+ while ( (buf = infile.ReadLine()) != null ) {
+ switch (buf.Trim()) {
+ case "<book>" :
+ // TODO more robust file reading
+ Phonebook c = new Phonebook();
+ c.Name = strip_tag(infile.ReadLine(), "name");
+ c.Type = strip_tag(infile.ReadLine(), "type");
+ c.Path = strip_tag(infile.ReadLine(), "path");
+
+ pbooks[i++] = c;
+ continue;
+ }
+ }
+ infile.Close();
+ }
+ catch (Exception e) {
+ // TODO catch file ops error
+ Console.WriteLine("add_book - Exception in phonebook.cs {0}", e);
+ return;
+ }
+
+
+ pbooks[i++] = p; // add the new book
+ save_phonebooks(pbooks);
+ }
+
+ // save a list (ArrayList) of contacts
+ public static void save_phonebook_items (string book, ArrayList contacts)
+ {
+ Phonebook p;
+ StreamWriter outfile;
+
+ p = get_book_from_name(book);
+
+ if (p.Type == "gfax") {
+ // TODO error reporting
+ try { outfile = File.CreateText(p.Path); }
+ catch (Exception e) {
+ Console.WriteLine("save_phonebook_items - Exception in phonebook.cs {0}", e);
+ return;
+ }
+
+ outfile.WriteLine("#Gfax phone book");
+
+ IEnumerator enu = contacts.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ GfaxContact c = new GfaxContact();
+ c = (GfaxContact)enu.Current;
+ outfile.WriteLine("{0}:{1}:{2}",c.PhoneNumber,c.ContactPerson,c.Organization);
+ }
+ outfile.Close();
+ }
+ }
+
+ public static StreamReader open_phonebook (Phonebook p)
+ {
+ StreamReader infile = null;
+
+ // If it doesn't exist yet just return
+ if (!File.Exists(p.Path))
+ return(null);
+
+ try {
+ infile = File.OpenText(p.Path);
+ }
+ catch (Exception e) {
+ Console.WriteLine("open_phonebook - Exception in phonebook.cs {0}", e);
+ return null;
+ }
+ return infile;
+ }
+
+ public static ArrayList get_contacts (Phonebook p)
+ {
+ string buf = null;
+ string[] sa;
+ //char[] ca = {':',':',':'}; delete me
+
+ ArrayList records = new ArrayList();
+ StreamReader fp = null;
+
+ // TODO add popup message
+ if ( p.Type == "gfax" ) {
+ fp = open_phonebook(p);
+ if (fp == null) {
+ Console.WriteLine(Catalog.GetString("Can't open file : {0}"), p.Path);
+ return records;
+ }
+
+ while ( (buf = fp.ReadLine()) != null ) {
+ buf.Trim();
+
+ if (buf[0] == '#')
+ continue;
+ else {
+ sa = buf.Split(':');
+ GfaxContact contact = new GfaxContact();
+ contact.PhoneNumber = sa[0];
+ contact.ContactPerson = sa[1];
+ contact.Organization = sa[2];
+ records.Add(contact);
+ }
+ }
+
+ fp.Close();
+ }
+
+ if ( p.Type == "evolution" ) {
+ EdsPhoneBooks eds = new EdsPhoneBooks();
+ ArrayList ebooks = new ArrayList();
+ ebooks = eds.GetPhoneBooks();
+
+ IEnumerator enu = ebooks.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ if ((string)enu.Current == p.Name) {
+ records = eds.GetContacts((string)enu.Current);
+ }
+ }
+ }
+
+ return records;
+
+ }
+
+ public static string strip_tag (string line, string tag)
+ {
+ string bt = "<" + tag + ">";
+ string et = "</" + tag + ">";
+ string s = (line.Trim()).Replace(bt, "");
+ return s.Replace(et, "");
+ }
+
+ private static int get_number_of_books ()
+ {
+ StreamReader infile = null;
+ string buf;
+ int count = 0;
+
+ // TODO get location from gconf
+ string PHONEBOOKS = gfax.ConfigDirectory + "/phonebooks";
+
+ if (!File.Exists(PHONEBOOKS))
+ return(0);
+
+ try {
+ infile = File.OpenText(PHONEBOOKS);
+ } catch (Exception e) {
+ Console.WriteLine("get_number_of_books - Exception in phonebook.cs {0}", e);
+ return 0;
+ }
+
+ // how many phone books do we have, Trim() removes white space
+ while ( (buf = infile.ReadLine()) != null ) {
+ if ( buf.Trim() == "<book>") {
+ count++;
+ }
+ }
+ infile.Close();
+ return count;
+ }
+
+ public static Phonebook get_book_from_name(string name)
+ {
+ Phonebook[] books;
+ //int count; delete me
+
+ //count = get_number_of_books(); delete me
+ books = get_phonebooks();
+
+ foreach (Phonebook p in books) {
+ if (name == p.Name)
+ return p;
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/sendphonebook.cs b/src/sendphonebook.cs
new file mode 100755
index 0000000..cc1dc62
--- /dev/null
+++ b/src/sendphonebook.cs
@@ -0,0 +1,242 @@
+// GFAX - Gnome fax application
+// Copyright (C) 2003 - 2008 George A. Farris
+//
+// 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace gfax {
+ using Mono.Unix;
+ using System;
+ using System.IO;
+ using GLib;
+ using Gtk;
+ using Gnome;
+ using Glade;
+ using GtkSharp;
+ using System.Runtime.InteropServices;
+ using System.Collections;
+ using System.Reflection;
+
+ //************************************************************************
+ // GfaxSendPhoneBook class
+ //
+ //
+ //
+ public class GfaxSendPhoneBook
+ {
+ Gtk.Dialog phbd;
+ Gtk.TreeView book, list;
+ //Gtk.TreeModel book_model; delete me
+ Gtk.ListStore book_store, list_store;
+ G_ListView bs, ls;
+ Glade.XML gsxml;
+
+ [Glade.Widget] Gtk.Dialog PhbookDialog;
+ [Glade.Widget] Gtk.TreeView book_treeview;
+ [Glade.Widget] Gtk.TreeView list_treeview;
+
+ const int COLUMN_0 = 0;
+ const int COLUMN_1 = 1;
+ const int COLUMN_2 = 2;
+ const int ALL_COLUMNS = -1;
+ //string parent; delete me
+ Phonebook[] myPhoneBooks;
+
+ public GfaxSendPhoneBook (Glade.XML xml, string myparent)
+ {
+
+ //Phonebook[] pb; delete me
+
+ //gxml = xml;
+ //parent = myparent; delete me
+ myPhoneBooks = Phonetools.get_phonebooks();
+
+ if ( myPhoneBooks == null ) {
+ G_Message m = new G_Message(Catalog.GetString("You don't have any phone books yet."));
+ m = null;
+ return;
+ }
+
+ gsxml = new Glade.XML (null, "send-druid.glade","PhbookDialog",null);
+ gsxml.Autoconnect (this);
+
+ // Get the widget so we can manipulate it
+ //phbd = (Gtk.Dialog) gsxml.GetWidget("PhbookDialog");
+ //book = (Gtk.TreeView) gsxml.GetWidget("book_treeview");
+ //list = (Gtk.TreeView) gsxml.GetWidget("list_treeview");
+ phbd = PhbookDialog;
+ book = book_treeview;
+ list = list_treeview;
+
+ book.Selection.Changed += new EventHandler (on_book_treeview_selection);
+
+ phbd.Resizable = true;
+ book_store = new ListStore(typeof(string));
+ book.HeadersVisible = false;
+ book.Selection.Mode = SelectionMode.Multiple;
+
+ bs = new G_ListView(book, book_store);
+ // Got have a column title or things won't show up
+ bs.AddColumnTitle(Catalog.GetString("Phone books"), 0, COLUMN_0);
+
+
+ list_store = new ListStore(
+ typeof (string),
+ typeof (string),
+ typeof (string));
+
+ ls = new G_ListView(list, list_store);
+ ls.AddColumnTitle(Catalog.GetString("Organization"), 0, COLUMN_0);
+ ls.AddColumnTitle(Catalog.GetString("Phone Number"), 1, COLUMN_1);
+ ls.AddColumnTitle(Catalog.GetString("Contact"), 2, COLUMN_2);
+ list.HeadersVisible = true;
+ list.Selection.Mode = SelectionMode.Multiple;
+
+ // populate the list
+ foreach (Phonebook p in myPhoneBooks)
+ bs.AddTextToRow(p.Name);
+
+ phbd.Run();
+ }
+
+ // load the phone book
+ // Since we have SelectionMode.Multiple turned on we have to
+ // jump through these hoops in GTK-2.0 to get a selection
+ private void on_book_treeview_selection(object o, EventArgs args)
+ {
+ Gtk.TreeIter iter = new Gtk.TreeIter();
+ //Value value = new Value(); delete me
+ string selectionText = null;
+
+ book_store.GetIterFirst(out iter);
+ if ( book.Selection.IterIsSelected(iter)) {
+ selectionText = (string)book_store.GetValue(iter, 0);
+ }
+
+ while (book_store.IterNext(ref iter)) {
+ if ( book.Selection.IterIsSelected(iter)) {
+ selectionText = (string)book_store.GetValue(iter, 0);
+ }
+ }
+
+ // Ok now we can finally load the phone book
+ foreach (Phonebook p in myPhoneBooks)
+ if (p.Name == selectionText)
+ load_phone_book(p);
+
+ }
+
+ // If we double click the phonebook.
+ private void on_book_treeview_row_activated(object o, RowActivatedArgs args)
+ {
+ /*
+ ArrayList bsdest = new ArrayList();
+ ArrayList contacts = new ArrayList();
+
+ bsdest = bs.GetSelections(COLUMN_0);
+ if ( bsdest.Count > 0 ) {
+ IEnumerator enu = bsdest.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ foreach (Phonebook p in myPhoneBooks)
+ if (p.Name == (string)enu.Current)
+ contacts = Phonetools.get_contacts(p);
+
+ // add contacts to global desinations
+ IEnumerator enuc = contacts.GetEnumerator();
+ while ( enuc.MoveNext() )
+ gfax.Destinations.Add((Contact)enuc.Current);
+ }
+ }
+
+ phbd.Destroy();
+ */
+ }
+
+
+ private void on_list_treeview_row_activated(object o, RowActivatedArgs args)
+ {
+ }
+
+ private void on_ok_button_clicked(object o, EventArgs args)
+ {
+ ArrayList lsdest = new ArrayList();
+ ArrayList bsdest = new ArrayList();
+ ArrayList contacts = new ArrayList();
+
+ lsdest = ls.GetSelections(ALL_COLUMNS);
+
+ // if there are indiviual entries don't do entire phonebooks
+ if (lsdest.Count > 0) {
+ IEnumerator enu = lsdest.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ GfaxContact c = new GfaxContact();
+ c.Organization = (string)enu.Current;
+ enu.MoveNext();
+ c.PhoneNumber = (string)enu.Current;
+ enu.MoveNext();
+ c.ContactPerson = (string)enu.Current;
+ gfax.Destinations.Add(c);
+ }
+ }
+ else {
+ bsdest = bs.GetSelections(COLUMN_0);
+ if ( bsdest.Count > 0 ) {
+ IEnumerator enu = bsdest.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ foreach (Phonebook p in myPhoneBooks)
+ if (p.Name == (string)enu.Current)
+ contacts = Phonetools.get_contacts(p);
+
+ // add contacts to global desinations
+ if (contacts.Count > 0) {
+ IEnumerator enuc = contacts.GetEnumerator();
+ while ( enuc.MoveNext() )
+ gfax.Destinations.Add((GfaxContact)enuc.Current);
+ }
+ }
+ }
+ }
+
+ phbd.Destroy();
+ }
+
+ // loads the phone book into list_store
+ private void load_phone_book(Phonebook p)
+ {
+ ArrayList contacts = null;
+
+ // Clear the list_store
+ list_store.Clear();
+
+ contacts = Phonetools.get_contacts(p);
+ if (contacts == null)
+ return;
+
+ IEnumerator enu = contacts.GetEnumerator();
+ while ( enu.MoveNext() ) {
+ GfaxContact c = new GfaxContact();
+ c = (GfaxContact)enu.Current;
+ ls.AddTextToRow(c.Organization, c.PhoneNumber, c.ContactPerson);
+ }
+ }
+
+ private void on_cancel_button_clicked(object o, EventArgs args)
+ {
+ phbd.Destroy();
+ }
+
+ }
+
+}