1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiWord
4  * Copyright (C) 2002 Patrick Lam
5  * Copyright (C) 2008 Robert Staudinger
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include "ap_Features.h"
28 #include "xap_Strings.h"
29 #include "ap_Strings.h"
30 #include "ap_Prefs_SchemeIds.h"
31 #include "ap_Args.h"
32 #include "ap_App.h"
33 #include "ap_Convert.h"
34 #include "ut_debugmsg.h"
35 #include "ut_string.h"
36 #include "ut_misc.h"
37 
38 // Static initializations:
39 #ifdef DEBUG
40 int AP_Args::m_iDumpstrings = 0;
41 #endif
42 const char * AP_Args::m_sGeometry = NULL;
43 const char * AP_Args::m_sToFormat = NULL;
44 const char * AP_Args::m_sPrintTo = NULL;
45 int AP_Args::m_iVerbose = 1;
46 const char ** AP_Args::m_sPluginArgs = NULL;
47 const char ** AP_Args::m_sFiles = NULL;
48 int AP_Args::m_iVersion = 0;
49 int AP_Args::m_iHelp = 0;
50 const char * AP_Args::m_sMerge = NULL;
51 const char * AP_Args::m_impProps=NULL;
52 const char * AP_Args::m_expProps=NULL;
53 const char * AP_Args::m_sUserProfile = NULL;
54 const char * AP_Args::m_sFileExtension = NULL;
55 int AP_Args::m_iToThumb = 0;
56 const char * AP_Args::m_sName = NULL; // name of output file
57 const char *  AP_Args::m_sThumbXY = "100x120"; // number of pixels in thumbnail by default
58 
59 
60 static GOptionEntry _entries[] = {
61         {"geometry", 'g', 0, G_OPTION_ARG_STRING, &AP_Args::m_sGeometry, "Set initial frame geometry", "GEOMETRY"} ,
62         {"to", 't', 0, G_OPTION_ARG_STRING, &AP_Args::m_sToFormat, "Target format of the file (abw, zabw, rtf, txt, utf8, html, ...), depends on available filter plugins", "FORMAT"},
63         {"verbose", '\0', 0, G_OPTION_ARG_INT, &AP_Args::m_iVerbose, "Set verbosity level (0, 1, 2), with 2 being the most verbose", "LEVEL"},
64         {"print", 'p',0, G_OPTION_ARG_STRING, &AP_Args::m_sPrintTo, "Print this file to printer","'Printer name' or '-' for default printer"},
65         {"plugin", 'E', 0, G_OPTION_ARG_STRING_ARRAY, &AP_Args::m_sPluginArgs, "Execute plugin NAME instead of the main application", NULL},
66         {"merge", 'm', 0, G_OPTION_ARG_STRING, &AP_Args::m_sMerge, "Mail-merge", "FILE"},
67         {"imp-props", 'i', 0, G_OPTION_ARG_STRING, &AP_Args::m_impProps, "Importer Arguments", "CSS String"},
68         {"exp-props", 'e', 0, G_OPTION_ARG_STRING, &AP_Args::m_expProps, "Exporter Arguments", "CSS String"},
69         {"thumb", '\0', 0, G_OPTION_ARG_INT, &AP_Args::m_iToThumb, "Make a thumb nail of the first page",""},
70         {"sizeXY",'S', 0, G_OPTION_ARG_STRING, &AP_Args::m_sThumbXY, "Size of PNG thumb nail in pixels","VALxVAL"},
71         {"to-name",'o', 0, G_OPTION_ARG_STRING, &AP_Args::m_sName, "Name of output file",NULL},
72         {"import-extension", '\0', 0, G_OPTION_ARG_STRING, &AP_Args::m_sFileExtension, "Override document type detection by specifying a file extension", NULL},
73         {"userprofile", 'u', 0, G_OPTION_ARG_STRING, &AP_Args::m_sUserProfile, "Use specified user profile.",NULL},
74         {"version", '\0', 0, G_OPTION_ARG_NONE, &AP_Args::m_iVersion, "Print AbiWord version", NULL},
75         { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &AP_Args::m_sFiles, NULL,  "[FILE...]" },
76 #ifdef DEBUG
77         {"dumpstrings", 'd', 0, G_OPTION_ARG_NONE, &AP_Args::m_iDumpstrings, "Dump strings to file", NULL},
78 #endif
79         {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
80 };
81 
82 
83 
AP_Args(XAP_Args * pArgs,const char *,AP_App * pApp)84 AP_Args::AP_Args(XAP_Args * pArgs, const char * /*szAppName*/, AP_App * pApp)
85 	: XArgs (pArgs),
86 	m_pApp(pApp)
87 {
88 	m_context = g_option_context_new ("- commandline options");
89 	g_option_context_add_main_entries (m_context, _entries, NULL);
90 }
91 
~AP_Args()92 AP_Args::~AP_Args()
93 {
94 	// Only free ctxt if not using gnome, otherwise libgnome owns it
95 	g_option_context_free (m_context);
96 }
97 
addOptions(GOptionGroup * options)98 void AP_Args::addOptions(GOptionGroup *options)
99 {
100 	g_option_context_add_group (m_context, options);
101 }
102 
103 #ifdef WIN32
104 
xdec(const char * s)105 static inline char xdec(const char *s)
106 {
107 	int a=0;
108 	for (int i=0; i<2; i++) {
109 		if (s[i]>='0' && s[i]<='9') {
110 			a=(a<<4)+s[i]-'0';
111 		} else if (s[i]>='a' && s[i]<='f') {
112 			a=(a<<4)+s[i]-'a'+10;
113 		} else if (s[i]>='A' && s[i]<='F') {
114 			a=(a<<4)+s[i]-'A'+10;
115 		}
116 	}
117 	return a;
118 }
119 
XX_inplaceDecode(const char * s)120 void XX_inplaceDecode(const char *s)
121 {
122 	char *d=(char*)s;
123 	while (*s) {
124 		if (*s=='%' && s[1] && s[2]) {
125 			*d++=xdec(s+1);
126 			s+=3;
127 		} else {
128 			*d++=*s++;
129 		}
130 	}
131 	*d=0;
132 }
133 
134 #endif
135 
136 /*! Processes all the command line options and puts them in AP_Args.
137  *
138  * Note that GNOME does this for us... but fails.
139  */
parseOptions()140 void AP_Args::parseOptions()
141 {
142 	GError *err;
143 	gboolean ret;
144 
145 	err = NULL;
146 	ret = g_option_context_parse (m_context, &XArgs->m_argc, &XArgs->m_argv, &err);
147 	if (!ret || err) {
148 		fprintf (stderr, "%s\n", err->message);
149 		g_error_free (err); err = NULL;
150 		return;
151 	}
152 #ifdef WIN32
153 	// otherwise, decode arguments
154 	const char **arr;
155 	arr=m_sFiles;
156 	if (arr) while (*arr) {
157 		XX_inplaceDecode(*arr);
158 		arr++;
159 	}
160 	arr=m_sPluginArgs;
161 	if (arr) while (*arr) {
162 		XX_inplaceDecode(*arr);
163 		arr++;
164 	}
165 	if (m_sMerge) XX_inplaceDecode(m_sMerge);
166 	if (m_impProps) XX_inplaceDecode(m_impProps);
167 	if (m_expProps) XX_inplaceDecode(m_expProps);
168 	if (m_sName) XX_inplaceDecode(m_sName);
169 	if (m_sFileExtension) XX_inplaceDecode(m_sFileExtension);
170 	if (m_sUserProfile) XX_inplaceDecode(m_sUserProfile);
171 #endif
172 }
173 
getPluginOptions() const174 UT_String * AP_Args::getPluginOptions() const
175 {
176 	UT_String *opts;
177 	int i;
178 
179 	UT_ASSERT(m_sPluginArgs && m_sPluginArgs[0]);
180 	opts = new UT_String();
181 	i = 1;
182 	while (m_sPluginArgs[i]) {
183 		(*opts) += m_sPluginArgs[i];
184 		(*opts) += " ";
185 		i++;
186 	}
187 
188 	return opts;
189 }
190 
191 /*!
192  * Handles arguments which require an XAP_App but no windows.
193  * It has a callback to getApp()::doWindowlessArgs().
194  */
doWindowlessArgs(bool & bSuccessful)195 bool AP_Args::doWindowlessArgs(bool & bSuccessful)
196 {
197   // start out optimistic
198   bSuccessful = true;
199 
200 #ifdef DEBUG
201 	if (m_iDumpstrings)
202 	{
203 		// dump the string table in english as a template for translators.
204 		// see abi/docs/AbiSource_Localization.abw for details.
205 		AP_BuiltinStringSet * pBuiltinStringSet =
206 			new AP_BuiltinStringSet(getApp(),
207 									static_cast<const gchar*>(AP_PREF_DEFAULT_StringSet));
208 		pBuiltinStringSet->dumpBuiltinSet("en-US.strings");
209 		delete pBuiltinStringSet;
210 	}
211 #endif
212 
213  	if (m_iVersion)
214  	{
215  		printf("%s\n", PACKAGE_VERSION);
216 		#ifdef TOOLKIT_WIN
217 #define ABI_WIDE_STRING(t) Z(t)
218 #define Z(t) L##t
219 			MessageBoxW(NULL, ABI_WIDE_STRING(PACKAGE_VERSION), L"Version", MB_OK);
220 		#endif
221 		exit(0);
222  	}
223 
224 	if (m_sToFormat)
225 	{
226 		AP_Convert * conv = new AP_Convert();
227 		conv->setVerbose(m_iVerbose);
228 		if (m_sMerge)
229 			conv->setMergeSource (m_sMerge);
230 		if (m_impProps)
231 			conv->setImpProps (m_impProps);
232 		if (m_expProps)
233 			conv->setExpProps (m_expProps);
234 		int i = 0;
235 		while (m_sFiles[i])
236 		{
237 			UT_DEBUGMSG(("Converting file (%s) to type (%s)\n", m_sFiles[i], m_sToFormat));
238 			if(m_sName)
239 			  bSuccessful = bSuccessful && conv->convertTo(m_sFiles[i], m_sFileExtension, m_sName, m_sToFormat);
240 			else
241 			  bSuccessful = bSuccessful && conv->convertTo(m_sFiles[i], m_sFileExtension, m_sToFormat);
242 			i++;
243 		}
244 		delete conv;
245 		return false;
246 	}
247 
248 	bool appWindowlessArgsWereSuccessful = true;
249 	bool res = m_pApp->doWindowlessArgs(this, appWindowlessArgsWereSuccessful);
250 	bSuccessful = bSuccessful && appWindowlessArgsWereSuccessful;
251 	if(!res)
252 		return false;
253 
254 	return true;
255 }
256 
257