| 1 | #include <stdio.h> |
|---|
| 2 | #include <string.h> |
|---|
| 3 | #include <fltk/Window.h> |
|---|
| 4 | #include <fltk/Browser.h> |
|---|
| 5 | #include <fltk/ItemGroup.h> |
|---|
| 6 | #include <fltk/StringList.h> |
|---|
| 7 | #include <fltk/draw.h> |
|---|
| 8 | #include <fltk/run.h> |
|---|
| 9 | |
|---|
| 10 | using namespace fltk; |
|---|
| 11 | |
|---|
| 12 | static void header_cb(fltk::Widget *wid, void* data) { |
|---|
| 13 | int n = (int)data; |
|---|
| 14 | // printf("header %d\n", n); |
|---|
| 15 | // header sort is not implemented |
|---|
| 16 | } |
|---|
| 17 | |
|---|
| 18 | int main(int argc, char* argv[]) { |
|---|
| 19 | FILE *fp = stdin; |
|---|
| 20 | if (argc != 1) |
|---|
| 21 | fp = fopen(argv[1], "r"); |
|---|
| 22 | if (!fp) return -1; |
|---|
| 23 | |
|---|
| 24 | Window* win = new Window(500, 500, "CSV Viewer"); |
|---|
| 25 | win->begin(); |
|---|
| 26 | Browser* browser = new Browser(10, 10, 480, 480); |
|---|
| 27 | browser->type(Browser::MULTI); |
|---|
| 28 | // browser->indented(1); |
|---|
| 29 | win->resizable(browser); |
|---|
| 30 | win->end(); |
|---|
| 31 | |
|---|
| 32 | char buffer[BUFSIZ]; |
|---|
| 33 | const char **pcolumn_labels = NULL; |
|---|
| 34 | int *pcolumn_widths = NULL; |
|---|
| 35 | while(fgets(buffer, sizeof(buffer), fp)) { |
|---|
| 36 | char* ptr = buffer; |
|---|
| 37 | int n = 1; |
|---|
| 38 | if (*ptr == '"') { |
|---|
| 39 | strcpy(ptr, ptr+1); |
|---|
| 40 | } |
|---|
| 41 | while(*ptr) { |
|---|
| 42 | if (*ptr == ',') { |
|---|
| 43 | *ptr = '\t'; |
|---|
| 44 | n++; |
|---|
| 45 | if (ptr > buffer && *(ptr-1) == '"') { |
|---|
| 46 | strcpy(ptr-1, ptr); |
|---|
| 47 | ptr--; |
|---|
| 48 | } |
|---|
| 49 | if (*(ptr+1) == '"') { |
|---|
| 50 | strcpy(ptr+1, ptr+2); |
|---|
| 51 | } |
|---|
| 52 | } |
|---|
| 53 | if (*ptr == '\r' || *ptr == '\n') { |
|---|
| 54 | if (ptr > buffer && *(ptr-1) == '"') { |
|---|
| 55 | strcpy(ptr-1, ptr); |
|---|
| 56 | ptr--; |
|---|
| 57 | } |
|---|
| 58 | *ptr = '\0'; |
|---|
| 59 | } |
|---|
| 60 | ptr++; |
|---|
| 61 | } |
|---|
| 62 | if (browser->nheader() == 0) { |
|---|
| 63 | pcolumn_labels = new const char*[n+1]; |
|---|
| 64 | pcolumn_widths = new int[n+1]; |
|---|
| 65 | char *dup = strdup(buffer); |
|---|
| 66 | pcolumn_labels[0] = dup; |
|---|
| 67 | pcolumn_widths[0] = 80; |
|---|
| 68 | int c = 0; |
|---|
| 69 | ptr = dup; |
|---|
| 70 | while(true) { |
|---|
| 71 | if (*ptr == '\t' || *ptr == '\0') { |
|---|
| 72 | c++; |
|---|
| 73 | pcolumn_labels[c] = ptr + 1; |
|---|
| 74 | pcolumn_widths[c] = 90; |
|---|
| 75 | if (*ptr == '\0') |
|---|
| 76 | break; |
|---|
| 77 | *ptr = '\0'; |
|---|
| 78 | } |
|---|
| 79 | ptr++; |
|---|
| 80 | } |
|---|
| 81 | pcolumn_labels[n] = NULL; |
|---|
| 82 | pcolumn_widths[n] = 0; |
|---|
| 83 | browser->column_labels(pcolumn_labels); |
|---|
| 84 | browser->column_widths(pcolumn_widths); |
|---|
| 85 | continue; |
|---|
| 86 | } |
|---|
| 87 | browser->begin(); |
|---|
| 88 | ItemGroup* item = new ItemGroup; |
|---|
| 89 | if (browser->nheader() > 0) { |
|---|
| 90 | const char **pcolumn_values_measure = new const char*[n+1]; |
|---|
| 91 | int *pcolumn_widths_measure = new int[n+1]; |
|---|
| 92 | char *dup = strdup(buffer); |
|---|
| 93 | pcolumn_values_measure[0] = dup; |
|---|
| 94 | int c = 0; |
|---|
| 95 | ptr = dup; |
|---|
| 96 | while(true) { |
|---|
| 97 | if (*ptr == '\t' || *ptr == '\0') { |
|---|
| 98 | c++; |
|---|
| 99 | *ptr = '\0'; |
|---|
| 100 | pcolumn_values_measure[c] = ptr + 1; |
|---|
| 101 | pcolumn_widths_measure[c-1] = (int)(getwidth(pcolumn_values_measure[c-1])*1.2); |
|---|
| 102 | if (c == n) |
|---|
| 103 | break; |
|---|
| 104 | } |
|---|
| 105 | ptr++; |
|---|
| 106 | } |
|---|
| 107 | pcolumn_widths_measure[n] = 0; |
|---|
| 108 | bool column_width_changed = false; |
|---|
| 109 | for(int i = 0; i < n; i++) { |
|---|
| 110 | if (pcolumn_widths[i] < pcolumn_widths_measure[i]) { |
|---|
| 111 | pcolumn_widths[i] = pcolumn_widths_measure[i]; |
|---|
| 112 | column_width_changed = true; |
|---|
| 113 | } |
|---|
| 114 | } |
|---|
| 115 | delete[] pcolumn_values_measure; |
|---|
| 116 | delete[] pcolumn_widths_measure; |
|---|
| 117 | if (column_width_changed) { |
|---|
| 118 | browser->column_widths(pcolumn_widths); |
|---|
| 119 | browser->relayout(); |
|---|
| 120 | } |
|---|
| 121 | } |
|---|
| 122 | item->copy_label(buffer); |
|---|
| 123 | item->align(fltk::ALIGN_LEFT|fltk::ALIGN_INSIDE|fltk::ALIGN_CLIP); |
|---|
| 124 | browser->end(); |
|---|
| 125 | browser->relayout(); |
|---|
| 126 | } |
|---|
| 127 | if (fp != stdin) fclose(fp); |
|---|
| 128 | for(int n = 0; n < browser->nheader(); n++) |
|---|
| 129 | browser->header(n)->callback(header_cb, (void*)n); |
|---|
| 130 | win->show(); |
|---|
| 131 | run(); |
|---|
| 132 | } |
|---|