1 /* AbiSource Application Framework
2  * Copyright (C) 1998 AbiSource, Inc.
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 
21 #include <glib/gstdio.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include "ut_types.h"
27 #include "ut_assert.h"
28 #include "ut_debugmsg.h"
29 #include "ut_vector.h"
30 #include "ut_string.h"
31 #include "ut_growbuf.h"
32 #include "ut_timer.h"
33 #include "ut_go_file.h"
34 #include "xap_App.h"
35 #include "xap_Frame.h"
36 #include "xap_FrameImpl.h"
37 #include "xap_Prefs.h"
38 #include "xap_ViewListener.h"
39 #include "ev_EditBinding.h"
40 #include "ev_EditEventMapper.h"
41 #include "ev_EditMethod.h"
42 #include "ev_Menu_Layouts.h"
43 #include "ev_Menu_Labels.h"
44 #include "xap_Menu_Layouts.h"
45 #include "xap_Menu_LabelSet.h"
46 #include "xav_View.h"
47 #include "xad_Document.h"
48 #include "xap_Scrollbar_ViewListener.h"
49 #include "ev_Keyboard.h"
50 #include "ev_Mouse.h"
51 #include "ev_Toolbar.h"
52 #include "ev_Menu.h"
53 #include "xap_Strings.h"
54 #include "xap_DialogFactory.h"
55 #include "xap_Dialog_Id.h"
56 #include "xap_Dlg_Zoom.h"
57 #include "xap_Toolbar_Layouts.h"
58 #include "ut_sleep.h"
59 
60 #ifdef _MSC_VER
61 // MSVC++ warns about using 'this' in initializer list.
62 #pragma warning(disable: 4355)
63 #endif
64 
XAP_Frame(XAP_FrameImpl * pFrameImpl)65 XAP_Frame::XAP_Frame(XAP_FrameImpl *pFrameImpl)
66 	: m_pDoc(0),
67 	  m_pView(0),
68 	  m_pViewListener(0),
69 	  m_lid(static_cast<AV_ListenerId>(-1)),
70 	  m_pScrollObj(0),
71 	  m_nView(0),
72 	  m_iUntitled(0),
73 	  m_pScrollbarViewListener(0),
74 	  m_lidScrollbarViewListener(static_cast<AV_ListenerId>(-1)),
75 	  m_zoomType(z_PAGEWIDTH),
76 	  m_pData(0),
77 	  m_bHideMenuScroll(false),
78 	  m_iIdAutoSaveTimer(0),
79 	  m_iAutoSavePeriod(0),
80 	  m_stAutoSaveExt(),
81 	  m_bBackupRunning(false),
82 	  m_bBackupInProgress(false),
83 	  m_isrcId(0),
84 	  m_isrcTBNr(0),
85 	  m_idestId(0),
86 	  m_idestTBNr(0),
87 	  m_bisDragging(false),
88 	  m_bHasDropped(false),
89 	  m_bHasDroppedTB(false),
90 	  m_bFirstDraw(false),
91 	  m_bShowStatusbar(true),
92 	  m_bShowMenubar(true),
93 	  m_bIsFrameLocked(false),
94 	  m_pFrameImpl(pFrameImpl),
95 	  m_iZoomPercentage(100)
96 {
97 	XAP_App::getApp()->rememberFrame(this);
98 //	UT_DEBUGMSG(("Remembering UnCloned Frame \n"));
99 //	UT_ASSERT_HARMLESS(0);
100 }
101 
XAP_Frame(XAP_Frame * f)102 XAP_Frame::XAP_Frame(XAP_Frame * f)
103 	: m_pDoc(REFP(f->m_pDoc)),
104 	m_pView(0),
105 	m_pViewListener(0),
106 	m_lid(static_cast<AV_ListenerId>(-1)),
107 	m_pScrollObj(0),
108 	m_nView(0),
109 	m_iUntitled(f->m_iUntitled),
110 	m_pScrollbarViewListener(0),
111 	m_lidScrollbarViewListener(static_cast<AV_ListenerId>(-1)),
112 	m_zoomType(f->m_zoomType),
113 	m_pData(0),
114 	m_bHideMenuScroll(f->m_bHideMenuScroll),
115 	m_iIdAutoSaveTimer(0),
116 	m_iAutoSavePeriod(f->m_iAutoSavePeriod),
117 	m_bBackupRunning(false),
118 	m_bBackupInProgress(false),
119 	m_isrcId(0),
120 	m_isrcTBNr(0),
121 	m_idestId(0),
122 	m_idestTBNr(0),
123 	m_bisDragging(false),
124 	m_bHasDropped(false),
125 	m_bHasDroppedTB(false),
126 	m_bFirstDraw(false),
127 	m_bShowStatusbar(f->m_bShowStatusbar),
128 	m_bIsFrameLocked(false),
129 	m_pFrameImpl(f->m_pFrameImpl->createInstance(this)),
130 	m_iZoomPercentage(f->m_iZoomPercentage)
131 {
132 	XAP_App::getApp()->rememberFrame(this, f);
133 //	UT_DEBUGMSG(("Remembering Cloned Frame \n"));
134 //	UT_ASSERT_HARMLESS(0);
135 }
136 
~XAP_Frame(void)137 XAP_Frame::~XAP_Frame(void)
138 {
139 	/* if we're auto-saving files and now we're exiting normally
140 	 * delete/unlink the file
141 	 */
142 	if (!m_stAutoSaveNamePrevious.empty())
143 	{
144 		_removeAutoSaveFile();
145 	}
146 
147 	// only delete the things that we created...
148 	// I do not like this; we should be deleting all our members,
149 	// since they are no-one else's bussines (Tomas, Jan 30, 2003)
150 
151 	if (m_pView)
152 		m_pView->removeListener(m_lid);
153 
154 
155 	DELETEP(m_pFrameImpl);
156 
157 	DELETEP(m_pViewListener);
158 	DELETEP(m_pView);
159 
160 	UNREFP(m_pDoc);
161 
162 	DELETEP(m_pScrollObj);
163 
164 	DELETEP(m_pScrollbarViewListener);
165 
166 	if (m_iIdAutoSaveTimer != 0)
167 	{
168 		UT_Timer *timer = UT_Timer::findTimer(m_iIdAutoSaveTimer);
169 		if (timer != 0)
170 		{
171 			UT_DEBUGMSG(("Stopping Autosave timer [%d]\n", m_iIdAutoSaveTimer));
172 			timer->stop();
173 			DELETEP(timer);
174 		}
175 		else
176 		{
177 			UT_DEBUGMSG(("Autosave Timer [%d] not found\n", m_iIdAutoSaveTimer));
178 		}
179 	}
180 }
181 
182 /*****************************************************************/
183 // sequence number tracker for untitled documents
184 
185 int XAP_Frame::s_iUntitled = 0;
_getNextUntitledNumber(void)186 int XAP_Frame::_getNextUntitledNumber(void)
187 {
188 	return ++s_iUntitled;
189 }
190 
191 /*****************************************************************/
192 
initialize(const char *,const char *,const char * szMenuLayoutKey,const char * szMenuLayoutDefaultValue,const char * szMenuLabelSetKey,const char * szMenuLabelSetDefaultValue,const char * szToolbarLayoutsKey,const char * szToolbarLayoutsDefaultValue,const char * szToolbarLabelSetKey,const char * szToolbarLabelSetDefaultValue)193 bool XAP_Frame::initialize(const char * /*szKeyBindingsKey*/, const char * /*szKeyBindingsDefaultValue*/,
194 						   const char * szMenuLayoutKey, const char * szMenuLayoutDefaultValue,
195 						   const char * szMenuLabelSetKey, const char * szMenuLabelSetDefaultValue,
196 						   const char * szToolbarLayoutsKey, const char * szToolbarLayoutsDefaultValue,
197 						   const char * szToolbarLabelSetKey, const char * szToolbarLabelSetDefaultValue)
198 {
199 	XAP_App * pApp = XAP_App::getApp();
200 
201 
202 	//////////////////////////////////////////////////////////////////
203 	// select which menu bar we should use
204 	//////////////////////////////////////////////////////////////////
205 
206 	const char * szMenuLayoutName = NULL;
207 	if ((pApp->getPrefsValue(szMenuLayoutKey,
208 				 static_cast<const gchar**>(&szMenuLayoutName))) &&
209 	    (szMenuLayoutName) && (*szMenuLayoutName))
210 		;
211 	else
212 		szMenuLayoutName = szMenuLayoutDefaultValue;
213 	m_pFrameImpl->m_szMenuLayoutName = g_strdup(szMenuLayoutName);
214 
215 	//////////////////////////////////////////////////////////////////
216 	// select language for menu labels
217 	//////////////////////////////////////////////////////////////////
218 
219 	const char * szMenuLabelSetName = NULL;
220 	if ((pApp->getPrefsValue(szMenuLabelSetKey,
221 				 static_cast<const gchar**>(&szMenuLabelSetName))) &&
222 	    (szMenuLabelSetName) && (*szMenuLabelSetName))
223 		;
224 	else
225 		szMenuLabelSetName = szMenuLabelSetDefaultValue;
226 	m_pFrameImpl->m_szMenuLabelSetName = g_strdup(szMenuLabelSetName);
227 
228 	//////////////////////////////////////////////////////////////////
229 	// select which toolbars we should display
230 	//////////////////////////////////////////////////////////////////
231 
232 	const char * szToolbarLayouts = NULL;
233 	if ((pApp->getPrefsValue(szToolbarLayoutsKey,
234 							 static_cast<const gchar**>(&szToolbarLayouts))) &&
235 	    (szToolbarLayouts) && (*szToolbarLayouts))
236 		;
237 	else
238 		szToolbarLayouts = szToolbarLayoutsDefaultValue;
239 
240 	// take space-delimited list and call addItem() for each name in the list.
241 
242 	{
243 		char * szTemp;
244 		szTemp = g_strdup(szToolbarLayouts);
245 		UT_ASSERT(szTemp);
246 		for (char * p=strtok(szTemp," "); (p); p=strtok(NULL," "))
247 		{
248 			char * szTempName;
249 			szTempName = g_strdup(p);
250 			m_pFrameImpl->m_vecToolbarLayoutNames.addItem(szTempName);
251 		}
252 		g_free(szTemp);
253 	}
254 
255 	//////////////////////////////////////////////////////////////////
256 	// select language for the toolbar labels.
257 	// i'm not sure if it would ever make sense to
258 	// deviate from what we set the menus to, but
259 	// we can if we have to.
260 	// all toolbars will have the same language.
261 	//////////////////////////////////////////////////////////////////
262 
263 	const char * szToolbarLabelSetName = NULL;
264 	if ((pApp->getPrefsValue(szToolbarLabelSetKey,
265 				 static_cast<const gchar**>(&szToolbarLabelSetName))) &&
266 	    (szToolbarLabelSetName) && (*szToolbarLabelSetName))
267 		;
268 	else
269 		szToolbarLabelSetName = szToolbarLabelSetDefaultValue;
270 	m_pFrameImpl->m_szToolbarLabelSetName = g_strdup(szToolbarLabelSetName);
271 
272 	//////////////////////////////////////////////////////////////////
273 	// select the appearance of the toolbar buttons
274 	//////////////////////////////////////////////////////////////////
275 
276 	const char * szToolbarAppearance = NULL;
277 	pApp->getPrefsValue(XAP_PREF_KEY_ToolbarAppearance,
278 			    static_cast<const gchar**>(&szToolbarAppearance));
279 	UT_ASSERT((szToolbarAppearance) && (*szToolbarAppearance));
280 	m_pFrameImpl->m_szToolbarAppearance = g_strdup(szToolbarAppearance);
281 
282 	//////////////////////////////////////////////////////////////////
283 	// select the auto save options
284 	//////////////////////////////////////////////////////////////////
285 	UT_String stTmp;
286 	bool autosave = true;
287 
288 	pApp->getPrefsValue(XAP_PREF_KEY_AutoSaveFileExt, m_stAutoSaveExt);
289 	pApp->getPrefsValueBool(XAP_PREF_KEY_AutoSaveFile, &autosave);
290 
291 	if (autosave)
292 		_createAutoSaveTimer();
293 	setAutoSaveFile(autosave);
294 
295 	//////////////////////////////////////////////////////////////////
296 	// select the default zoom settings
297 	//////////////////////////////////////////////////////////////////
298 	pApp->getPrefsValue(XAP_PREF_KEY_ZoomType, stTmp);
299 	UT_DEBUGMSG(("Zoom type from prefs is %s \n",stTmp.c_str()));
300 	UT_uint32 iZoom = 100;
301 	if( g_ascii_strcasecmp( stTmp.c_str(), "100" ) == 0 )
302 	{
303 		m_zoomType = z_100;
304 		iZoom = 100;
305 	}
306 	else if( g_ascii_strcasecmp( stTmp.c_str(), "75" ) == 0 )
307 	{
308 		m_zoomType = z_75;
309 		iZoom = 75;
310 	}
311 	else if( g_ascii_strcasecmp( stTmp.c_str(), "200" ) == 0 )
312 	{
313 		m_zoomType = z_200;
314 		iZoom = 200;
315 	}
316 	else if( g_ascii_strcasecmp( stTmp.c_str(), "Width" ) == 0 )
317 	{
318 		m_zoomType = z_PAGEWIDTH;
319 		const gchar * szZoom = NULL;
320 		pApp->getPrefsValue(XAP_PREF_KEY_ZoomPercentage,
321 							  static_cast<const gchar**>(&szZoom));
322 		if(szZoom)
323 		{
324 			iZoom = atoi(szZoom);
325 			if(iZoom < XAP_DLG_ZOOM_MINIMUM_ZOOM)
326 				iZoom = 100;
327 			else if (iZoom > XAP_DLG_ZOOM_MAXIMUM_ZOOM)
328 				iZoom = 100;
329 		}
330 		else
331 		{
332 			iZoom = 100;
333 		}
334 	}
335 	else if( g_ascii_strcasecmp( stTmp.c_str(), "Page" ) == 0 )
336 	{
337 		m_zoomType = z_WHOLEPAGE;
338 		const gchar * szZoom = NULL;
339 		pApp->getPrefsValue(XAP_PREF_KEY_ZoomPercentage,
340 							  static_cast<const gchar**>(&szZoom));
341 		if(szZoom)
342 		{
343 			iZoom = atoi(szZoom);
344 			if(iZoom < XAP_DLG_ZOOM_MINIMUM_ZOOM)
345 				iZoom = 100;
346 			else if (iZoom > XAP_DLG_ZOOM_MAXIMUM_ZOOM)
347 				iZoom = 100;
348 		}
349 		else
350 		{
351 			iZoom = 100;
352 		}
353 	}
354 	else
355 	{
356 		iZoom = atoi( stTmp.c_str() );
357 
358 		// These limits are defined in xap_Dlg_Zoom.h
359 		if ((iZoom <= XAP_DLG_ZOOM_MAXIMUM_ZOOM) && (iZoom >= XAP_DLG_ZOOM_MINIMUM_ZOOM))
360 		{
361 			m_zoomType = z_PERCENT;
362 			XAP_Frame::setZoomPercentage( iZoom );
363 		}
364 		else
365 		  m_zoomType = z_100;
366 	}
367 	XAP_Frame::setZoomPercentage( iZoom );
368 
369 
370 	//////////////////////////////////////////////////////////////////
371 	// ... add other stuff here ...
372 	//////////////////////////////////////////////////////////////////
373 
374 	// initialize our helper
375 	m_pFrameImpl->_initialize();
376 
377 	return true;
378 }
379 
380 extern "C" {
autoSaveCallback(UT_Worker * wkr)381 static void autoSaveCallback(UT_Worker *wkr)
382 {
383 	xxx_UT_DEBUGMSG(("Autosaving doc...\n"));
384 	XAP_Frame *me = static_cast<XAP_Frame *> (wkr->getInstanceData());
385 	AD_Document * pDoc = me->getCurrentDoc();
386 	if(pDoc && pDoc->isPieceTableChanging())
387 	{
388 		UT_DEBUGMSG(("PieceTable is changing no backup made \n"));
389 	}
390 	if (me->isDirty())
391 	{
392 		UT_Error error = me->backup();
393 
394 		if (!error) {
395 			xxx_UT_DEBUGMSG(("Document Auto saved\n"));
396 		}
397 		else {
398 			xxx_UT_DEBUGMSG(("Error [%d] saving document.\n", error));
399 		}
400 	}
401 	else
402 	{
403 		 UT_DEBUGMSG(("Doc is not dirty\n"));
404 	}
405 }
406 }
407 
_createAutoSaveTimer()408 void XAP_Frame::_createAutoSaveTimer()
409 {
410 	UT_Timer *timer = UT_Timer::static_constructor(autoSaveCallback, this);
411 	UT_String stPeriod;
412 
413 	bool bFound = XAP_App::getApp()->getPrefsValue(XAP_PREF_KEY_AutoSaveFilePeriod, stPeriod);
414 
415 	if(!bFound || stPeriod.empty())
416 		m_iAutoSavePeriod = atoi(XAP_PREF_DEFAULT_AutoSaveFilePeriod);
417 	else
418 		m_iAutoSavePeriod = atoi(stPeriod.c_str());
419 
420 	if(m_iAutoSavePeriod < 1)
421 		m_iAutoSavePeriod = 1;
422 
423 	// stPeriod is in minutes, and we should use milliseconds
424 	timer->set(m_iAutoSavePeriod * 60000);
425 	m_iIdAutoSaveTimer = timer->getIdentifier();
426 	UT_DEBUGMSG(("Creating auto save timer [%d] with a timeout of [%d] minutes.\n", m_iIdAutoSaveTimer, m_iAutoSavePeriod));
427 }
428 
_removeAutoSaveFile()429 void XAP_Frame::_removeAutoSaveFile()
430 {
431 	const char *filename = NULL;
432 	gboolean bURI = UT_go_path_is_uri(m_stAutoSaveNamePrevious.c_str());
433 
434 	if(bURI)
435 	{
436 		filename = UT_go_filename_from_uri(m_stAutoSaveNamePrevious.c_str());
437 	}
438 	else
439 	{
440 		// It shouldn't be a file name here, but handle it nonetheless
441 		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
442 		filename = m_stAutoSaveNamePrevious.c_str();
443 	}
444 
445 	if(filename)
446 	{
447 		UT_DEBUGMSG(("DOM: removing backup file %s\n", filename));
448 		int res = g_unlink(filename);
449 
450 		if(res == -1)
451 		{
452 			UT_DEBUGMSG(("Failed to unlink old backup file %s\n", filename));
453 		}
454 
455 		// only g_free in the UT_go_filename_from_uri case
456 		if(bURI)
457 			FREEP(filename);
458 	}
459 }
460 
461 /*!
462  * This starts the auto Updater for the view
463  */
_startViewAutoUpdater(void)464 void XAP_FrameImpl::_startViewAutoUpdater(void)
465 {
466 	if(m_ViewAutoUpdaterID == 0)
467 	{
468 		m_ViewAutoUpdater = UT_Timer::static_constructor(viewAutoUpdater, this);
469 		m_ViewAutoUpdater->set(500);
470 		m_ViewAutoUpdaterID = m_ViewAutoUpdater->getIdentifier();
471 		m_ViewAutoUpdater->start();
472 		m_pFrame->m_bFirstDraw = false;
473 	}
474 }
475 
476 /*!
477  * This static function updates the current view in frame while the layout
478  * is filling.
479  */
viewAutoUpdater(UT_Worker * wkr)480 void /* static*/ XAP_FrameImpl::viewAutoUpdater(UT_Worker *wkr)
481 {
482 	XAP_FrameImpl *pFrameImpl = static_cast<XAP_FrameImpl *> (wkr->getInstanceData());
483 	XAP_App *pApp = XAP_App::getApp();
484 	const XAP_StringSet * pSS = pApp->getStringSet();
485 	std::string msg;
486 	pSS->getValue(XAP_STRING_ID_MSG_BuildingDoc, pApp->getDefaultEncoding(),msg);
487 	pFrameImpl->_setCursor(GR_Graphics::GR_CURSOR_WAIT);
488 	AV_View * pView = pFrameImpl->m_pFrame->getCurrentView();
489 	UT_DEBUGMSG(("SEVIOR: frame view updater \n"));
490 	if(!pView)
491 	{
492 		pFrameImpl->m_pFrame->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
493 		pFrameImpl->m_ViewAutoUpdater->stop();
494 		pFrameImpl->m_ViewAutoUpdaterID = 0;
495 		DELETEP(pFrameImpl->m_ViewAutoUpdater);
496 		return;
497 	}
498 	if(!pView->isLayoutFilling() && (pView->getPoint() > 0))
499 	{
500 		GR_Graphics * pG = pView->getGraphics();
501 		pG->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
502 		pFrameImpl->m_pFrame->setCursor(GR_Graphics::GR_CURSOR_DEFAULT);
503 		pView->setCursorToContext();
504 		pFrameImpl->m_ViewAutoUpdater->stop();
505 		pFrameImpl->m_ViewAutoUpdaterID = 0;
506 		DELETEP(pFrameImpl->m_ViewAutoUpdater);
507 		pView->draw();
508 		pG->flush();
509 		return;
510 	}
511 	if(!pView->isLayoutFilling() && !pFrameImpl->m_pFrame->m_bFirstDraw)
512 	{
513 		GR_Graphics * pG = pView->getGraphics();
514 		pG->setCursor(GR_Graphics::GR_CURSOR_WAIT);
515 		pFrameImpl->_setCursor(GR_Graphics::GR_CURSOR_WAIT);
516 		pFrameImpl->m_pFrame->setStatusMessage ( static_cast<const gchar *>(msg.c_str()) );
517 		pG->flush();
518 		return;
519 	}
520 	GR_Graphics * pG = pView->getGraphics();
521 	pG->setCursor(GR_Graphics::GR_CURSOR_WAIT);
522 	pFrameImpl->_setCursor(GR_Graphics::GR_CURSOR_WAIT);
523 	pFrameImpl->m_pFrame->setStatusMessage ( static_cast<const gchar *>(msg.c_str()) );
524 
525 	if(pView->getPoint() > 0)
526 	{
527 		pView->updateLayout();
528 		if(!pFrameImpl->m_pFrame->m_bFirstDraw)
529 		{
530 			pView->draw();
531 			pFrameImpl->m_pFrame->m_bFirstDraw = true;
532 		}
533 		else
534 		{
535 			pView->updateScreen();
536 		}
537 	}
538 	pG->flush();
539 }
540 
getColorSelBackground() const541 UT_RGBColor XAP_Frame::getColorSelBackground () const
542 {
543   return m_pFrameImpl->getColorSelBackground ();
544 }
545 
getColorSelForeground() const546 UT_RGBColor XAP_Frame::getColorSelForeground () const
547 {
548   return m_pFrameImpl->getColorSelForeground ();
549 }
550 
551 
getCurrentView(void) const552 AV_View * XAP_Frame::getCurrentView(void) const
553 {
554 	// TODO i called this ...Current... in anticipation of having
555 	// TODO more than one view (think splitter windows) in this
556 	// TODO frame.  but i'm just guessing right now....
557 
558 	return m_pView;
559 }
560 
getCurrentDoc(void) const561 AD_Document * XAP_Frame::getCurrentDoc(void) const
562 {
563 	return m_pDoc;
564 }
565 
getFilename(void) const566 const char * XAP_Frame::getFilename(void) const
567 {
568 	if (m_pDoc == NULL) return NULL;
569 	return m_pDoc->getFilename();
570 }
571 
isDirty(void) const572 bool XAP_Frame::isDirty(void) const
573 {
574 	if (m_pDoc == NULL) return false;
575 	return m_pDoc->isDirty();
576 }
577 
setViewNumber(UT_uint32 n)578 void XAP_Frame::setViewNumber(UT_uint32 n)
579 {
580 	m_nView = n;
581 }
582 
getViewNumber(void) const583 UT_uint32 XAP_Frame::getViewNumber(void) const
584 {
585 	return m_nView;
586 }
587 
getViewKey(void) const588 const char * XAP_Frame::getViewKey(void) const
589 {
590 	/*
591 		We want a string key which uniquely identifies a AD_Document instance,
592 		so that we can match up top-level views on the same document.
593 
594 		We can't use the filename, since it might not exist (untitled43) and
595 		is likely to change when the document is saved.
596 
597 		So, we just use the AD_Document pointer.  :-)
598 	*/
599 
600 	// The buffer must be wide enough to hold character representation
601 	// of a pointer on any platform.  For Intel that would be 32-bits, which
602 	// would be 8 chars plus a null.  Double that for 64.
603 	// Why "+3"?  For the "0x" and the null.
604 	static char buf[(sizeof(void *) * 2) + 3];
605 
606 	sprintf(buf, "%p", static_cast<void *>(m_pDoc));
607 
608 	return buf;
609 }
610 
getTitle() const611 const UT_UTF8String & XAP_Frame::getTitle() const
612 {
613 	return m_sTitle;
614 }
615 
getNonDecoratedTitle() const616 const char * XAP_Frame::getNonDecoratedTitle() const
617 {
618 	return m_sNonDecoratedTitle.utf8_str();
619 }
620 
setZoomPercentage(UT_uint32 iZoom)621 void XAP_Frame::setZoomPercentage(UT_uint32 iZoom)
622 {
623 	m_iZoomPercentage = iZoom;
624 	XAP_App * pApp = XAP_App::getApp();
625 	UT_return_if_fail(pApp);
626 	XAP_Prefs * pPrefs = pApp->getPrefs();
627 	UT_return_if_fail(pPrefs);
628 	XAP_PrefsScheme * pScheme = pPrefs->getCurrentScheme(true);
629 	UT_return_if_fail(pScheme);
630 	UT_String sZoom;
631 	UT_String_sprintf(sZoom,"%d",iZoom);
632 	if(getZoomType() == z_PAGEWIDTH)
633 	{
634 		pScheme->setValue(XAP_PREF_KEY_ZoomType,"Width");
635 	}
636 	else if(getZoomType() == z_WHOLEPAGE)
637 	{
638 		pScheme->setValue(XAP_PREF_KEY_ZoomType,"Page");
639 	}
640 	else
641 	{
642 		pScheme->setValue(XAP_PREF_KEY_ZoomType,sZoom.c_str());
643 	}
644 	UT_DEBUGMSG(("zoom is set to %s \n",sZoom.c_str()));
645 	pScheme->setValue(XAP_PREF_KEY_ZoomPercentage,sZoom.c_str());
646 }
647 
getZoomPercentage(void)648 UT_uint32 XAP_Frame::getZoomPercentage(void)
649 {
650 	return m_iZoomPercentage;
651 }
652 
getToolbar(UT_sint32 ibar)653 EV_Toolbar *  XAP_Frame::getToolbar(UT_sint32 ibar)
654 {
655 	if(ibar >= m_pFrameImpl->m_vecToolbars.getItemCount())
656 		return NULL;
657 	return m_pFrameImpl->m_vecToolbars.getNthItem(ibar);
658 }
659 
repopulateCombos(void)660 bool XAP_Frame::repopulateCombos(void)
661 {
662   //
663 // Update the styles combo box.
664 //
665 	EV_Toolbar * pTbar = NULL;
666 	UT_uint32 ibar = 0;
667 	do
668 	{
669 		pTbar = getToolbar(ibar++);
670 		if(pTbar)
671 			pTbar->repopulateStyles();
672 	}
673 	while(pTbar);
674 	return true;
675 }
676 
_createToolbars(void)677 void XAP_FrameImpl::_createToolbars(void)
678 {
679 	bool bResult;
680 	UT_sint32 nrToolbars = m_vecToolbarLayoutNames.getItemCount();
681 	for (UT_sint32 k=0; k < nrToolbars; k++)
682 	{
683 		EV_Toolbar * pToolbar = m_pFrame->_newToolbar(m_pFrame,
684 							      reinterpret_cast<const char *>(m_vecToolbarLayoutNames.getNthItem(k)),
685 							      reinterpret_cast<const char *>(m_szToolbarLabelSetName));
686 		UT_continue_if_fail(pToolbar);
687 		bResult = pToolbar->synthesize();
688 		UT_ASSERT(bResult);
689 
690 		m_vecToolbars.addItem(pToolbar);
691 	}
692 	UT_UNUSED(bResult); // TODO deal with the result
693 }
694 
findToolbarNr(EV_Toolbar * pTB)695 UT_sint32 XAP_Frame::findToolbarNr(EV_Toolbar * pTB)
696 {
697 	UT_sint32 i = 0;
698 	bool bFound =  false;
699 	for(i =0; !bFound && (i < m_pFrameImpl->m_vecToolbars.getItemCount()); i++)
700 	{
701 		EV_Toolbar * pTmp = getToolbar(i);
702 		if(pTmp == pTB)
703 		{
704 			bFound  = true;
705 			break;
706 		}
707 	}
708 	if(bFound)
709 	{
710 		return static_cast<UT_sint32>(i);
711 	}
712 	return -1;
713 }
714 
setAutoSaveFile(bool b)715 void XAP_Frame::setAutoSaveFile(bool b)
716 {
717 	m_bBackupRunning = b;
718 	if (b && !m_iIdAutoSaveTimer)
719 	{
720 		UT_Timer *timer = UT_Timer::static_constructor(autoSaveCallback, this);
721 		if(m_iAutoSavePeriod < 1)
722 		{
723 			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
724 			m_iAutoSavePeriod = 1;
725 		}
726 
727 		timer->set(m_iAutoSavePeriod * 60000);
728 		m_iIdAutoSaveTimer = timer->getIdentifier();
729 		timer->start();
730 		return;
731 	}
732 
733 	if (!b && m_iIdAutoSaveTimer)
734 	{
735 		// TODO: We're leaking UT_Timer objects.  We should
736 		// TODO: give the posibility to erase a UT_Timer...
737 		// TODO: something like UT_Timer::eraseTimer(...) should
738 		// TODO: do the work (we should change the sign. of findTimer).
739 		UT_Timer *timer = UT_Timer::findTimer(m_iIdAutoSaveTimer);
740 		if (timer)
741 			timer->stop();
742 	}
743 	if(b)
744 	{
745 		UT_Timer *timer = UT_Timer::findTimer(m_iIdAutoSaveTimer);
746 		if(m_iAutoSavePeriod < 1)
747 		{
748 			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
749 			m_iAutoSavePeriod = 1;
750 		}
751 
752 		// reset the timer, because the interval might have changed (Bug 9329)
753 		timer->set(m_iAutoSavePeriod * 60000);
754 		timer->start();
755 		return;
756 	}
757 }
758 
setAutoSaveFilePeriod(int min)759 void XAP_Frame::setAutoSaveFilePeriod(int min)
760 {
761 	m_iAutoSavePeriod = min;
762 
763 	if (m_iIdAutoSaveTimer != 0)
764 	{
765 		// I know, it looks weird... I just want to restart the timer
766 		setAutoSaveFile(false);
767 		setAutoSaveFile(true);
768 	}
769 }
770 
setAutoSaveFileExt(const UT_String & stExt)771 void XAP_Frame::setAutoSaveFileExt(const UT_String &stExt)
772 {
773 	m_stAutoSaveExt = stExt;
774 }
775 
createMessageBox(XAP_String_Id id,XAP_Dialog_MessageBox::tButtons buttons,XAP_Dialog_MessageBox::tAnswer default_answer,...)776 XAP_Dialog_MessageBox * XAP_Frame::createMessageBox(XAP_String_Id id,
777 						    XAP_Dialog_MessageBox::tButtons buttons,
778 						    XAP_Dialog_MessageBox::tAnswer default_answer,
779 						    ...)
780 {
781   	XAP_DialogFactory * pDialogFactory
782 		= static_cast<XAP_DialogFactory *>(getDialogFactory());
783 
784 	XAP_Dialog_MessageBox * pDialog
785 		= static_cast<XAP_Dialog_MessageBox *>(pDialogFactory->requestDialog(XAP_DIALOG_ID_MESSAGE_BOX));
786 	UT_return_val_if_fail(pDialog, NULL);
787 
788 	if (id > 0) {
789 		char * szNewMessage = static_cast<char *>(g_try_malloc(sizeof(char) * 256));
790 		const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet();
791 		std::string s;
792 		pSS->getValue(id, XAP_App::getApp()->getDefaultEncoding(), s);
793 
794 		va_list args;
795 		va_start(args, default_answer);
796 		vsprintf(szNewMessage, s.c_str(), args);
797 		va_end(args);
798 
799 		pDialog->setMessage("%s", szNewMessage);
800 
801 		// XAP_MessageBox makes a copy of the message, so g_free it
802 		FREEP(szNewMessage);
803 	}
804 	pDialog->setButtons(buttons);
805 	pDialog->setDefaultAnswer(default_answer);
806 
807 	return pDialog;
808 }
showMessageBox(XAP_Dialog_MessageBox * pDialog)809 XAP_Dialog_MessageBox::tAnswer XAP_Frame::showMessageBox(XAP_Dialog_MessageBox * pDialog)
810 {
811 	raise();
812 
813 	pDialog->runModal(this);
814 	XAP_Dialog_MessageBox::tAnswer ans = pDialog->getAnswer();
815 	delete pDialog;
816 
817 	return ans;
818 }
819 
showMessageBox(XAP_String_Id id,XAP_Dialog_MessageBox::tButtons buttons,XAP_Dialog_MessageBox::tAnswer default_answer)820 XAP_Dialog_MessageBox::tAnswer XAP_Frame::showMessageBox(XAP_String_Id id,
821 							 XAP_Dialog_MessageBox::tButtons buttons,
822 							 XAP_Dialog_MessageBox::tAnswer default_answer)
823 {
824   XAP_Dialog_MessageBox * pDialog = createMessageBox(id, buttons, default_answer);
825   return showMessageBox(pDialog);
826 }
827 
showMessageBox(XAP_String_Id id,XAP_Dialog_MessageBox::tButtons buttons,XAP_Dialog_MessageBox::tAnswer default_answer,const char * sz)828 XAP_Dialog_MessageBox::tAnswer XAP_Frame::showMessageBox(XAP_String_Id id,
829 							 XAP_Dialog_MessageBox::tButtons buttons,
830 							 XAP_Dialog_MessageBox::tAnswer default_answer,
831 							 const char * sz)
832 {
833   XAP_Dialog_MessageBox * pDialog = createMessageBox(id, buttons, default_answer, sz);
834   return showMessageBox(pDialog);
835 }
836 
showMessageBox(const std::string & msg,XAP_Dialog_MessageBox::tButtons buttons,XAP_Dialog_MessageBox::tAnswer default_answer)837 XAP_Dialog_MessageBox::tAnswer XAP_Frame::showMessageBox(const std::string & msg,
838 							 XAP_Dialog_MessageBox::tButtons buttons,
839 							 XAP_Dialog_MessageBox::tAnswer default_answer)
840 {
841 	return showMessageBox(msg.c_str(), buttons, default_answer);
842 }
843 
showMessageBox(const char * szMessage,XAP_Dialog_MessageBox::tButtons buttons,XAP_Dialog_MessageBox::tAnswer default_answer)844 XAP_Dialog_MessageBox::tAnswer XAP_Frame::showMessageBox(const char * szMessage,
845 							 XAP_Dialog_MessageBox::tButtons buttons,
846 							 XAP_Dialog_MessageBox::tAnswer default_answer)
847 {
848   XAP_Dialog_MessageBox * pDialog = createMessageBox(0, buttons, default_answer);
849   pDialog->setMessage(szMessage);
850   return showMessageBox(pDialog);
851 }
852 
makeBackupName(const char * szExt)853 UT_String XAP_Frame::makeBackupName(const char* szExt)
854 {
855   UT_String ext(szExt ? szExt : m_stAutoSaveExt.c_str());
856   UT_String oldName(m_pDoc->getFilename() ? m_pDoc->getFilename() : "");
857   UT_String backupName;
858   UT_DEBUGMSG(("In make Backup name. Old Name is (%s) \n",oldName.c_str()));
859   if (oldName.empty())
860   {
861       const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet();
862       std::string sTmp;
863       pSS->getValue(XAP_STRING_ID_UntitledDocument, XAP_App::getApp()->getDefaultEncoding(), sTmp);
864       UT_String_sprintf(oldName, sTmp.c_str(), m_iUntitled);
865 
866       UT_DEBUGMSG(("Untitled.  We will give it the name [%s]\n", oldName.c_str()));
867   }
868   else {
869     UT_DEBUGMSG(("Filename [%s]\n", oldName.c_str()));
870   }
871 
872   backupName = oldName + ext;
873 
874   const char* uri = NULL;
875   gboolean bURI = UT_go_path_is_uri(backupName.c_str());
876 
877   if(!bURI)
878     uri = UT_go_filename_to_uri(backupName.c_str());
879 
880   if(uri)
881   {
882     backupName = uri;
883     FREEP(uri);
884   }
885 
886   UT_DEBUGMSG(("DOM: created backup filename (%s)\n", backupName.c_str()));
887 
888   return backupName;
889 }
890 
891 /**
892  * It saves the current document with an extension stExt.
893  * If the extension is empty, then it save the document with
894  * the default extension (as defined in the preferences dialog box)
895  */
backup(const char * szExt,UT_sint32 iEFT)896 UT_Error XAP_Frame::backup(const char* szExt, UT_sint32 iEFT)
897 {
898 	if (m_bBackupInProgress)
899 		return UT_OK;
900 
901 	if (!m_pDoc)
902 	{
903 		UT_DEBUGMSG(("File NOT saved! doc is NULL.\n"));
904 		return UT_OK;
905 	}
906 
907 	m_bBackupInProgress = true;
908 
909 	UT_String backupName = makeBackupName ( szExt );
910 
911 	if (m_stAutoSaveNamePrevious.size() && (backupName != m_stAutoSaveNamePrevious))
912 	{
913 		/* If the user does a Save-As to rename the file then the auto-save name also changes, so
914 		 * need to remove the old backup file...
915 		 */
916 		_removeAutoSaveFile();
917 	}
918 	m_stAutoSaveNamePrevious = backupName;
919 
920 	UT_Error error;
921 //
922 // Don't put this auto-save in the most recent list.
923 //
924 	XAP_App::getApp()->getPrefs()->setIgnoreNextRecent();
925 
926 	if(iEFT < 0)
927 	{
928 	        iEFT = 1; // *.abw format
929 		error = m_pDoc->saveAs(backupName.c_str(), iEFT, false);
930 	}
931 	else
932 	{
933 		error = m_pDoc->saveAs(backupName.c_str(), iEFT, false);
934 	}
935 
936 	if(error == UT_OK)
937 	{
938 		UT_DEBUGMSG(("File %s saved.\n", backupName.c_str()));
939 	}
940 	else
941 	{
942 		// TODO: alert the user
943 		UT_DEBUGMSG(("File backup failed.\n"));
944 	}
945 
946 	m_bBackupInProgress = false;
947 	return error;
948 }
949 
quickZoom(void)950 void XAP_Frame::quickZoom(void)
951 {
952 	if( !m_pView ) return;
953 	UT_uint32 newZoom = 100;
954 	switch( getZoomType() )
955 	{
956 	case z_PAGEWIDTH:
957 		newZoom = m_pView->calculateZoomPercentForPageWidth();
958 		if      (newZoom < XAP_DLG_ZOOM_MINIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MINIMUM_ZOOM;
959 		else if (newZoom > XAP_DLG_ZOOM_MAXIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MAXIMUM_ZOOM;
960 		XAP_Frame::setZoomPercentage( newZoom );
961 		quickZoom( newZoom );
962 		break;
963 	case z_WHOLEPAGE:
964 		newZoom = m_pView->calculateZoomPercentForWholePage() ;
965 		if      (newZoom < XAP_DLG_ZOOM_MINIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MINIMUM_ZOOM;
966 		else if (newZoom > XAP_DLG_ZOOM_MAXIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MAXIMUM_ZOOM;
967 		XAP_Frame::setZoomPercentage( newZoom );
968 		quickZoom( newZoom );
969 		break;
970 	default:
971 		m_pView->updateScreen(false);
972        ;
973    }
974 }
975 
updateZoom(void)976 void XAP_Frame::updateZoom(void)
977 {
978 	if( !m_pView ) return;
979 	UT_uint32 newZoom = 100;
980 	switch( getZoomType() )
981 	{
982 	case z_PAGEWIDTH:
983 		newZoom = m_pView->calculateZoomPercentForPageWidth();
984 		if      (newZoom < XAP_DLG_ZOOM_MINIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MINIMUM_ZOOM;
985 		else if (newZoom > XAP_DLG_ZOOM_MAXIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MAXIMUM_ZOOM;
986 		XAP_Frame::setZoomPercentage( newZoom );
987 		quickZoom( newZoom );
988 //		setZoomPercentage( newZoom );
989 		break;
990 	case z_WHOLEPAGE:
991 		newZoom = m_pView->calculateZoomPercentForWholePage() ;
992 		if      (newZoom < XAP_DLG_ZOOM_MINIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MINIMUM_ZOOM;
993 		else if (newZoom > XAP_DLG_ZOOM_MAXIMUM_ZOOM) newZoom = XAP_DLG_ZOOM_MAXIMUM_ZOOM;
994 		XAP_Frame::setZoomPercentage( newZoom );
995 		quickZoom( newZoom );
996 //		setZoomPercentage( newZoom );
997 		break;
998 	default:
999        ;
1000    }
1001 }
1002 
1003 /*!
1004  * This method rebuilds all the toolbars in the frame. Useful for when the
1005  * user wants to revert to default toolbars.
1006  */
rebuildAllToolbars(void)1007 void XAP_Frame::rebuildAllToolbars(void)
1008 {
1009 	UT_uint32 count = m_pFrameImpl->m_vecToolbars.getItemCount();
1010 	UT_uint32 i =0;
1011 	for(i=0; i< count; i++)
1012 	{
1013 		m_pFrameImpl->_rebuildToolbar(i);
1014 	}
1015 }
1016 
1017 
1018 /*!
1019  * Record stuff for start of drag.
1020 \param XAP_Toolbar_Id srcId - source of Toolbar Icon.
1021 \param EV_Toolbar * pTBSrc pointer to toolbar class that contains the icon.
1022 */
dragBegin(XAP_Toolbar_Id srcId,EV_Toolbar * pTBsrc)1023 void XAP_Frame::dragBegin(XAP_Toolbar_Id srcId, EV_Toolbar * pTBsrc)
1024 {
1025 	m_isrcId = srcId;
1026 	m_isrcTBNr = findToolbarNr(pTBsrc);
1027 	m_bisDragging = true;
1028 	m_bHasDropped = false;
1029 	m_bHasDroppedTB = false;
1030 	m_idestId = 0;
1031 	m_idestTBNr = 0;
1032 }
1033 
1034 /*
1035  * Record the XP stuff from drop event recorded from the toolbars onto an icon
1036  */
dragDropToIcon(XAP_Toolbar_Id srcId,XAP_Toolbar_Id destId,EV_Toolbar * pTBsrc,EV_Toolbar * pTBdest)1037 void XAP_Frame::dragDropToIcon(XAP_Toolbar_Id srcId,XAP_Toolbar_Id destId, EV_Toolbar * pTBsrc, EV_Toolbar * pTBdest)
1038 {
1039 	UT_UNUSED(srcId);
1040 	UT_UNUSED(pTBsrc);
1041 	UT_ASSERT(m_isrcId == srcId);
1042 	UT_ASSERT(m_isrcTBNr == findToolbarNr(pTBsrc));
1043 	m_idestId = destId;
1044 	m_idestTBNr = findToolbarNr(pTBdest);
1045 	m_bHasDropped = true;
1046 }
1047 
1048 /*
1049  * Record the XP stuff from drop event recorded from the toolbars onto a bare
1050  * toolbar
1051  */
dragDropToTB(XAP_Toolbar_Id srcId,EV_Toolbar * pTBsrc,EV_Toolbar * pTBdest)1052 void XAP_Frame::dragDropToTB(XAP_Toolbar_Id srcId,EV_Toolbar * pTBsrc, EV_Toolbar * pTBdest)
1053 {
1054 	UT_UNUSED(srcId);
1055 	UT_UNUSED(pTBsrc);
1056 	UT_ASSERT(m_isrcId == srcId);
1057 	UT_ASSERT(m_isrcTBNr == findToolbarNr(pTBsrc));
1058 	m_idestTBNr = findToolbarNr(pTBdest);
1059 	m_bHasDroppedTB = true;
1060 }
1061 
getTimeSinceSave() const1062 time_t XAP_Frame::getTimeSinceSave() const
1063 {
1064 	return m_pDoc->getTimeSinceSave();
1065 }
1066 
getFrameMode()1067 XAP_FrameMode XAP_Frame::getFrameMode()
1068 {
1069 	return m_pFrameImpl->m_iFrameMode;
1070 }
setFrameMode(XAP_FrameMode iFrameMode)1071 void XAP_Frame::setFrameMode(XAP_FrameMode iFrameMode)
1072 {
1073 	m_pFrameImpl->m_iFrameMode = iFrameMode;
1074 }
1075 
dragText()1076 void XAP_Frame::dragText()
1077 {
1078   m_pFrameImpl->dragText();
1079 }
1080