1 /*
2 *
3 * Copyright (C) 2001 by Dom Lachowicz & Michael D. Pritchett
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA.
19 */
20
21 #include "xap_Module.h"
22 #include "xap_App.h"
23 #include "xap_Frame.h"
24 #include "fv_View.h"
25 #include "ap_Menu_Id.h"
26 #include "ev_Menu_Actions.h"
27 #include "ev_Menu.h"
28 #include "ev_Menu_Layouts.h"
29 #include "ev_Menu_Labels.h"
30 #include "ev_EditMethod.h"
31 #include "xap_Menu_Layouts.h"
32 #include "ut_string_class.h"
33
34 #ifdef ABI_PLUGIN_BUILTIN
35 #define abi_plugin_register abipgn_wikipedia_register
36 #define abi_plugin_unregister abipgn_wikipedia_unregister
37 #define abi_plugin_supports_version abipgn_wikipedia_supports_version
38 // dll exports break static linking
39 #define ABI_BUILTIN_FAR_CALL extern "C"
40 #else
41 #define ABI_BUILTIN_FAR_CALL ABI_FAR_CALL
42 ABI_PLUGIN_DECLARE ("Wikipedia")
43 #endif
44
45 // -----------------------------------------------------------------------
46 // -----------------------------------------------------------------------
47
48 //
49 // _ucsToAscii
50 // -----------------------
51 // Helper function to convert UCS-4 strings into Ascii.
52 // NOTE: you must call delete[] on the returned text!!!
53 //
54 inline static char*
_ucsToAscii(const UT_UCSChar * text)55 _ucsToAscii(const UT_UCSChar* text)
56 {
57 UT_return_val_if_fail(text,0);
58
59 // calculate length of text so that we can create a character
60 // buffer of equal size.
61 const unsigned int length = UT_UCS4_strlen(static_cast<const UT_UCS4Char *>(text));
62
63 // allocate ascii characters plus room for a null terminator.
64 char* ret = new char[length+1];
65
66 // do the string conversion. this is simple we just cast to
67 // char since UCS-4 is the same as Ascii for english.
68 for(unsigned int i = 0;i < length;++i)
69 {
70 ret[i] = static_cast<char>(text[i]);
71 }
72
73 // finally null terminate the string.
74 ret[length] = '\0';
75
76 // and now return it.
77 return ret;
78 }
79
80 //
81 // Wikipedia_invoke
82 // -------------------
83 // This is the function that we actually call to invoke the on-line encyclopedia.
84 // It should be called when the user selects from the context menu
85 //
86 static bool
Wikipedia_invoke(AV_View *,EV_EditMethodCallData *)87 Wikipedia_invoke(AV_View* /*v*/, EV_EditMethodCallData * /*d*/)
88 {
89 // Get the current view that the user is in.
90 XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame();
91 FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView());
92
93 // If the user is on a word, but does not have it selected, we need
94 // to go ahead and select that word so that the search/replace goes
95 // correctly.
96 pView->moveInsPtTo(FV_DOCPOS_EOW_MOVE);
97 pView->moveInsPtTo(FV_DOCPOS_BOW);
98 pView->extSelTo(FV_DOCPOS_EOW_SELECT);
99
100 // Now we will figure out what word to look up when we open our dialog.
101 // http://en.wikipedia.org/w/wiki.phtml?search=war&go=Go
102 UT_String url ("http://www.wikipedia.com/");
103 if (!pView->isSelectionEmpty())
104 {
105 url += "w/wiki.phtml?search=";
106 // We need to get the Ascii version of the current word.
107 UT_UCS4Char *ucs4ST;
108 pView->getSelectionText(*&ucs4ST);
109 char* search = _ucsToAscii(
110 ucs4ST
111 );
112
113 url += search;
114 DELETEPV(search);
115 FREEP(ucs4ST);
116
117 url += "&go=Go";
118 }
119
120 XAP_App::getApp()->openURL( url.c_str() );
121
122 return true;
123 }
124
125 static const char* Wikipedia_MenuLabel = "Wi&ki Encyclopedia";
126 static const char* Wikipedia_MenuTooltip = "Opens the libre Wiki on-line encyclopedia";
127
128 static void
Wikipedia_removeFromMenus()129 Wikipedia_removeFromMenus()
130 {
131 // First we need to get a pointer to the application itself.
132 XAP_App *pApp = XAP_App::getApp();
133
134 // remove the edit method
135 EV_EditMethodContainer* pEMC = pApp->getEditMethodContainer() ;
136 EV_EditMethod * pEM = ev_EditMethod_lookup ( "Wikipedia_invoke" ) ;
137 pEMC->removeEditMethod ( pEM ) ;
138 DELETEP( pEM ) ;
139
140 // now remove crap from the menus
141 int frameCount = pApp->getFrameCount();
142 XAP_Menu_Factory * pFact = pApp->getMenuFactory();
143
144 pFact->removeMenuItem("Main",NULL,Wikipedia_MenuLabel);
145 pFact->removeMenuItem("contextText",NULL,Wikipedia_MenuLabel);
146 for(int i = 0;i < frameCount;++i)
147 {
148 // Get the current frame that we're iterating through.
149 XAP_Frame* pFrame = pApp->getFrame(i);
150 pFrame->rebuildMenus();
151 }
152 }
153
154 static void
Wikipedia_addToMenus()155 Wikipedia_addToMenus()
156 {
157 // First we need to get a pointer to the application itself.
158 XAP_App *pApp = XAP_App::getApp();
159
160 // Create an EditMethod that will link our method's name with
161 // it's callback function. This is used to link the name to
162 // the callback.
163 EV_EditMethod *myEditMethod = new EV_EditMethod(
164 "Wikipedia_invoke", // name of callback function
165 Wikipedia_invoke, // callback function itself.
166 0, // no additional data required.
167 "" // description -- allegedly never used for anything
168 );
169
170 // Now we need to get the EditMethod container for the application.
171 // This holds a series of Edit Methods and links names to callbacks.
172 EV_EditMethodContainer* pEMC = pApp->getEditMethodContainer();
173
174 // We have to add our EditMethod to the application's EditMethodList
175 // so that the application will know what callback to call when a call
176 // to "Wikipedia_invoke" is received.
177 pEMC->addEditMethod(myEditMethod);
178
179
180 // Now we need to grab an ActionSet. This is going to be used later
181 // on in our for loop. Take a look near the bottom.
182 EV_Menu_ActionSet* pActionSet = pApp->getMenuActionSet();
183
184
185 // We need to go through and add the menu element to each "frame"
186 // of the application. We can iterate through the frames by doing
187 // XAP_App::getFrameCount() to tell us how many frames there are,
188 // then calling XAP_App::getFrame(i) to get the i-th frame.
189
190 int frameCount = pApp->getFrameCount();
191 XAP_Menu_Factory * pFact = pApp->getMenuFactory();
192
193 //
194 // Put it in the context menu.
195 //
196 XAP_Menu_Id newID = pFact->addNewMenuAfter("contextText",NULL,"Bullets and &Numbering",EV_MLF_Normal);
197 pFact->addNewLabel(NULL,newID,Wikipedia_MenuLabel, Wikipedia_MenuTooltip);
198
199 //
200 // Also put it under word Wount in the main menu,
201 //
202 pFact->addNewMenuAfter("Main",NULL,"&Word Count",EV_MLF_Normal,newID);
203
204 // Create the Action that will be called.
205 EV_Menu_Action* myAction = new EV_Menu_Action(
206 newID, // id that the layout said we could use
207 0, // no, we don't have a sub menu.
208 0, // no, we don't raise a dialog.
209 0, // no, we don't have a checkbox.
210 0,
211 "Wikipedia_invoke", // name of callback function to call.
212 NULL, // don't know/care what this is for
213 NULL // don't know/care what this is for
214 );
215
216 // Now what we need to do is add this particular action to the ActionSet
217 // of the application. This forms the link between our new ID that we
218 // got for this particular frame with the EditMethod that knows how to
219 // call our callback function.
220
221 pActionSet->addAction(myAction);
222
223 for(int i = 0;i < frameCount;++i)
224 {
225 // Get the current frame that we're iterating through.
226 XAP_Frame* pFrame = pApp->getFrame(i);
227 pFrame->rebuildMenus();
228 }
229 }
230
231 // -----------------------------------------------------------------------
232 //
233 // Abiword Plugin Interface
234 //
235 // -----------------------------------------------------------------------
236
237 ABI_BUILTIN_FAR_CALL
abi_plugin_register(XAP_ModuleInfo * mi)238 int abi_plugin_register (XAP_ModuleInfo * mi)
239 {
240 mi->name = "Wikipedia plugin";
241 mi->desc = "On-line Encyclopedia support for AbiWord. Search site is http://www.wikipedia.com/";
242 mi->version = ABI_VERSION_STRING;
243 mi->author = "Francis James Franklin"; // and Michael D. Pritchett and Dom Lachowicz
244 mi->usage = "No Usage";
245
246 // Add the dictionary to AbiWord's menus.
247 Wikipedia_addToMenus();
248
249 return 1;
250 }
251
252
253 ABI_BUILTIN_FAR_CALL
abi_plugin_unregister(XAP_ModuleInfo * mi)254 int abi_plugin_unregister (XAP_ModuleInfo * mi)
255 {
256 mi->name = 0;
257 mi->desc = 0;
258 mi->version = 0;
259 mi->author = 0;
260 mi->usage = 0;
261
262 Wikipedia_removeFromMenus();
263
264 return 1;
265 }
266
267
268 ABI_BUILTIN_FAR_CALL
abi_plugin_supports_version(UT_uint32,UT_uint32,UT_uint32)269 int abi_plugin_supports_version (UT_uint32 /*major*/, UT_uint32 /*minor*/, UT_uint32 /*release*/)
270 {
271 return 1;
272 }
273