2 #ifdef ENABLE_QUICKSTART_APPLET
4 #include <svtools/moduleoptions.hxx>
6 #include <svtools/dynamicmenuoptions.hxx>
10 #include <eggtray/eggtrayicon.h>
11 #include <vos/mutex.hxx>
12 #include <vcl/bitmapex.hxx>
13 #include <vcl/bmpacc.hxx>
14 #include <sfx2/app.hxx>
18 #ifndef __SHUTDOWNICON_HXX__
19 #define USE_APP_SHORTCUTS
20 #include "shutdownicon.hxx"
23 // Cut/paste from vcl/inc/svids.hrc
24 #define SV_ICON_SMALL_START 25000
26 #define SV_ICON_ID_OFFICE 1
27 #define SV_ICON_ID_TEXT 2
28 #define SV_ICON_ID_SPREADSHEET 4
29 #define SV_ICON_ID_DRAWING 6
30 #define SV_ICON_ID_PRESENTATION 8
31 #define SV_ICON_ID_DATABASE 14
32 #define SV_ICON_ID_FORMULA 15
33 #define SV_ICON_ID_TEMPLATE 16
35 using namespace ::rtl
;
36 using namespace ::osl
;
38 static ResMgr
*pVCLResMgr
;
39 static EggTrayIcon
*pTrayIcon
;
40 static GtkWidget
*pExitMenuItem
= NULL
;
41 static GtkWidget
*pOpenMenuItem
= NULL
;
43 static void open_url_cb( GtkWidget
*, gpointer data
)
45 ShutdownIcon::OpenURL( *(OUString
*)data
,
46 OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
49 static void open_file_cb( GtkWidget
* )
51 if ( !ShutdownIcon::bModalMode
)
52 ShutdownIcon::FileOpen();
55 static void open_template_cb( GtkWidget
* )
57 if ( !ShutdownIcon::bModalMode
)
58 ShutdownIcon::FromTemplate();
61 static void systray_disable_cb()
63 ShutdownIcon::SetAutostart( false );
64 ShutdownIcon::terminateDesktop();
67 static void exit_quickstarter_cb( GtkWidget
* )
69 egg_tray_icon_cancel_message (pTrayIcon
, 1 );
70 ShutdownIcon::getInstance()->terminateDesktop();
71 plugin_shutdown_sys_tray();
74 static void menu_deactivate_cb( GtkWidget
*pMenu
)
76 gtk_menu_popdown( GTK_MENU( pMenu
) );
79 static GdkPixbuf
* ResIdToPixbuf( USHORT nResId
)
81 ResId
aResId( SV_ICON_SMALL_START
+ nResId
, *pVCLResMgr
);
82 BitmapEx
aIcon( aResId
);
83 Bitmap pInSalBitmap
= aIcon
.GetBitmap();
84 AlphaMask pInSalAlpha
= aIcon
.GetAlpha();
86 BitmapReadAccess
* pSalBitmap
= pInSalBitmap
.AcquireReadAccess();
87 BitmapReadAccess
* pSalAlpha
= pInSalAlpha
.AcquireReadAccess();
89 g_return_val_if_fail( pSalBitmap
!= NULL
, NULL
);
91 Size
aSize( pSalBitmap
->Width(), pSalBitmap
->Height() );
92 g_return_val_if_fail( Size( pSalAlpha
->Width(), pSalAlpha
->Height() ) == aSize
, NULL
);
95 guchar
*pPixbufData
= ( guchar
* )g_malloc( 4 * aSize
.Width() * aSize
.Height() );
96 guchar
*pDestData
= pPixbufData
;
98 for( nY
= 0; nY
< pSalBitmap
->Height(); nY
++ )
100 for( nX
= 0; nX
< pSalBitmap
->Width(); nX
++ )
103 aPix
= pSalBitmap
->GetPixel( nY
, nX
);
104 pDestData
[0] = aPix
.GetRed();
105 pDestData
[1] = aPix
.GetGreen();
106 pDestData
[2] = aPix
.GetBlue();
109 aPix
= pSalAlpha
->GetPixel( nY
, nX
);
110 pDestData
[3] = 255 - aPix
.GetIndex();
118 pInSalBitmap
.ReleaseAccess( pSalBitmap
);
120 pInSalAlpha
.ReleaseAccess( pSalAlpha
);
122 return gdk_pixbuf_new_from_data( pPixbufData
,
123 GDK_COLORSPACE_RGB
, TRUE
, 8,
124 aSize
.Width(), aSize
.Height(),
126 (GdkPixbufDestroyNotify
) g_free
,
131 static void oustring_delete (gpointer data
,
132 GClosure
* /* closure */)
134 OUString
*pURL
= (OUString
*) data
;
139 static void add_item( GtkMenuShell
*pMenuShell
, const char *pAsciiURL
,
140 OUString
*pOverrideLabel
,
141 USHORT nResId
, GCallback pFnCallback
)
143 OUString
*pURL
= new OUString (OStringToOUString( pAsciiURL
,
144 RTL_TEXTENCODING_UTF8
));
147 aLabel
= OUStringToOString (*pOverrideLabel
, RTL_TEXTENCODING_UTF8
);
150 ShutdownIcon
*pShutdownIcon
= ShutdownIcon::getInstance();
151 aLabel
= OUStringToOString (pShutdownIcon
->GetUrlDescription( *pURL
),
152 RTL_TEXTENCODING_UTF8
);
155 GdkPixbuf
*pPixbuf
= ResIdToPixbuf( nResId
);
156 GtkWidget
*pImage
= gtk_image_new_from_pixbuf( pPixbuf
);
157 g_object_unref( G_OBJECT( pPixbuf
) );
159 GtkWidget
*pMenuItem
= gtk_image_menu_item_new_with_label( aLabel
);
160 gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem
), pImage
);
161 g_signal_connect_data( pMenuItem
, "activate", pFnCallback
, pURL
,
162 oustring_delete
, GConnectFlags(0));
164 gtk_menu_shell_append( pMenuShell
, pMenuItem
);
167 // Unbelievably nasty
168 using namespace ::com::sun::star::uno
;
169 using namespace ::com::sun::star::task
;
170 using namespace ::com::sun::star::lang
;
171 using namespace ::com::sun::star::beans
;
173 static void add_ugly_db_item( GtkMenuShell
*pMenuShell
, const char *pAsciiURL
,
174 USHORT nResId
, GCallback pFnCallback
)
176 SvtDynamicMenuOptions aOpt
;
177 Sequence
< Sequence
< PropertyValue
> > aMenu
= aOpt
.GetMenu( E_NEWMENU
);
178 for ( sal_Int32 n
=0; n
<aMenu
.getLength(); n
++ )
180 ::rtl::OUString aURL
;
181 ::rtl::OUString aDescription
;
182 Sequence
< PropertyValue
>& aEntry
= aMenu
[n
];
183 for ( sal_Int32 m
=0; m
<aEntry
.getLength(); m
++ )
185 if ( aEntry
[m
].Name
.equalsAsciiL( "URL", 3 ) )
186 aEntry
[m
].Value
>>= aURL
;
187 if ( aEntry
[m
].Name
.equalsAsciiL( "Title", 5 ) )
188 aEntry
[m
].Value
>>= aDescription
;
191 if ( aURL
.equalsAscii( BASE_URL
) && aDescription
.getLength() )
193 add_item (pMenuShell
, pAsciiURL
, &aDescription
, nResId
, pFnCallback
);
200 add_image_menu_item( GtkMenuShell
*pMenuShell
,
201 const gchar
*stock_id
,
202 rtl::OUString aLabel
,
203 GCallback activate_cb
)
205 OString aUtfLabel
= rtl::OUStringToOString (aLabel
, RTL_TEXTENCODING_UTF8
);
208 pImage
= gtk_image_new_from_stock( stock_id
, GTK_ICON_SIZE_MENU
);
210 GtkWidget
*pMenuItem
;
211 pMenuItem
= gtk_image_menu_item_new_with_label( aUtfLabel
);
212 gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem
), pImage
);
214 gtk_menu_shell_append( pMenuShell
, pMenuItem
);
215 g_signal_connect( pMenuItem
, "activate", activate_cb
, NULL
);
220 static void populate_menu( GtkWidget
*pMenu
)
222 ShutdownIcon
*pShutdownIcon
= ShutdownIcon::getInstance();
223 GtkMenuShell
*pMenuShell
= GTK_MENU_SHELL( pMenu
);
224 SvtModuleOptions aModuleOptions
;
226 if ( aModuleOptions
.IsWriter() )
227 add_item (pMenuShell
, WRITER_URL
, NULL
,
228 SV_ICON_ID_TEXT
, G_CALLBACK( open_url_cb
));
230 if ( aModuleOptions
.IsCalc() )
231 add_item (pMenuShell
, CALC_URL
, NULL
,
232 SV_ICON_ID_SPREADSHEET
, G_CALLBACK( open_url_cb
));
234 if ( aModuleOptions
.IsImpress() )
235 add_item (pMenuShell
, IMPRESS_URL
, NULL
,
236 SV_ICON_ID_PRESENTATION
, G_CALLBACK( open_url_cb
));
238 if ( aModuleOptions
.IsDraw() )
239 add_item (pMenuShell
, DRAW_URL
, NULL
,
240 SV_ICON_ID_DRAWING
, G_CALLBACK( open_url_cb
));
242 if ( aModuleOptions
.IsDataBase() )
243 add_ugly_db_item (pMenuShell
, BASE_URL
,
244 SV_ICON_ID_DATABASE
, G_CALLBACK( open_url_cb
));
246 if ( aModuleOptions
.IsMath() )
247 add_item (pMenuShell
, MATH_URL
, NULL
,
248 SV_ICON_ID_FORMULA
, G_CALLBACK( open_url_cb
));
250 OUString aULabel
= pShutdownIcon
->GetResString( STR_QUICKSTART_FROMTEMPLATE
);
251 add_item (pMenuShell
, "dummy", &aULabel
,
252 SV_ICON_ID_TEMPLATE
, G_CALLBACK( open_template_cb
));
255 GtkWidget
*pMenuItem
;
257 pMenuItem
= gtk_separator_menu_item_new();
258 gtk_menu_shell_append( pMenuShell
, pMenuItem
);
260 pOpenMenuItem
= add_image_menu_item
261 (pMenuShell
, GTK_STOCK_OPEN
,
262 pShutdownIcon
->GetResString( STR_QUICKSTART_FILEOPEN
),
263 G_CALLBACK( open_file_cb
));
265 pMenuItem
= gtk_separator_menu_item_new();
266 gtk_menu_shell_append( pMenuShell
, pMenuItem
);
268 (void) add_image_menu_item
269 ( pMenuShell
, GTK_STOCK_CLOSE
,
270 pShutdownIcon
->GetResString( STR_QUICKSTART_PRELAUNCH_UNX
),
271 G_CALLBACK( systray_disable_cb
) );
273 pMenuItem
= gtk_separator_menu_item_new();
274 gtk_menu_shell_append( pMenuShell
, pMenuItem
);
276 pExitMenuItem
= add_image_menu_item
277 ( pMenuShell
, GTK_STOCK_QUIT
,
278 pShutdownIcon
->GetResString( STR_QUICKSTART_EXIT
),
279 G_CALLBACK( exit_quickstarter_cb
) );
281 gtk_widget_show_all( pMenu
);
284 static void refresh_menu( GtkWidget
*pMenu
)
287 populate_menu( pMenu
);
289 bool bModal
= ShutdownIcon::bModalMode
;
290 gtk_widget_set_sensitive( pExitMenuItem
, !bModal
);
291 gtk_widget_set_sensitive( pOpenMenuItem
, !bModal
);
296 layout_menu( GtkMenu
*menu
,
297 gint
*x
, gint
*y
, gboolean
*push_in
,
301 GtkWidget
*ebox
= GTK_BIN( pTrayIcon
)->child
;
303 gtk_widget_size_request( GTK_WIDGET( menu
), &req
);
304 gdk_window_get_origin( ebox
->window
, x
, y
);
306 (*x
) += ebox
->allocation
.x
;
307 (*y
) += ebox
->allocation
.y
;
309 if (*y
>= gdk_screen_get_height (gtk_widget_get_screen (ebox
)) / 2)
312 (*y
) += ebox
->allocation
.height
;
318 static gboolean
display_menu_cb( GtkWidget
*,
319 GdkEventButton
*event
, GtkWidget
*pMenu
)
321 if (event
->button
== 2)
324 #ifdef TEMPLATE_DIALOG_MORE_POLISHED
325 if (event
->button
== 1 &&
326 event
->type
== GDK_2BUTTON_PRESS
)
328 open_template_cb( NULL
);
331 if (event
->button
== 3)
336 refresh_menu( pMenu
);
338 gtk_menu_popup( GTK_MENU( pMenu
), NULL
, NULL
,
339 layout_menu
, NULL
, 0, event
->time
);
346 show_at_idle( gpointer
)
348 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
349 gtk_widget_show_all( GTK_WIDGET( pTrayIcon
) );
354 void SAL_DLLPUBLIC_EXPORT
plugin_init_sys_tray()
356 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
358 if( !g_type_from_name( "GdkDisplay" ) )
362 ShutdownIcon
*pShutdownIcon
= ShutdownIcon::getInstance();
364 aLabel
= rtl::OUStringToOString (
365 pShutdownIcon
->GetResString( STR_QUICKSTART_TIP
),
366 RTL_TEXTENCODING_UTF8
);
368 pTrayIcon
= egg_tray_icon_new( aLabel
);
370 GtkWidget
*pParent
= gtk_event_box_new();
371 GtkTooltips
*pTooltips
= gtk_tooltips_new();
372 gtk_tooltips_set_tip( GTK_TOOLTIPS( pTooltips
), pParent
, aLabel
, NULL
);
374 GtkWidget
*pIconImage
= gtk_image_new();
375 gtk_container_add( GTK_CONTAINER( pParent
), pIconImage
);
377 pVCLResMgr
= CREATEVERSIONRESMGR( vcl
);
379 GdkPixbuf
*pPixbuf
= ResIdToPixbuf( SV_ICON_ID_OFFICE
);
380 gtk_image_set_from_pixbuf( GTK_IMAGE( pIconImage
), pPixbuf
);
381 g_object_unref( pPixbuf
);
383 GtkWidget
*pMenu
= gtk_menu_new();
384 g_signal_connect (pMenu
, "deactivate",
385 G_CALLBACK (menu_deactivate_cb
), NULL
);
386 g_signal_connect( pParent
, "button_press_event",
387 G_CALLBACK( display_menu_cb
), pMenu
);
388 gtk_container_add( GTK_CONTAINER( pTrayIcon
), pParent
);
390 // Show at idle to avoid artefacts at startup
391 g_idle_add (show_at_idle
, (gpointer
) pTrayIcon
);
394 pShutdownIcon
->SetVeto( true );
395 pShutdownIcon
->addTerminateListener();
398 void SAL_DLLPUBLIC_EXPORT
plugin_shutdown_sys_tray()
400 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
403 gtk_widget_destroy( GTK_WIDGET( pTrayIcon
) );
405 pExitMenuItem
= NULL
;
406 pOpenMenuItem
= NULL
;
409 #endif // ENABLE_QUICKSTART_APPLET