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