Skip to content

Commit 25bbee5

Browse files
author
nicolas.with@st.ovgu.de
committed
added following specific process
1 parent 71ee2d8 commit 25bbee5

8 files changed

+356
-20
lines changed

pgdb.gresource.xml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<file>res/breakpoint.svg</file>
55
<file compressed="true">ui/about_dialog.glade</file>
66
<file compressed="true">ui/breakpoint_dialog.glade</file>
7+
<file compressed="true">ui/follow_dialog.glade</file>
78
<file compressed="true">ui/startup_dialog.glade</file>
89
<file compressed="true">ui/window.glade</file>
910
</gresource>

src/master/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ $(BUILDDIR)/libmigdb.a:
2828
$(BUILDDIR)/resources.c:
2929
cd $(ROOTDIR) && glib-compile-resources pgdb.gresource.xml --target=bin/resources.c --generate-source
3030

31-
$(BUILDDIR)/pgdb: $(addprefix $(BUILDDIR)/, $(addsuffix .o, startup breakpoint breakpoint_dialog canvas window master resources)) $(BUILDDIR)/libmigdb.a
31+
$(BUILDDIR)/pgdb: $(addprefix $(BUILDDIR)/, $(addsuffix .o, startup breakpoint breakpoint_dialog follow_dialog canvas window master resources)) $(BUILDDIR)/libmigdb.a
3232
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(GTKMM) $(GTKSRCVIEW) $(LIBSSH)
3333

3434
$(BUILDDIR)/%.o: %.cpp

src/master/follow_dialog.cpp

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
This file is part of ParallelGDB.
3+
4+
Copyright (c) 2023 by Nicolas With
5+
6+
ParallelGDB is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
ParallelGDB is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with ParallelGDB. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
/**
21+
* @file follow_dialog.cpp
22+
*
23+
* @brief Contains the implementation of the FollowDialog class.
24+
*
25+
* This file contains the implementation of the FollowDialog class.
26+
*/
27+
28+
#include <string>
29+
30+
#include "follow_dialog.hpp"
31+
32+
using std::string;
33+
34+
/**
35+
* This function is a wrapper for the Gtk::get_widget function.
36+
*
37+
* @tparam T The widget class.
38+
*
39+
* @param[in] widget_name The widget name.
40+
*
41+
* @return The pointer to the widget object on success, @c nullptr on error.
42+
*/
43+
template <class T>
44+
T *FollowDialog::get_widget(const std::string &widget_name)
45+
{
46+
T *widget;
47+
m_builder->get_widget<T>(widget_name, widget);
48+
return widget;
49+
}
50+
51+
/**
52+
* This is the default constructor for the FollowDialog class. It will generate
53+
* a grid of radiobuttons for the user to select the process to follow.
54+
*
55+
* @param num_processes The number of processes.
56+
*
57+
* @param max_buttons_per_row The number of buttons per grid row.
58+
*/
59+
FollowDialog::FollowDialog(const int num_processes, const int max_buttons_per_row)
60+
: m_num_processes(num_processes),
61+
m_max_buttons_per_row(max_buttons_per_row)
62+
{
63+
// parse glade file
64+
m_builder =
65+
Gtk::Builder::create_from_resource("/pgdb/ui/follow_dialog.glade");
66+
m_dialog = get_widget<Gtk::Dialog>("dialog");
67+
68+
// generate radiobuttons grid
69+
m_grid = get_widget<Gtk::Grid>("radiobuttons-grid");
70+
Gtk::RadioButton *first_radiobutton = Gtk::manage(new Gtk::RadioButton("0"));
71+
m_grid->attach(*first_radiobutton, 0, 0);
72+
Gtk::RadioButton::Group radiobutton_group = first_radiobutton->get_group();
73+
for (int rank = 1; rank < m_num_processes; ++rank)
74+
{
75+
Gtk::RadioButton *radiobutton =
76+
Gtk::manage(new Gtk::RadioButton(std::to_string(rank)));
77+
radiobutton->set_group(radiobutton_group);
78+
m_grid->attach(*radiobutton, rank % m_max_buttons_per_row,
79+
rank / m_max_buttons_per_row);
80+
}
81+
82+
// connect signal handlers
83+
m_dialog->signal_response().connect(
84+
sigc::mem_fun(*this, &FollowDialog::on_dialog_response));
85+
86+
m_dialog->add_button("Ok", Gtk::RESPONSE_OK);
87+
m_dialog->show_all();
88+
}
89+
90+
/**
91+
* Closes the dialog and destroys the object.
92+
*/
93+
FollowDialog::~FollowDialog()
94+
{
95+
delete m_dialog;
96+
}
97+
98+
/**
99+
* This function gets called when the user clicks on the "Ok" button or the
100+
* close button. Checks which radiobutton is selected and saves the rank for
101+
* later use.
102+
*
103+
* @param response_id The response ID of the pressed button.
104+
*/
105+
void FollowDialog::on_dialog_response(const int response_id)
106+
{
107+
if (Gtk::RESPONSE_OK != response_id)
108+
{
109+
return;
110+
}
111+
for (int rank = 0; rank < m_num_processes; ++rank)
112+
{
113+
Gtk::RadioButton *radiobutton =
114+
dynamic_cast<Gtk::RadioButton *>(m_grid->get_child_at(
115+
rank % m_max_buttons_per_row, rank / m_max_buttons_per_row));
116+
if (radiobutton->get_active())
117+
{
118+
m_follow_rank = rank;
119+
break;
120+
}
121+
}
122+
}

