"Fossies" - the Fresh Open Source Software Archive

Member "Ted-2.23/appFrame/appDocument.c" (1 Feb 2013, 25463 Bytes) of archive /linux/misc/ted-2.23.src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "appDocument.c" see the Fossies "Dox" file reference documentation.

    1 /************************************************************************/
    2 /*                                  */
    3 /*  Document window application independent functionality.      */
    4 /*                                  */
    5 /************************************************************************/
    6 
    7 #   include "appFrameConfig.h"
    8 
    9 #   include <stddef.h>
   10 #   include <stdio.h>
   11 #   include <stdlib.h>
   12 
   13 #   include <appSystem.h>
   14 #   include "appFrame.h"
   15 #   include "appQuestion.h"
   16 #   include "guiWidgetDrawingSurface.h"
   17 #   include "guiDrawingWidget.h"
   18 #   include "appFileChooser.h"
   19 #   include "utilMemoryBufferPrintf.h"
   20 
   21 #   include <appDebugon.h>
   22 
   23 #   define  LOG_REDRAWS 0
   24 
   25 /************************************************************************/
   26 /*                                  */
   27 /*  Callback for the file menu.                     */
   28 /*                                  */
   29 /************************************************************************/
   30 
   31 APP_MENU_CALLBACK_H( appDocFileSave, option, voided, e )
   32     {
   33     EditDocument *      ed= (EditDocument *)voided;
   34     EditApplication *       ea= ed->edApplication;
   35 
   36     APP_WIDGET          relative= ed->edToplevel.atTopWidget;
   37 
   38     if  ( ! ea->eaSaveDocument )
   39     { XDEB(ea->eaSaveDocument); return; }
   40 
   41     if  ( utilMemoryBufferIsEmpty( &(ed->edFilename) )  ||
   42       ed->edFileReadOnly                ||
   43       ed->edFormat < 0              )
   44     {
   45     appRunSaveChooser( option, ed->edToplevel.atTopWidget,
   46                 APPFILE_CAN_SAVE, appDocSaveDocument,
   47                 ed, ed->edPrivateData );
   48 
   49     return;
   50     }
   51 
   52     if  ( ! appDocSaveDocument( ed, (void *)0, relative, option,
   53                         ed->edFormat, &(ed->edFilename) ) )
   54     { appDocumentChanged( ed, 0 ); }
   55 
   56     return;
   57     }
   58 
   59 /************************************************************************/
   60 /*                                  */
   61 /*  'Close' callback for the file menu and for the window manager menu  */
   62 /*                                  */
   63 /*  1)  As 'mwm' sometimes sends a 'Save yourself' when 'Close' is  */
   64 /*  selected from the window manager menu, deactivate the protocol. */
   65 /*  B.T.W. This does not help.                  */
   66 /*                                  */
   67 /*                                  */
   68 /************************************************************************/
   69 
   70 APP_MENU_CALLBACK_H( appDocFileClose, option, voided, e )
   71     {
   72     EditDocument *  ed= (EditDocument *)voided;
   73 
   74     if  ( ed->edHasBeenChanged )
   75     { appRunReallyCloseDialog( option, ed ); return; }
   76 
   77     appCloseDocument( ed );
   78 
   79     return;
   80     }
   81 
   82 APP_CLOSE_CALLBACK_H( appDocFileCloseCallback, w, voided )
   83     {
   84     EditDocument *  ed= (EditDocument *)voided;
   85 
   86     if  ( ed->edHasBeenChanged )
   87     { appRunReallyCloseDialog( ed->edFileCloseOption, ed ); return; }
   88 
   89     appCloseDocument( ed );
   90     }
   91 
   92 APP_MENU_CALLBACK_H( appDocFileNew, option, voided, e )
   93     {
   94     EditDocument *      ed= (EditDocument *)voided;
   95     EditApplication *       ea= ed->edApplication;
   96     const MemoryBuffer *    filename= (const MemoryBuffer *)0;
   97 
   98     if  ( appNewDocument( ea, filename ) )
   99     { LDEB(1); }
  100 
  101     return;
  102     }
  103 
  104 APP_MENU_CALLBACK_H( appDocFileQuit, option, voided, e )
  105     {
  106     EditDocument *  ed= (EditDocument *)voided;
  107     EditApplication *   ea= ed->edApplication;
  108 
  109     appQuitApplication( option, ed->edToplevel.atTopWidget, ea );
  110 
  111     return;
  112     }
  113 
  114 void appReportSaveFailure(  EditApplication *   ea,
  115                 APP_WIDGET      option,
  116                 APP_WIDGET      relative,
  117                 const MemoryBuffer *    filename )
  118     {
  119     AppFileMessageResources *   afmr= &(ea->eaFileMessageResources);
  120 
  121     if  ( appTestFileWritable( filename ) )
  122     {
  123     appQuestionRunFilenameErrorDialog( ea, relative, option,
  124                     filename, afmr->afmrFileNotWritable );
  125     }
  126     else{
  127     appQuestionRunFilenameErrorDialog( ea, relative, option,
  128                     filename, afmr->afmrFileNotWritable );
  129     }
  130     }
  131 
  132 /************************************************************************/
  133 /*                                  */
  134 /*  The user selected the 'about' option.               */
  135 /*                                  */
  136 /************************************************************************/
  137 
  138 APP_MENU_CALLBACK_H( appDocAbout, option, voided, e )
  139     {
  140     EditDocument *      ed= (EditDocument *)voided;
  141     EditApplication *       ea= ed->edApplication;
  142 
  143     ea->eaMainVisibleAsAbout= 1;
  144 
  145     appShowShellWidget( ea, ea->eaToplevel.atTopWidget );
  146 
  147     return;
  148     }
  149 
  150 /************************************************************************/
  151 /*                                  */
  152 /*  Callback for the option in the files menu.              */
  153 /*                                  */
  154 /************************************************************************/
  155 
  156 void appMakeDocVisible( EditApplication *   ea,
  157             EditDocument *      ed )
  158     {
  159     appShowShellWidget( ea, ed->edToplevel.atTopWidget );
  160 
  161     if  ( ! ed->edIsVisible )
  162     {
  163     ed->edIsVisible= 1;
  164 
  165     appDocVisible( ea, ed, ed->edIsVisible );
  166     }
  167     }
  168 
  169 void appDocToFront( APP_WIDGET  option,
  170             void *      voided,
  171             void *      e )
  172     {
  173     EditDocument *      ed= (EditDocument *)voided;
  174     EditApplication *       ea= ed->edApplication;
  175 
  176     appMakeDocVisible( ea, ed );
  177 
  178     appGuiSetToggleItemState( option, ed->edHasBeenChanged );
  179 
  180     return;
  181     }
  182 
  183 /************************************************************************/
  184 /*                                  */
  185 /*  Callbacks for the edit menu.                    */
  186 /*                                  */
  187 /************************************************************************/
  188 
  189 APP_MENU_CALLBACK_H( appDocEditCopy, option, voided, e )
  190     {
  191     EditDocument *          ed= (EditDocument *)voided;
  192     EditApplication *           ea= ed->edApplication;
  193 
  194     if  ( ! ea->eaDocCopy )
  195     { XDEB(ea->eaDocCopy); return;  }
  196 
  197     (*ea->eaDocCopy)( ed ); return;
  198     }
  199 
  200 APP_MENU_CALLBACK_H( appDocEditCut, option, voided, e )
  201     {
  202     EditDocument *          ed= (EditDocument *)voided;
  203     EditApplication *           ea= ed->edApplication;
  204 
  205     if  ( ! ea->eaDocCut )
  206     { XDEB(ea->eaDocCut); return;   }
  207 
  208     (*ea->eaDocCut)( ed ); return;
  209     }
  210 
  211 APP_MENU_CALLBACK_H( appDocEditSelAll, option, voided, e )
  212     {
  213     EditDocument *          ed= (EditDocument *)voided;
  214     EditApplication *           ea= ed->edApplication;
  215 
  216     if  ( ! ea->eaDocSelAll )
  217     { XDEB(ea->eaDocSelAll); return;    }
  218 
  219     ea->eaDocSelAll( ed ); return;
  220     }
  221 
  222 int appSetDocumentFilename( EditDocument *      ed,
  223                 const MemoryBuffer *    filename )
  224     {
  225     if  ( filename )
  226     {
  227     if  ( utilCopyMemoryBuffer( &(ed->edFilename), filename ) )
  228         { LDEB(1); return -1;   }
  229     }
  230     else{ utilEmptyMemoryBuffer( &(ed->edFilename) );   }
  231 
  232     return 0;
  233     }
  234 
  235 int appFormatDocumentTitle( MemoryBuffer *      windowTitle,
  236                 MemoryBuffer *      iconTitle,
  237                 EditApplication *   ea,
  238                 const MemoryBuffer *    title )
  239     {
  240     int         rval= 0;
  241 
  242     MemoryBuffer    baseName;
  243 
  244     utilInitMemoryBuffer( &baseName );
  245 
  246     if  ( appFileGetRelativeName( &baseName, title ) < 0 )
  247     { LDEB(1); rval= -1; goto ready;    }
  248 
  249     if  ( utilMemoryBufferSetString( windowTitle, ea->eaApplicationName ) )
  250     { LDEB(1); rval= -1; goto ready;    }
  251     if  ( utilMemoryBufferAppendString( windowTitle, ": " ) )
  252     { LDEB(1); rval= -1; goto ready;    }
  253     if  ( utilMemoryAppendBuffer( windowTitle, title ) )
  254     { LDEB(1); rval= -1; goto ready;    }
  255 
  256     if  ( utilMemoryBufferSetString( iconTitle, ea->eaApplicationName ) )
  257     { LDEB(1); rval= -1; goto ready;    }
  258     if  ( utilMemoryBufferAppendString( iconTitle, ": " ) )
  259     { LDEB(1); rval= -1; goto ready;    }
  260     if  ( utilMemoryAppendBuffer( iconTitle, &baseName ) )
  261     { LDEB(1); rval= -1; goto ready;    }
  262 
  263   ready:
  264 
  265     utilCleanMemoryBuffer( &baseName );
  266 
  267     return rval;
  268     }
  269 
  270 int appSetDocumentTitle(    EditDocument *      ed,
  271                 const MemoryBuffer *    title )
  272     {
  273     int             rval= 0;
  274     EditApplication *       ea= ed->edApplication;
  275 
  276     MemoryBuffer        fullTitle;
  277     MemoryBuffer        iconName;
  278 
  279     utilInitMemoryBuffer( &fullTitle );
  280     utilInitMemoryBuffer( &iconName );
  281 
  282     if  ( utilCopyMemoryBuffer( &(ed->edTitle), title ) )
  283     { LDEB(1); rval= -1; goto ready;    }
  284 
  285     if  ( appFormatDocumentTitle( &fullTitle, &iconName, ea, &(ed->edTitle) ) )
  286     { LDEB(1); rval= -1; goto ready;    }
  287 
  288     appGuiSetShellTitle( ed->edToplevel.atTopWidget, &fullTitle );
  289     appGuiSetIconTitle( ed->edToplevel.atTopWidget, &iconName );
  290 
  291     appRenameDocumentOptions( ed->edApplication, ed, &(ed->edTitle) );
  292 
  293   ready:
  294 
  295     utilCleanMemoryBuffer( &fullTitle );
  296     utilCleanMemoryBuffer( &iconName );
  297 
  298     return rval;
  299     }
  300 
  301 
  302 /************************************************************************/
  303 /*                                  */
  304 /*  Free all resources allocated for a document.            */
  305 /*                                  */
  306 /************************************************************************/
  307 
  308 static void appCleanDocumentWidget( DocumentWidget *    dw )
  309     {
  310 #   ifdef USE_MOTIF
  311     if  ( dw->dwInputContext )
  312     { XDestroyIC( dw->dwInputContext ); }
  313 #   endif
  314 
  315 #   if defined(USE_GTK) && defined(GTK_TYPE_IM_CONTEXT)
  316     if  ( dw->dwInputContext )
  317     { g_object_unref( dw->dwInputContext ); }
  318 #   endif
  319     }
  320 
  321 static void appCleanDocument(       EditApplication *   ea,
  322                     EditDocument *      ed )
  323     {
  324     if  ( ed->edLeftRuler )
  325     { (*ea->eaFreeLeftRuler)( ed->edLeftRuler ); }
  326     if  ( ed->edTopRuler )
  327     { (*ea->eaFreeTopRuler)( ed->edTopRuler ); }
  328     if  ( ed->edRightRuler )
  329     { (*ea->eaFreeRightRuler)( ed->edRightRuler ); }
  330     if  ( ed->edBottomRuler )
  331     { (*ea->eaFreeBottomRuler)( ed->edBottomRuler ); }
  332 
  333     utilCleanMemoryBuffer( &(ed->edFilename) );
  334     utilCleanMemoryBuffer( &(ed->edTitle) );
  335 
  336     appCleanDocumentWidget( &(ed->edDocumentWidget) );
  337     if  ( ed->edDrawingSurface )
  338     { drawFreeDrawingSurface( ed->edDrawingSurface ); }
  339 
  340     return;
  341     }
  342 
  343 static void appFreeDocument(        EditApplication *   ea,
  344                     EditDocument *      ed )
  345     {
  346     appCleanDocument( ea, ed );
  347     free( ed );
  348 
  349     return;
  350     }
  351 
  352 static void appInitDocumentWidget(  DocumentWidget *    dw )
  353     {
  354     dw->dwWidget= (APP_WIDGET)0;
  355 
  356 #   ifdef USE_MOTIF
  357     dw->dwInputContext= (XIC)0;
  358 #   endif
  359 
  360 #   ifdef USE_GTK
  361 #   ifdef GTK_TYPE_IM_CONTEXT
  362     dw->dwInputContext= (GtkIMContext *)0;
  363 #   else
  364     dw->dwInputContext= 0;
  365 #   endif
  366 #   endif
  367     }
  368 
  369 static void appInitEditDocument(    EditApplication *   ea,
  370                     EditDocument *      ed )
  371     {
  372     ed->edApplication= ea;
  373 
  374     utilInitMemoryBuffer( &(ed->edFilename) );
  375     utilInitMemoryBuffer( &(ed->edTitle) );
  376 
  377     ed->edFormat= -1;
  378     ed->edFileReadOnly= 0;
  379 
  380     ed->edMenuBar= (APP_WIDGET)0;
  381     ed->edMainWindow= (APP_WIDGET)0;
  382     ed->edFileMenu= (APP_WIDGET)0;
  383     ed->edFileMenuButton= (APP_WIDGET)0;
  384         ed->edFileCloseOption= (APP_WIDGET)0;
  385     ed->edEditMenu= (APP_WIDGET)0;
  386     ed->edEditMenuButton= (APP_WIDGET)0;
  387     ed->edWindowMenu= (APP_WIDGET)0;
  388     ed->edWindowMenuButton= (APP_WIDGET)0;
  389     ed->edHelpMenu= (APP_WIDGET)0;
  390     ed->edHelpMenuButton= (APP_WIDGET)0;
  391 
  392     ed->edToolbar= (APP_WIDGET)0;
  393     ed->edScrolledWindow= (APP_WIDGET)0;
  394     ed->edVerticalScrollbar= (APP_WIDGET)0;
  395     ed->edHorizontalScrollbar= (APP_WIDGET)0;
  396     ed->edWorkWidget= (APP_WIDGET)0;
  397     appInitDocumentWidget( &(ed->edDocumentWidget) );
  398     ed->edDrawingSurface= (DrawingSurface)0;
  399 
  400     ed->edLeftRulerWidget= (APP_WIDGET)0;
  401     ed->edTopRulerWidget= (APP_WIDGET)0;
  402     ed->edRightRulerWidget= (APP_WIDGET)0;
  403     ed->edBottomRulerWidget= (APP_WIDGET)0;
  404 
  405     ed->edLeftRuler= (void *)0;
  406     ed->edTopRuler= (void *)0;
  407     ed->edRightRuler= (void *)0;
  408     ed->edBottomRuler= (void *)0;
  409 
  410     ed->edLeftRulerWidePixels= 0;
  411     ed->edTopRulerHighPixels= 0;
  412     ed->edRightRulerWidePixels= 0;
  413     ed->edBottomRulerHighPixels= 0;
  414 
  415     ed->edHasBeenChanged= 0;
  416     ed->edIsReadonly= 0;
  417     ed->edIsVisible= 0;
  418 
  419     ed->edMapped= 0;
  420     ed->edNotYetDrawn= 1;
  421 
  422     appInitSelectRectangle( &(ed->edSelectRectangle) );
  423     return;
  424     }
  425 
  426 int appMakeDocumentWindow(      EditDocument **     pEd,
  427                     EditApplication *   ea,
  428                     int         readOnly,
  429                     const MemoryBuffer *    title,
  430                     const MemoryBuffer *    filename )
  431     {
  432     int             rval= 0;
  433     EditDocument *      ed= (EditDocument *)0;
  434 
  435     MemoryBuffer        scratch;
  436 
  437     utilInitMemoryBuffer( &scratch );
  438 
  439     if  ( ! title || utilMemoryBufferIsEmpty( title ) )
  440     {
  441     static int          count= 1;
  442 
  443     AppFileMessageResources *   afmr= &(ea->eaFileMessageResources);
  444 
  445     utilMemoryBufferPrintf( &scratch,
  446                     afmr->afmrNamelessTitleFormat, count++ );
  447     title= &scratch;
  448     }
  449 
  450     /*  1  */
  451     ed= (EditDocument *)malloc( sizeof(EditDocument) );
  452     if  ( ! ed )
  453     { XDEB(ed); rval= -1; goto ready;   }
  454 
  455     appInitEditDocument( ea, ed );
  456 
  457     ea->eaNextDocumentId++; /* Never 0 */
  458     ed->edDocumentId= ea->eaNextDocumentId;
  459 
  460     if  ( filename && utilCopyMemoryBuffer( &(ed->edFilename), filename ) )
  461     { LDEB(1); rval= -1; goto ready;    }
  462 
  463     ed->edIsReadonly= readOnly;
  464     if  ( utilCopyMemoryBuffer( &(ed->edTitle), title ) )
  465     { LDEB(1); rval= -1; goto ready;    }
  466 
  467     if  ( ea->eaMakePrivateData )
  468     {
  469     ed->edPrivateData= (*ea->eaMakePrivateData)();
  470     if  ( ! ed->edPrivateData )
  471         { XDEB(ed->edPrivateData); rval= -1; goto ready; }
  472     }
  473 
  474     if  ( appFinishDocumentWindow( ed ) )
  475     { LDEB(1); rval= -1; goto ready; }
  476 
  477     *pEd= ed; ed= (EditDocument *)0; /* steal */
  478 
  479   ready:
  480 
  481     utilCleanMemoryBuffer( &scratch );
  482 
  483     if  ( ed )
  484     { appFreeDocument( ea, ed ); }
  485 
  486     return rval;
  487     }
  488 
  489 int appSetupDocument(   EditApplication *   ea,
  490             EditDocument *      ed )
  491     {
  492     DocumentWidget *        dw= &(ed->edDocumentWidget);
  493 
  494     int             wide;
  495     int             high;
  496 
  497 #   ifdef USE_MOTIF
  498     XtRealizeWidget( ed->edToplevel.atTopWidget );
  499 #   endif
  500 
  501 #   ifdef USE_GTK
  502     gtk_widget_realize( ed->edToplevel.atTopWidget );
  503 #   endif
  504 
  505     ed->edDrawingSurface= guiDrawingSurfaceForNativeWidget(
  506                         ed->edDocumentWidget.dwWidget,
  507                         ea->eaAvoidFontconfigInt > 0 );
  508     if  ( ! ed->edDrawingSurface )
  509     { PDEB(ed->edDrawingSurface); appFreeDocument( ea, ed ); return -1; }
  510 
  511     if  ( (*ea->eaLayoutDocument)( &(ed->edFullRect),
  512                     &(ed->edVisibleRect),
  513                     ed->edPrivateData, ed->edFormat,
  514                     ed->edDrawingSurface,
  515                     &(ea->eaPostScriptFontList),
  516                     &(ea->eaDefaultDocumentGeometry) ) )
  517     { LDEB(1); return -1; }
  518 
  519     wide= ed->edVisibleRect.drX1- ed->edVisibleRect.drX0;
  520     high= ed->edVisibleRect.drY1- ed->edVisibleRect.drY0;
  521 
  522     if  ( wide > ( 4* ea->eaScreenPixelsWide )/ 5 )
  523     { wide=  ( 4* ea->eaScreenPixelsWide )/ 5; }
  524     if  ( high > ( 4* ea->eaScreenPixelsHigh )/ 5 )
  525     { high=  ( 4* ea->eaScreenPixelsHigh )/ 5; }
  526 
  527 #   ifdef USE_MOTIF
  528     {
  529     Dimension docW= -1, docH= -1;
  530     Dimension topW= -1, topH= -1;
  531 
  532     XtVaSetValues( dw->dwWidget,
  533                 XmNborderWidth,     0,
  534                 XmNshadowThickness,     0,
  535                 XmNwidth,           wide,
  536                 XmNheight,          high,
  537                 NULL );
  538 
  539     /*
  540      * Cope with the fact that Motif performs the geometry calculations
  541      * when the widget is realised (And that we need to realize the widget 
  542      * before we perform the layout of the document.)
  543      */
  544 
  545     XtVaGetValues( dw->dwWidget,
  546                 XmNwidth,           &docW,
  547                 XmNheight,          &docH,
  548                 NULL );
  549     XtVaGetValues( ed->edToplevel.atTopWidget,
  550                 XmNwidth,           &topW,
  551                 XmNheight,          &topH,
  552                 NULL );
  553 
  554     if  ( docW != wide && docH != high && topW > docW && topH > docH )
  555     {
  556     XtVaSetValues( ed->edToplevel.atTopWidget,
  557                 XmNwidth,           wide+ ( topW- docW ),
  558                 XmNheight,          high+ ( topH- docH ),
  559                 NULL );
  560     }
  561     }
  562 #   endif
  563 
  564 #   ifdef USE_GTK
  565     gtk_drawing_area_size( GTK_DRAWING_AREA( ed->edTopRulerWidget ),
  566                     ed->edLeftRulerWidePixels+
  567                     wide+
  568                     ed->edRightRulerWidePixels,
  569                     ed->edTopRulerHighPixels );
  570     gtk_drawing_area_size( GTK_DRAWING_AREA( ed->edLeftRulerWidget ),
  571                     ed->edLeftRulerWidePixels, high );
  572 
  573 
  574     gtk_drawing_area_size( GTK_DRAWING_AREA( dw->dwWidget ), wide, high );
  575 
  576     gtk_drawing_area_size( GTK_DRAWING_AREA( ed->edRightRulerWidget ),
  577                         ed->edRightRulerWidePixels, high );
  578     gtk_drawing_area_size( GTK_DRAWING_AREA( ed->edBottomRulerWidget ),
  579                     ed->edLeftRulerWidePixels+
  580                     wide+
  581                     ed->edRightRulerWidePixels,
  582                     ed->edBottomRulerHighPixels );
  583 
  584     gtk_object_set_user_data( GTK_OBJECT( dw->dwWidget ), (void *)ed );
  585 #   endif
  586 
  587     if  ( ea->eaSetTopRuler     &&
  588       (*ea->eaSetTopRuler)( ed )    )
  589     { LDEB(1);  }
  590 
  591     if  ( ea->eaSetLeftRuler        &&
  592       (*ea->eaSetLeftRuler)( ed )   )
  593     { LDEB(1);  }
  594 
  595     if  ( ea->eaSetRightRuler       &&
  596       (*ea->eaSetRightRuler)( ed )  )
  597     { LDEB(1);  }
  598 
  599     if  ( ea->eaSetBottomRuler      &&
  600       (*ea->eaSetBottomRuler)( ed ) )
  601     { LDEB(1);  }
  602 
  603     guiGetBackgroundColor( &(ed->edBackgroundColor), dw->dwWidget );
  604 
  605     appDocSetScrollbarValues( ed );
  606 
  607     ed->edHasBeenChanged= 0;  /*  Can be changed in eaFinishDocumentSetup */
  608 
  609     if  ( ea->eaFinishDocumentSetup && (*ea->eaFinishDocumentSetup)( ed ) )
  610     { LDEB(1); return -1; }
  611 
  612     appShowShellWidget( ea, ed->edToplevel.atTopWidget );
  613 
  614     ed->edIsVisible= 1;
  615 
  616     appDocVisible( ea, ed, ed->edIsVisible );
  617 
  618     return 0;
  619     }
  620 
  621 /************************************************************************/
  622 /*                                  */
  623 /*  Close a a document.                         */
  624 /*                                  */
  625 /************************************************************************/
  626 
  627 void appCloseDocument(  EditDocument *      ed )
  628     {
  629     EditApplication *   ea= ed->edApplication;
  630 
  631     appRemoveDocument( ea, ed );
  632 
  633     /* Is done by the widget destroy callback for GTK: */
  634 #   ifdef USE_MOTIF
  635     if  ( ed->edPrivateData )
  636     {
  637     (*ea->eaFreeDocument)( ed->edPrivateData, ed->edFormat );
  638     ed->edPrivateData= (void *)0;
  639     }
  640 #   endif
  641 
  642     appCleanDocument( ea, ed );
  643     appDestroyShellWidget( ed->edToplevel.atTopWidget );
  644 
  645     /* Is done by the widget destroy callback that is called asynchronuously */
  646 #   if 0
  647     free( ed );
  648 #   endif
  649 
  650     return;
  651     }
  652 
  653 /************************************************************************/
  654 /*                                  */
  655 /*  Destroy callback on a document widget.              */
  656 /*                                  */
  657 /************************************************************************/
  658 
  659 APP_DESTROY_CALLBACK_H( appDestroyEditDocument, w, voided )
  660     {
  661     EditDocument *      ed= (EditDocument *)voided;
  662     EditApplication *       ea= ed->edApplication;
  663 
  664     if  ( ed->edPrivateData )
  665     {
  666     (*ea->eaFreeDocument)( ed->edPrivateData, ed->edFormat );
  667     ed->edPrivateData= (void *)0;
  668     }
  669 
  670     free( ed );
  671 
  672     return;
  673     }
  674 
  675 /************************************************************************/
  676 /*                                  */
  677 /*  Fill the menu of a document window.                 */
  678 /*                                  */
  679 /************************************************************************/
  680 
  681 void appDocFillMenu(    EditDocument *      ed )
  682     {
  683     EditApplication *   ea= ed->edApplication;
  684 
  685     ed->edFileMenu= appMakeMenu( &(ed->edFileMenuButton),
  686             &(ed->edToplevel), ea, ed->edMenuBar,
  687             *(ea->eaDocFileMenuText), 0,
  688             ea->eaDocFileMenuItems, ea->eaDocFileMenuItemCount,
  689             (void *)ed );
  690 
  691     ed->edEditMenu= appMakeMenu( &(ed->edEditMenuButton),
  692             &(ed->edToplevel), ea, ed->edMenuBar,
  693             *(ea->eaDocEditMenuText), 0,
  694             ea->eaDocEditMenuItems, ea->eaDocEditMenuItemCount,
  695             (void *)ed );
  696 
  697     if  ( ea->eaMakePrivateDocumentMenus )
  698     { (*ea->eaMakePrivateDocumentMenus)( ea, ed, ed->edMenuBar ); }
  699 
  700     ed->edWindowMenu= appMakeMenu( &(ed->edWindowMenuButton),
  701             &(ed->edToplevel), ea, ed->edMenuBar,
  702             *(ea->eaDocWindowMenuText), 0,
  703             ea->eaDocWindowMenuItems, ea->eaDocWindowMenuItemCount,
  704             (void *)ed );
  705 
  706     if  ( ea->eaDocHelpMenuItems )
  707     {
  708     ed->edHelpMenu= appMakeMenu( &(ed->edHelpMenuButton),
  709             &(ed->edToplevel), ea, ed->edMenuBar,
  710             *(ea->eaDocHelpMenuText), 1,
  711             ea->eaDocHelpMenuItems, ea->eaDocHelpMenuItemCount,
  712             (void *)ed );
  713     }
  714 
  715     }
  716 
  717 /************************************************************************/
  718 /*                                  */
  719 /*  Open a a document.                          */
  720 /*                                  */
  721 /*  1)  Allocate a document.                        */
  722 /*  3)  Make a shell to contain everything.             */
  723 /*  4)  Make the window pane.                       */
  724 /*                                  */
  725 /************************************************************************/
  726 
  727 EditDocument * appOpenDocumentFile( EditApplication *   ea,
  728                     APP_WIDGET      relative,
  729                     APP_WIDGET      option,
  730                     int         readOnly,
  731                     int         suggestStdin,
  732                     int         formatHint,
  733                     const MemoryBuffer *    filename )
  734     {
  735     EditDocument *      ed;
  736     int             fileReadonly= 0;
  737     AppFileMessageResources *   afmr= &(ea->eaFileMessageResources);
  738 
  739     if  ( readOnly || suggestStdin )
  740     { fileReadonly= 1;  }
  741     else{
  742     if  ( appTestFileReadable( filename ) )
  743         {
  744         int         resp;
  745 
  746         resp= appQuestionRunFilenameOkCancelDialog( ea, relative, option,
  747                         filename, afmr->afmrFileReadOnly );
  748 
  749         if  ( resp != AQDrespOK )
  750         { return (EditDocument *)0; }
  751 
  752         fileReadonly= 1;
  753         }
  754     }
  755 
  756     /*  1,3,4  */
  757     if  ( appMakeDocumentWindow( &ed, ea, readOnly, filename, filename ) )
  758     { LDEB(1); return (EditDocument *)0;    }
  759 
  760     ed->edFileReadOnly= fileReadonly;
  761 
  762     if  ( (*ea->eaOpenDocument)( ea, ed->edPrivateData, &(ed->edFormat),
  763                 relative, option,
  764                 readOnly, suggestStdin, formatHint, filename ) )
  765     { return (EditDocument *)0; }
  766 
  767     if  ( appSetupDocument( ea, ed ) )
  768     { LDEB(1); return (EditDocument *)0; }
  769 
  770     appSetDocument( ea, ed );
  771 
  772     return ed;
  773     }
  774 
  775 EditDocument * appOpenDocument( EditApplication *   ea,
  776                 APP_WIDGET      relative,
  777                 APP_WIDGET      option,
  778                 int         readOnly,
  779                 const MemoryBuffer *    filename )
  780     {
  781     const int   suggestStdin= 0;
  782     int     formatHint= -1;
  783 
  784     formatHint= appDocumentGetOpenFormat( (int *)0,
  785             ea->eaFileExtensions, ea->eaFileExtensionCount,
  786             filename, formatHint );
  787 
  788     return appOpenDocumentFile( ea, relative, option,
  789                 readOnly, suggestStdin, formatHint, filename );
  790     }
  791 
  792 int appNewDocument( EditApplication *   ea,
  793             const MemoryBuffer *    filename )
  794     {
  795     const int           readOnly= 0;
  796     const char *        title= (const char *)0;
  797 
  798     EditDocument *      ed;
  799 
  800     /*  1,3,4  */
  801     if  ( appMakeDocumentWindow( &ed, ea, readOnly, filename, filename ) )
  802     { LDEB(1); return -1;   }
  803 
  804     if  ( (*ea->eaNewDocument)( ed, filename ) )
  805     { SDEB(title); return -1; }
  806 
  807     if  ( appSetupDocument( ea, ed ) )
  808     { SDEB(title); return -1; }
  809 
  810     appSetDocument( ea, ed );
  811 
  812     return 0;
  813     }
  814 
  815 /************************************************************************/
  816 /*                                  */
  817 /*  Redraw a rectangle in the document widget.              */
  818 /*                                  */
  819 /************************************************************************/
  820 
  821 APP_EVENT_HANDLER_H( appDocExposeHandler, w, voided, exposeEvent )
  822     {
  823     EditDocument *      ed= (EditDocument *)voided;
  824     EditApplication *       ea= ed->edApplication;
  825 
  826     int             ox= ed->edVisibleRect.drX0;
  827     int             oy= ed->edVisibleRect.drY0;
  828 
  829     DocumentRectangle       drClip;
  830 
  831     if  ( ed->edNotYetDrawn             &&
  832       ea->eaDocumentFirstVisible            )
  833     { (*ea->eaDocumentFirstVisible)( ed );  }
  834 
  835     ed->edNotYetDrawn= 0;
  836 
  837     /*  1  */
  838     guiCollectExposures( &drClip, ed->edDocumentWidget.dwWidget, exposeEvent );
  839     drawSetClipRect( ed->edDrawingSurface, &drClip );
  840 
  841     geoShiftRectangle( &drClip, ox, oy );
  842 
  843     /*  2,3,4  */
  844     (*ea->eaDrawRectangle)( ed, &drClip, ox, oy );
  845 
  846     drawNoClipping( ed->edDrawingSurface );
  847 
  848     return;
  849     }
  850 
  851 /************************************************************************/
  852 /*                                  */
  853 /*  Cause a rectangle to be redrawn.                    */
  854 /*                                  */
  855 /*  Cause the smallest rectangle that contains the selection to be  */
  856 /*  redrawn.                                */
  857 /*                                  */
  858 /*  drChanged is a rectangle in the document (pixel) coordinate system. */
  859 /*  it is shifted to accomodate for the scrollbars.         */
  860 /*                                  */
  861 /************************************************************************/
  862 
  863 void appDocExposeRectangle( const EditDocument *        ed,
  864                 const DocumentRectangle *   drChanged,
  865                 int             scrolledX,
  866                 int             scrolledY )
  867     {
  868     DocumentRectangle       drExpose;
  869     DocumentRectangle       drScrolled;
  870 
  871     const DocumentRectangle *   drVisible= &(ed->edVisibleRect);
  872 
  873     if  ( ! drChanged )
  874     { guiExposeDrawingWidget( ed->edDocumentWidget.dwWidget ); return; }
  875 
  876     drScrolled= *drChanged;
  877     geoShiftRectangle( &drScrolled, -scrolledX, -scrolledY );
  878 
  879     if  ( scrolledX != 0 )
  880     {
  881     drScrolled.drY0= drVisible->drY0;
  882     drScrolled.drY1= drVisible->drY1;
  883     }
  884 
  885     if  ( scrolledY != 0 )
  886     {
  887     drScrolled.drX0= drVisible->drX0;
  888     drScrolled.drX1= drVisible->drX1;
  889     }
  890 
  891     geoUnionRectangle( &drScrolled, &drScrolled, drChanged );
  892 
  893     drExpose= *drVisible;
  894 
  895     if  ( geoIntersectRectangle( &drExpose, &drExpose, &drScrolled ) )
  896     {
  897     geoShiftRectangle( &drExpose, -drVisible->drX0, -drVisible->drY0 );
  898 
  899     if  ( drExpose.drX0 < 0 )
  900         { drExpose.drX0=  0;    }
  901     if  ( drExpose.drY0 < 0 )
  902         { drExpose.drY0=  0;    }
  903 
  904 #   if LOG_REDRAWS
  905     docLogRectangle( "CLEAR!", &drExpose );
  906 #   endif
  907 
  908     if  ( drExpose.drX1 >= drExpose.drX0 && drExpose.drY1 >= drExpose.drY0 )
  909         {
  910         guiExposeDrawingWidgetRectangle( ed->edDocumentWidget.dwWidget,
  911                                     &drExpose );
  912         }
  913     }
  914     }
  915 
  916 void appInitSelectRectangle(    SelectRectangle *   sr )
  917     {
  918     sr->srDirection= DOCselNONE;
  919 
  920     geoInitRectangle( &(sr->srSelected) );
  921     geoInitRectangle( &(sr->srLTM) );
  922     geoInitRectangle( &(sr->srRBM) );
  923     }
  924 
  925 /************************************************************************/
  926 /*                                  */
  927 /*  Callback from the 'Save As' action of the filechooser.      */
  928 /*                                  */
  929 /************************************************************************/
  930 
  931 int appDocSaveDocument( EditDocument *      ed,
  932             void *          through,
  933             APP_WIDGET      relative,
  934             APP_WIDGET      option,
  935             int         format,
  936             const MemoryBuffer *    filename )
  937     {
  938     EditApplication *   ea= ed->edApplication;
  939     const int       suggestStdout= 0;
  940 
  941     int         canOpen= appFileCanOpen( ea, format );
  942     int         isDocName= canOpen;
  943 
  944     if  ( (*ea->eaSaveDocument)( ea, ed->edDrawingSurface,
  945                 ed->edPrivateData, format, &(ed->edTitle),
  946                 suggestStdout, filename, isDocName ) )
  947     {
  948     appReportSaveFailure( ea, option, relative, filename );
  949     return -1;
  950     }
  951 
  952     if  ( canOpen )
  953     {
  954     appDocumentChanged( ed, 0 );
  955     ed->edFileReadOnly= 0;
  956     ed->edFormat= format;
  957 
  958     if  ( ! utilEqualMemoryBuffer( &(ed->edFilename), filename ) )
  959         {
  960         if  ( appSetDocumentFilename( ed, filename ) )
  961         { LDEB(1);  }
  962         if  ( appSetDocumentTitle( ed, filename ) )
  963         { LDEB(1);  }
  964         }
  965     }
  966 
  967     return 0;
  968     }
  969