1 /* AbiWord
2  * Copyright (C) 1998 AbiSource, Inc.
3  * Copyright (C) 2003 Marc Maurer
4  * Copyright (c) 2009 Hubert Figuiere
5  * Copyright (c) 2010 Maleesh Prasan
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301 USA.
20  */
21 
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 
26 #include "ap_Features.h"
27 
28 #include "ut_assert.h"
29 #include "ut_string.h"
30 #include "ut_std_string.h"
31 #include "ut_debugmsg.h"
32 
33 #include "xap_App.h"
34 #include "xap_Dialog_Id.h"
35 #include "xap_DialogFactory.h"
36 #include "xap_Dlg_MessageBox.h"
37 #include "fv_View.h"
38 #include "pd_Document.h"
39 #include "pt_Types.h"
40 #include "fp_Line.h"
41 #include "fp_Run.h"
42 #include "fp_ContainerObject.h"
43 #include "fp_TableContainer.h"
44 #include "fl_TableLayout.h"
45 #include "fl_BlockLayout.h"
46 #include "fl_DocLayout.h"
47 #include "ut_timer.h"
48 #include "fg_GraphicRaster.h"
49 #include "fg_GraphicVector.h"
50 #include "ap_Dialog_Border_Shading.h"
51 #include "ut_png.h"
52 #include "gr_Painter.h"
53 #include "ut_units.h"
54 #include "ap_Strings.h"
55 #include "pp_PropertyMap.h"
56 
AP_Dialog_Border_Shading(XAP_DialogFactory * pDlgFactory,XAP_Dialog_Id id)57 AP_Dialog_Border_Shading::AP_Dialog_Border_Shading(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id)
58 	: XAP_Dialog_Modeless(pDlgFactory,id, "interface/dialogbordershading"),
59 	  m_answer(a_OK),
60 	  m_pBorderShadingPreview(NULL),
61 	  m_borderColor(0,0,0),
62 	  m_lineStyle(LS_NORMAL),
63 	  m_bgFillStyle(NULL),
64 	  m_bSettingsChanged(false),
65 	  m_iOldPos(0),
66 	  m_pAutoUpdaterMC(NULL),
67 	  m_bDestroy_says_stopupdating(false),
68 	  m_bAutoUpdate_happening_now(false)
69 // 	  m_sImagePath(""),
70 // 	  m_iGraphicType(0),
71 // 	  m_pImage(NULL),
72 // 	  m_pGraphic(NULL)
73 {
74 	const char * sBordersThickness[BORDER_SHADING_NUMTHICKNESS] ={"0.25pt","0.5pt",
75 													   "0.75pt","1.0pt",
76 													   "1.5pt","2.25pt","3pt",
77 													   "4.5pt","6.0pt"};
78 
79 	const char * sShadingOffset[BORDER_SHADING_NUMOFFSETS] ={"0.25pt","0.5pt",
80 														"0.75pt","1.0pt",
81 														"1.5pt","2.25pt","3pt",
82 														"4.5pt","6.0pt"};
83 
84 	UT_sint32 i = 0;
85 	for(i=0; i< BORDER_SHADING_NUMTHICKNESS ;i++)
86 	{
87 		m_dThickness[i] = UT_convertToInches(sBordersThickness[i]);
88 	}
89 
90 	UT_sint32 j = 0;
91 	for(j=0; j< BORDER_SHADING_NUMOFFSETS ;j++)
92 	{
93 		m_dShadingOffset[j] = UT_convertToInches(sShadingOffset[j]);
94 	}
95 
96 	if(m_vecProps.getItemCount() > 0)
97 		m_vecProps.clear();
98 /*
99 	if(m_vecPropsAdjRight.getItemCount() > 0)
100 		m_vecPropsAdjRight.clear();
101 
102 	if(m_vecPropsAdjBottom.getItemCount() > 0)
103 		m_vecPropsAdjBottom.clear();
104 */
105 	guint border_style_id = (guint)PP_PropertyMap::linestyle_none - 1;
106 	m_sDefaultStyle = UT_String_sprintf("%d", border_style_id);
107 }
108 
~AP_Dialog_Border_Shading(void)109 AP_Dialog_Border_Shading::~AP_Dialog_Border_Shading(void)
110 {
111 	stopUpdater();
112 	DELETEP(m_pBorderShadingPreview);
113 // 	DELETEP(m_pGraphic);
114 // 	DELETEP(m_pImage);
115 }
116 
getAnswer(void) const117 AP_Dialog_Border_Shading::tAnswer AP_Dialog_Border_Shading::getAnswer(void) const
118 {
119 	return m_answer;
120 }
121 
setActiveFrame(XAP_Frame *)122 void AP_Dialog_Border_Shading::setActiveFrame(XAP_Frame * /*pFrame*/)
123 {
124 	notifyActiveFrame(getActiveFrame());
125 }
126 
ConstructWindowName(void)127 void AP_Dialog_Border_Shading::ConstructWindowName(void)
128 {
129 	const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet();
130 	gchar * tmp = NULL;
131 	UT_XML_cloneNoAmpersands(tmp, pSS->getValue(AP_STRING_ID_DLG_BorderShading_Title));
132 	BuildWindowName(static_cast<char *>(m_WindowName),static_cast<char*>(tmp),sizeof(m_WindowName));
133 	FREEP(tmp);
134 }
135 
startUpdater(void)136 void AP_Dialog_Border_Shading::startUpdater(void)
137 {
138 	m_bDestroy_says_stopupdating = false;
139 	m_bAutoUpdate_happening_now = false;
140 	m_pAutoUpdaterMC =  UT_Timer::static_constructor(autoUpdateMC,this);
141 	m_pAutoUpdaterMC->set(100); // use a fast time, so the dialogs behavior looks "snappy"
142 	m_pAutoUpdaterMC->start();
143 }
144 
stopUpdater(void)145 void AP_Dialog_Border_Shading::stopUpdater(void)
146 {
147 	if(m_pAutoUpdaterMC == NULL)
148 	{
149 		return;
150 	}
151 	m_bDestroy_says_stopupdating = true;
152 	m_pAutoUpdaterMC->stop();
153 	DELETEP(m_pAutoUpdaterMC);
154 	m_pAutoUpdaterMC = NULL;
155 }
156 /*!
157  Auto-updater of the dialog.
158  */
autoUpdateMC(UT_Worker * pTimer)159 void AP_Dialog_Border_Shading::autoUpdateMC(UT_Worker * pTimer)
160 {
161 	UT_return_if_fail (pTimer);
162 
163 	// get the dialog pointer from the timer instance data
164 	AP_Dialog_Border_Shading * pDialog = static_cast<AP_Dialog_Border_Shading *>(pTimer->getInstanceData());
165 
166 	// Handshaking code
167 	if( pDialog->m_bDestroy_says_stopupdating != true)
168 	{
169 		pDialog->m_bAutoUpdate_happening_now = true;
170 		pDialog->setAllSensitivities();
171 		pDialog->setCurBlockProps();
172 		pDialog->m_bAutoUpdate_happening_now = false;
173 	}
174 }
175 
176 /*!
177  Sets the sensitivity of the radio buttons to top/bottom/left/right line buttons
178  Call this right after constructing the widget and before dropping into the main loop.
179  */
setAllSensitivities(void)180 void AP_Dialog_Border_Shading::setAllSensitivities(void)
181 {
182 	setSensitivity(true);
183 }
184 
setCurBlockProps(void)185 void AP_Dialog_Border_Shading::setCurBlockProps(void)
186 {
187 	XAP_Frame *frame = XAP_App::getApp()->getLastFocussedFrame();
188 	if (frame) {
189 		FV_View * pView = static_cast<FV_View *>(frame->getCurrentView());
190 
191 		if (m_bSettingsChanged || m_iOldPos == pView->getPoint())
192 			return;
193 
194 		m_iOldPos = pView->getPoint();
195 
196 		/*
197 		 * update the border colors
198 		 */
199 
200 		fl_BlockLayout* current_block = pView->getCurrentBlock();
201 
202 		const char* style_left	= current_block->getProperty("left-style");
203 		const char* style_right	= current_block->getProperty("right-style");
204 		const char* style_top	= current_block->getProperty("top-style");
205 		const char* style_bot	= current_block->getProperty("bot-style");
206 
207 
208 		// 8/8/2010 Maleesh - Update the border styles.
209 		UT_UTF8String active_style	= m_sDefaultStyle.c_str();
210 		UT_UTF8String default_style = m_sDefaultStyle.c_str();
211 
212 		if (style_left)
213 		{
214 			m_vecProps.addOrReplaceProp("left-style", style_left);
215 			if (active_style == default_style)
216 				active_style = style_left;
217 		}
218 		else
219 			m_vecProps.removeProp("left-style");
220 
221 		if (style_right)
222 		{
223 			m_vecProps.addOrReplaceProp("right-style", style_right);
224 			if (active_style == default_style)
225 				active_style = style_right;
226 		}
227 		else
228 			m_vecProps.removeProp("right-style");
229 
230 		if (style_top)
231 		{
232 			m_vecProps.addOrReplaceProp("top-style", style_top);
233 			if (active_style == default_style)
234 				active_style = style_top;
235 		}
236 		else
237 			m_vecProps.removeProp("top-style");
238 
239 		if (style_bot)
240 		{
241 			m_vecProps.addOrReplaceProp("bot-style", style_bot);
242 			if (active_style == default_style)
243 				active_style = style_bot;
244 		}
245 		else
246 			m_vecProps.removeProp("bot-style");
247 
248 		setBorderStyleInGUI(active_style);
249 
250 		const char* color_left	= current_block->getProperty("left-color");
251 		const char* thickness_left	= current_block->getProperty("left-thickness");
252 
253 		if (color_left)
254 		{
255 			m_vecProps.addOrReplaceProp("left-color", color_left);
256 			m_vecProps.addOrReplaceProp("right-color", color_left);
257 			m_vecProps.addOrReplaceProp("top-color", color_left);
258 			m_vecProps.addOrReplaceProp("bot-color", color_left);
259 
260 			UT_RGBColor clr;
261 			clr.setColor(color_left);
262 			setBorderColorInGUI(clr);
263 		}
264 		else
265 		{
266 			m_vecProps.removeProp("left-color");
267 			m_vecProps.removeProp("right-color");
268 			m_vecProps.removeProp("top-color");
269 			m_vecProps.removeProp("bot-color");
270 		}
271 
272 		if (thickness_left)
273 		{
274 			m_vecProps.addOrReplaceProp("left-thickness", thickness_left);
275 			m_vecProps.addOrReplaceProp("right-thickness", thickness_left);
276 			m_vecProps.addOrReplaceProp("top-thickness", thickness_left);
277 			m_vecProps.addOrReplaceProp("bot-thickness", thickness_left);
278 
279 			UT_UTF8String thickness_utf8 = thickness_left;
280 			setBorderThicknessInGUI(thickness_utf8);
281 		}
282 		else
283 		{
284 			m_vecProps.removeProp("left-thickness");
285 			m_vecProps.removeProp("right-thickness");
286 			m_vecProps.removeProp("top-thickness");
287 			m_vecProps.removeProp("bot-thickness");
288 		}
289 
290 		// 8/8/2010 Maleesh - Update shading.
291 
292 		const char* shading_pattern	= current_block->getProperty("shading-pattern");
293 		const char* shading_color	= current_block->getProperty("shading-foreground-color");
294 
295 		if (shading_pattern)
296 		{
297 			m_vecProps.addOrReplaceProp("shading-pattern", shading_pattern);
298 
299 			UT_UTF8String pattern_utf8 = shading_pattern;
300 			setShadingPatternInGUI(pattern_utf8);
301 		}
302 		else
303 		{
304 			m_vecProps.removeProp("shading-pattern");
305 			UT_UTF8String pattern_utf8 = BORDER_SHADING_SHADING_DISABLE;
306 			setShadingPatternInGUI(pattern_utf8);
307 		}
308 
309 		if (shading_color)
310 		{
311 			m_vecProps.addOrReplaceProp("shading-foreground-color", shading_color);
312 
313 			UT_RGBColor clr;
314 			clr.setColor(shading_color);
315 			setShadingColorInGUI(clr);
316 		}
317 		else
318 		{
319 			m_vecProps.removeProp("shading-foreground-color");
320 			setShadingColorInGUI(UT_RGBColor(255, 255, 255));
321 		}
322 
323 
324 		// 8/8/2010 Maleesh - TEMP
325 		UT_DEBUGMSG(("Maleesh =============== Border props %s|%s|%s\n",style_left, color_left, thickness_left));
326 		UT_DEBUGMSG(("Maleesh =============== Shading props %s|%s\n",shading_pattern, shading_color));
327 
328 		// draw the preview with the changed properties
329 		if(m_pBorderShadingPreview)
330 			m_pBorderShadingPreview->queueDraw();
331 	}
332 }
333 
applyChanges()334 void AP_Dialog_Border_Shading::applyChanges()
335 {
336 	UT_DEBUGMSG(("Doing apply changes number props %d \n",m_vecProps.getItemCount()));
337 	if (m_vecProps.getItemCount() == 0)
338 		return;
339 
340     FV_View * pView = static_cast<FV_View *>(XAP_App::getApp()->getLastFocussedFrame()->getCurrentView());
341 	const gchar ** propsArray  = new const gchar * [m_vecProps.getItemCount()+1];
342 	propsArray[m_vecProps.getItemCount()] = NULL;
343 
344 	UT_sint32 i = m_vecProps.getItemCount();
345 	UT_sint32 j;
346 	for(j= 0; j<i; j=j+2)
347 	{
348 		propsArray[j] = static_cast<gchar *>(m_vecProps.getNthItem(j));
349 		propsArray[j+1] = static_cast<gchar *>(m_vecProps.getNthItem(j+1));
350 
351 		UT_DEBUGMSG(("Maleesh ======================= %s | %s \n", propsArray[j], propsArray[j + 1]));
352 	}
353 	pView->setBlockFormat(propsArray);
354 
355 	delete [] propsArray;
356 	m_bSettingsChanged = false;
357 }
358 
finalize(void)359 void AP_Dialog_Border_Shading::finalize(void)
360 {
361 	stopUpdater();
362 	modeless_cleanup();
363 }
364 
365 /*!
366  Set the color and style and thickness of the toggled button
367  */
toggleLineType(toggle_button btn,bool enabled)368 void AP_Dialog_Border_Shading::toggleLineType(toggle_button btn, bool enabled)
369 {
370 	UT_String cTmp = UT_String_sprintf("%02x%02x%02x", m_borderColor.m_red, m_borderColor.m_grn, m_borderColor.m_blu);
371 	UT_String sTmp = UT_String_sprintf("%d", (enabled ? m_lineStyle : LS_OFF));
372 
373 	switch (btn)
374 	{
375 		case toggle_left:
376 		{
377 			m_vecProps.addOrReplaceProp("left-style", sTmp.c_str());
378 			m_vecProps.addOrReplaceProp("left-color", cTmp.c_str());
379 			m_vecProps.addOrReplaceProp("left-thickness",m_sBorderThickness.utf8_str());
380 		}
381 		break;
382 		case toggle_right:
383 		{
384 			m_vecProps.addOrReplaceProp("right-style", sTmp.c_str());
385 			m_vecProps.addOrReplaceProp("right-color", cTmp.c_str());
386 			m_vecProps.addOrReplaceProp("right-thickness",m_sBorderThickness.utf8_str());
387 		}
388 		break;
389 		case toggle_top:
390 		{
391 			m_vecProps.addOrReplaceProp("top-style", sTmp.c_str());
392 			m_vecProps.addOrReplaceProp("top-color", cTmp.c_str());
393 			m_vecProps.addOrReplaceProp("top-thickness",m_sBorderThickness.utf8_str());
394 		}
395 		break;
396 		case toggle_bottom:
397 		{
398 			m_vecProps.addOrReplaceProp("bot-style", sTmp.c_str());
399 			m_vecProps.addOrReplaceProp("bot-color", cTmp.c_str());
400 			m_vecProps.addOrReplaceProp("bot-thickness",m_sBorderThickness.utf8_str());
401 		}
402 		break;
403 	}
404 	m_bSettingsChanged = true;
405 	UT_DEBUGMSG(("Maleesh ======================= toggleLineType\n"));
406 }
407 
setBorderThickness(UT_UTF8String & sThick)408 void AP_Dialog_Border_Shading::setBorderThickness(UT_UTF8String & sThick)
409 {
410 	m_sBorderThickness = sThick;
411 
412 	m_vecProps.addOrReplaceProp("left-thickness", m_sBorderThickness.utf8_str());
413 	m_vecProps.addOrReplaceProp("right-thickness", m_sBorderThickness.utf8_str());
414 	m_vecProps.addOrReplaceProp("top-thickness", m_sBorderThickness.utf8_str());
415 	m_vecProps.addOrReplaceProp("bot-thickness", m_sBorderThickness.utf8_str());
416 
417 	guint index			= _findClosestThickness(sThick.utf8_str());
418 	double space		= m_dThickness[index] + 0.02;
419 	UT_String str_space = UT_String_sprintf("%fin", space);
420 
421 	m_vecProps.addOrReplaceProp("left-space", str_space.c_str());
422 	m_vecProps.addOrReplaceProp("right-space", str_space.c_str());
423 	m_vecProps.addOrReplaceProp("top-space", str_space.c_str());
424 	m_vecProps.addOrReplaceProp("bot-space", str_space.c_str());
425 
426 	m_bSettingsChanged = true;
427 	UT_DEBUGMSG(("Maleesh ======================= setBorderThickness\n"));
428 }
429 
setBorderStyle(UT_UTF8String & sStyle)430 void AP_Dialog_Border_Shading::setBorderStyle(UT_UTF8String & sStyle)
431 {
432 	m_vecProps.addOrReplaceProp("left-style", sStyle.utf8_str());
433 	m_vecProps.addOrReplaceProp("right-style",sStyle.utf8_str());
434 	m_vecProps.addOrReplaceProp("top-style",sStyle.utf8_str());
435 	m_vecProps.addOrReplaceProp("bot-style",sStyle.utf8_str());
436 
437 	m_bSettingsChanged = true;
438 	UT_DEBUGMSG(("Maleesh ======================= setBorderStyle %s: \n", sStyle.utf8_str()));
439 }
440 
setBorderColor(UT_RGBColor clr)441 void AP_Dialog_Border_Shading::setBorderColor(UT_RGBColor clr)
442 {
443 	m_borderColor = clr;
444 
445 	UT_String s = UT_String_sprintf("%02x%02x%02x", clr.m_red, clr.m_grn, clr.m_blu);
446 
447 	m_vecProps.addOrReplaceProp("left-color", s.c_str());
448 	m_vecProps.addOrReplaceProp("right-color", s.c_str());
449 	m_vecProps.addOrReplaceProp("top-color", s.c_str());
450 	m_vecProps.addOrReplaceProp("bot-color", s.c_str());
451 
452 //	m_vecPropsAdjRight.addOrReplaceProp("left-color", s.c_str());
453 //	m_vecPropsAdjBottom.addOrReplaceProp("top-color", s.c_str());
454 
455 	m_bSettingsChanged = true;
456 	UT_DEBUGMSG(("Maleesh ======================= setBorderColor\n"));
457 }
458 
setShadingPattern(UT_UTF8String & sPattern)459 void AP_Dialog_Border_Shading::setShadingPattern(UT_UTF8String & sPattern)
460 {
461 	m_vecProps.addOrReplaceProp ("shading-pattern", sPattern.utf8_str());
462 	m_bSettingsChanged = true;
463 	UT_DEBUGMSG(("Maleesh ======================= setShadingPattern\n"));
464 }
465 
setShadingColor(UT_RGBColor clr)466 void AP_Dialog_Border_Shading::setShadingColor(UT_RGBColor clr)
467 {
468 	UT_String bgcol = UT_String_sprintf("%02x%02x%02x", clr.m_red, clr.m_grn, clr.m_blu);
469 
470 	if (clr.isTransparent ())
471 	{
472 		m_vecProps.removeProp ("shading-foreground-color");
473 	}
474 	else
475 	{
476 		m_vecProps.addOrReplaceProp ("shading-foreground-color", bgcol.c_str ());
477 	}
478 	m_bSettingsChanged = true;
479 	UT_DEBUGMSG(("Maleesh ======================= setShadingColor\n"));
480 }
481 
setShadingOffset(UT_UTF8String &)482 void AP_Dialog_Border_Shading::setShadingOffset(UT_UTF8String & /*sOffset*/)
483 {
484 	// 7/7/2010 Maleesh  - TODO
485 }
486 
_createPreviewFromGC(GR_Graphics * gc,UT_uint32 width,UT_uint32 height)487 void AP_Dialog_Border_Shading::_createPreviewFromGC(GR_Graphics * gc,
488 											     UT_uint32 width,
489 											     UT_uint32 height)
490 {
491 	UT_return_if_fail (gc);
492 
493 	delete m_pBorderShadingPreview;
494 	m_pBorderShadingPreview = new AP_Border_Shading_preview(gc,this);
495 	UT_return_if_fail (m_pBorderShadingPreview);
496 
497 	m_pBorderShadingPreview->setWindowSize(width, height);
498 }
499 
_getToggleButtonStatus(const char * lineStyle) const500 bool AP_Dialog_Border_Shading::_getToggleButtonStatus(const char * lineStyle) const
501 {
502 	const gchar * pszStyle = NULL;
503 	std::string lsOff = UT_std_string_sprintf("%d", LS_OFF);
504 
505 	m_vecProps.getProp(lineStyle, pszStyle);
506 
507 	if ((pszStyle && strcmp(pszStyle, lsOff.c_str())) ||
508 		!pszStyle)
509 		return true;
510 	else
511 		return false;
512 }
513 
getTopToggled() const514 bool AP_Dialog_Border_Shading::getTopToggled() const
515 {
516 	return _getToggleButtonStatus("top-style");
517 }
518 
getBottomToggled() const519 bool AP_Dialog_Border_Shading::getBottomToggled() const
520 {
521 	return _getToggleButtonStatus("bot-style");
522 }
523 
getRightToggled() const524 bool AP_Dialog_Border_Shading::getRightToggled() const
525 {
526 	return _getToggleButtonStatus("right-style");
527 }
528 
getLeftToggled() const529 bool AP_Dialog_Border_Shading::getLeftToggled() const
530 {
531 	return _getToggleButtonStatus("left-style");
532 }
533 
_findClosestThickness(const char * sthickness) const534 guint AP_Dialog_Border_Shading::_findClosestThickness(const char *sthickness) const
535 {
536 	double thickness = UT_convertToInches(sthickness);
537 	guint i = 0;
538 	guint closest = 0;
539 	double dClose = 100000000.;
540 	for(i = 0; i < BORDER_SHADING_NUMTHICKNESS; i++)
541 	{
542 		double diff = thickness - m_dThickness[i];
543 		if(diff < 0)
544 			diff = -diff;
545 		if(diff < dClose)
546 		{
547 			closest = i;
548 			dClose = diff;
549 		}
550 	}
551 	return closest;
552 }
553 
554 
_findClosestOffset(const char * sOffset) const555 guint AP_Dialog_Border_Shading::_findClosestOffset(const char *sOffset) const
556 {
557 	double thickness = UT_convertToInches(sOffset);
558 	guint i = 0;
559 	guint closest = 0;
560 	double dClose = 100000000.;
561 	for(i = 0; i < BORDER_SHADING_NUMOFFSETS; i++)
562 	{
563 		double diff = thickness - m_dShadingOffset[i];
564 		if(diff < 0)
565 			diff = -diff;
566 		if(diff < dClose)
567 		{
568 			closest = i;
569 			dClose = diff;
570 		}
571 	}
572 	return closest;
573 }
574 
575 //////////////////////////////////////////////////////////////////
576 //////////////////////////////////////////////////////////////////
577 
AP_Border_Shading_preview(GR_Graphics * gc,AP_Dialog_Border_Shading * pFormatTable)578 AP_Border_Shading_preview::AP_Border_Shading_preview(GR_Graphics * gc, AP_Dialog_Border_Shading * pFormatTable)
579 	: XAP_Preview(gc)
580 {
581 	m_pBorderShading = pFormatTable;
582 }
583 
~AP_Border_Shading_preview()584 AP_Border_Shading_preview::~AP_Border_Shading_preview()
585 {
586 }
587 
draw(const UT_Rect * clip)588 void AP_Border_Shading_preview::draw(const UT_Rect *clip)
589 {
590 	UT_UNUSED(clip);
591 	GR_Painter painter(m_gc);
592 
593 	UT_sint32 iWidth = m_gc->tlu (getWindowWidth());
594 	UT_sint32 iHeight = m_gc->tlu (getWindowHeight());
595 	UT_Rect pageRect(m_gc->tlu(7), m_gc->tlu(7), iWidth - m_gc->tlu(14), iHeight - m_gc->tlu(14));
596 
597 	painter.fillRect(GR_Graphics::CLR3D_Background, 0, 0, iWidth, iHeight);
598 	painter.clearArea(pageRect.left, pageRect.top, pageRect.width, pageRect.height);
599 
600 	UT_RGBColor tmpCol;
601 
602 	UT_RGBColor black(0, 0, 0);
603 	m_gc->setLineWidth(m_gc->tlu(1));
604 
605 	int border = m_gc->tlu(20);
606 	int cornerLength = m_gc->tlu(5);
607 
608 //
609 //  Draw the cell background (Shading)
610 //
611 
612 	const gchar * pszShadingColor	= NULL;
613 	const gchar * pszShadingPattern = NULL;
614 	m_pBorderShading->getPropVector().getProp(static_cast<const gchar *>("shading-pattern"), pszShadingPattern);
615 
616 	if(pszShadingPattern && strcmp(pszShadingPattern, BORDER_SHADING_SHADING_DISABLE))
617 	{
618 		m_pBorderShading->getPropVector().getProp(static_cast<const gchar *>("shading-foreground-color"), pszShadingColor);
619 		if (pszShadingColor && *pszShadingColor)
620 		{
621 			UT_parseColor(pszShadingColor, tmpCol);
622 			painter.fillRect(tmpCol, pageRect.left + border, pageRect.top + border, pageRect.width - 2*border, pageRect.height - 2*border);
623 		}
624 	}
625 
626 //
627 //  Draw the cell corners
628 //
629 
630 	m_gc->setColor(UT_RGBColor(127,127,127));
631 
632 	// top left corner
633 	painter.drawLine(pageRect.left + border - cornerLength, pageRect.top + border,
634 				   pageRect.left + border, pageRect.top + border);
635 	painter.drawLine(pageRect.left + border, pageRect.top + border  - cornerLength,
636 				   pageRect.left + border, pageRect.top + border);
637 
638 	// top right corner
639 	painter.drawLine(pageRect.left + pageRect.width - border + cornerLength, pageRect.top + border,
640 				   pageRect.left + pageRect.width - border, pageRect.top + border);
641 	painter.drawLine(pageRect.left + pageRect.width - border, pageRect.top + border - cornerLength,
642 				   pageRect.left + pageRect.width - border, pageRect.top + border);
643 
644 	// bottom left corner
645 	painter.drawLine(pageRect.left + border - cornerLength, pageRect.top + pageRect.height - border,
646 				   pageRect.left + border, pageRect.top + pageRect.height - border);
647 	painter.drawLine(pageRect.left + border, pageRect.top + pageRect.height - border + cornerLength,
648 				   pageRect.left + border, pageRect.top + pageRect.height - border);
649 
650 	// bottom right corner
651 	painter.drawLine(pageRect.left + pageRect.width - border + cornerLength, pageRect.top + pageRect.height - border,
652 				   pageRect.left + pageRect.width - border, pageRect.top + pageRect.height - border);
653 	painter.drawLine(pageRect.left + pageRect.width - border, pageRect.top + pageRect.height - border + cornerLength,
654 				   pageRect.left + pageRect.width - border, pageRect.top + pageRect.height - border);
655 
656 //
657 //  Draw the cell borders
658 //
659 
660 	// top border
661 	if (m_pBorderShading->getTopToggled())
662 	{
663 		const gchar * pszTopColor = NULL;
664 		m_pBorderShading->getPropVector().getProp("top-color", pszTopColor);
665 		if (pszTopColor)
666 		{
667 			UT_parseColor(pszTopColor, tmpCol);
668 			m_gc->setColor(tmpCol);
669 		}
670 		else
671 			m_gc->setColor(black);
672 		const gchar * pszTopThickness = NULL;
673 		m_pBorderShading->getPropVector().getProp("top-thickness", pszTopThickness);
674 		if(pszTopThickness)
675 		{
676 			UT_sint32 iTopThickness = UT_convertToLogicalUnits(pszTopThickness);
677 			m_gc->setLineWidth(iTopThickness);
678 		}
679 		else
680 		{
681 			m_gc->setLineWidth(m_gc->tlu(1));
682 		}
683 
684 		painter.drawLine(pageRect.left + border, pageRect.top + border,
685 					   pageRect.left + pageRect.width - border, pageRect.top + border);
686 	}
687 
688 	// left border
689 	if (m_pBorderShading->getLeftToggled())
690 	{
691 		const gchar * pszLeftColor = NULL;
692 		m_pBorderShading->getPropVector().getProp("left-color", pszLeftColor);
693 		if (pszLeftColor)
694 		{
695 			UT_parseColor(pszLeftColor, tmpCol);
696 			m_gc->setColor(tmpCol);
697 		}
698 		else
699 			m_gc->setColor(black);
700 		const gchar * pszLeftThickness = NULL;
701 		m_pBorderShading->getPropVector().getProp("left-thickness", pszLeftThickness);
702 		if(pszLeftThickness)
703 		{
704 			UT_sint32 iLeftThickness = UT_convertToLogicalUnits(pszLeftThickness);
705 			m_gc->setLineWidth(iLeftThickness);
706 		}
707 		else
708 		{
709 			m_gc->setLineWidth(m_gc->tlu(1));
710 		}
711 		painter.drawLine(pageRect.left + border, pageRect.top + border,
712 					   pageRect.left + border, pageRect.top + pageRect.height - border);
713 	}
714 
715 	// right border
716 	if (m_pBorderShading->getRightToggled())
717 	{
718 		const gchar * pszRightColor = NULL;
719 		m_pBorderShading->getPropVector().getProp("right-color", pszRightColor);
720 		if (pszRightColor)
721 		{
722 			UT_parseColor(pszRightColor, tmpCol);
723 			m_gc->setColor(tmpCol);
724 		}
725 		else
726 			m_gc->setColor(black);
727 		const gchar * pszRightThickness = NULL;
728 		m_pBorderShading->getPropVector().getProp("right-thickness", pszRightThickness);
729 		if(pszRightThickness)
730 		{
731 			UT_sint32 iRightThickness = UT_convertToLogicalUnits(pszRightThickness);
732 			m_gc->setLineWidth(iRightThickness);
733 		}
734 		else
735 		{
736 			m_gc->setLineWidth(m_gc->tlu(1));
737 		}
738 		painter.drawLine(pageRect.left + pageRect.width - border, pageRect.top + border,
739 					   pageRect.left + pageRect.width - border, pageRect.top + pageRect.height - border);
740 	}
741 
742 	// bottom border
743 	if (m_pBorderShading->getBottomToggled())
744 	{
745 		const gchar * pszBottomColor = NULL;
746 		m_pBorderShading->getPropVector().getProp("bot-color", pszBottomColor);
747 		if (pszBottomColor)
748 		{
749 			UT_parseColor(pszBottomColor, tmpCol);
750 			m_gc->setColor(tmpCol);
751 		}
752 		else
753 			m_gc->setColor(black);
754 		const gchar * pszBotThickness = NULL;
755 		m_pBorderShading->getPropVector().getProp("bot-thickness", pszBotThickness);
756 		if(pszBotThickness)
757 		{
758 			UT_sint32 iBotThickness = UT_convertToLogicalUnits(pszBotThickness);
759 			m_gc->setLineWidth(iBotThickness);
760 		}
761 		else
762 		{
763 			m_gc->setLineWidth(m_gc->tlu(1));
764 		}
765 		painter.drawLine(pageRect.left + border, pageRect.top + pageRect.height - border,
766 					   pageRect.left + pageRect.width - border, pageRect.top + pageRect.height - border);
767 	}
768 }
769