1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2
3 /* AbiWord
4 * Copyright (C) 2002 Dom Lachowicz, William Lachance and others
5 *
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 "ut_types.h"
23 #include "ap_Frame.h"
24 #include "xap_App.h"
25
26 #include "ap_Features.h"
27
28 #include "ap_FrameData.h"
29 #include "ap_Strings.h"
30 #include "fv_View.h"
31 #include "xav_View.h"
32 #include "xad_Document.h"
33 #include "pd_Document.h"
34 #include "xap_ViewListener.h"
35 #include "xap_Scrollbar_ViewListener.h"
36 #include "ap_TopRuler.h"
37 #include "ap_LeftRuler.h"
38 #include "ap_StatusBar.h"
39 #include "xap_Dlg_Zoom.h"
40
41 /*****************************************************************/
42
43 #define ENSUREP_C(p) do { UT_ASSERT_HARMLESS(p); if (!p) goto Cleanup; } while (0)
44
45 /*****************************************************************/
46
setZoomPercentage(UT_uint32 iZoom)47 void AP_Frame::setZoomPercentage(UT_uint32 iZoom)
48 {
49 XAP_Frame::setZoomPercentage(iZoom);
50 _showDocument(iZoom);
51 }
52
53 /*!
54 * This zooms an existing document in a frame by just changing the zoom
55 * in the graphics class.
56 */
quickZoom(UT_uint32 iZoom)57 void AP_Frame::quickZoom(UT_uint32 iZoom)
58 {
59 bool bChanged = (getZoomPercentage() != iZoom);
60 XAP_Frame::setZoomPercentage(iZoom);
61 FV_View * pView = static_cast<FV_View *>(getCurrentView());
62 if(!pView)
63 return;
64 if (bChanged)
65 {
66 FL_DocLayout * pDocLayout = pView->getLayout();
67 pDocLayout->incrementGraphicTick();
68 GR_Graphics * pOldGraphics = pView->getGraphics();
69 pOldGraphics->setZoomPercentage(iZoom);
70 pOldGraphics->clearFont();
71
72 if(pView->getViewMode() == VIEW_WEB)
73 {
74 UT_sint32 iAdjustZoom = pView->calculateZoomPercentForPageWidth();
75 UT_Dimension orig_ut = DIM_IN;
76 orig_ut = pDocLayout->m_docViewPageSize.getDims();
77 double orig_width = pDocLayout->getDocument()->m_docPageSize.Width(orig_ut);
78 double orig_height = pDocLayout->getDocument()->m_docPageSize.Height(orig_ut);
79 double rat = static_cast<double>(iAdjustZoom)/static_cast<double>(iZoom) ;
80 double new_width = orig_width*rat;
81 UT_DEBUGMSG(("AP_Frame zoom VIEW_WEB old width %f new width %f old height %f \n",orig_width,new_width,orig_height));
82 bool p = pDocLayout->m_docViewPageSize.isPortrait();
83 pDocLayout->m_docViewPageSize.Set(new_width,orig_height,orig_ut);
84 pDocLayout->m_docViewPageSize.Set(fp_PageSize::psCustom,orig_ut);
85 if(p)
86 {
87 pDocLayout->m_docViewPageSize.setPortrait();
88 }
89 else
90 {
91 pDocLayout->m_docViewPageSize.setLandscape();
92 }
93 fl_SectionLayout* pSL = pDocLayout->getFirstSection();
94 while (pSL)
95 {
96 pSL->lookupMarginProperties();
97 pSL = static_cast<fl_SectionLayout *>(pSL->getNext());
98 }
99 pView->rebuildLayout();
100 pDocLayout->formatAll();
101
102 }
103 AP_TopRuler * pTop = pView->getTopRuler();
104 if(pTop)
105 {
106 pTop->setZoom(iZoom);
107 }
108 AP_LeftRuler * pLeft = pView->getLeftRuler();
109 if(pLeft)
110 {
111 pLeft->setZoom(iZoom);
112 }
113 pView->calculateNumHorizPages();
114 setYScrollRange();
115 setXScrollRange();
116 if(pTop && !pTop->isHidden())
117 {
118 pTop->queueDraw();
119 }
120 if(pLeft && !pLeft->isHidden())
121 {
122 pLeft->queueDraw();
123 }
124 //
125 // Redraw the entire screen
126 //
127 pView->setPoint(pView->getPoint()); // place the cursor correctly
128 pView->ensureInsertionPointOnScreen(); // on the screen
129 pView->updateScreen(false);
130 }
131 else
132 {
133 //
134 // Redraw the entire screen
135 //
136 pView->updateScreen(false);
137 }
138
139 // Notify listeners of new zoom (to update the zoom combo in toolbar)
140 // We do this regardless of bChanged since a change from 100% zoom to
141 // "Page Width" zoom may not change the logical zoom level.
142 pView->notifyListeners(AV_CHG_ALL);
143 }
144
getZoomPercentage(void)145 UT_uint32 AP_Frame::getZoomPercentage(void)
146 {
147 // !m_pData can happen when calling dlgZoom from AbiCommand;
148 // !m_pG can happen when called from an uninitialized abiwidget
149 if(m_pData && static_cast<AP_FrameData*>(m_pData)->m_pG)
150 return static_cast<AP_FrameData*>(m_pData)->m_pG->getZoomPercentage();
151
152 return 100; // 100 seems like the sanest default
153 }
154
~AP_Frame()155 AP_Frame::~AP_Frame()
156 {
157 }
158
159
initFrameData()160 bool AP_Frame::initFrameData()
161 {
162 UT_ASSERT_HARMLESS(!static_cast<AP_FrameData*>(m_pData));
163
164 AP_FrameData* pData = new AP_FrameData();
165
166 m_pData = static_cast<void*>(pData);
167 return (pData ? true : false);
168 }
169
killFrameData()170 void AP_Frame::killFrameData()
171 {
172 AP_FrameData* pData = static_cast<AP_FrameData*>(m_pData);
173 DELETEP(pData);
174 m_pData = NULL;
175 }
176
_loadDocument(const char * szFilename,IEFileType ieft,bool createNew)177 UT_Error AP_Frame::_loadDocument(const char * szFilename, IEFileType ieft,
178 bool createNew)
179 {
180 #ifdef DEBUG
181 if (szFilename) {
182 UT_DEBUGMSG(("DOM: trying to load %s (%d, %d)\n", szFilename, ieft, createNew));
183 }
184 else {
185 UT_DEBUGMSG(("DOM: trying to load %s (%d, %d)\n", "(NULL)", ieft, createNew));
186 }
187 #endif
188
189 // are we replacing another document?
190 if (m_pDoc)
191 {
192 // yep. first make sure it's OK to discard it,
193 // TODO: query user if dirty...
194 }
195
196 // load a document into the current frame.
197 // if no filename, create a new document.
198 if(XAP_App::getApp()->findFrame(this) < 0)
199 {
200 XAP_App::getApp()->rememberFrame(this);
201 }
202 AD_Document * pNewDoc = new PD_Document();
203 UT_return_val_if_fail (pNewDoc, UT_ERROR);
204 UT_Error errorCode = UT_OK;
205
206 if (!szFilename || !*szFilename)
207 {
208 pNewDoc->newDocument();
209 m_iUntitled = _getNextUntitledNumber();
210 goto ReplaceDocument;
211 }
212 errorCode = pNewDoc->readFromFile(szFilename, ieft);
213 if (UT_IS_IE_SUCCESS(errorCode))
214 goto ReplaceDocument;
215
216 if (createNew)
217 {
218 // we have a file name but couldn't load it
219 pNewDoc->newDocument();
220
221 // here, we want to open a new document if it doesn't exist.
222 // errorCode could also take several other values, indicating
223 // that the document exists but for some reason we could not
224 // open it. in those cases, we do not wish to overwrite the
225 // existing documents, but instead open a new blank document.
226 // this fixes bug 1668 - DAL
227
228 UT_DEBUGMSG(("Could not open the document - create new istead error code is %d \n", errorCode));
229 if ( UT_IE_FILENOTFOUND == errorCode || UT_INVALIDFILENAME == errorCode )
230 {
231 UT_DEBUGMSG(("File NOT found!! Create new doc \n"));
232 if( UT_IE_FILENOTFOUND == errorCode)
233 {
234 errorCode = pNewDoc->saveAs(szFilename, ieft);
235 }
236 else
237 {
238 errorCode = 0;
239 }
240 UT_DEBUGMSG(("errocode after save is %d\n",errorCode));
241 }
242 }
243 if (!errorCode)
244 goto ReplaceDocument;
245
246 UT_DEBUGMSG(("ap_Frame: could not open the file [%s]\n",szFilename));
247 UNREFP(pNewDoc);
248 return errorCode;
249
250 ReplaceDocument:
251 XAP_App::getApp()->forgetClones(this);
252 UT_DEBUGMSG(("Doing replace document \n"));
253
254 // NOTE: prior document is discarded in _showDocument()
255 m_pDoc = pNewDoc;
256 return errorCode;
257 }
258
_loadDocument(GsfInput * input,IEFileType ieft)259 UT_Error AP_Frame::_loadDocument(GsfInput * input, IEFileType ieft)
260 {
261 UT_return_val_if_fail (input != NULL, UT_ERROR);
262
263 // are we replacing another document?
264 if (m_pDoc)
265 {
266 // yep. first make sure it's OK to discard it,
267 // TODO: query user if dirty...
268 }
269
270 // load a document into the current frame.
271 // if no filename, create a new document.
272 if(XAP_App::getApp()->findFrame(this) < 0)
273 {
274 XAP_App::getApp()->rememberFrame(this);
275 }
276 AD_Document * pNewDoc = new PD_Document();
277 UT_return_val_if_fail (pNewDoc, UT_ERROR);
278
279 UT_Error errorCode;
280 errorCode = static_cast<PD_Document*>(pNewDoc)->readFromFile(input, ieft);
281 if (errorCode)
282 {
283 UT_DEBUGMSG(("ap_Frame: could not open the file\n"));
284 UNREFP(pNewDoc);
285 return errorCode;
286 }
287
288 XAP_App::getApp()->forgetClones(this);
289 UT_DEBUGMSG(("Doing replace document \n"));
290
291 // NOTE: prior document is discarded in _showDocument()
292 m_pDoc = pNewDoc;
293 return UT_OK;
294 }
295
_importDocument(const char * szFilename,int ieft,bool markClean)296 UT_Error AP_Frame::_importDocument(const char * szFilename, int ieft,
297 bool markClean)
298 {
299 UT_DEBUGMSG(("DOM: trying to import %s (%d, %d)\n", szFilename, ieft, markClean));
300
301 // are we replacing another document?
302 if (m_pDoc)
303 {
304 // yep. first make sure it's OK to discard it,
305 // TODO: query user if dirty...
306 }
307
308 // load a document into the current frame.
309 // if no filename, create a new document.
310
311 AD_Document * pNewDoc = new PD_Document();
312 UT_return_val_if_fail (pNewDoc, UT_ERROR);
313
314 if (!szFilename || !*szFilename)
315 {
316 pNewDoc->newDocument();
317 goto ReplaceDocument;
318 }
319 UT_Error errorCode;
320 errorCode = pNewDoc->importFile(szFilename, ieft, markClean);
321 if (!errorCode)
322 goto ReplaceDocument;
323
324 UT_DEBUGMSG(("ap_Frame: could not open the file [%s]\n",szFilename));
325
326 UNREFP(pNewDoc);
327 return errorCode;
328
329 ReplaceDocument:
330 XAP_App::getApp()->forgetClones(this);
331
332 m_iUntitled = _getNextUntitledNumber();
333
334 // NOTE: prior document is discarded in _showDocument()
335 m_pDoc = pNewDoc;
336 return UT_OK;
337 }
338
buildFrame(XAP_Frame * pF)339 XAP_Frame * AP_Frame::buildFrame(XAP_Frame * pF)
340 {
341 UT_Error error = UT_OK;
342 AP_Frame * pClone = static_cast<AP_Frame *>(pF);
343 XAP_Frame::tZoomType iZoomType = pF->getZoomType();
344 setZoomType(iZoomType);
345 UT_uint32 iZoom = XAP_Frame::getZoomPercentage();
346 ENSUREP_C(pClone);
347 if (!pClone->initialize())
348 goto Cleanup;
349
350 // we remember the view of the parent frame ...
351 static_cast<AP_FrameData*>(pClone->m_pData)->m_pRootView = m_pView;
352
353 error = pClone->_showDocument(iZoom);
354 if (error)
355 goto Cleanup;
356
357 pClone->show();
358 return static_cast<XAP_Frame *>(pClone);
359
360 Cleanup:
361 // clean up anything we created here
362 if (pClone)
363 {
364 XAP_App::getApp()->forgetFrame(pClone);
365 delete pClone;
366 }
367 return NULL;
368 }
369
loadDocument(AD_Document * pDoc)370 UT_Error AP_Frame::loadDocument(AD_Document* pDoc) {
371 bool bUpdateClones;
372 UT_GenericVector<XAP_Frame*> vClones;
373 XAP_App * pApp = XAP_App::getApp();
374 UT_sint32 j = 0;
375 if(pApp->findFrame(this) < 0)
376 {
377 pApp->rememberFrame(this);
378 }
379 bUpdateClones = (getViewNumber() > 0);
380 if (bUpdateClones)
381 {
382 pApp->getClones(&vClones, this);
383 }
384 for(j=0; j<vClones.getItemCount();j++)
385 {
386 AP_Frame * pFrame = static_cast<AP_Frame *>(vClones.getNthItem(j));
387 if(pApp->findFrame(pFrame) < 0)
388 {
389 pFrame->_replaceDocument(pDoc);
390 }
391 }
392
393 return _replaceDocument(pDoc);
394 }
395
loadDocument(GsfInput * input,int ieft)396 UT_Error AP_Frame::loadDocument(GsfInput * input, int ieft)
397 {
398 bool bUpdateClones;
399 UT_GenericVector<XAP_Frame*> vClones;
400 XAP_App * pApp = XAP_App::getApp();
401 UT_sint32 j = 0;
402 if(pApp->findFrame(this) < 0)
403 {
404 pApp->rememberFrame(this);
405 }
406 bUpdateClones = (getViewNumber() > 0);
407 if (bUpdateClones)
408 {
409 pApp->getClones(&vClones, this);
410 }
411 for(j=0; j<vClones.getItemCount();j++)
412 {
413 XAP_Frame * pFrame = vClones.getNthItem(j);
414 if(pApp->findFrame(pFrame) < 0)
415 {
416 pApp->rememberFrame(pFrame,this);
417 }
418 }
419 UT_Error errorCode;
420 errorCode = _loadDocument(input, static_cast<IEFileType>(ieft));
421 if (!UT_IS_IE_SUCCESS(errorCode))
422 {
423 // we could not load the document.
424 // we cannot complain to the user here, we don't know
425 // if the app is fully up yet. we force our caller
426 // to deal with the problem.
427 return errorCode;
428 }
429 XAP_Frame::tZoomType iZoomType;
430 UT_uint32 iZoom = getNewZoom(&iZoomType);
431 setZoomType(iZoomType);
432 if(pApp->findFrame(this) < 0)
433 {
434 pApp->rememberFrame(this);
435 }
436 if (bUpdateClones)
437 {
438 for (UT_sint32 i = 0; i < vClones.getItemCount(); i++)
439 {
440 AP_Frame * pFrame = static_cast<AP_Frame*>(vClones.getNthItem(i));
441 if(pFrame != this)
442 {
443 pFrame->_replaceDocument(m_pDoc);
444 }
445 }
446 }
447
448 return _showDocument(iZoom);
449 }
450
loadDocument(const char * szFilename,int ieft,bool createNew)451 UT_Error AP_Frame::loadDocument(const char * szFilename, int ieft, bool createNew)
452 {
453 bool bUpdateClones;
454 UT_GenericVector<XAP_Frame*> vClones;
455 XAP_App * pApp = XAP_App::getApp();
456 UT_sint32 j = 0;
457 if(pApp->findFrame(this) < 0)
458 {
459 pApp->rememberFrame(this);
460 }
461 bUpdateClones = (getViewNumber() > 0);
462 if (bUpdateClones)
463 {
464 pApp->getClones(&vClones, this);
465 }
466 for(j=0; j<vClones.getItemCount();j++)
467 {
468 XAP_Frame * pFrame = vClones.getNthItem(j);
469 if(pApp->findFrame(pFrame) < 0)
470 {
471 pApp->rememberFrame(pFrame,this);
472 }
473 }
474 UT_Error errorCode;
475 errorCode = _loadDocument(szFilename, static_cast<IEFileType>(ieft), createNew);
476 if (!UT_IS_IE_SUCCESS(errorCode))
477 {
478 // we could not load the document.
479 // we cannot complain to the user here, we don't know
480 // if the app is fully up yet. we force our caller
481 // to deal with the problem.
482 return errorCode;
483 }
484 XAP_Frame::tZoomType iZoomType;
485 UT_uint32 iZoom = getNewZoom(&iZoomType);
486 setZoomType(iZoomType);
487 if(pApp->findFrame(this) < 0)
488 {
489 pApp->rememberFrame(this);
490 }
491 if (bUpdateClones)
492 {
493 for (UT_sint32 i = 0; i < vClones.getItemCount(); i++)
494 {
495 AP_Frame * pFrame = static_cast<AP_Frame*>(vClones.getNthItem(i));
496 if(pFrame != this)
497 {
498 pFrame->_replaceDocument(m_pDoc);
499 }
500 }
501 }
502
503 UT_Error errorCode2 = _showDocument(iZoom);
504 if((errorCode2 == UT_OK) && (errorCode == UT_IE_TRY_RECOVER))
505 {
506 return errorCode;
507 }
508 return errorCode2;
509 }
510
loadDocument(const char * szFilename,int ieft)511 UT_Error AP_Frame::loadDocument(const char * szFilename, int ieft)
512 {
513 return loadDocument(szFilename, ieft, false);
514 }
515
importDocument(const char * szFilename,int ieft,bool markClean)516 UT_Error AP_Frame::importDocument(const char * szFilename, int ieft, bool markClean)
517 {
518 bool bUpdateClones;
519 UT_GenericVector<XAP_Frame*> vClones;
520 XAP_App * pApp = XAP_App::getApp();
521
522 bUpdateClones = (getViewNumber() > 0);
523 if (bUpdateClones)
524 {
525 pApp->getClones(&vClones, this);
526 }
527 UT_Error errorCode;
528 errorCode = _importDocument(szFilename, static_cast<IEFileType>(ieft), markClean);
529 if (!UT_IS_IE_SUCCESS(errorCode))
530 {
531 return errorCode;
532 }
533
534 if (bUpdateClones)
535 {
536 for (UT_sint32 i = 0; i < vClones.getItemCount(); i++)
537 {
538 AP_Frame * pFrame = static_cast<AP_Frame *>(vClones.getNthItem(i));
539 if(pFrame != this)
540 {
541 pFrame->_replaceDocument(m_pDoc);
542 }
543 }
544 }
545 XAP_Frame::tZoomType iZoomType;
546 UT_uint32 iZoom = getNewZoom(&iZoomType);
547 setZoomType(iZoomType);
548 UT_Error errorCode2 = _showDocument(iZoom);
549 if((errorCode2 == UT_OK) && (errorCode == UT_IE_TRY_RECOVER))
550 {
551 return errorCode;
552 }
553 return errorCode2;
554 }
555
556 /*!
557 * This method returns the zoomPercentage of the new frame.
558 * Logic goes like this.
559 * If there is a valid last focussed frame return the zoom and zoom type
560 * for that.
561 * Otherwise use the preference value.
562 */
getNewZoom(XAP_Frame::tZoomType * tZoom)563 UT_uint32 AP_Frame::getNewZoom(XAP_Frame::tZoomType * tZoom)
564 {
565 UT_GenericVector<XAP_Frame*> vecClones;
566 XAP_Frame *pF = NULL;
567 XAP_App * pApp = XAP_App::getApp();
568 UT_return_val_if_fail (pApp, 0);
569 XAP_Frame * pLastFrame = pApp->getLastFocussedFrame();
570 UT_uint32 iZoom = 100;
571 if(pLastFrame == NULL)
572 {
573 UT_String sZoom;
574 pApp->getPrefsValue(XAP_PREF_KEY_ZoomType, sZoom);
575 *tZoom = getZoomType();
576 if( (g_ascii_strcasecmp( sZoom.c_str(), "Width" ) == 0 ) || (g_ascii_strcasecmp( sZoom.c_str(), "Page" ) == 0 ))
577 {
578 iZoom = 100;
579 }
580 else
581 {
582 iZoom = atoi( sZoom.c_str() );
583 }
584 return iZoom;
585 }
586 else
587 {
588 UT_uint32 nFrames = getViewNumber();
589
590 if(nFrames == 0)
591 {
592 iZoom = pLastFrame->getZoomPercentage();
593 *tZoom = pLastFrame->getZoomType();
594 return iZoom;
595 }
596 XAP_App::getApp()->getClones(&vecClones,this);
597 UT_sint32 i =0;
598 bool bMatch = false;
599 for (i=0; !bMatch && (i< vecClones.getItemCount()); i++)
600 {
601 pF = static_cast<XAP_Frame *>(vecClones.getNthItem(i));
602 bMatch = (pF == pLastFrame);
603 }
604 if(bMatch)
605 {
606 iZoom = pLastFrame->getZoomPercentage();
607 *tZoom = pLastFrame->getZoomType();
608 return iZoom;
609 }
610 }
611 iZoom = pF->getZoomPercentage();
612 *tZoom = pF->getZoomType();
613 return iZoom;
614 }
615
_replaceDocument(AD_Document * pDoc)616 UT_Error AP_Frame::_replaceDocument(AD_Document * pDoc)
617 {
618 // NOTE: prior document is discarded in _showDocument()
619 m_pDoc = pDoc; // This was a REFP(pDoc) but it just a caused leak
620 XAP_Frame::tZoomType iZoomType;
621 UT_uint32 iZoom = getNewZoom(&iZoomType);
622 setZoomType(iZoomType);
623 UT_Error res = _showDocument(iZoom);
624 // notify our listeners
625 _signal(APF_ReplaceDocument);
626 return res;
627 }
628
_showDocument(UT_uint32 iZoom)629 UT_Error AP_Frame::_showDocument(UT_uint32 iZoom)
630 {
631 if (!m_pDoc)
632 {
633 UT_DEBUGMSG(("Can't show a non-existent document\n"));
634 return UT_IE_FILENOTFOUND;
635 }
636 if(isFrameLocked())
637 {
638 UT_DEBUGMSG(("_showDocument: Nasty race bug, please fix me!! \n"));
639 UT_ASSERT_HARMLESS(0);
640 return UT_IE_ADDLISTENERERROR;
641 }
642 setFrameLocked(true);
643 if (!static_cast<AP_FrameData*>(m_pData))
644 {
645 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
646 setFrameLocked(false);
647 return UT_IE_IMPORTERROR;
648 }
649
650 // static_cast<XAP_FrameImpl *>(m_pFrameImpl)->setShowDocLocked(true);
651
652 GR_Graphics * pG = NULL;
653 FL_DocLayout * pDocLayout = NULL;
654 AV_View * pView = NULL;
655 AV_ScrollObj * pScrollObj = NULL;
656 ap_ViewListener * pViewListener = NULL;
657 AD_Document * pOldDoc = NULL;
658 ap_Scrollbar_ViewListener * pScrollbarViewListener = NULL;
659 AV_ListenerId lid;
660 AV_ListenerId lidScrollbarViewListener;
661
662 xxx_UT_DEBUGMSG(("_showDocument: Initial m_pView %x \n",m_pView));
663
664 if(iZoom < XAP_DLG_ZOOM_MINIMUM_ZOOM)
665 iZoom = 100;
666 else if (iZoom > XAP_DLG_ZOOM_MAXIMUM_ZOOM)
667 iZoom = 100;
668 UT_DEBUGMSG(("!!!!!!!!! _showdOCument: Initial izoom is %d \n",iZoom));
669
670 if (!_createViewGraphics(pG, iZoom))
671 goto Cleanup;
672
673 pDocLayout = new FL_DocLayout(static_cast<PD_Document *>(m_pDoc), pG);
674 ENSUREP_C(pDocLayout);
675
676 pView = new FV_View(XAP_App::getApp(), this, pDocLayout);
677 ENSUREP_C(pView);
678
679 if(getZoomType() == XAP_Frame::z_PAGEWIDTH)
680 {
681 iZoom = pView->calculateZoomPercentForPageWidth();
682 pG->setZoomPercentage(iZoom);
683 }
684 else if(getZoomType() == XAP_Frame::z_WHOLEPAGE)
685 {
686 iZoom = pView->calculateZoomPercentForWholePage();
687 pG->setZoomPercentage(iZoom);
688 }
689 UT_DEBUGMSG(("!!!!!!!!! _showdOCument: izoom is %d \n",iZoom));
690 XAP_Frame::setZoomPercentage(iZoom);
691 _setViewFocus(pView);
692
693 if (!_createScrollBarListeners(pView, pScrollObj, pViewListener, pScrollbarViewListener,
694 lid, lidScrollbarViewListener))
695 goto Cleanup;
696 if(getFrameMode() ==XAP_NormalFrame)
697 {
698 _bindToolbars(pView);
699 }
700 _replaceView(pG, pDocLayout, pView, pScrollObj, pViewListener, pOldDoc,
701 pScrollbarViewListener, lid, lidScrollbarViewListener, iZoom);
702
703 setXScrollRange();
704 setYScrollRange();
705
706 m_pView->draw();
707
708 if ( static_cast<AP_FrameData*>(m_pData)->m_bShowRuler )
709 {
710 if ( static_cast<AP_FrameData*>(m_pData)->m_pTopRuler )
711 {
712 static_cast<AP_FrameData*>(m_pData)->m_pTopRuler->setZoom(iZoom);
713 static_cast<AP_FrameData*>(m_pData)->m_pTopRuler->queueDraw();
714 }
715 if ( static_cast<AP_FrameData*>(m_pData)->m_pLeftRuler )
716 {
717 static_cast<AP_FrameData*>(m_pData)->m_pLeftRuler->setZoom(iZoom);
718 static_cast<AP_FrameData*>(m_pData)->m_pLeftRuler->queueDraw();
719 }
720 }
721 if(isStatusBarShown())
722 {
723 if (static_cast<AP_FrameData*>(m_pData)->m_pStatusBar)
724 static_cast<AP_FrameData*>(m_pData)->m_pStatusBar->notify(m_pView, AV_CHG_ALL);
725 }
726 m_pView->notifyListeners(AV_CHG_ALL);
727 m_pView->focusChange(AV_FOCUS_HERE);
728
729 //static_cast<XAP_FrameImpl *>(m_pFrameImpl)->setShowDocLocked(false);
730 setFrameLocked(false);
731 return UT_OK;
732
733 Cleanup:
734 // clean up anything we created here
735 DELETEP(pG);
736 DELETEP(pDocLayout);
737 DELETEP(pView);
738 DELETEP(pViewListener);
739 DELETEP(pScrollObj);
740 DELETEP(pScrollbarViewListener);
741
742 // change back to prior document
743 UNREFP(m_pDoc);
744 setFrameLocked(false);
745 UT_return_val_if_fail(static_cast<AP_FrameData*>(m_pData)->m_pDocLayout, UT_IE_ADDLISTENERERROR);
746 m_pDoc = static_cast<AP_FrameData*>(m_pData)->m_pDocLayout->getDocument();
747 //static_cast<XAP_FrameImpl *>(m_pFrameImpl)->setShowDocLocked(false);
748 return UT_IE_ADDLISTENERERROR;
749 }
750
_replaceView(GR_Graphics * pG,FL_DocLayout * pDocLayout,AV_View * pView,AV_ScrollObj * pScrollObj,ap_ViewListener * pViewListener,AD_Document * pOldDoc,ap_Scrollbar_ViewListener * pScrollbarViewListener,AV_ListenerId lid,AV_ListenerId lidScrollbarViewListener,UT_uint32 iZoom)751 void AP_Frame::_replaceView(GR_Graphics * pG, FL_DocLayout *pDocLayout,
752 AV_View *pView, AV_ScrollObj * pScrollObj,
753 ap_ViewListener *pViewListener, AD_Document *pOldDoc,
754 ap_Scrollbar_ViewListener *pScrollbarViewListener,
755 AV_ListenerId lid, AV_ListenerId lidScrollbarViewListener,
756 UT_uint32 iZoom)
757 {
758 bool holdsSelection = false, hadView = true;
759 PD_DocumentRange range;
760 PT_DocPosition inspt = 0;
761
762 // we want to remember point/selection when that is appropriate, which is when the new view is a
763 // view of the same doc as the old view, or if this frame is being cloned from an existing frame
764
765 // these are the view and doc from which this frame is being cloned
766 FV_View * pRootView = NULL; // this should really be const, but
767 // getDocumentRangeOfCurrentSelection() is not
768 const AD_Document * pRootDoc = NULL;
769
770 if (m_pView && !m_pView->isSelectionEmpty ())
771 {
772 holdsSelection = true;
773 static_cast<FV_View*>(m_pView)->getDocumentRangeOfCurrentSelection (&range);
774 } else if (m_pView)
775 {
776 inspt = static_cast<FV_View*>(m_pView)->getInsPoint ();
777 }
778 else if(static_cast<AP_FrameData*>(m_pData)->m_pRootView)
779 {
780 pRootView = static_cast<FV_View*>(static_cast<AP_FrameData*>(m_pData)->m_pRootView);
781 pRootDoc = pRootView->getDocument();
782
783 if (!pRootView->isSelectionEmpty())
784 {
785 holdsSelection = true;
786 pRootView->getDocumentRangeOfCurrentSelection (&range);
787 } else if (pRootView)
788 {
789 inspt = pRootView->getInsPoint ();
790 }
791 else
792 hadView = false;
793
794 // we want to set m_pData->m_pRootView to NULL, since it has fullfilled its function and we
795 // do not want any dead pointers hanging around
796 static_cast<AP_FrameData*>(m_pData)->m_pRootView = NULL;
797 }
798 else
799 hadView = false;
800
801 // switch to new view, cleaning up previous settings
802 if (static_cast<AP_FrameData*>(m_pData)->m_pDocLayout)
803 {
804 pOldDoc = (static_cast<AP_FrameData*>(m_pData)->m_pDocLayout->getDocument());
805 }
806
807 REPLACEP(static_cast<AP_FrameData*>(m_pData)->m_pG, pG);
808 REPLACEP(static_cast<AP_FrameData*>(m_pData)->m_pDocLayout, pDocLayout);
809
810 bool bSameDocument = false; // be cautious ...
811
812 if(!pOldDoc)
813 {
814 // this is the case when this is a new frame unrelated to anything, or a frame cloned from
815 // existing frame
816 if(pRootDoc == m_pDoc)
817 {
818 // we have been cloned from a frame which related to the same document
819 bSameDocument = true;
820 }
821 }
822 else if (pOldDoc != m_pDoc)
823 {
824 static_cast<PD_Document *>(pOldDoc)->changeConnectedDocument(static_cast<PD_Document *>(m_pDoc));
825 UNREFP(pOldDoc);
826 }
827 else
828 {
829 // pOldDoc == m_pDoc
830 bSameDocument = true;
831 }
832
833 AV_View * pReplacedView = m_pView;
834 m_pView = pView;
835
836 XAP_App::getApp()->setViewSelection(NULL);
837
838 REPLACEP(m_pScrollObj, pScrollObj);
839 REPLACEP(m_pViewListener, pViewListener);
840 m_lid = lid;
841 REPLACEP(m_pScrollbarViewListener, pScrollbarViewListener);
842 m_lidScrollbarViewListener = lidScrollbarViewListener;
843
844 m_pView->addScrollListener(m_pScrollObj);
845
846 // Associate the new view with the existing TopRuler, LeftRuler.
847 // Because of the binding to the actual on-screen widgets we do
848 // not destroy and recreate the TopRuler, LeftRuler when we change
849 // views, like we do for all the other objects. We also do not
850 // allocate the TopRuler, LeftRuler here; that is done as the
851 // frame is created.
852 if ( static_cast<AP_FrameData*>(m_pData)->m_bShowRuler )
853 {
854 if ( static_cast<AP_FrameData*>(m_pData)->m_pTopRuler )
855 static_cast<AP_FrameData*>(m_pData)->m_pTopRuler->setView(pView, iZoom);
856 if ( static_cast<AP_FrameData*>(m_pData)->m_pLeftRuler )
857 static_cast<AP_FrameData*>(m_pData)->m_pLeftRuler->setView(pView, iZoom);
858 }
859
860 if ( static_cast<AP_FrameData*>(m_pData)->m_pStatusBar && (getFrameMode() != XAP_NoMenusWindowLess))
861 static_cast<AP_FrameData*>(m_pData)->m_pStatusBar->setView(pView);
862 static_cast<FV_View *>(m_pView)->setShowPara(static_cast<AP_FrameData*>(m_pData)->m_bShowPara);
863
864 pView->setInsertMode((static_cast<AP_FrameData*>(m_pData)->m_bInsertMode));
865 m_pView->setWindowSize(_getDocumentAreaWidth(), _getDocumentAreaHeight());
866
867 updateTitle();
868 XAP_App * pApp = XAP_App::getApp();
869 if(pApp->findFrame(this) < 0)
870 {
871 pApp->rememberFrame(this);
872 }
873 //
874 // Remove the old layout before we fill the layouts to prevent
875 // stale pointers being accessed during the fill phase.
876 //
877 if(bSameDocument)
878 {
879 static_cast<PD_Document *>(m_pDoc)->disableListUpdates();
880 }
881 pDocLayout->fillLayouts();
882 if(bSameDocument)
883 {
884 static_cast<PD_Document *>(m_pDoc)->enableListUpdates();
885 static_cast<PD_Document *>(m_pDoc)->updateDirtyLists();
886 }
887
888 // can only hold selection/point if the two views are for the same doc !!!
889 if(bSameDocument)
890 {
891 FV_View * pFV_View = static_cast<FV_View*>(m_pView);
892 if (holdsSelection)
893 pFV_View->cmdSelect (range.m_pos1, range.m_pos2);
894 else if (hadView)
895 pFV_View->moveInsPtTo(inspt);
896 }
897
898 if (XAP_FrameImpl * pFrameImpl = getFrameImpl())
899 {
900 pFrameImpl->notifyViewChanged(m_pView);
901 }
902 DELETEP(pReplacedView);
903
904 // notify our listeners
905 _signal(APF_ReplaceView);
906 }
907
registerListener(AP_FrameListener * pListener)908 UT_sint32 AP_Frame::registerListener(AP_FrameListener* pListener)
909 {
910 UT_return_val_if_fail(pListener, -1);
911 m_listeners.push_back(pListener); // TODO: look for gaps that we can reuse, caused by unregister calls - MARCM
912 return m_listeners.size()-1;
913 }
914
unregisterListener(UT_sint32 iListenerId)915 void AP_Frame::unregisterListener(UT_sint32 iListenerId)
916 {
917 UT_return_if_fail(iListenerId >= 0);
918 UT_return_if_fail(iListenerId >= static_cast<UT_sint32>(m_listeners.size()));
919 m_listeners[iListenerId] = NULL;
920 }
921
_signal(AP_FrameSignal sig)922 void AP_Frame::_signal(AP_FrameSignal sig)
923 {
924 for (std::vector<AP_FrameListener*>::iterator it = m_listeners.begin(); it != m_listeners.end(); it++)
925 {
926 AP_FrameListener* pListener = *it;
927 if (pListener)
928 pListener->signalFrame(sig);
929 }
930 }
931