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