LCOV - code coverage report
Current view: top level - gui/source - gui_file_export_dialog.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 0 136 0.0 %
Date: 2024-10-26 21:44:38 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /* File: gui_file_export_dialog.c; Copyright and License: see below */
       2             : 
       3             : #include "gui_file_export_dialog.h"
       4             : #include "set/data_stat.h"
       5             : #include "u8/u8_trace.h"
       6             : #include "utf8stringbuf/utf8string.h"
       7             : #include "utf8stringbuf/utf8stringbuf.h"
       8             : #include <gdk/gdk.h>
       9             : #include <gtk/gtk.h>
      10             : #include <stdio.h>
      11             : #include <stdbool.h>
      12             : 
      13           0 : void gui_file_export_dialog_init ( gui_file_export_dialog_t *this_,
      14             :                                    data_database_t *database,
      15             :                                    data_database_reader_t *db_reader,
      16             :                                    GtkWindow *parent_window,
      17             :                                    gui_simple_message_to_user_t *message_to_user )
      18             : {
      19           0 :     U8_TRACE_BEGIN();
      20           0 :     assert( NULL != database );
      21           0 :     assert( NULL != db_reader );
      22           0 :     assert( NULL != parent_window );
      23           0 :     assert( NULL != message_to_user );
      24             : 
      25           0 :     (*this_).database = database;
      26           0 :     (*this_).parent_window = parent_window;
      27           0 :     (*this_).message_to_user = message_to_user;
      28             : 
      29           0 :     (*this_).format_docbook = gtk_check_button_new_with_label ("docbook");
      30           0 :     (*this_).format_html = gtk_check_button_new_with_label ("html");
      31           0 :     (*this_).format_xmi2 = gtk_check_button_new_with_label ("xmi");
      32           0 :     (*this_).format_json= gtk_check_button_new_with_label ("json");
      33             : 
      34           0 :     (*this_).format_pdf = gtk_check_button_new_with_label ("pdf");
      35           0 :     (*this_).format_png = gtk_check_button_new_with_label ("png");
      36           0 :     (*this_).format_ps = gtk_check_button_new_with_label ("ps");
      37           0 :     (*this_).format_svg = gtk_check_button_new_with_label ("svg");
      38           0 :     (*this_).format_txt = gtk_check_button_new_with_label ("txt");
      39             : 
      40           0 :     gtk_check_button_set_active( GTK_CHECK_BUTTON((*this_).format_html), TRUE );
      41             : 
      42           0 :     (*this_).options_layout = gtk_grid_new();
      43             : 
      44           0 :     (*this_).diagram_set_label = gtk_label_new ( "Diagram-sets:" );
      45           0 :     (*this_).document_label = gtk_label_new ( "Documents:" );
      46           0 :     gtk_label_set_xalign (GTK_LABEL( (*this_).document_label ), 0.0 );
      47           0 :     gtk_label_set_xalign (GTK_LABEL( (*this_).diagram_set_label ), 0.0 );
      48           0 :     (*this_).export_button = GTK_BUTTON( gtk_button_new() );
      49           0 :     gtk_button_set_label( (*this_).export_button, "Export to folder..." );
      50           0 :     gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).export_button ), false );
      51           0 :     gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).export_button ), false );
      52             : 
      53             :     /* parameter info: gtk_grid_attach (GtkGrid *grid, GtkWidget *child, gint left, gint top, gint width, gint height); */
      54           0 :     gtk_grid_set_column_homogeneous ( GTK_GRID((*this_).options_layout), false );
      55           0 :     gtk_grid_set_row_homogeneous ( GTK_GRID((*this_).options_layout), false );
      56           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).diagram_set_label, 0, 0, 2, 1 );
      57           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).document_label, 0, 1, 2, 1 );
      58             : 
      59           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_docbook, 2, 1, 2, 1 );
      60           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_html, 4, 1, 1, 1 );
      61           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_json, 5, 1, 1, 1 );
      62           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_xmi2, 6, 1, 2, 1 );
      63             : 
      64           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_pdf, 2, 0, 1, 1 );
      65           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_png, 3, 0, 1, 1 );
      66           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_ps, 4, 0, 1, 1 );
      67           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_svg, 5, 0, 1, 1 );
      68           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), (*this_).format_txt, 6, 0, 1, 1 );
      69             : 
      70           0 :     gtk_grid_attach( GTK_GRID((*this_).options_layout), GTK_WIDGET( (*this_).export_button ), 8, 0, 1, 2 );
      71             : 
      72           0 :     gtk_widget_set_visible( (*this_).options_layout, FALSE );
      73             : 
      74             : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
      75           0 :     (*this_).export_file_chooser = gtk_file_chooser_dialog_new ( "Select Export Folder",
      76             :                                                                  parent_window,
      77             :                                                                  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
      78             :                                                                  "Cancel",
      79             :                                                                  GTK_RESPONSE_CANCEL,
      80             :                                                                  "Export Files",
      81             :                                                                  GTK_RESPONSE_ACCEPT,
      82             :                                                                  NULL
      83             :                                                                );
      84             : 
      85             : #if 0
      86             :     GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG((*this_).export_file_chooser));
      87             :     gtk_box_append( GTK_BOX(content_area), GTK_WIDGET( (*this_).options_layout ) );
      88             :     /* no need to g_object_unref( content_area ); here */
      89             : #endif
      90             : #else
      91             :     (*this_).export_file_dialog = gtk_file_dialog_new();
      92             :     gtk_file_dialog_set_accept_label( (*this_).export_file_dialog, "Export Files" );
      93             :     gtk_file_dialog_set_modal( (*this_).export_file_dialog, false );
      94             :     gtk_file_dialog_set_title( (*this_).export_file_dialog, "Select Export Folder" );
      95             : #endif
      96             : 
      97           0 :     io_exporter_init( &((*this_).file_exporter), db_reader );
      98             : 
      99             : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
     100           0 :     g_signal_connect( G_OBJECT((*this_).export_file_chooser),
     101             :                       "response",
     102             :                       G_CALLBACK(gui_file_export_dialog_response_callback),
     103             :                       this_
     104             :                     );
     105           0 :     gtk_window_set_hide_on_close( GTK_WINDOW((*this_).export_file_chooser), true);
     106             : #else
     107             :     /* no signal at new FileDialog - this works with Async, see gtk_file_dialog_save */
     108             : #endif
     109           0 :     g_signal_connect( G_OBJECT((*this_).export_button), "clicked", G_CALLBACK( gui_file_export_dialog_export_btn_callback ), this_ );
     110             : 
     111           0 :     U8_TRACE_END();
     112           0 : }
     113             : 
     114           0 : void gui_file_export_dialog_destroy( gui_file_export_dialog_t *this_ )
     115             : {
     116           0 :     U8_TRACE_BEGIN();
     117             : 
     118             :     /* no need to g_object_unref ( (*this_).format_html ); here */
     119             : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
     120           0 :     gtk_window_destroy( GTK_WINDOW((*this_).export_file_chooser) );
     121             :     /* no need to g_object_unref ( (*this_).export_file_chooser ); here */
     122             : #else
     123             :     g_object_unref( (*this_).export_file_dialog );
     124             : #endif
     125             : 
     126           0 :     io_exporter_destroy( &((*this_).file_exporter) );
     127             : 
     128           0 :     (*this_).message_to_user = NULL;
     129           0 :     (*this_).parent_window = NULL;
     130           0 :     (*this_).database = NULL;
     131             : 
     132           0 :     U8_TRACE_END();
     133           0 : }
     134             : 
     135           0 : GtkWidget *gui_file_export_dialog_get_options( gui_file_export_dialog_t *this_ )
     136             : {
     137           0 :     return GTK_WIDGET( (*this_).options_layout );
     138             : }
     139             : 
     140           0 : void gui_file_export_dialog_export_btn_callback( GtkWidget* button, gpointer data )
     141             : {
     142           0 :     U8_TRACE_BEGIN();
     143           0 :     gui_file_export_dialog_t *this_ = data;
     144             : 
     145           0 :     gui_simple_message_to_user_hide( (*this_).message_to_user );
     146             : 
     147           0 :     gui_file_export_dialog_show ( this_ );
     148             : 
     149           0 :     U8_TRACE_TIMESTAMP();
     150           0 :     U8_TRACE_END();
     151           0 : }
     152             : 
     153           0 : void gui_file_export_dialog_show( gui_file_export_dialog_t *this_ )
     154             : {
     155           0 :     U8_TRACE_BEGIN();
     156             : 
     157             : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
     158           0 :     gtk_widget_set_visible( GTK_WIDGET( (*this_).export_file_chooser ), TRUE );
     159           0 :     gtk_widget_set_sensitive( GTK_WIDGET((*this_).export_file_chooser), TRUE );  /* idea taken from gtk demo */
     160             : 
     161           0 :     GdkSurface *surface = gtk_native_get_surface( GTK_NATIVE((*this_).export_file_chooser) );
     162           0 :     gdk_surface_set_cursor( surface, NULL );  /* idea taken from gtk3->4 guide */
     163             : #else
     164             :     gtk_file_dialog_select_folder( (*this_).export_file_dialog,
     165             :                                    (*this_).parent_window,
     166             :                                    NULL,
     167             :                                    &gui_file_export_dialog_async_ready_callback,
     168             :                                    this_
     169             :                                  );
     170             : #endif
     171             : 
     172           0 :     U8_TRACE_END();
     173           0 : }
     174             : 
     175             : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
     176             : 
     177           0 : void gui_file_export_dialog_response_callback( GtkDialog *dialog, gint response_id, gpointer user_data )
     178             : {
     179           0 :     U8_TRACE_BEGIN();
     180           0 :     gui_file_export_dialog_t *this_ = user_data;
     181             : 
     182           0 :     gtk_widget_set_visible( (*this_).options_layout, FALSE );
     183             : 
     184           0 :     switch ( response_id )
     185             :     {
     186           0 :         case GTK_RESPONSE_CANCEL:
     187             :         {
     188           0 :             U8_LOG_EVENT( "GTK_RESPONSE_CANCEL" );
     189           0 :             gtk_widget_set_visible( GTK_WIDGET ( dialog ), FALSE );
     190             :         }
     191           0 :         break;
     192             : 
     193           0 :         case GTK_RESPONSE_ACCEPT:
     194             :         {
     195           0 :             U8_LOG_EVENT( "GTK_RESPONSE_ACCEPT" );
     196           0 :             u8_error_t export_err = U8_ERROR_NONE;
     197             :             data_stat_t export_stat;
     198           0 :             data_stat_init ( &export_stat );
     199           0 :             io_file_format_t selected_format = IO_FILE_FORMAT_NONE;
     200             : 
     201           0 :             gchar *folder_path = NULL;
     202           0 :             GFile *selected_file = NULL;
     203           0 :             selected_file = gtk_file_chooser_get_file( GTK_FILE_CHOOSER(dialog) );
     204           0 :             if ( selected_file != NULL )
     205             :             {
     206           0 :                 folder_path = g_file_get_path( selected_file );
     207             :             }
     208           0 :             gtk_widget_set_visible( GTK_WIDGET ( dialog ), FALSE );
     209           0 :             if ( folder_path != NULL )
     210             :             {
     211           0 :                 U8_TRACE_INFO_STR( "chosen folder:", folder_path );
     212             : 
     213           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_pdf) )) { selected_format |= IO_FILE_FORMAT_PDF; }
     214           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_png) )) { selected_format |= IO_FILE_FORMAT_PNG; }
     215           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_ps) )) { selected_format |= IO_FILE_FORMAT_PS; }
     216           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_svg) )) { selected_format |= IO_FILE_FORMAT_SVG; }
     217           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_txt) )) { selected_format |= IO_FILE_FORMAT_TXT; }
     218           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_docbook) )) { selected_format |= IO_FILE_FORMAT_DOCBOOK; }
     219           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_html) )) { selected_format |= IO_FILE_FORMAT_HTML; }
     220           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_xmi2) )) { selected_format |= IO_FILE_FORMAT_XMI2; }
     221           0 :                 if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_json) )) { selected_format |= IO_FILE_FORMAT_JSON; }
     222             : 
     223             :                 /* react immediately */
     224           0 :                 gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
     225             :                                                                    GUI_SIMPLE_MESSAGE_TYPE_INFO,
     226             :                                                                    GUI_SIMPLE_MESSAGE_CONTENT_EXPORTING_WAIT,
     227             :                                                                    folder_path
     228             :                                                                  );
     229           0 :                 bool events_handled = true;
     230           0 :                 for ( uint_fast8_t max_loop = 40; events_handled && ( max_loop > 0 ); max_loop-- )
     231             :                 {
     232           0 :                     events_handled = g_main_context_iteration( NULL, /*may_block*/ FALSE );
     233             :                 }
     234             : 
     235             :                 /* determine the database file path for a document title and export: */
     236           0 :                 const char *db_path = data_database_get_filename_ptr( (*this_).database );
     237           0 :                 if ( data_database_is_open((*this_).database) )
     238             :                 {
     239           0 :                     export_err = io_exporter_export_files( &((*this_).file_exporter), selected_format, folder_path, db_path, &export_stat );
     240             :                 }
     241             :                 else
     242             :                 {
     243           0 :                     export_err = U8_ERROR_NO_DB;
     244             :                 }
     245             : 
     246             :                 /* finished, notify user */
     247             :                 char temp_format_buf[64];
     248           0 :                 utf8stringbuf_t temp_fileformat = UTF8STRINGBUF( temp_format_buf );
     249           0 :                 io_file_format_to_string( selected_format, temp_fileformat );
     250             : 
     251           0 :                 if ( U8_ERROR_NONE == export_err )
     252             :                 {
     253           0 :                     gui_simple_message_to_user_show_message_with_names_and_stat( (*this_).message_to_user,
     254             :                                                                                  GUI_SIMPLE_MESSAGE_TYPE_INFO,
     255             :                                                                                  GUI_SIMPLE_MESSAGE_CONTENT_EXPORT_FINISHED,
     256           0 :                                                                                  utf8stringbuf_get_string( temp_fileformat ),
     257             :                                                                                  &export_stat
     258             :                                                                                );
     259             : 
     260             :                 }
     261             :                 else
     262             :                 {
     263           0 :                     gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
     264             :                                                                        GUI_SIMPLE_MESSAGE_TYPE_ERROR,
     265             :                                                                        GUI_SIMPLE_MESSAGE_CONTENT_FILE_EXPORT_FAILED,
     266             :                                                                        folder_path
     267             :                                                                      );
     268             :                 }
     269             : 
     270           0 :                 g_free (folder_path);
     271             :             }
     272             :             else
     273             :             {
     274           0 :                 U8_LOG_WARNING( "Export dialog returned no folder path" );
     275             :             }
     276           0 :             if ( selected_file != NULL )
     277             :             {
     278           0 :                 g_object_unref( selected_file );
     279             :             }
     280           0 :             data_stat_trace( &export_stat );
     281           0 :             data_stat_destroy ( &export_stat );
     282             :         }
     283           0 :         break;
     284             : 
     285           0 :         case GTK_RESPONSE_DELETE_EVENT:
     286             :         {
     287           0 :             U8_LOG_EVENT( "GTK_RESPONSE_DELETE_EVENT" );
     288             :         }
     289           0 :         break;
     290             : 
     291           0 :         default:
     292             :         {
     293           0 :             U8_LOG_ERROR( "unexpected response_id" );
     294             :         }
     295             :     }
     296             : 
     297           0 :     U8_TRACE_END();
     298           0 : }
     299             : 
     300             : #else  /* GTK >= 4.10 */
     301             : 
     302             : void gui_file_export_dialog_async_ready_callback( GObject* source_object,
     303             :                                                   GAsyncResult* res,
     304             :                                                   gpointer user_data )
     305             : {
     306             :     U8_TRACE_BEGIN();
     307             : 
     308             :     gui_file_export_dialog_t *this_ = user_data;
     309             : 
     310             :     gtk_widget_set_visible( (*this_).options_layout, FALSE );
     311             : 
     312             :     GError* error = NULL;
     313             :     GFile *result = gtk_file_dialog_select_folder_finish( GTK_FILE_DIALOG(source_object), res, &error );
     314             :     if ( error != NULL )
     315             :     {
     316             :         /* User pressed cancel */
     317             :         U8_TRACE_INFO_STR( "unexpected response from file dialog:", error->message );
     318             :         g_error_free( error );
     319             :     }
     320             :     if ( result != NULL )
     321             :     {
     322             :         gchar *folder_path = g_file_get_path ( result );
     323             :         if ( folder_path != NULL )
     324             :         {
     325             :             u8_error_t export_err = U8_ERROR_NONE;
     326             :             data_stat_t export_stat;
     327             :             data_stat_init ( &export_stat );
     328             :             io_file_format_t selected_format = IO_FILE_FORMAT_NONE;
     329             : 
     330             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_pdf) )) { selected_format |= IO_FILE_FORMAT_PDF; }
     331             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_png) )) { selected_format |= IO_FILE_FORMAT_PNG; }
     332             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_ps) )) { selected_format |= IO_FILE_FORMAT_PS; }
     333             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_svg) )) { selected_format |= IO_FILE_FORMAT_SVG; }
     334             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_txt) )) { selected_format |= IO_FILE_FORMAT_TXT; }
     335             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_docbook) )) { selected_format |= IO_FILE_FORMAT_DOCBOOK; }
     336             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_html) )) { selected_format |= IO_FILE_FORMAT_HTML; }
     337             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_xmi2) )) { selected_format |= IO_FILE_FORMAT_XMI2; }
     338             :             if ( gtk_check_button_get_active( GTK_CHECK_BUTTON((*this_).format_json) )) { selected_format |= IO_FILE_FORMAT_JSON; }
     339             : 
     340             :             /* react immediately, handle events */
     341             :             gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
     342             :                                                                GUI_SIMPLE_MESSAGE_TYPE_INFO,
     343             :                                                                GUI_SIMPLE_MESSAGE_CONTENT_EXPORTING_WAIT,
     344             :                                                                folder_path
     345             :                                                              );
     346             :             bool events_handled = true;
     347             :             for ( uint_fast8_t max_loop = 40; events_handled && ( max_loop > 0 ); max_loop-- )
     348             :             {
     349             :                 events_handled = g_main_context_iteration( NULL, /*may_block*/ FALSE );
     350             :             }
     351             : 
     352             :             /* determine the database file path for a document title and export: */
     353             :             const char *db_path = data_database_get_filename_ptr( (*this_).database );
     354             :             if ( data_database_is_open((*this_).database) )
     355             :             {
     356             :                 export_err = io_exporter_export_files( &((*this_).file_exporter),
     357             :                                                        selected_format,
     358             :                                                        folder_path,
     359             :                                                        db_path,
     360             :                                                        &export_stat
     361             :                                                      );
     362             :             }
     363             :             else
     364             :             {
     365             :                 export_err = U8_ERROR_NO_DB;
     366             :             }
     367             : 
     368             :             /* finished, notify user */
     369             :             char temp_format_buf[64];
     370             :             utf8stringbuf_t temp_fileformat = UTF8STRINGBUF( temp_format_buf );
     371             :             io_file_format_to_string( selected_format, temp_fileformat );
     372             : 
     373             :             if ( U8_ERROR_NONE == export_err )
     374             :             {
     375             :                 gui_simple_message_to_user_show_message_with_names_and_stat( (*this_).message_to_user,
     376             :                                                                              GUI_SIMPLE_MESSAGE_TYPE_INFO,
     377             :                                                                              GUI_SIMPLE_MESSAGE_CONTENT_EXPORT_FINISHED,
     378             :                                                                              utf8stringbuf_get_string( temp_fileformat ),
     379             :                                                                              &export_stat
     380             :                                                                            );
     381             : 
     382             :             }
     383             :             else
     384             :             {
     385             :                 gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
     386             :                                                                    GUI_SIMPLE_MESSAGE_TYPE_ERROR,
     387             :                                                                    GUI_SIMPLE_MESSAGE_CONTENT_FILE_EXPORT_FAILED,
     388             :                                                                    folder_path
     389             :                                                                  );
     390             :             }
     391             : 
     392             :             data_stat_trace( &export_stat );
     393             :             data_stat_destroy ( &export_stat );
     394             :             g_free (folder_path);
     395             :         }
     396             :         g_object_unref( result );
     397             :     }
     398             : 
     399             :     U8_TRACE_END();
     400             : }
     401             : 
     402             : #endif  /* GTK ? 4.10 */
     403             : 
     404             : 
     405             : /*
     406             : Copyright 2019-2024 Andreas Warnke
     407             : 
     408             : Licensed under the Apache License, Version 2.0 (the "License");
     409             : you may not use this file except in compliance with the License.
     410             : You may obtain a copy of the License at
     411             : 
     412             :     http://www.apache.org/licenses/LICENSE-2.0
     413             : 
     414             : Unless required by applicable law or agreed to in writing, software
     415             : distributed under the License is distributed on an "AS IS" BASIS,
     416             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     417             : See the License for the specific language governing permissions and
     418             : limitations under the License.
     419             : */

Generated by: LCOV version 1.16