src/master/follow_dialog.hpp

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
This file is part of ParallelGDB.
3+
4+
Copyright (c) 2023 by Nicolas With
5+
6+
ParallelGDB is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
ParallelGDB is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with ParallelGDB. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
/**
21+
* @file follow_dialog.hpp
22+
*
23+
* @brief Header file for the FollowDialog class.
24+
*
25+
* This is the header file for the FollowDialog class.
26+
*/
27+
28+
#ifndef FOLLOW_DIALOG_HPP
29+
#define FOLLOW_DIALOG_HPP
30+
31+
#include <gtkmm.h>
32+
#include <iosfwd>
33+
34+
/// A wrapper class for a Gtk::Dialog.
35+
/**
36+
* This is a wrapper class for a Gtk::Dialog. It will generate a dialog for the
37+
* user to select the processes to follow.
38+
*/
39+
class FollowDialog
40+
{
41+
const int m_num_processes;
42+
const int m_max_buttons_per_row;
43+
44+
int m_follow_rank;
45+
46+
Glib::RefPtr<Gtk::Builder> m_builder;
47+
Gtk::Dialog *m_dialog;
48+
Gtk::Grid *m_grid;
49+
50+
/// Signal handler for the accept/close action of the dialog.
51+
void on_dialog_response(const int response_id);
52+
53+
/// Wrapper for the Gtk::get_widget function.
54+
template <class T>
55+
T *get_widget(const std::string &widget_name);
56+
57+
public:
58+
/// Default constructor.
59+
FollowDialog(const int num_processes, const int max_buttons_per_row);
60+
/// Destructor.
61+
~FollowDialog();
62+
63+
/// Runs the dialog.
64+
/**
65+
* This function runs the dialog.
66+
*
67+
* @return The response ID.
68+
*/
69+
inline int run()
70+
{
71+
return m_dialog->run();
72+
}
73+
74+
/// Returns the process rank to follow.
75+
/**
76+
* @return The processes rank to follow.
77+
*/
78+
inline int follow_rank() const
79+
{
80+
return m_follow_rank;
81+
}
82+
};
83+
84+
#endif /* FOLLOW_DIALOG_HPP */

src/master/window.cpp

+38-7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "window.hpp"
4040
#include "breakpoint.hpp"
4141
#include "breakpoint_dialog.hpp"
42+
#include "follow_dialog.hpp"
4243
#include "canvas.hpp"
4344

