///////////////////////////////////////////////////////////////////////////// /* Copyright 2008,2009 Ronald S. Burkey This file is part of GutenMark. GutenMark 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. GutenMark 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 GutenMark; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Filename: main.cpp Purpose: This is a simple GUI front-end for GutenMark. Mods: 04/18/2008 RSB Began. 04/21/2008 RSB I'd cautiously say, "It's working." 05/09/2008 RSB On Mac OS X target, altered the name of the GutenMark application to correspond to the way I actually build it, namely GutenMark-macosx. 05/18/2008 RSB A bunch of the Mac OS X stuff no longer compiles, for some reason. But no matter, since I needed to mod it for the directory structures needed in "application bundles" anyway. 05/28/2008 RSB Fixed C-string to/from wxString conversions so that it would would with Unicode-enabled wxWidgets like on Mac OS X. 05/29/2008 RSB Added stuff related to GutenSplit. 10/08/2008 RSB Worked around wxGetHomeDir() in the __APPLE__ case by using native Mac (Carbon) API, since wxGetHomeDir() fails when wxWidgets is compiled by IMCROSS for some reason, and this prevents GUItenMark as compiled by IMCROSS from working on Macs at all. 10/09/2008 RSB It's really *all* of the wx file functions, like wxDirExists(), wxMkdir(), etc., as well. I've checked with both unicode and non-unicode builds of wxWidgets, and it still doesn't work. Fortunately, my use of all these functions is localized to teh BaseDirectory class, and so were easy to work around. 02/15/2009 RSB If found some comments online that there's something about the wxMac string functions that aren't thread- safe, so if there are string-conver- sions that occur in multiple threads, eventually the program will crash. I've therefore changed the BaseDir variable so that even though it remains a global variable, its content strings are initialized by the main program thread. This seems to alleviate the problem. This program is written using wxWidgets, and is intended to be as cross-platform as GutenMark is ... or at least as much as possible. Basically, all it does is to provide a way to do all of the same stuff as GutenMark, but to avoid the command-line. The user interface was designed with wxGlade, and the files GUItenMark.h and GUItenMark.cpp consist entirely of code generated by wxGlade. The event handlers in this file were all originally auto-generated to reside in GUItenMark.cpp. For some reason that now escapes me, I thought it was better to move them into this separate file ... I guess, to make sure that wxGlade didn't overwrite them later. But it wouldn't have anyhow. */ #include "GUItenMark.h" #include #include #ifdef __APPLE__ #include // For CFxxxxx() #include // For FSxxxxx() #include // For MAXPATHLEN #endif // I found out somewhat belatedly that if you try to create a // directory that already exists, it will cause the app to silently // die in Mac OS X 10.4. (I had no problems with it in Linux, // Windows, or Mac OS X 10.5.) #define wxMkdirRon(x) if (!wxDirExists (x)) wxMkdir (x); //#define DEBUG_LOG #ifdef DEBUG_LOG #include static FILE *LogFile = NULL; static int LogBroken = 0; static void LOGTHIS (wxString ws) { static char s[1025]; if (LogBroken) return; strcpy (s, ws.char_str ()); if (LogFile == NULL) { LogFile = fopen ("GUItenMark.log", "w"); if (LogFile == NULL) { LogBroken = 1; return; } } fprintf (LogFile, "%s\n", s); fflush (LogFile); } #else #define LOGTHIS(x) #endif //////////////////////////////////////////////////////////////////////////// // Auxiliary functions not in MyFrame or MyApp classes. //----------------------------------------------------- // Define working/configuration directory. #ifdef WIN32 #define DIRECTORY_DELIMITER "\\" #else #define DIRECTORY_DELIMITER "/" #endif // At the present writing (02/15/2009), there is a problem in wxMac 2.8.9 // in which string-conversion functions are not thread-safe. The method // BaseDirectory2() is really the constructor for this class, but we // give it a different name so that we can call it explicitly from the // main program thread. Otherwise, a global definition of a BaseDirectory // would have its constructor called at power-up outside of the main // thread, and the program would crash on the Mac. class BaseDirectory { public: void BaseDirectory2 (void); wxString Name; wxString ExeDirectory; wxString GUIConfigDirectory; wxString GutConfigDirectory; wxString WordlistDirectory; wxString DesktopDirectory; }; void BaseDirectory::BaseDirectory2 (void) { wxString HomeDirectory; LOGTHIS (wxT ("BaseDirectory: entry")); #ifdef __APPLE__ HomeDirectory = wxGetHomeDir (); DesktopDirectory = HomeDirectory + wxT (DIRECTORY_DELIMITER "Desktop"); // Find path to GUItenMark application bundle. const char *AppBundle; LOGTHIS (wxT ("BaseDirectory: 1")); AppBundle = CFStringGetCStringPtr (CFURLCopyFileSystemPath (CFBundleCopyBundleURL (CFBundleGetMainBundle()), kCFURLPOSIXPathStyle), CFStringGetSystemEncoding()); LOGTHIS (wxT ("BaseDirectory: 2")); Name = wxString (AppBundle, wxConvUTF8); Name += wxT ("/Contents"); LOGTHIS (wxT ("BaseDirectory: 3")); ExeDirectory = Name + wxT ("/MacOS"); GUIConfigDirectory = Name + wxT ("/Resources/GUIConfigs"); GutConfigDirectory = Name + wxT ("/Resources"); WordlistDirectory = Name + wxT ("/Resources"); #else // must not be __APPLE__ after all. HomeDirectory = wxGetHomeDir (); DesktopDirectory = HomeDirectory + wxT (DIRECTORY_DELIMITER "Desktop"); #ifdef WIN32 Name = wxT ("c:\\Program Files\\GutenMark"); #else // Linux Name = HomeDirectory + wxT ("/.GutenMark"); #endif LOGTHIS (wxT ("BaseDirectory: 4")); ExeDirectory = Name + wxT (DIRECTORY_DELIMITER "binary"); GUIConfigDirectory = Name + wxT (DIRECTORY_DELIMITER "GUIConfigs"); GutConfigDirectory = Name + wxT (DIRECTORY_DELIMITER "GutConfigs"); WordlistDirectory = Name + wxT (DIRECTORY_DELIMITER "binary"); //wxMkdirRon (Name + wxT (DIRECTORY_DELIMITER "Outputs")); #endif // __APPLE__ vs. not __APPLE__ LOGTHIS (wxT ("BaseDirectory: 5")); LOGTHIS (Name); wxMkdirRon (Name); LOGTHIS (wxT ("BaseDirectory: 6")); LOGTHIS (GUIConfigDirectory); wxMkdirRon (GUIConfigDirectory); LOGTHIS (wxT ("BaseDirectory: 7")); LOGTHIS (GutConfigDirectory); wxMkdirRon (GutConfigDirectory); LOGTHIS (wxT ("BaseDirectory: 8")); LOGTHIS (ExeDirectory); wxMkdirRon (ExeDirectory); LOGTHIS (wxT ("BaseDirectory: 9")); LOGTHIS (WordlistDirectory); wxMkdirRon (WordlistDirectory); LOGTHIS (wxT ("BaseDirectory: 10")); LOGTHIS (WordlistDirectory); wxSetWorkingDirectory (WordlistDirectory); LOGTHIS (wxT ("BaseDirectory: exit")); } BaseDirectory *BaseDir = new BaseDirectory (); //////////////////////////////////////////////////////////////////////////// // Functions for the MyApp class. class MyApp: public wxApp { public: virtual bool OnInit(); }; IMPLEMENT_APP (MyApp) bool MyApp::OnInit() { BaseDir->BaseDirectory2 (); LOGTHIS (BaseDir->Name); LOGTHIS (BaseDir->GUIConfigDirectory); LOGTHIS (BaseDir->GutConfigDirectory); LOGTHIS (BaseDir->ExeDirectory); LOGTHIS (BaseDir->WordlistDirectory); wxInitAllImageHandlers (); MyFrame *frame = new MyFrame( NULL, -1, wxT ("") ); frame->SetTitle (wxT ("GUItenMark build " __DATE__ ", (c)2008-2009 by Ron Burkey , " "http://www.sandroid.org/GutenMark")); frame->SideEffectsOfLists (); frame->GetConfiguration (wxT ("Default")); #ifdef __APPLE__ wxMenu *file_menu = new wxMenu; file_menu->Append(MyFrame::ID_APPLE_QUIT, _T("E&xit\tAlt-X"), _T("Quit this program")); wxMenuBar *menu_bar = new wxMenuBar( wxMB_DOCKABLE ); menu_bar->Append(file_menu, _T("&File")); frame->SetMenuBar(menu_bar); #endif // __APPLE__ frame->Maximize(TRUE); frame->Show(TRUE); SetTopWindow(frame); return TRUE; } //////////////////////////////////////////////////////////////////////////// // Event handlers for the MyFrame class. void MyFrame::OnClose (wxCloseEvent & event) { PutConfiguration (wxT ("Default")); Destroy (); } void MyFrame::ClickPopulate(wxCommandEvent &event) { wxArrayString Filenames; wxDir::GetAllFiles (OutputFolder->GetValue (), &Filenames, wxT (""), wxDIR_FILES); OutputFiles->Append (Filenames); SideEffectsOfLists (); } void MyFrame::ClickOutputFile(wxCommandEvent &event) { int i; wxString Name; //event.Skip(); i = OutputFiles->GetSelection (); if (i == wxNOT_FOUND) return; Name = OutputFiles->GetString (i); if (Name.Matches (wxT ("*.html")) || Name.Matches (wxT ("*.log")) || Name.Matches (wxT ("*.tex"))) wxLaunchDefaultBrowser (wxT ("file://") + Name); } void MyFrame::ClickInputFile(wxCommandEvent &event) { int i; wxString Name; //event.Skip(); i = InputFiles->GetSelection (); if (i == wxNOT_FOUND) return; Name = InputFiles->GetString (i); wxLaunchDefaultBrowser (wxT ("file://") + Name); } void MyFrame::ClickOutputFolderBrowse(wxCommandEvent &event) { //event.Skip(); wxString Dir = wxDirSelector (wxT ("Choose a folder for output"), OutputFolder->GetValue ()); if (!Dir.empty ()) OutputFolder->SetValue (Dir); } void MyFrame::ClickAddFiles(wxCommandEvent &event) { //int i; //wxString Directory; wxArrayString Filenames; //event.Skip(); //i = InputFiles->GetCount (); //if (!i) // Directory = ""; //else // Directory = wxPathOnly (InputFiles->GetString (i - 1)); wxFileDialog *Dialog = new wxFileDialog (this, wxT ("Choose etext file(s)"), Directory, wxT (""), wxT ("Text files (*.txt)|*.txt|All files (*.*)|*.*"), wxFD_DEFAULT_STYLE | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR); if (wxID_OK == Dialog->ShowModal ()) { Dialog->GetPaths (Filenames); InputFiles->Append (Filenames); Directory = Dialog->GetDirectory (); SideEffectsOfLists (); } delete Dialog; } void MyFrame::ClickClearInputFiles(wxCommandEvent &event) { //event.Skip(); InputFiles->Clear (); SideEffectsOfLists (); } void MyFrame::ClickConvertTexts(wxCommandEvent &event) { wxArrayString Filenames; int Count, i, j, Skip = 0; LOGTHIS (wxT ("ClickConvertTexts: start")); //event.Skip(); Filenames = InputFiles->GetStrings (); for (i = 0, Count = Filenames.GetCount (); i < Count; i++) { LOGTHIS (wxT ("ClickConvertTexts: loop")); // Name of the output file (from GutenMark). wxString OutputFile, OutputDirSplit; wxFileName *Input = new wxFileName (Filenames[i]); OutputDirSplit = OutputFolder->GetValue () + wxT (DIRECTORY_DELIMITER) + Input->GetName (); if (LatexOutput->GetValue ()) OutputFile = OutputDirSplit + wxT (".tex"); else OutputFile = OutputDirSplit + wxT (".html"); //------------------------------------------------------------- // First, construct GutenSplit command line. // Program name for GutenSplit. wxString CommandLineSplit = wxT ("\"") + BaseDir->ExeDirectory + wxT (DIRECTORY_DELIMITER "GutenSplit"); #if defined (WIN32) CommandLineSplit += wxT (".exe"); #endif CommandLineSplit += wxT ("\""); if (LevelOne->GetValue ()) CommandLineSplit += wxT (" -1"); if (LevelTwo->GetValue ()) CommandLineSplit += wxT (" -2"); if (LevelThree->GetValue ()) CommandLineSplit += wxT (" -3"); if (LevelFour->GetValue ()) CommandLineSplit += wxT (" -4"); if (!SkipFirstHeading->GetValue ()) CommandLineSplit += wxT (" --no-skip"); if (!TableOfContents->GetValue ()) CommandLineSplit += wxT (" --no-toc"); // Input file is the output file from GutenMark. CommandLineSplit += wxT (" \""); CommandLineSplit += OutputFile; CommandLineSplit += wxT ("\""); // Output base. CommandLineSplit += wxT (" \"") + Input->GetName () + wxT ("_\""); //------------------------------------------------------------- // Then, construct GutenMark command line. // Program name for GutenMark. wxString CommandLine = wxT (""); CommandLine += wxT ("\"") + BaseDir->ExeDirectory + wxT (DIRECTORY_DELIMITER "GutenMark"); #if defined (WIN32) CommandLine += wxT (".exe"); #endif CommandLine += wxT ("\""); // --author if (AuthorOverride->IsEnabled () && !AuthorOverride->IsEmpty ()) { CommandLine += wxT (" \"--author="); CommandLine += AuthorOverride->GetValue (); CommandLine += wxT ("\""); } // --caps-ok if (AllCapsOk->GetValue ()) CommandLine += wxT (" --caps-ok"); if (!ConfigurationFile->IsEmpty ()) { CommandLine += wxT (" \"--config="); CommandLine += ConfigurationFile->GetValue (); CommandLine += wxT ("\""); } // --first-capital if (FirstWordAllCapsOk->GetValue ()) CommandLine += wxT (" --first-capital"); // --first-italics if (FirstWordItalicsOk->GetValue ()) CommandLine += wxT (" --first-italics"); // --force-symbolic/--force-numeric if (HtmlOutput->GetValue () && HtmlUseSymbolicEntities->GetValue ()) CommandLine += wxT (" --force-symbolic"); else CommandLine += wxT (" --force-numeric"); // --latex if (LatexOutput->GetValue ()) CommandLine += wxT (" --latex"); // --latex if (LatexOutput->GetValue () && LatexSectionMarkup->GetValue ()) CommandLine += wxT (" --latex-sections"); // --no-diacritical if (!RestoreDiacrits->GetValue ()) CommandLine += wxT (" --no-diacritical"); // --no-foreign if (!ItalicizeNonEnglish->GetValue ()) CommandLine += wxT (" --no-foreign"); // --no-justify if (RaggedRightMargin->GetValue ()) CommandLine += wxT (" --no-justify"); // --no-mdash if (PreserveStringsOfHyphens->GetValue ()) CommandLine += wxT (" --no-mdash"); // --no-parskip if (LatexOutput->GetValue () && LatexIndentParagraphs->GetValue ()) CommandLine += wxT (" --no-parskip"); // --no-prefatory if (HtmlOutput->GetValue () && HtmlAddPrefatoryMarks->GetValue ()) CommandLine += wxT (" --no-prefatory"); // --no-toc if (LatexOutput->GetValue () && LatexEliminateToc->GetValue ()) CommandLine += wxT (" --no-toc"); // --page-breaks if (HtmlOutput->GetValue () && HtmlAddPageBreakMarks->GetValue ()) CommandLine += wxT (" --page-breaks"); // --profile j = Profile->GetSelection (); if (wxNOT_FOUND != j) { CommandLine += wxT (" \"--profile="); CommandLine += Profile->GetString (j); CommandLine += wxT ("\""); } // --single-space if (SingleSpaceBetweenSentences->GetValue ()) CommandLine += wxT (" --single-space"); // --title if (TitleOverride->IsEnabled () && !TitleOverride->IsEmpty ()) { CommandLine += wxT (" \"--title="); CommandLine += TitleOverride->GetValue (); CommandLine += wxT ("\""); } // --yes-header if (RetainProjectGutenbergHeader->GetValue ()) CommandLine += wxT (" --yes-header"); // --debug if (Debug->GetValue ()) CommandLine += wxT (" --debug"); // --ron if (RonsOptions->GetValue ()) CommandLine += wxT (" --ron"); // Input file. CommandLine += wxT (" \""); CommandLine += Filenames[i]; CommandLine += wxT ("\""); // Output file. CommandLine += wxT (" \""); CommandLine += OutputFile; CommandLine += wxT ("\""); //wxMessageBox (CommandLine); wxBeginBusyCursor (); //--------------------------------------------------------------- // Now convert the text. LOGTHIS (wxT ("ClickConvertTexts: conversion command line")); LOGTHIS (CommandLine); long ConversionCode = wxExecute (CommandLine, wxEXEC_SYNC); LOGTHIS (wxT ("ClickConvertTexts: converted")); //--------------------------------------------------------------- // Check results. if (Debug->GetValue ()) { wxString LogFile; LOGTHIS (wxT ("ClickConvertTexts: moving log")); LogFile = Input->GetPath (); LogFile += wxT (DIRECTORY_DELIMITER "GutenMark.log"); OutputFiles->Append (LogFile); } if (ConversionCode) { LOGTHIS (wxT ("ClickConvertTexts: error code")); OutputFile += wxT (" (Conversion error "); OutputFile += wxString::Format (wxT ("%ld"), ConversionCode); OutputFile += wxT (")"); OutputFiles->Append (OutputFile); Skip++; } else { LOGTHIS (wxT ("ClickConvertTexts: moving filename")); OutputFiles->Append (OutputFile); // If we're suppose to run GutenSplit, then do it now. if (!LatexOutput->GetValue () && RunGutenSplit->GetValue ()) { wxMkdirRon (OutputDirSplit); if (wxSetWorkingDirectory (OutputDirSplit)) { long ConversionCodeSplit = wxExecute (CommandLineSplit, wxEXEC_SYNC); if (ConversionCodeSplit) OutputDirSplit += wxT (" (Splitting exec error)"); else OutputDirSplit += wxT (DIRECTORY_DELIMITER) + Input->GetName () + wxT ("_000.html"); wxSetWorkingDirectory (BaseDir->WordlistDirectory); } else OutputDirSplit += wxT (" (Splitting folder error)"); OutputFiles->Append (OutputDirSplit); } InputFiles->Delete (Skip); } wxEndBusyCursor (); delete Input; LOGTHIS (wxT ("ClickConvertTexts: continue")); } // All done! LOGTHIS (wxT ("ClickConvertTexts: side effects")); SideEffectsOfLists (); LOGTHIS (wxT ("ClickConvertTexts: done!")); } void MyFrame::ClickClearOutputList(wxCommandEvent &event) { //event.Skip(); OutputFiles->Clear (); SideEffectsOfLists (); } void MyFrame::ClickHtmlOutput(wxCommandEvent &event) { //event.Skip(); if (HtmlOutput->GetValue ()) { // LaTeX options. LatexSectionMarkup->Disable (); LatexIndentParagraphs->Disable (); LatexEliminateToc->Disable (); // HTML options. HtmlUseSymbolicEntities->Enable (); HtmlAddPrefatoryMarks->Enable (); HtmlAddPageBreakMarks->Enable (); RonsOptions->SetValue (FALSE); // GutenSplitOptions. RunGutenSplit->Enable (); LevelOne->Enable (RunGutenSplit->GetValue ()); LevelTwo->Enable (RunGutenSplit->GetValue ()); LevelThree->Enable (RunGutenSplit->GetValue ()); LevelFour->Enable (RunGutenSplit->GetValue ()); SkipFirstHeading->Enable (RunGutenSplit->GetValue ()); TableOfContents->Enable (RunGutenSplit->GetValue ()); } } void MyFrame::ClickLatexOutput(wxCommandEvent &event){ //event.Skip(); if (LatexOutput->GetValue ()) { // LaTeX options. LatexSectionMarkup->Enable (); LatexIndentParagraphs->Enable (); LatexEliminateToc->Enable (); // HTML options HtmlUseSymbolicEntities->Disable (); HtmlAddPrefatoryMarks->Disable (); HtmlAddPageBreakMarks->Disable (); // GutenSplit options RunGutenSplit->Disable (); LevelOne->Disable (); LevelTwo->Disable (); LevelThree->Disable (); LevelFour->Disable (); SkipFirstHeading->Disable (); TableOfContents->Disable (); } } void MyFrame::ClickRon (wxCommandEvent &event) { //event.Skip (); LatexOutput->SetValue (TRUE); LatexIndentParagraphs->SetValue (TRUE); ClickLatexOutput (event); } void MyFrame::ClickLatexIndentParagraphs (wxCommandEvent &event) { //event.Skip (); if (!LatexIndentParagraphs->GetValue ()) RonsOptions->SetValue (FALSE); ClickLatexOutput (event); } void MyFrame::NewConfigurationFiles(wxCommandEvent &event){ #define MAXSTRING 1024 FILE *fp; char *s, *ss; //event.Skip(); // What we need to do here is to parse the configuration // file to see what profiles are available in it. The // profiles (in regex terms) match "^\[.*\]$". Profile->Clear (); s = (char *) malloc (MAXSTRING); strcpy (s, ConfigurationFile->GetValue ().char_str ()); fp = fopen ((const char *) s, "r"); free (s); if (fp != NULL) { s = (char *) malloc (MAXSTRING); while (NULL != fgets (s, MAXSTRING, fp)) if (*s == '[') { for (ss = s + 1; *ss && *ss != ']'; ss++); if (*ss == ']') { *ss = 0; Profile->Append (wxString (&s[1], wxConvUTF8)); } } fclose (fp); free (s); } Profile->SetSelection (0); #undef MAXSTRING } void MyFrame::ClickConfigurationFileBrowse(wxCommandEvent &event){ //event.Skip(); wxString Path = wxPathOnly ( ConfigurationFile->GetValue ()); wxString File = wxFileSelector (wxT ("Choose a GutenMark configuration file"), Path, wxT (""), wxT (""), wxT ("Configuration files (*.cfg)|*.cfg|All files (*.*)|*.*")); if (!File.empty ()) { ConfigurationFile->SetValue (File); NewConfigurationFiles (event); } } void MyFrame::ClickProfile(wxCommandEvent &event){ //event.Skip(); } void MyFrame::ClickSaveSettings(wxCommandEvent &event){ //event.Skip(); wxString Path = BaseDir->GUIConfigDirectory; wxString File = wxFileSelector (wxT ("Save your GUItenMark configuration as"), Path, wxT (""), wxT (""), wxT ("*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (!File.empty ()) { wxFileName *Filename = new wxFileName (File); PutConfiguration (Filename->GetName ()); delete Filename; } } void MyFrame::ClickRestoreSettings(wxCommandEvent &event){ //event.Skip(); wxString Path = BaseDir->GUIConfigDirectory; wxString File = wxFileSelector (wxT ("Restore your GUItenMark configuration from"), Path, wxT (""), wxT (""), wxT ("*"), wxFD_OPEN | wxFD_FILE_MUST_EXIST); if (!File.empty ()) { wxFileName *Filename = new wxFileName (File); GetConfiguration (Filename->GetName ()); delete Filename; } } void MyFrame::ClickGoodbye(wxCommandEvent &event){ //event.Skip(); Close (); } void MyFrame::ClickDefaultSettings(wxCommandEvent &event){ //event.Skip(); GetConfiguration (wxT ("ThisFilenameDoesNotExistSoTheHardCodedDefaultIsUsed")); } void MyFrame::SplitCheck (wxCommandEvent & event) { LevelOne->Enable (RunGutenSplit->GetValue ()); LevelTwo->Enable (RunGutenSplit->GetValue ()); LevelThree->Enable (RunGutenSplit->GetValue ()); LevelFour->Enable (RunGutenSplit->GetValue ()); SkipFirstHeading->Enable (RunGutenSplit->GetValue ()); TableOfContents->Enable (RunGutenSplit->GetValue ()); } //////////////////////////////////////////////////////////////////////////// // Non-event-handler auxiliary functions which I've added to the MyFrame class. void MyFrame::SideEffectsOfLists (void) { switch (InputFiles->GetCount ()) { case 0: ClearInputList->Disable (); ConvertTexts->Disable (); AuthorOverride->Disable (); AuthorLabel->Disable (); TitleOverride->Disable (); TitleLabel->Disable (); break; case 1: ClearInputList->Enable (); ConvertTexts->Enable (); AuthorOverride->Enable (); AuthorLabel->Enable (); TitleOverride->Enable (); TitleLabel->Enable (); break; default: ClearInputList->Enable (); ConvertTexts->Enable (); AuthorOverride->Enable (); AuthorLabel->Enable (); TitleOverride->Disable (); TitleLabel->Disable (); break; } if (OutputFiles->GetCount ()) ClearOutputList->Enable (); else ClearOutputList->Disable (); } // Get a saved configuration identified by Name. (Name is not a filename, // but a base from which a filename is constructed by prefixing a path and // suffixing an extension.) Returns 0 on success, non-zero on failure. // "Failure" means that that configuration doesn't exist. In this case, the // configuration is replaced by a fallback configuration of my choosing. // On entry to the program, there is an automatic call with Name=="Default". int MyFrame::GetConfiguration (wxString Name) { FILE *fp; int ReturnValue = 1, i; wxCommandEvent DummyEvent; wxString CfgName; char *s; s = (char *) malloc (2048); if (s == NULL) return (ReturnValue); // Configure according to my preferences. OutputFolder->SetValue (BaseDir->DesktopDirectory); AllCapsOk->SetValue (FALSE); RestoreDiacrits->SetValue (TRUE); RaggedRightMargin->SetValue (FALSE); HtmlOutput->SetValue (TRUE); ClickHtmlOutput (DummyEvent); FirstWordAllCapsOk->SetValue (FALSE); ItalicizeNonEnglish->SetValue (TRUE); PreserveStringsOfHyphens->SetValue (FALSE); HtmlUseSymbolicEntities->SetValue (FALSE); LatexSectionMarkup->SetValue (FALSE); FirstWordItalicsOk->SetValue (FALSE); SingleSpaceBetweenSentences->SetValue (FALSE); HtmlAddPrefatoryMarks->SetValue (FALSE); LatexIndentParagraphs->SetValue (TRUE); RetainProjectGutenbergHeader->SetValue (FALSE); HtmlAddPageBreakMarks->SetValue (FALSE); LatexEliminateToc->SetValue (FALSE); wxString ConfigFilename = BaseDir->GutConfigDirectory + wxT (DIRECTORY_DELIMITER "GutenMark.cfg"); ConfigurationFile->SetValue (ConfigFilename); RunGutenSplit->SetValue (FALSE); SplitCheck (DummyEvent); LevelOne->SetValue (TRUE); LevelTwo->SetValue (FALSE); LevelThree->SetValue (FALSE); LevelFour->SetValue (FALSE); SkipFirstHeading->SetValue (TRUE); TableOfContents->SetValue (TRUE); NewConfigurationFiles (DummyEvent); // Note that NewConfigurationFiles automatically sets Profile. However, // I don't necessarily like the default selection it makes. i = Profile->FindString (wxT ("english")); if (i != wxNOT_FOUND) Profile->SetSelection (i); Directory = BaseDir->DesktopDirectory; Debug->SetValue (FALSE); RonsOptions->SetValue (FALSE); // Fetch the named configuration. CfgName = BaseDir->GUIConfigDirectory + wxT (DIRECTORY_DELIMITER) + Name; strcpy (s, CfgName.char_str ()); fp = fopen ((const char *) s, "r"); if (fp != NULL) { int i; if (1 == fscanf (fp, "OutputFolder=%[^\n]\n", s)) OutputFolder->SetValue (wxString (s, wxConvUTF8)); else goto Done; if (1 == fscanf (fp, "AllCapsOk=%d\n", &i)) AllCapsOk->SetValue (i); else goto Done; if (1 == fscanf (fp, "RestoreDiacrits=%d\n", &i)) RestoreDiacrits->SetValue (i); else goto Done; if (1 == fscanf (fp, "RaggedRightMargin=%d\n", &i)) RaggedRightMargin->SetValue (i); else goto Done; if (1 == fscanf (fp, "HtmlOutput=%d\n", &i)) { if (i) { HtmlOutput->SetValue (TRUE); ClickHtmlOutput (DummyEvent); } else { LatexOutput->SetValue (TRUE); ClickLatexOutput (DummyEvent); } } else goto Done; if (1 == fscanf (fp, "FirstWordAllCapsOk=%d\n", &i)) FirstWordAllCapsOk->SetValue (i); else goto Done; if (1 == fscanf (fp, "ItalicizeNonEnglish=%d\n", &i)) ItalicizeNonEnglish->SetValue (i); else goto Done; if (1 == fscanf (fp, "PreserveStringsOfHyphens=%d\n", &i)) PreserveStringsOfHyphens->SetValue (i); else goto Done; if (1 == fscanf (fp, "HtmlUseSymbolicEntities=%d\n", &i)) HtmlUseSymbolicEntities->SetValue (i); else goto Done; if (1 == fscanf (fp, "LatexSectionMarkup=%d\n", &i)) LatexSectionMarkup->SetValue (i); else goto Done; if (1 == fscanf (fp, "FirstWordItalicsOk=%d\n", &i)) FirstWordItalicsOk->SetValue (i); else goto Done; if (1 == fscanf (fp, "SingleSpaceBetweenSentences=%d\n", &i)) SingleSpaceBetweenSentences->SetValue (i); else goto Done; if (1 == fscanf (fp, "HtmlAddPrefatoryMarks=%d\n", &i)) HtmlAddPrefatoryMarks->SetValue (i); else goto Done; if (1 == fscanf (fp, "LatexIndentParagraphs=%d\n", &i)) LatexIndentParagraphs->SetValue (i); else goto Done; if (1 == fscanf (fp, "RetainProjectGutenbergHeader=%d\n", &i)) RetainProjectGutenbergHeader->SetValue (i); else goto Done; if (1 == fscanf (fp, "HtmlAddPageBreakMarks=%d\n", &i)) HtmlAddPageBreakMarks->SetValue (i); else goto Done; if (1 == fscanf (fp, "LatexEliminateToc=%d\n", &i)) LatexEliminateToc->SetValue (i); else goto Done; if (1 == fscanf (fp, "ConfigurationFile=%[^\n]\n", s)) ConfigurationFile->SetValue (wxString (s, wxConvUTF8)); else goto Done; NewConfigurationFiles (DummyEvent); if (1 == fscanf (fp, "Profile=%d\n", &i)) Profile->SetSelection (i); else goto Done; if (1 == fscanf (fp, "InputDirectory=%[^\n]\n", s)) Directory = wxString (s, wxConvUTF8); else goto Done; if (1 == fscanf (fp, "Debug=%d\n", &i)) Debug->SetValue (i); else goto Done; if (1 == fscanf (fp, "RonsOptions=%d\n", &i)) RonsOptions->SetValue (i); else goto Done; if (1 == fscanf (fp, "RunGutenSplit=%d\n", &i)) { RunGutenSplit->SetValue (i); SplitCheck (DummyEvent); } else goto Done; if (1 == fscanf (fp, "LevelOne=%d\n", &i)) LevelOne->SetValue (i); else goto Done; if (1 == fscanf (fp, "LevelTwo=%d\n", &i)) LevelTwo->SetValue (i); else goto Done; if (1 == fscanf (fp, "LevelThree=%d\n", &i)) LevelThree->SetValue (i); else goto Done; if (1 == fscanf (fp, "LevelFour=%d\n", &i)) LevelFour->SetValue (i); else goto Done; if (1 == fscanf (fp, "SkipFirstHeading=%d\n", &i)) SkipFirstHeading->SetValue (i); else goto Done; if (1 == fscanf (fp, "TableOfContents=%d\n", &i)) TableOfContents->SetValue (i); else goto Done; fclose (fp); } ReturnValue = 0; Done: free (s); return (ReturnValue); } // Write a saved configuration identified by Name. (Name is not a filename, // but a base from which a filename is constructed by prefixing a path and // suffixing an extension.) Returns 0 on success, non-zero on failure. // On exit from the program, there is an automatic call with Name=="Default". int MyFrame::PutConfiguration (wxString Name) { FILE *fp; int ReturnValue = 0; wxString CfgName; char *s; CfgName = BaseDir->GUIConfigDirectory + wxT (DIRECTORY_DELIMITER) + Name; s = (char *) malloc (1025); strcpy (s, CfgName.char_str ()); fp = fopen ((const char *)s, "w"); if (fp != NULL) { strcpy (s, OutputFolder->GetValue ().char_str ()); fprintf (fp, "OutputFolder=%s\n", (const char *) s); fprintf (fp, "AllCapsOk=%d\n", AllCapsOk->GetValue ()); fprintf (fp, "RestoreDiacrits=%d\n", RestoreDiacrits->GetValue ()); fprintf (fp, "RaggedRightMargin=%d\n", RaggedRightMargin->GetValue ()); fprintf (fp, "HtmlOutput=%d\n", HtmlOutput->GetValue ()); fprintf (fp, "FirstWordAllCapsOk=%d\n", FirstWordAllCapsOk->GetValue ()); fprintf (fp, "ItalicizeNonEnglish=%d\n", ItalicizeNonEnglish->GetValue ()); fprintf (fp, "PreserveStringsOfHyphens=%d\n", PreserveStringsOfHyphens->GetValue ()); fprintf (fp, "HtmlUseSymbolicEntities=%d\n", HtmlUseSymbolicEntities->GetValue ()); fprintf (fp, "LatexSectionMarkup=%d\n", LatexSectionMarkup->GetValue ()); fprintf (fp, "FirstWordItalicsOk=%d\n", FirstWordItalicsOk->GetValue ()); fprintf (fp, "SingleSpaceBetweenSentences=%d\n", SingleSpaceBetweenSentences->GetValue ()); fprintf (fp, "HtmlAddPrefatoryMarks=%d\n", HtmlAddPrefatoryMarks->GetValue ()); fprintf (fp, "LatexIndentParagraphs=%d\n", LatexIndentParagraphs->GetValue ()); fprintf (fp, "RetainProjectGutenbergHeader=%d\n", RetainProjectGutenbergHeader->GetValue ()); fprintf (fp, "HtmlAddPageBreakMarks=%d\n", HtmlAddPageBreakMarks->GetValue ()); fprintf (fp, "LatexEliminateToc=%d\n", LatexEliminateToc->GetValue ()); strcpy (s, ConfigurationFile->GetValue ().char_str ()); fprintf (fp, "ConfigurationFile=%s\n", (const char *) s); fprintf (fp, "Profile=%d\n", Profile->GetSelection ()); strcpy (s, Directory.char_str ()); fprintf (fp, "InputDirectory=%s\n", (const char *) s); fprintf (fp, "Debug=%d\n", Debug->GetValue ()); fprintf (fp, "RonsOptions=%d\n", RonsOptions->GetValue ()); fprintf (fp, "RunGutenSplit=%d\n", RunGutenSplit->GetValue ()); fprintf (fp, "LevelOne=%d\n", LevelOne->GetValue ()); fprintf (fp, "LevelTwo=%d\n", LevelTwo->GetValue ()); fprintf (fp, "LevelThree=%d\n", LevelThree->GetValue ()); fprintf (fp, "LevelFour=%d\n", LevelFour->GetValue ()); fprintf (fp, "SkipFirstHeading=%d\n", SkipFirstHeading->GetValue ()); fprintf (fp, "TableOfContents=%d\n", TableOfContents->GetValue ()); fclose (fp); } free (s); return (ReturnValue); }