PageRenderTime 59ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/fuse-1.0.0.1/ui/widget/error.c

#
C | 184 lines | 108 code | 42 blank | 34 comment | 16 complexity | 760e3724907f0332f19bc8511ea100fe MD5 | raw file
Possible License(s): GPL-2.0
  1. /* error.c: The error reporting widget
  2. Copyright (c) 2002-2005 Philip Kendall
  3. $Id: error.c 4103 2009-11-21 10:16:36Z fredm $
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. Author contact information:
  16. E-mail: philip-fuse@shadowmagic.org.uk
  17. */
  18. #include <config.h>
  19. #include <ctype.h>
  20. #include <stddef.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include "fuse.h"
  24. #include "widget_internals.h"
  25. widget_error_t *error_info;
  26. int
  27. ui_error_specific( ui_error_level severity, const char *message )
  28. {
  29. widget_error_t error_info;
  30. /* Can't output widgets if we don't have a display yet */
  31. if( !display_ui_initialised ) return 0;
  32. error_info.severity = severity;
  33. error_info.message = message;
  34. fuse_emulation_pause();
  35. widget_do( WIDGET_TYPE_ERROR, &error_info );
  36. fuse_emulation_unpause();
  37. return 0;
  38. }
  39. int widget_error_draw( void *data )
  40. {
  41. char **lines; size_t count;
  42. size_t i;
  43. error_info = (widget_error_t*)data;
  44. if( split_message( error_info->message, &lines, &count, 28 ) ) return 1;
  45. widget_dialog_with_border( 1, 2, 30, count+2 );
  46. switch( error_info->severity ) {
  47. case UI_ERROR_INFO:
  48. widget_printstring( 10, 16, WIDGET_COLOUR_TITLE, "Info" );
  49. break;
  50. case UI_ERROR_WARNING:
  51. widget_printstring( 10, 16, WIDGET_COLOUR_TITLE, "Warning" );
  52. break;
  53. case UI_ERROR_ERROR:
  54. widget_printstring( 10, 16, WIDGET_COLOUR_TITLE, "Error" );
  55. break;
  56. default:
  57. widget_printstring( 10, 16, WIDGET_COLOUR_TITLE, "(Unknown message)" );
  58. break;
  59. }
  60. for( i=0; i<count; i++ ) {
  61. widget_printstring( 17, i*8+24, WIDGET_COLOUR_FOREGROUND, lines[i] );
  62. free( lines[i] );
  63. }
  64. free( lines );
  65. widget_display_lines( 2, count + 3 );
  66. return 0;
  67. }
  68. int
  69. split_message( const char *message, char ***lines, size_t *count,
  70. size_t line_length )
  71. {
  72. const char *ptr = message;
  73. int position;
  74. line_length *= 8;
  75. /* Setup so we'll allocate the first line as soon as we get the first
  76. word */
  77. *lines = NULL; *count = 0; position = line_length;
  78. while( *ptr ) {
  79. /* Skip any whitespace */
  80. while( *ptr && isspace( *ptr ) ) ptr++; message = ptr;
  81. /* Find end of word */
  82. while( *ptr && !isspace( *ptr ) ) ptr++;
  83. /* message now points to a word of length (ptr-message); if
  84. that's longer than an entire line (most likely filenames), just
  85. take the last bit */
  86. while( widget_substringwidth( message, ptr - message ) >= line_length )
  87. message++;
  88. /* Check we've got room for the word, plus some prefixing space */
  89. if( position + widget_substringwidth( message, ptr - message ) + 4
  90. >= line_length ) {
  91. char **new_lines; size_t i;
  92. /* If we've filled the screen, stop */
  93. if( *count == 18 ) return 0;
  94. new_lines = realloc( (*lines), (*count + 1) * sizeof( char** ) );
  95. if( new_lines == NULL ) {
  96. for( i=0; i<*count; i++ ) free( (*lines)[i] );
  97. if(*lines) free( (*lines) );
  98. return 1;
  99. }
  100. (*lines) = new_lines;
  101. (*lines)[*count] = malloc( (line_length+1) );
  102. if( (*lines)[*count] == NULL ) {
  103. for( i=0; i<*count; i++ ) free( (*lines)[i] );
  104. free( (*lines) );
  105. return 1;
  106. }
  107. strncpy( (*lines)[*count], message, ptr - message );
  108. position = widget_substringwidth( message, ptr - message );
  109. (*lines)[*count][ptr - message] = '\0';
  110. (*count)++;
  111. } else { /* Enough room on this line */
  112. strcat( (*lines)[*count-1], " " );
  113. (*lines)[*count-1][strlen( (*lines)[*count-1] ) + ptr - message] = '\0';
  114. strncat( (*lines)[*count-1], message, ptr - message );
  115. position += widget_substringwidth( message, ptr - message ) + 4;
  116. }
  117. message = ptr;
  118. }
  119. return 0;
  120. }
  121. void
  122. widget_error_keyhandler( input_key key )
  123. {
  124. switch( key ) {
  125. case INPUT_KEY_Escape:
  126. widget_end_widget( WIDGET_FINISHED_CANCEL );
  127. return;
  128. case INPUT_KEY_Return:
  129. case INPUT_KEY_KP_Enter:
  130. widget_end_widget( WIDGET_FINISHED_OK );
  131. return;
  132. default: /* Keep gcc happy */
  133. break;
  134. }
  135. }