Line data Source code
1 : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <sal/types.h>
11 :
12 : #define LOK_USE_UNSTABLE_API
13 : #include <LibreOfficeKit/LibreOfficeKit.h>
14 :
15 : #include <LibreOfficeKit/LibreOfficeKitGtk.h>
16 :
17 : static void lok_docview_class_init( LOKDocViewClass* pClass );
18 : static void lok_docview_init( LOKDocView* pDocView );
19 :
20 : // We specifically need to destroy the document when closing in order to ensure
21 : // that lock files etc. are cleaned up.
22 0 : void lcl_onDestroy( LOKDocView* pDocView, gpointer pData )
23 : {
24 : (void) pData;
25 0 : if ( pDocView->pDocument )
26 0 : pDocView->pDocument->pClass->destroy( pDocView->pDocument );
27 0 : pDocView->pDocument = NULL;
28 0 : }
29 :
30 0 : SAL_DLLPUBLIC_EXPORT guint lok_docview_get_type()
31 : {
32 : static guint lok_docview_type = 0;
33 :
34 0 : if (!lok_docview_type)
35 : {
36 0 : GtkTypeInfo lok_docview_info =
37 : {
38 : "LokDocView",
39 : sizeof( LOKDocView ),
40 : sizeof( LOKDocViewClass ),
41 : (GtkClassInitFunc) lok_docview_class_init,
42 : (GtkObjectInitFunc) lok_docview_init,
43 : NULL,
44 : NULL,
45 : (GtkClassInitFunc) NULL
46 : };
47 :
48 0 : lok_docview_type = gtk_type_unique( gtk_scrolled_window_get_type(), &lok_docview_info );
49 : }
50 0 : return lok_docview_type;
51 : }
52 :
53 0 : static void lok_docview_class_init( LOKDocViewClass* pClass )
54 : {
55 0 : pClass->lok_docview = NULL;
56 0 : }
57 :
58 0 : static void lok_docview_init( LOKDocView* pDocView )
59 : {
60 : // Gtk ScrolledWindow is apparently not fully initialised yet, we specifically
61 : // have to set the [hv]adjustment to prevent GTK assertions from firing, see
62 : // https://bugzilla.gnome.org/show_bug.cgi?id=438114 for more info.
63 0 : gtk_scrolled_window_set_hadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL );
64 0 : gtk_scrolled_window_set_vadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL );
65 :
66 0 : pDocView->pEventBox = gtk_event_box_new();
67 0 : gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView),
68 : pDocView->pEventBox );
69 :
70 0 : pDocView->pCanvas = gtk_image_new();
71 0 : gtk_container_add( GTK_CONTAINER( pDocView->pEventBox ), pDocView->pCanvas );
72 :
73 0 : gtk_widget_show( pDocView->pCanvas );
74 0 : gtk_widget_show( pDocView->pEventBox );
75 :
76 0 : pDocView->pPixBuf = 0;
77 :
78 : // TODO: figure out a clever view of getting paths set up.
79 0 : pDocView->pOffice = 0;
80 0 : pDocView->pDocument = 0;
81 :
82 0 : pDocView->fZoom = 1;
83 :
84 0 : gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
85 : GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
86 0 : }
87 :
88 0 : SAL_DLLPUBLIC_EXPORT GtkWidget* lok_docview_new( LibreOfficeKit* pOffice )
89 : {
90 0 : LOKDocView* pDocView = gtk_type_new( lok_docview_get_type() );
91 0 : pDocView->pOffice = pOffice;
92 0 : return GTK_WIDGET( pDocView );
93 : }
94 :
95 0 : void renderDocument( LOKDocView* pDocView )
96 : {
97 : long nWidth, nHeight;
98 : int nRenderWidth, nRenderHeight;
99 : unsigned char* pBuffer;
100 : int nRowStride;
101 : // TODO: we really should scale by screen DPI here -- 10 seems to be a vaguely
102 : // correct factor for my screen at least.
103 0 : const float fScaleFactor = 0.1;
104 :
105 : // Various things blow up if we try to draw too large a tile,
106 : // this size seems to be safe. (Very rare/unlikely that
107 0 : const int nMaxWidth = 100000;
108 :
109 0 : g_assert( pDocView->pDocument );
110 :
111 0 : if ( pDocView->pPixBuf )
112 : {
113 0 : g_object_unref( G_OBJECT( pDocView->pPixBuf ) );
114 : }
115 :
116 0 : pDocView->pDocument->pClass->getDocumentSize( pDocView->pDocument, &nWidth, &nHeight );
117 :
118 0 : if ( nWidth * fScaleFactor > nMaxWidth )
119 : {
120 0 : nWidth = nMaxWidth;
121 : }
122 0 : if ( nHeight * fScaleFactor > nMaxWidth )
123 : {
124 0 : nHeight = nMaxWidth;
125 : }
126 :
127 : // Draw the whole document at once (for now)
128 :
129 0 : nRenderWidth = nWidth * pDocView->fZoom * fScaleFactor;
130 0 : nRenderHeight = nHeight * pDocView->fZoom * fScaleFactor;
131 :
132 0 : pDocView->pPixBuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
133 : TRUE, 8,
134 : nRenderWidth, nRenderHeight);
135 :
136 :
137 0 : pBuffer = gdk_pixbuf_get_pixels( pDocView->pPixBuf );
138 0 : pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
139 : pBuffer,
140 : nRenderWidth, nRenderHeight,
141 : &nRowStride,
142 : 0, 0, // origin
143 : nWidth, nHeight );
144 : // TODO: double check that the rowstride really matches what we expected,
145 : // although presumably we'd already be crashing by now if things were
146 : // wrong.
147 : (void) nRowStride;
148 :
149 0 : gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas ), pDocView->pPixBuf );
150 0 : }
151 :
152 0 : SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, char* pPath )
153 : {
154 0 : if ( pDocView->pDocument )
155 : {
156 0 : pDocView->pDocument->pClass->destroy( pDocView->pDocument );
157 0 : pDocView->pDocument = NULL;
158 : }
159 :
160 0 : pDocView->pDocument = pDocView->pOffice->pClass->documentLoad( pDocView->pOffice,
161 : pPath );
162 0 : if ( !pDocView->pDocument )
163 : {
164 : // FIXME: should have a GError parameter and populate it.
165 0 : char *pError = pDocView->pOffice->pClass->getError( pDocView->pOffice );
166 0 : fprintf( stderr, "Error opening document '%s'\n", pError );
167 0 : return FALSE;
168 : }
169 : else
170 0 : renderDocument( pDocView );
171 :
172 0 : return TRUE;
173 : }
174 :
175 0 : SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZoom )
176 : {
177 0 : pDocView->fZoom = fZoom;
178 :
179 0 : if ( pDocView->pDocument )
180 : {
181 0 : renderDocument( pDocView );
182 : }
183 : // TODO: maybe remember and reset positiong?
184 0 : }
185 :
186 0 : SAL_DLLPUBLIC_EXPORT float lok_docview_get_zoom ( LOKDocView* pDocView )
187 : {
188 0 : return pDocView->fZoom;
189 : }
190 :
191 0 : SAL_DLLPUBLIC_EXPORT int lok_docview_get_parts( LOKDocView* pDocView )
192 : {
193 0 : return pDocView->pDocument->pClass->getParts( pDocView->pDocument );
194 : }
195 :
196 0 : SAL_DLLPUBLIC_EXPORT int lok_docview_get_part( LOKDocView* pDocView )
197 : {
198 0 : return pDocView->pDocument->pClass->getPart( pDocView->pDocument );
199 : }
200 :
201 0 : SAL_DLLPUBLIC_EXPORT void lok_docview_set_part( LOKDocView* pDocView, int nPart)
202 : {
203 0 : pDocView->pDocument->pClass->setPart( pDocView->pDocument, nPart );
204 0 : renderDocument( pDocView );
205 0 : }
206 :
207 0 : SAL_DLLPUBLIC_EXPORT char* lok_docview_get_part_name( LOKDocView* pDocView, int nPart )
208 : {
209 0 : return pDocView->pDocument->pClass->getPartName( pDocView->pDocument, nPart );
210 : }
211 :
212 0 : SAL_DLLPUBLIC_EXPORT void lok_docview_set_partmode( LOKDocView* pDocView,
213 : LibreOfficeKitPartMode ePartMode )
214 : {
215 0 : pDocView->pDocument->pClass->setPartMode( pDocView->pDocument, ePartMode );
216 0 : renderDocument( pDocView );
217 0 : }
218 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|