1 /*
2 *
3 * Copyright (C) 2003 by Dom Lachowicz
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_google_register
36 #define abi_plugin_unregister abipgn_google_unregister
37 #define abi_plugin_supports_version abipgn_google_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("Google")
43 #endif
44
45 // -----------------------------------------------------------------------
46 // -----------------------------------------------------------------------
47
48 //
49 // AbiGoogle_invoke
50 // -------------------
51 // This is the function that we actually call to invoke the on-line dictionary.
52 // It should be called when the user selects from the context menu
53 //
54 static bool
AbiGoogle_invoke(AV_View *,EV_EditMethodCallData *)55 AbiGoogle_invoke(AV_View* /*v*/, EV_EditMethodCallData * /*d*/)
56 {
57 // Get the current view that the user is in.
58 XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame();
59 FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView());
60
61 // If the user is on a word, but does not have it selected, we need
62 // to go ahead and select that word so that the search/replace goes
63 // correctly.
64 if (pView->isSelectionEmpty()) {
65 pView->moveInsPtTo(FV_DOCPOS_EOW_MOVE);
66 pView->moveInsPtTo(FV_DOCPOS_BOW);
67 pView->extSelTo(FV_DOCPOS_EOW_SELECT);
68 }
69
70 // Now we will figure out what word to look up
71 UT_UTF8String url ("http://www.google.com/search?hl=en&ie=UTF-8&oe=UTF-8&q=");
72
73 // url escaping should be moved somewhere more generic
74 UT_UCS4Char *ucs4ST;
75 pView->getSelectionText(*&ucs4ST);
76 UT_UCS4String data (ucs4ST);
77 bool last_was_space = false;
78 for (size_t i = 0; i < data.length (); i++) {
79 UT_UCS4Char ch = data[i];
80 if (!UT_UCS4_isspace (ch)) {
81 url.appendUCS4 (&ch, 1);
82 last_was_space = false;
83 }
84 else if (!last_was_space) {
85 ch = '+';
86 url.appendUCS4 (&ch, 1);
87 last_was_space = true;
88 }
89 }
90
91 XAP_App::getApp()->openURL( url.utf8_str() );
92 FREEP(ucs4ST);
93
94 return true;
95 }
96
97 static const char* Google_MenuLabel = "&Google Search";
98 static const char* Google_MenuTooltip = "Search the web with Google";
99
100 static void
Google_removeFromMenus()101 Google_removeFromMenus()
102 {
103 // First we need to get a pointer to the application itself.
104 XAP_App *pApp = XAP_App::getApp();
105
106 // remove the edit method
107 EV_EditMethodContainer* pEMC = pApp->getEditMethodContainer() ;
108 EV_EditMethod * pEM = ev_EditMethod_lookup ( "AbiGoogle_invoke" ) ;
109 pEMC->removeEditMethod ( pEM ) ;
110 DELETEP( pEM ) ;
111
112 // now remove crap from the menus
113 int frameCount = pApp->getFrameCount();
114 XAP_Menu_Factory * pFact = pApp->getMenuFactory();
115
116 pFact->removeMenuItem("Main",NULL,Google_MenuLabel);
117 pFact->removeMenuItem("contextText",NULL,Google_MenuLabel);
118 for(int i = 0;i < frameCount;++i)
119 {
120 // Get the current frame that we're iterating through.
121 XAP_Frame* pFrame = pApp->getFrame(i);
122 pFrame->rebuildMenus();
123 }
124 }
125
126 static void
Google_addToMenus()127 Google_addToMenus()
128 {
129 // First we need to get a pointer to the application itself.
130 XAP_App *pApp = XAP_App::getApp();
131
132 // Create an EditMethod that will link our method's name with
133 // it's callback function. This is used to link the name to
134 // the callback.
135 EV_EditMethod *myEditMethod = new EV_EditMethod(
136 "AbiGoogle_invoke", // name of callback function
137 AbiGoogle_invoke, // callback function itself.
138 0, // no additional data required.
139 "" // description -- allegedly never used for anything
140 );
141
142 // Now we need to get the EditMethod container for the application.
143 // This holds a series of Edit Methods and links names to callbacks.
144 EV_EditMethodContainer* pEMC = pApp->getEditMethodContainer();
145
146 // We have to add our EditMethod to the application's EditMethodList
147 // so that the application will know what callback to call when a call
148 // to "AbiGoogle_invoke" is received.
149 pEMC->addEditMethod(myEditMethod);
150
151
152 // Now we need to grab an ActionSet. This is going to be used later
153 // on in our for loop. Take a look near the bottom.
154 EV_Menu_ActionSet* pActionSet = pApp->getMenuActionSet();
155
156
157 // We need to go through and add the menu element to each "frame"
158 // of the application. We can iterate through the frames by doing
159 // XAP_App::getFrameCount() to tell us how many frames there are,
160 // then calling XAP_App::getFrame(i) to get the i-th frame.
161
162 int frameCount = pApp->getFrameCount();
163 XAP_Menu_Factory * pFact = pApp->getMenuFactory();
164
165 //
166 // Put it in the context menu.
167 //
168 XAP_Menu_Id newID = pFact->addNewMenuAfter("contextText",NULL,"Bullets and &Numbering",EV_MLF_Normal);
169 pFact->addNewLabel(NULL,newID,Google_MenuLabel, Google_MenuTooltip);
170
171 //
172 // Also put it under word Wount in the main menu,
173 //
174 pFact->addNewMenuAfter("Main",NULL,"&Word Count",EV_MLF_Normal,newID);
175
176 // Create the Action that will be called.
177 EV_Menu_Action* myAction = new EV_Menu_Action(
178 newID, // id that the layout said we could use
179 0, // no, we don't have a sub menu.
180 0, // yes, we raise a dialog.
181 0, // no, we don't have a checkbox.
182 0, // not a radio button
183 "AbiGoogle_invoke", // name of callback function to call.
184 NULL, // don't know/care what this is for
185 NULL // don't know/care what this is for
186 );
187
188 // Now what we need to do is add this particular action to the ActionSet
189 // of the application. This forms the link between our new ID that we
190 // got for this particular frame with the EditMethod that knows how to
191 // call our callback function.
192
193 pActionSet->addAction(myAction);
194
195 for(int i = 0;i < frameCount;++i)
196 {
197 // Get the current frame that we're iterating through.
198 XAP_Frame* pFrame = pApp->getFrame(i);
199 pFrame->rebuildMenus();
200 }
201 }
202
203 // -----------------------------------------------------------------------
204 //
205 // Abiword Plugin Interface
206 //
207 // -----------------------------------------------------------------------
208
209 ABI_BUILTIN_FAR_CALL
abi_plugin_register(XAP_ModuleInfo * mi)210 int abi_plugin_register (XAP_ModuleInfo * mi)
211 {
212 mi->name = "Google plugin";
213 mi->desc = "Google search for AbiWord";
214 mi->version = ABI_VERSION_STRING;
215 mi->author = "Dom Lachowicz";
216 mi->usage = "No Usage";
217
218 Google_addToMenus();
219
220 return 1;
221 }
222
223
224 ABI_BUILTIN_FAR_CALL
abi_plugin_unregister(XAP_ModuleInfo * mi)225 int abi_plugin_unregister (XAP_ModuleInfo * mi)
226 {
227 mi->name = 0;
228 mi->desc = 0;
229 mi->version = 0;
230 mi->author = 0;
231 mi->usage = 0;
232
233 Google_removeFromMenus() ;
234
235 return 1;
236 }
237
238
239 ABI_BUILTIN_FAR_CALL
abi_plugin_supports_version(UT_uint32,UT_uint32,UT_uint32)240 int abi_plugin_supports_version (UT_uint32 /*major*/, UT_uint32 /*minor*/, UT_uint32 /*release*/)
241 {
242 return 1;
243 }
244