File: exceptiontest.cc

package info (click to toggle)
gtkmm-documentation 4.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,772 kB
  • sloc: cpp: 15,541; javascript: 1,208; makefile: 1,080; python: 401; xml: 106; perl: 67; sh: 8
file content (136 lines) | stat: -rw-r--r-- 3,286 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

#include <iostream>
#include <gtkmm/box.h>
#include <glibmm/convert.h>
#include <glibmm/exceptionhandler.h>
#include <gtkmm/application.h>
#include <gtkmm/window.h>
#include <gtkmm/button.h>


namespace
{

class MyButton : public Gtk::Button
{
public:
  explicit MyButton(const Glib::ustring& label);

protected:
  void on_clicked() override; // signal handler
};

class MyException1 {};
class MyException2 {};
class MyException3 {};


MyButton::MyButton(const Glib::ustring& label)
:
  Gtk::Button(label)
{}

void MyButton::on_clicked()
{
  std::cout << "The Button was clicked.\n";
  throw MyException1();
}

void global_on_clicked()
{
  std::cout << "The Button was clicked.\n";
  throw MyException2();
}

void global_on_clicked_throw_glib_error()
{
  std::cout << "The Button was clicked.\n";
  Glib::locale_from_utf8("Und tschss!"); // invalid UTF-8
}

void global_on_clicked_throw_std_exception()
{
  std::cout << "The Button was clicked.\n";
  Glib::ustring str;
  str.at(3); // out of range
}

void handler1()
{
  std::cout << "exception handler 1\n";

  try
  {
    throw; // rethrow exception
  }
  catch(MyException1&)
  {
    std::cout << "caught MyException1\n";
  }
  // if not handled it gets passed to next handler
}

void handler2()
{
  std::cout << "exception handler 2\n";

  try
  {
    throw; // rethrow exception
  }
  catch(MyException2&)
  {
    std::cout << "caught MyException2\n";
  }
  // if not handled it gets passed to next handler
}

class MyWindow : public Gtk::Window
{
public:
  MyWindow();
};

MyWindow::MyWindow()
{
  set_title("Exception Handlers");

  Gtk::Box *const box = new Gtk::Box(Gtk::Orientation::VERTICAL, 5);
  box->set_margin(10);
  set_child(*Gtk::manage(box));

  // New exception handlers are inserted at the front of the per-thread
  // handler list.  Thus, in this example handler2() is executed before
  // handler1().
  sigc::connection conn_handler1 = Glib::add_exception_handler(&handler1);
  sigc::connection conn_handler2 = Glib::add_exception_handler(&handler2);

  Gtk::Button *const button1 = new MyButton("From virtual method");
  box->append(*Gtk::manage(button1));
  Gtk::Button *const button2 = new Gtk::Button("From signal handler");
  box->append(*Gtk::manage(button2));
  Gtk::Button *const button3 = new Gtk::Button("Unhandled Glib::Error");
  box->append(*Gtk::manage(button3));
  Gtk::Button *const button4 = new Gtk::Button("Unhandled std::exception (crash!)");
  box->append(*Gtk::manage(button4));
  Gtk::Button *const button5 = new Gtk::Button("Disconnect handler 1");
  box->append(*Gtk::manage(button5));
  Gtk::Button *const button6 = new Gtk::Button("Disconnect handler 2");
  box->append(*Gtk::manage(button6));

  button2->signal_clicked().connect(&global_on_clicked);
  button3->signal_clicked().connect(&global_on_clicked_throw_glib_error);
  button4->signal_clicked().connect(&global_on_clicked_throw_std_exception);
  button5->signal_clicked().connect(sigc::mem_fun(conn_handler1, &sigc::connection::disconnect));
  button6->signal_clicked().connect(sigc::mem_fun(conn_handler2, &sigc::connection::disconnect));
}

} // anonymous namespace


int main(int argc, char** argv)
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  return app->make_window_and_run<MyWindow>(argc, argv);
}