1 /* AbiWord
2 * Copyright (C) 2003 Dom Lachowicz
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA.
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "ap_Features.h"
25
26 #include "ut_assert.h"
27 #include "ut_string.h"
28 #include "ut_debugmsg.h"
29
30 #include "ap_Dialog_Id.h"
31
32 #include "ap_Dialog_FormatTOC.h"
33 #include "ap_Strings.h"
34
35 #include "xap_App.h"
36 #include "xap_Dialog_Id.h"
37 #include "xap_DialogFactory.h"
38 #include "xap_Dlg_MessageBox.h"
39 #include "fv_View.h"
40 #include "pd_Document.h"
41 #include "pd_Style.h"
42 #include "pt_Types.h"
43 #include "fp_Line.h"
44 #include "fp_Run.h"
45 #include "fp_ContainerObject.h"
46 #include "fp_TableContainer.h"
47 #include "fl_TableLayout.h"
48 #include "fl_BlockLayout.h"
49 #include "fl_DocLayout.h"
50 #include "ut_timer.h"
51 #include "pd_Document.h"
52 #include "ap_Dialog_Stylist.h"
53 #include "pp_Property.h"
54
AP_Dialog_FormatTOC(XAP_DialogFactory * pDlgFactory,XAP_Dialog_Id id)55 AP_Dialog_FormatTOC::AP_Dialog_FormatTOC(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id)
56 : XAP_Dialog_Modeless(pDlgFactory,id),
57 m_pDoc(NULL),
58 m_pAutoUpdater(0),
59 m_iTick(0),
60 m_pAP(NULL),
61 m_bTOCFilled(false),
62 m_sTOCProps(""),
63 m_iMainLevel(1),
64 m_iDetailsLevel(1)
65 {
66 const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet ();
67 static std::string s1, s2, s3, s4;
68
69 pSS->getValueUTF8(AP_STRING_ID_DLG_FormatTOC_None, s1);
70 m_vecTABLeadersLabel.addItem(s1.c_str());
71 pSS->getValueUTF8(AP_STRING_ID_DLG_FormatTOC_Dot, s2);
72 m_vecTABLeadersLabel.addItem(s2.c_str());
73 pSS->getValueUTF8(AP_STRING_ID_DLG_FormatTOC_Dash, s3);
74 m_vecTABLeadersLabel.addItem(s3.c_str());
75 pSS->getValueUTF8(AP_STRING_ID_DLG_FormatTOC_Underline, s4);
76 m_vecTABLeadersLabel.addItem(s4.c_str());
77 m_vecTABLeadersProp.addItem("none");
78 m_vecTABLeadersProp.addItem("dot");
79 m_vecTABLeadersProp.addItem("hyphen");
80 m_vecTABLeadersProp.addItem("underline");
81 }
82
~AP_Dialog_FormatTOC(void)83 AP_Dialog_FormatTOC::~AP_Dialog_FormatTOC(void)
84 {
85 stopUpdater();
86 }
87
setActiveFrame(XAP_Frame *)88 void AP_Dialog_FormatTOC::setActiveFrame(XAP_Frame * /*pFrame*/)
89 {
90 updateDialog();
91 notifyActiveFrame(getActiveFrame());
92 }
93
startUpdater(void)94 void AP_Dialog_FormatTOC::startUpdater(void)
95 {
96 m_pAutoUpdater = UT_Timer::static_constructor(autoUpdate,this);
97 m_pAutoUpdater->set(500);
98 m_pAutoUpdater->start();
99 }
100
101 /*!
102 * Apply current style to the current selection in the current view
103 */
Apply(void)104 void AP_Dialog_FormatTOC::Apply(void)
105 {
106 FV_View * pView = static_cast<FV_View *>(getActiveFrame()->getCurrentView());
107 if(pView->getPoint() == 0)
108 {
109 return;
110 }
111 if(!pView->isTOCSelected())
112 {
113 setSensitivity(false);
114 return;
115 }
116 applyTOCPropsToDoc();
117 }
118
stopUpdater(void)119 void AP_Dialog_FormatTOC::stopUpdater(void)
120 {
121 if(m_pAutoUpdater == NULL)
122 {
123 return;
124 }
125 m_pAutoUpdater->stop();
126 DELETEP(m_pAutoUpdater);
127 m_pAutoUpdater = NULL;
128 }
129
130 /*!
131 * Autoupdater of the dialog.
132 */
autoUpdate(UT_Worker * pTimer)133 void AP_Dialog_FormatTOC::autoUpdate(UT_Worker * pTimer)
134 {
135
136 UT_return_if_fail (pTimer);
137
138 // this is a static callback method and does not have a 'this' pointer
139
140 AP_Dialog_FormatTOC * pDialog = static_cast<AP_Dialog_FormatTOC *>(pTimer->getInstanceData());
141 pDialog->updateDialog();
142 }
143
getNewStyle(UT_UTF8String & sProp)144 UT_UTF8String AP_Dialog_FormatTOC::getNewStyle(UT_UTF8String & sProp)
145 {
146 // Handshaking code
147 static UT_UTF8String sNewStyle("");
148 FV_View * pView = static_cast<FV_View *>(getActiveFrame()->getCurrentView());
149 if(pView->getPoint() == 0)
150 {
151 return sNewStyle;
152 }
153 XAP_Frame * pFrame = static_cast<XAP_Frame *> (pView->getParentData());
154 UT_return_val_if_fail (pFrame, sNewStyle);
155 XAP_DialogFactory * pDialogFactory
156 = static_cast<XAP_DialogFactory *>(pFrame->getDialogFactory());
157
158 // use justMakeTheDialog instead of requestDialog to allow modeless and modal versions of
159 // the stylist to exist
160
161 AP_Dialog_Stylist * pDialog
162 = static_cast<AP_Dialog_Stylist *>(pDialogFactory->justMakeTheDialog((AP_DIALOG_ID_STYLIST)));
163 UT_return_val_if_fail (pDialog, sNewStyle);
164 UT_UTF8String sVal = getTOCPropVal(sProp);
165
166 pDialog->setCurStyle(sVal);
167 pDialog->runModal(pFrame);
168 if(pDialog->isStyleValid())
169 {
170 sNewStyle = pDialog->getSelectedStyle();
171 }
172 pDialogFactory->releaseDialog(pDialog);
173 return sNewStyle;
174 }
175
176 /*!
177 * This method actually updates the dialog, in particular the style Tree and
178 * the current style.
179 */
updateDialog(void)180 void AP_Dialog_FormatTOC::updateDialog(void)
181 {
182 XAP_Frame * pFrame = getActiveFrame();
183 if (pFrame == 0)
184 {
185 setSensitivity(false);
186 return;
187 }
188 // Handshaking code
189 FV_View * pView = static_cast<FV_View *>(pFrame->getCurrentView());
190 if(pView->getPoint() == 0)
191 {
192 return;
193 }
194 if(!pView->isTOCSelected())
195 {
196 setSensitivity(false);
197 return;
198 }
199 setSensitivity(true);
200 PD_Document * pDoc = pView->getDocument();
201 if((m_iTick != pView->getTick()) || (m_pDoc != pDoc) || !m_bTOCFilled)
202 {
203 m_iTick = pView->getTick();
204 if(pDoc != m_pDoc)
205 {
206 m_pDoc = pDoc;
207 }
208 fillTOCPropsFromDoc();
209 setTOCPropsInGUI();
210 return;
211 }
212 }
213
214 /*!
215 * Finalize the dialog.
216 */
finalize(void)217 void AP_Dialog_FormatTOC::finalize(void)
218 {
219 stopUpdater();
220 modeless_cleanup();
221 }
222
getTOCPropVal(UT_UTF8String & sProp)223 UT_UTF8String AP_Dialog_FormatTOC::getTOCPropVal(UT_UTF8String & sProp)
224 {
225 return UT_UTF8String_getPropVal(m_sTOCProps,sProp);
226 }
227
228
getTOCPropVal(const char * szProp)229 UT_UTF8String AP_Dialog_FormatTOC::getTOCPropVal(const char * szProp)
230 {
231 UT_UTF8String sProp = szProp;
232 return UT_UTF8String_getPropVal(m_sTOCProps,sProp);
233 }
234
235
getTOCPropVal(const char * szProp,UT_sint32 i)236 UT_UTF8String AP_Dialog_FormatTOC::getTOCPropVal(const char * szProp, UT_sint32 i)
237 {
238 UT_UTF8String sProp = szProp;
239 UT_UTF8String sVal = UT_UTF8String_sprintf("%d",i);
240 sProp += sVal;
241 return UT_UTF8String_getPropVal(m_sTOCProps,sProp);
242 }
243
setTOCProperty(const char * szProp,const char * szVal)244 void AP_Dialog_FormatTOC::setTOCProperty(const char * szProp, const char * szVal)
245 {
246 UT_UTF8String sProp = szProp;
247 UT_UTF8String sVal = szVal;
248 /* don't return on empty prop strings - see Bug 9141
249 if(sVal.size() == 0)
250 {
251 return;
252 }
253 */
254 UT_DEBUGMSG((" Prop: %s Val: %s \n",sProp.utf8_str(),sVal.utf8_str()));
255 UT_UTF8String_setProperty(m_sTOCProps,sProp,sVal);
256 // m_sTOCProps.dump();
257 }
258
setTOCProperty(UT_UTF8String & sProp,UT_UTF8String & sVal)259 void AP_Dialog_FormatTOC::setTOCProperty(UT_UTF8String & sProp, UT_UTF8String & sVal)
260 {
261 /* don't return on empty prop strings - see Bug 9141
262 if(sVal.size() == 0)
263 {
264 return;
265 }
266 */
267 UT_DEBUGMSG((" Prop: %s Val: %s \n",sProp.utf8_str(),sVal.utf8_str()));
268 UT_UTF8String_setProperty(m_sTOCProps,sProp,sVal);
269 // m_sTOCProps.dump();
270 }
271
272 /*!
273 Retrieves a property value from the document, and stores it in the dialog property list.
274 @param szProp The property name to retrieve
275 @return true if the property value was retrieved from the document, false if
276 the property value was retrieved from default property values list or could
277 not be retrieved at all.
278 */
setPropFromDoc(const char * szProp)279 bool AP_Dialog_FormatTOC::setPropFromDoc(const char * szProp)
280 {
281 UT_return_val_if_fail (m_pAP, false);
282 bool bRes = true;
283 const char * szVal = NULL;
284 m_pAP->getProperty(szProp,szVal);
285 if(szVal == NULL)
286 {
287 bRes = false;
288 const PP_Property * pProp = PP_lookupProperty(szProp);
289 if(pProp == NULL)
290 {
291 UT_ASSERT_HARMLESS(0);
292 return bRes;
293 }
294 szVal = pProp->m_pszInitial;
295 }
296 setTOCProperty(szProp,szVal);
297 return bRes;
298 }
299
300 /*!
301 * Increment the "start at" property
302 */
incrementStartAt(UT_sint32 iLevel,bool bInc)303 void AP_Dialog_FormatTOC::incrementStartAt(UT_sint32 iLevel, bool bInc)
304 {
305 UT_UTF8String sProp = "toc-label-start";
306 UT_UTF8String sLevel = UT_UTF8String_sprintf("%d",iLevel);
307 sProp += sLevel.utf8_str();
308 UT_UTF8String sStartVal = getTOCPropVal(sProp);
309 UT_sint32 iVal = atoi(sStartVal.utf8_str());
310 if(bInc)
311 {
312 iVal++;
313 }
314 else
315 {
316 iVal--;
317 }
318 sStartVal = UT_UTF8String_sprintf("%d",iVal);
319 setTOCProperty(sProp,sStartVal);
320 }
321
322
323 /*!
324 * Increment the "indent" property
325 */
incrementIndent(UT_sint32 iLevel,bool bInc)326 void AP_Dialog_FormatTOC::incrementIndent(UT_sint32 iLevel, bool bInc)
327 {
328 UT_UTF8String sProp = "toc-indent";
329 UT_UTF8String sLevel = UT_UTF8String_sprintf("%d",iLevel);
330 sProp += sLevel.utf8_str();
331 UT_UTF8String sVal = getTOCPropVal(sProp);
332 double inc = getIncrement(sVal.utf8_str());
333 if(!bInc)
334 {
335 inc = -inc;
336 }
337 sVal = UT_incrementDimString(sVal.utf8_str(),inc);
338 setTOCProperty(sProp,sVal);
339 }
340
341
342 /*!
343 * Returns the increment associated with the dimension defined in the string.
344 \param const char * sz the dimensioned string.
345 \returns double - the increment associated with the dimension in sz
346 */
getIncrement(const char * sz)347 double AP_Dialog_FormatTOC::getIncrement(const char * sz)
348 {
349 double inc = 0.1;
350 UT_Dimension dim = UT_determineDimension(sz);
351 if(dim == DIM_IN)
352 {
353 inc = 0.02;
354 }
355 else if(dim == DIM_CM)
356 {
357 inc = 0.1;
358 }
359 else if(dim == DIM_MM)
360 {
361 inc = 1.0;
362 }
363 else if(dim == DIM_PI)
364 {
365 inc = 1.0;
366 }
367 else if(dim == DIM_PT)
368 {
369 inc = 1.0;
370 }
371 else if(dim == DIM_PX)
372 {
373 inc = 1.0;
374 }
375 else
376 {
377 inc = 0.02;
378 }
379 return inc;
380 }
381
fillTOCPropsFromDoc(void)382 void AP_Dialog_FormatTOC::fillTOCPropsFromDoc(void)
383 {
384 FV_View * pView = static_cast<FV_View *>(getActiveFrame()->getCurrentView());
385 PD_Document * pDoc = pView->getDocument();
386 if(pDoc != m_pDoc)
387 {
388 m_pDoc = pDoc;
389 }
390 if(!pView->isTOCSelected())
391 {
392 fl_BlockLayout * pBL = pView->getCurrentBlock();
393 pBL->getAP(m_pAP);
394 }
395 else
396 {
397 PT_DocPosition pos = pView->getSelectionAnchor()+1;
398 pf_Frag_Strux* sdhTOC = NULL;
399 m_pDoc->getStruxOfTypeFromPosition(pos,PTX_SectionTOC, &sdhTOC);
400 UT_return_if_fail (sdhTOC);
401 //
402 // OK Now lets gets all props from here and place them in our local cache
403 //
404 PT_AttrPropIndex iAPI = m_pDoc->getAPIFromSDH(sdhTOC);
405 m_pDoc->getAttrProp(iAPI,&m_pAP);
406 }
407 m_bTOCFilled = true;
408 setPropFromDoc("toc-dest-style1");
409 setPropFromDoc("toc-dest-style2");
410 setPropFromDoc("toc-dest-style3");
411 setPropFromDoc("toc-dest-style4");
412
413 setPropFromDoc("toc-has-heading");
414
415 setPropFromDoc("toc-has-label1");
416 setPropFromDoc("toc-has-label2");
417 setPropFromDoc("toc-has-label3");
418 setPropFromDoc("toc-has-label4");
419
420 bool bRes = setPropFromDoc("toc-heading");
421 if (!bRes)
422 {
423 std::string pszTOCHeading;
424 const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet ();
425 pSS->getValueUTF8(AP_STRING_ID_TOC_TocHeading, pszTOCHeading);
426 setTOCProperty("toc-heading", pszTOCHeading.c_str());
427 }
428 setPropFromDoc("toc-heading-style");
429 setPropFromDoc("toc-id");
430
431 setPropFromDoc("toc-indent1");
432 setPropFromDoc("toc-indent2");
433 setPropFromDoc("toc-indent3");
434 setPropFromDoc("toc-indent4");
435
436 setPropFromDoc("toc-label-after1");
437 setPropFromDoc("toc-label-after2");
438 setPropFromDoc("toc-label-after3");
439 setPropFromDoc("toc-label-after4");
440
441 setPropFromDoc("toc-label-before1");
442 setPropFromDoc("toc-label-before2");
443 setPropFromDoc("toc-label-before3");
444 setPropFromDoc("toc-label-before4");
445
446 setPropFromDoc("toc-label-inherits1");
447 setPropFromDoc("toc-label-inherits2");
448 setPropFromDoc("toc-label-inherits3");
449 setPropFromDoc("toc-label-inherits4");
450
451 setPropFromDoc("toc-label-start1");
452 setPropFromDoc("toc-label-start2");
453 setPropFromDoc("toc-label-start3");
454 setPropFromDoc("toc-label-start4");
455
456 setPropFromDoc("toc-label-type1");
457 setPropFromDoc("toc-label-type2");
458 setPropFromDoc("toc-label-type3");
459 setPropFromDoc("toc-label-type4");
460
461 setPropFromDoc("toc-page-type1");
462 setPropFromDoc("toc-page-type2");
463 setPropFromDoc("toc-page-type3");
464 setPropFromDoc("toc-page-type4");
465
466 setPropFromDoc("toc-source-style1");
467 setPropFromDoc("toc-source-style2");
468 setPropFromDoc("toc-source-style3");
469 setPropFromDoc("toc-source-style4");
470
471 setPropFromDoc("toc-tab-leader1");
472 setPropFromDoc("toc-tab-leader2");
473 setPropFromDoc("toc-tab-leader3");
474 setPropFromDoc("toc-tab-leader4");
475
476 setPropFromDoc("toc-label-start1");
477 setPropFromDoc("toc-label-start2");
478 setPropFromDoc("toc-label-start3");
479 setPropFromDoc("toc-label-start4");
480 }
481
applyTOCPropsToDoc(void)482 void AP_Dialog_FormatTOC::applyTOCPropsToDoc(void)
483 {
484 FV_View * pView = static_cast<FV_View *>(getActiveFrame()->getCurrentView());
485 PT_DocPosition pos = pView->getSelectionAnchor()+1;
486 pView->setTOCProps(pos,m_sTOCProps.utf8_str());
487 // m_sTOCProps.dump();
488 }
489