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