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