4445
using asio::ip::tcp;
@@ -58,6 +59,7 @@ const char *const open_file_id = "open-file";
5859
*/
5960
UIWindow::UIWindow(const int num_processes)
6061
: m_num_processes(num_processes),
62+
m_follow_rank(0),
6163
m_sent_run(false)
6264
{
6365
// allocate memory
@@ -307,6 +309,10 @@ bool UIWindow::init(Glib::RefPtr<Gtk::Application> app)
307309
sigc::mem_fun(*this, &UIWindow::on_key_press), false);
308310
m_root_window->signal_delete_event().connect(
309311
sigc::mem_fun(*this, &UIWindow::on_delete));
312+
get_widget<Gtk::Button>("follow-process-button")
313+
->signal_clicked()
314+
.connect(
315+
sigc::mem_fun(*this, &UIWindow::on_follow_button_clicked));
310316
get_widget<Gtk::Button>("step-over-button")
311317
->signal_clicked()
312318
.connect(sigc::bind(
@@ -422,6 +428,22 @@ bool UIWindow::on_delete(GdkEventAny *)
422428
return false;
423429
}
424430

431+
/**
432+
* This function opens a dialog to select the process to follow.
433+
*/
434+
void UIWindow::on_follow_button_clicked()
435+
{
436+
std::unique_ptr<FollowDialog> dialog = std::make_unique<FollowDialog>(
437+
m_num_processes, m_max_buttons_per_row);
438+
if (Gtk::RESPONSE_OK != dialog->run())
439+
{
440+
return;
441+
}
442+
m_follow_rank = dialog->follow_rank();
443+
get_widget<Gtk::Button>("follow-process-button")
444+
->set_label("Following Process " + std::to_string(m_follow_rank));
445+
}
446+
425447
/**
426448
* This function scrolls a scrolled window to the bottom. After scrolling the
427449
* event listener is deleted, so that the user can freely scroll in the ouput.
@@ -1097,12 +1119,15 @@ void UIWindow::append_overview_row(const string &basename,
10971119
*
10981120
* @param[in] fullpath The fullpath of the source file to append.
10991121
*/
1100-
void UIWindow::append_source_file(const string &fullpath)
1122+
void UIWindow::append_source_file(const string &fullpath, const int rank)
11011123
{
11021124
// check that file is not opened already
11031125
if (m_opened_files.find(fullpath) != m_opened_files.end())
11041126
{
1105-
m_files_notebook->set_current_page(m_path_2_pagenum[fullpath]);
1127+
if (rank == m_follow_rank)
1128+
{
1129+
m_files_notebook->set_current_page(m_path_2_pagenum[fullpath]);
1130+
}
11061131
return;
11071132
}
11081133
m_opened_files.insert(fullpath);
@@ -1156,7 +1181,10 @@ void UIWindow::append_source_file(const string &fullpath)
11561181
}
11571182
scrolled_window->show_all();
11581183
int page_num = m_files_notebook->append_page(*scrolled_window, *label);
1159-
m_files_notebook->set_current_page(page_num);
1184+
if (rank == m_follow_rank)
1185+
{
1186+
m_files_notebook->set_current_page(page_num);
1187+
}
11601188
m_path_2_pagenum[fullpath] = page_num;
11611189
m_pagenum_2_path[page_num] = fullpath;
11621190
m_path_2_view[fullpath] = source_view;
@@ -1228,7 +1256,7 @@ void UIWindow::open_file()
12281256
if (Gtk::RESPONSE_OK == dialog->run())
12291257
{
12301258
string fullpath = dialog->get_filename();
1231-
append_source_file(fullpath);
1259+
append_source_file(fullpath, m_follow_rank);
12321260
}
12331261
dialog.reset();
12341262
}
@@ -1402,8 +1430,11 @@ void UIWindow::do_scroll(const int rank) const
14021430
*/
14031431
void UIWindow::scroll_to_line(const int rank) const
14041432
{
1405-
Glib::signal_idle().connect_once(
1406-
sigc::bind(sigc::mem_fun(this, &UIWindow::do_scroll), rank));
1433+
if (rank == m_follow_rank)
1434+
{
1435+
Glib::signal_idle().connect_once(
1436+
sigc::bind(sigc::mem_fun(this, &UIWindow::do_scroll), rank));
1437+
}
14071438
}
14081439

14091440
/**
@@ -1523,7 +1554,7 @@ void UIWindow::print_data_gdb(const char *const data, const int rank)
15231554
// this index is one-based!
15241555
const int line = stop_record->frame->line;
15251556
set_position(rank, fullpath, line);
1526-
append_source_file(fullpath);
1557+
append_source_file(fullpath, rank);
15271558
scroll_to_line(rank);
15281559
}
15291560
mi_free_stop(stop_record);

src/master/window.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class UIWindow
6464
{
6565
const int m_num_processes;
6666
int m_max_buttons_per_row;
67+
int m_follow_rank;
6768

6869
int *m_current_line;
6970
std::string *m_current_file;
@@ -127,7 +128,7 @@ class UIWindow
127128
void append_overview_row(const std::string &basename,
128129
const std::string &fullpath);
129130
/// Appends a source file page to the source view notebook.
130-
void append_source_file(const std::string &fullpath);
131+
void append_source_file(const std::string &fullpath, const int rank);
131132
/// Tokenizes, parses and analyzes the received GDB output.
132133
void print_data_gdb(const char *const data, const int rank);
133134
/// Appends text to the target I/O text view.
@@ -182,6 +183,8 @@ class UIWindow
182183
void on_about_clicked();
183184
/// Terminates the slaves and then quits the application.
184185
void on_quit_clicked();
186+
/// Opens a dialog to select the process to follow.
187+
void on_follow_button_clicked();
185188
/// Signal handler for all the interaction buttons.
186189
void on_interaction_button_clicked(const int key_value);
187190
/// Signal handler for key-press events.

0 commit comments

Comments
 (0)