Mercurial > thymian
comparison 3rdparty/vmime/examples/viewer/viewer.cpp @ 0:a4671277546c tip
created the repository for the thymian project
| author | ferencd |
|---|---|
| date | Tue, 17 Aug 2021 11:19:54 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:a4671277546c |
|---|---|
| 1 // | |
| 2 // VMime library (http://www.vmime.org) | |
| 3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org> | |
| 4 // | |
| 5 // This program is free software; you can redistribute it and/or | |
| 6 // modify it under the terms of the GNU General Public License as | |
| 7 // published by the Free Software Foundation; either version 3 of | |
| 8 // the License, or (at your option) any later version. | |
| 9 // | |
| 10 // This program is distributed in the hope that it will be useful, | |
| 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 // General Public License for more details. | |
| 14 // | |
| 15 // You should have received a copy of the GNU General Public License along | |
| 16 // with this program; if not, write to the Free Software Foundation, Inc., | |
| 17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 18 // | |
| 19 // Linking this library statically or dynamically with other modules is making | |
| 20 // a combined work based on this library. Thus, the terms and conditions of | |
| 21 // the GNU General Public License cover the whole combination. | |
| 22 // | |
| 23 | |
| 24 // | |
| 25 // EXAMPLE DESCRIPTION: | |
| 26 // ==================== | |
| 27 // A simple MIME viewer to show all the components of a message. | |
| 28 // The user interface is written using GTK+ 2.6. | |
| 29 // | |
| 30 // For more information, please visit: | |
| 31 // http://www.vmime.org/ | |
| 32 // | |
| 33 | |
| 34 #include <iostream> | |
| 35 #include <fstream> | |
| 36 #include <vector> | |
| 37 #include <typeinfo> | |
| 38 | |
| 39 #include <gtk/gtk.h> | |
| 40 | |
| 41 #include "vmime/vmime.hpp" | |
| 42 #include "vmime/platforms/posix/posixHandler.hpp" | |
| 43 | |
| 44 | |
| 45 | |
| 46 GtkWidget* window = NULL; | |
| 47 GtkWidget* treeView = NULL; | |
| 48 GtkWidget* textArea = NULL; | |
| 49 | |
| 50 GtkTreeStore* treeModel = NULL; | |
| 51 | |
| 52 vmime::shared_ptr <vmime::message> currentMessage; | |
| 53 | |
| 54 | |
| 55 | |
| 56 void insertRowInModel(GtkTreeStore* model, vmime::shared_ptr <vmime::component> comp, GtkTreeIter* parent = NULL) | |
| 57 { | |
| 58 GtkTreeIter iter; | |
| 59 | |
| 60 gtk_tree_store_append(model, &iter, parent); | |
| 61 gtk_tree_store_set(model, &iter, 0, typeid(*comp).name(), 1, comp.get(), -1); | |
| 62 | |
| 63 const std::vector <vmime::shared_ptr <vmime::component> > children = comp->getChildComponents(); | |
| 64 | |
| 65 for (int i = 0 ; i < children.size() ; ++i) | |
| 66 { | |
| 67 insertRowInModel(model, children[i], &iter); | |
| 68 } | |
| 69 } | |
| 70 | |
| 71 | |
| 72 void updateTreeView() | |
| 73 { | |
| 74 GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView))); | |
| 75 | |
| 76 g_object_ref(model); | |
| 77 gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), NULL); | |
| 78 | |
| 79 gtk_tree_store_clear(model); | |
| 80 | |
| 81 insertRowInModel(model, currentMessage); | |
| 82 | |
| 83 gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(model)); | |
| 84 g_object_unref(model); | |
| 85 } | |
| 86 | |
| 87 | |
| 88 static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData) | |
| 89 { | |
| 90 GtkTreePath* path = NULL; | |
| 91 GtkTreeViewColumn* col = NULL; | |
| 92 | |
| 93 gtk_tree_view_get_cursor(treeView, &path, &col); | |
| 94 | |
| 95 GtkTreeIter iter; | |
| 96 gtk_tree_model_get_iter(GTK_TREE_MODEL(treeModel), &iter, path); | |
| 97 | |
| 98 vmime::component* comp = NULL; | |
| 99 gtk_tree_model_get(GTK_TREE_MODEL(treeModel), &iter, 1, &comp, -1); | |
| 100 | |
| 101 GtkTextBuffer* textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)); | |
| 102 GtkTextIter start, end; | |
| 103 | |
| 104 gtk_text_buffer_get_iter_at_offset(textBuffer, &start, comp->getParsedOffset()); | |
| 105 gtk_text_buffer_get_iter_at_offset(textBuffer, &end, comp->getParsedOffset() + comp->getParsedLength()); | |
| 106 | |
| 107 gtk_text_buffer_select_range(textBuffer, &start, &end); | |
| 108 | |
| 109 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(textArea), &start, 0.0, FALSE, 0.0, 0.0); | |
| 110 | |
| 111 gtk_tree_path_free(path); | |
| 112 } | |
| 113 | |
| 114 | |
| 115 static void destroy(GtkWidget* widget, gpointer data) | |
| 116 { | |
| 117 gtk_main_quit(); | |
| 118 } | |
| 119 | |
| 120 | |
| 121 void openFile(const std::string& filename) | |
| 122 { | |
| 123 std::ifstream file; | |
| 124 file.open(filename.c_str(), std::ios::in | std::ios::binary); | |
| 125 | |
| 126 if (!file) | |
| 127 { | |
| 128 std::cerr << "Can't open file '" << filename << "'." << std::endl; | |
| 129 return; | |
| 130 } | |
| 131 | |
| 132 vmime::string data; | |
| 133 char buffer[16384]; | |
| 134 | |
| 135 do | |
| 136 { | |
| 137 file.read(buffer, sizeof(buffer)); | |
| 138 data += vmime::string(buffer, file.gcount()); | |
| 139 } | |
| 140 while (file.gcount()); | |
| 141 | |
| 142 vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>(); | |
| 143 msg->parse(data); | |
| 144 | |
| 145 currentMessage = msg; | |
| 146 | |
| 147 char* convData = g_convert_with_fallback(data.c_str(), data.length(), | |
| 148 "UTF-8", "ISO-8859-1", "?", NULL, NULL, NULL); | |
| 149 | |
| 150 if (convData == NULL) | |
| 151 { | |
| 152 gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)), | |
| 153 "GLib UTF-8 conversion error.", -1); | |
| 154 } | |
| 155 else | |
| 156 { | |
| 157 gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)), | |
| 158 convData, strlen(convData)); | |
| 159 | |
| 160 g_free(convData); | |
| 161 } | |
| 162 | |
| 163 updateTreeView(); | |
| 164 } | |
| 165 | |
| 166 | |
| 167 static void onFileOpen() | |
| 168 { | |
| 169 GtkWidget* dlg = gtk_file_chooser_dialog_new | |
| 170 ("Open Message File", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, | |
| 171 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
| 172 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, | |
| 173 NULL); | |
| 174 | |
| 175 if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) | |
| 176 { | |
| 177 char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg)); | |
| 178 | |
| 179 openFile(filename); | |
| 180 | |
| 181 g_free(filename); | |
| 182 } | |
| 183 | |
| 184 gtk_widget_destroy(dlg); | |
| 185 } | |
| 186 | |
| 187 | |
| 188 | |
| 189 // UI definitions | |
| 190 static const GtkActionEntry uiActions[] = | |
| 191 { | |
| 192 { "FileMenu", NULL, "_File" }, | |
| 193 { "FileOpen", GTK_STOCK_OPEN, "_Open...", "<control>O", NULL, G_CALLBACK(onFileOpen) }, | |
| 194 { "FileExit", GTK_STOCK_QUIT, "_Exit", "<control>Q", NULL, G_CALLBACK(gtk_main_quit) } | |
| 195 }; | |
| 196 | |
| 197 static const char* uiDefinition = | |
| 198 "<ui>" \ | |
| 199 " <menubar name=\"MainMenuBar\">" \ | |
| 200 " <menu action=\"FileMenu\">" \ | |
| 201 " <menuitem action=\"FileOpen\"/>" \ | |
| 202 " <menuitem action=\"FileExit\"/>" \ | |
| 203 " </menu>" \ | |
| 204 " </menubar>" \ | |
| 205 "</ui>"; | |
| 206 | |
| 207 | |
| 208 int main(int argc, char* argv[]) | |
| 209 { | |
| 210 // VMime initialization | |
| 211 vmime::platform::setHandler<vmime::platforms::posix::posixHandler>(); | |
| 212 | |
| 213 // GTK+ initialization | |
| 214 gtk_init(&argc, &argv); | |
| 215 | |
| 216 // Create a new window | |
| 217 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
| 218 | |
| 219 gtk_window_set_default_size(GTK_WINDOW(window), 800, 550); | |
| 220 gtk_window_set_title(GTK_WINDOW(window), "VMime Viewer Example"); | |
| 221 | |
| 222 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL); | |
| 223 | |
| 224 GtkWidget* vbox = gtk_vbox_new(FALSE, 0); | |
| 225 gtk_container_add(GTK_CONTAINER(window), vbox); | |
| 226 | |
| 227 // Menubar | |
| 228 GtkActionGroup* actionGroup = gtk_action_group_new ("Actions"); | |
| 229 gtk_action_group_add_actions(actionGroup, uiActions, G_N_ELEMENTS(uiActions), NULL); | |
| 230 | |
| 231 GtkUIManager* uiManager = gtk_ui_manager_new(); | |
| 232 gtk_ui_manager_insert_action_group(uiManager, actionGroup, 1); | |
| 233 gtk_ui_manager_add_ui_from_string(uiManager, uiDefinition, -1, NULL); | |
| 234 | |
| 235 GtkWidget* menuBar = gtk_ui_manager_get_widget(uiManager, "/MainMenuBar"); | |
| 236 | |
| 237 gtk_box_pack_start(GTK_BOX(vbox), menuBar, FALSE, FALSE, 0); | |
| 238 | |
| 239 // Horizontal Pane | |
| 240 GtkWidget* hpane = gtk_hpaned_new(); | |
| 241 gtk_box_pack_start(GTK_BOX(vbox), hpane, TRUE, TRUE, 0); | |
| 242 | |
| 243 // Tree View | |
| 244 treeModel = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); | |
| 245 | |
| 246 treeView = gtk_tree_view_new(); | |
| 247 | |
| 248 g_signal_connect(G_OBJECT(treeView), "cursor-changed", G_CALLBACK(treeViewSelChanged), NULL); | |
| 249 | |
| 250 GtkWidget* scroll = gtk_scrolled_window_new(NULL, NULL); | |
| 251 | |
| 252 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
| 253 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN); | |
| 254 gtk_container_add(GTK_CONTAINER(scroll), treeView); | |
| 255 | |
| 256 gtk_paned_add1(GTK_PANED(hpane), scroll); | |
| 257 | |
| 258 GtkTreeViewColumn* col = gtk_tree_view_column_new(); | |
| 259 gtk_tree_view_column_set_title(col, "Component Name"); | |
| 260 gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), col); | |
| 261 | |
| 262 GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); | |
| 263 | |
| 264 gtk_tree_view_column_pack_start(col, renderer, TRUE); | |
| 265 gtk_tree_view_column_add_attribute(col, renderer, "text", 0); | |
| 266 | |
| 267 gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(treeModel)); | |
| 268 g_object_unref(treeModel); | |
| 269 | |
| 270 gtk_widget_set_size_request(treeView, 200, 100); | |
| 271 | |
| 272 // Text Area | |
| 273 textArea = gtk_text_view_new(); | |
| 274 | |
| 275 gtk_text_view_set_editable(GTK_TEXT_VIEW(textArea), FALSE); | |
| 276 | |
| 277 scroll = gtk_scrolled_window_new(NULL, NULL); | |
| 278 | |
| 279 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
| 280 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN); | |
| 281 gtk_container_add(GTK_CONTAINER(scroll), textArea); | |
| 282 | |
| 283 gtk_paned_add2(GTK_PANED(hpane), scroll); | |
| 284 | |
| 285 // Show main window | |
| 286 gtk_widget_show_all(window); | |
| 287 | |
| 288 // GTK main loop | |
| 289 gtk_main(); | |
| 290 | |
| 291 return 0; | |
| 292 } | |
| 293 | |
| 294 |
