1 #pragma once
2 #include "core/core.hpp"
3 #include "imp_interface.hpp"
4 #include "keyseq_dialog.hpp"
5 #include "main_window.hpp"
6 #include "pool/pool.hpp"
7 #include "preferences/preferences.hpp"
8 #include "selection_filter_dialog.hpp"
9 #include "util/window_state_store.hpp"
10 #include "widgets/spin_button_dim.hpp"
11 #include "widgets/warnings_box.hpp"
12 #include "action.hpp"
13 #include "nlohmann/json.hpp"
14 #include "search/searcher.hpp"
15 #include <zmq.hpp>
16 #include "util/item_set.hpp"
17 #include "canvas/canvas_gl.hpp"
18 #include "grid_controller.hpp"
19 #include "util/action_label.hpp"
20 #include <optional>
21 #include "core/clipboard/clipboard.hpp"
22 #include "clipboard_handler.hpp"
23 #include "util/win32_undef.hpp"
24 
25 namespace horizon {
26 
27 class PoolParams {
28 public:
PoolParams(const std::string & bp)29     PoolParams(const std::string &bp) : base_path(bp)
30     {
31     }
32     std::string base_path;
33 };
34 
35 class ImpBase {
36     friend class ImpInterface;
37 
38 public:
39     ImpBase(const PoolParams &params);
40     void run(int argc, char *argv[]);
41     virtual void handle_tool_change(ToolID id);
42     virtual void construct() = 0;
43     void canvas_update_from_pp();
~ImpBase()44     virtual ~ImpBase()
45     {
46     }
47     void set_read_only(bool v);
48 
49     std::set<ObjectRef> highlights;
update_highlights()50     virtual void update_highlights(){};
51 
52     class SelectionFilterInfo {
53     public:
54         enum class Flag {
55             DEFAULT,
56             HAS_OTHERS,
57             WORK_LAYER_ONLY_ENABLED,
58         };
SelectionFilterInfo()59         SelectionFilterInfo()
60         {
61         }
SelectionFilterInfo(const std::vector<int> & l,Flag fl)62         SelectionFilterInfo(const std::vector<int> &l, Flag fl) : layers(l), flags(fl)
63         {
64         }
65         std::vector<int> layers;
66         Flag flags = Flag::DEFAULT;
67     };
68 
69     virtual std::map<ObjectType, SelectionFilterInfo> get_selection_filter_info() const;
is_layered() const70     virtual bool is_layered() const
71     {
72         return false;
73     };
74 
75 protected:
76     MainWindow *main_window;
77     CanvasGL *canvas;
78     class PropertyPanels *panels;
79     WarningsBox *warnings_box;
80     class ToolPopover *tool_popover;
81     Gtk::Menu *context_menu = nullptr;
82     std::unique_ptr<SelectionFilterDialog> selection_filter_dialog;
83     std::optional<GridController> grid_controller;
84     class GridsWindow *grids_window = nullptr;
85 
86     std::unique_ptr<Pool> pool;
87     std::unique_ptr<Pool> real_pool_caching;
88     Pool *pool_caching;
89     class Core *core = nullptr;
90     std::unique_ptr<ClipboardBase> clipboard = nullptr;
91     std::unique_ptr<ClipboardHandler> clipboard_handler = nullptr;
92     std::unique_ptr<KeySequenceDialog> key_sequence_dialog = nullptr;
93     std::unique_ptr<ImpInterface> imp_interface = nullptr;
94     Glib::RefPtr<Glib::Binding> grid_spacing_binding;
95 
96     std::map<ActionToolID, ActionConnection> action_connections;
97     ActionConnection &connect_action(ToolID tool_id, std::function<void(const ActionConnection &)> cb);
98     ActionConnection &connect_action(ToolID tool_id);
99     ActionConnection &connect_action(ActionID action_id, std::function<void(const ActionConnection &)> cb);
100 
101     class RulesWindow *rules_window = nullptr;
102 
103     zmq::context_t zctx;
104     zmq::socket_t sock_broadcast_rx;
105     zmq::socket_t sock_project;
106     bool sockets_connected = false;
107     int mgr_pid = -1;
108     bool no_update = false;
109     bool distraction_free = false;
110 
111     virtual void canvas_update() = 0;
112     virtual void expand_selection_for_property_panel(std::set<SelectableRef> &sel_extra,
113                                                      const std::set<SelectableRef> &sel);
114     void handle_selection_changed(void);
handle_selection_cross_probe()115     virtual void handle_selection_cross_probe()
116     {
117     }
118     bool handle_key_press(const GdkEventKey *key_event);
119     void handle_cursor_move(const Coordi &pos);
120     bool handle_click(const GdkEventButton *button_event);
handle_extra_button(const GdkEventButton * button_event)121     virtual void handle_extra_button(const GdkEventButton *button_event)
122     {
123     }
124     bool handle_click_release(const GdkEventButton *button_event);
125     bool handle_context_menu(const GdkEventButton *button_event);
126     void tool_process(ToolResponse &resp);
127     void tool_begin(ToolID id, bool override_selection = false, const std::set<SelectableRef> &sel = {},
128                     std::unique_ptr<ToolData> data = nullptr);
129     void add_tool_button(ToolID id, const std::string &label, bool left = true);
130     void handle_warning_selected(const Coordi &pos);
131     virtual bool handle_broadcast(const json &j);
132     bool handle_close(const GdkEventAny *ev);
133     json send_json(const json &j);
134 
135     bool trigger_action(const ActionToolID &action);
136     bool trigger_action(ActionID aid);
137     bool trigger_action(ToolID tid);
138 
139     void add_tool_action(ToolID tid, const std::string &action);
140     void add_tool_action(ActionID aid, const std::string &action);
141     void add_hamburger_menu();
142 
143     Preferences preferences;
144 
get_canvas_preferences()145     virtual const CanvasPreferences &get_canvas_preferences()
146     {
147         return preferences.canvas_non_layer;
148     }
149     virtual void apply_preferences();
150 
151     std::unique_ptr<WindowStateStore> state_store = nullptr;
152 
153     virtual void handle_maybe_drag(bool ctrl);
154 
155     virtual ActionCatalogItem::Availability get_editor_type_for_action() const = 0;
156     ObjectType get_editor_type() const;
157 
158     void layer_up_down(bool up);
159     void goto_layer(int layer);
160 
161     Gtk::Button *create_action_button(ActionToolID action);
162 
163     void set_action_sensitive(ActionToolID, bool v);
164     bool get_action_sensitive(ActionToolID) const;
165     virtual void update_action_sensitivity();
166 
167     typedef sigc::signal<void> type_signal_action_sensitive;
signal_action_sensitive()168     type_signal_action_sensitive signal_action_sensitive()
169     {
170         return s_signal_action_sensitive;
171     }
172 
173     virtual std::string get_hud_text(std::set<SelectableRef> &sel);
174     std::string get_hud_text_for_component(const Component *comp);
175     std::string get_hud_text_for_net(const Net *net);
176 
177     void set_monitor_files(const std::set<std::string> &files);
178     void set_monitor_items(const ItemSet &items);
update_monitor()179     virtual void update_monitor()
180     {
181     }
182     void edit_pool_item(ObjectType type, const UUID &uu);
183 
184     void parameter_window_add_polygon_expand(class ParameterWindow *parameter_window);
185 
186     bool read_only = false;
187 
188     void tool_update_data(std::unique_ptr<ToolData> &data);
189 
190     virtual void search_center(const Searcher::SearchResult &res);
191     virtual ActionToolID get_doubleclick_action(ObjectType type, const UUID &uu);
192 
193     Glib::RefPtr<Gio::Menu> hamburger_menu;
194 
195     json m_meta;
196     void load_meta();
197     static const std::string meta_suffix;
198 
get_save_meta(json & j)199     virtual void get_save_meta(json &j)
200     {
201     }
202 
203     void set_window_title(const std::string &s);
204     void set_window_title_from_block();
205 
206     void update_view_hints();
207     virtual std::vector<std::string> get_view_hints();
208 
209     Gtk::Box *view_options_menu = nullptr;
210     void view_options_menu_append_action(const std::string &label, const std::string &action);
211 
get_searcher_ptr()212     virtual Searcher *get_searcher_ptr()
213     {
214         return nullptr;
215     }
216 
has_searcher()217     bool has_searcher()
218     {
219         return get_searcher_ptr();
220     }
221 
get_searcher()222     Searcher &get_searcher()
223     {
224         auto s = get_searcher_ptr();
225         if (!s)
226             throw std::runtime_error("not implemented");
227         return *s;
228     }
229 
230     class ActionButton &add_action_button(ActionToolID action);
231     class ActionButtonMenu &add_action_button_menu(const char *icon_name);
232     class ActionButton &add_action_button_polygon();
233     class ActionButton &add_action_button_line();
234 
235     virtual ToolID get_tool_for_drag_move(bool ctrl, const std::set<SelectableRef> &sel) const;
236     void force_end_tool();
237     void reset_tool_hint_label();
238 
239 private:
240     void fix_cursor_pos();
241     Glib::RefPtr<Gio::FileMonitor> preferences_monitor;
242     void handle_drag();
243     void update_selection_label();
244     std::string get_tool_settings_filename(ToolID id);
245 
246     void hud_update();
247 
248     std::map<std::string, Glib::RefPtr<Gio::FileMonitor>> file_monitors;
249     sigc::connection file_monitor_delay_connection;
250 
251     void handle_file_changed(const Glib::RefPtr<Gio::File> &file1, const Glib::RefPtr<Gio::File> &file2,
252                              Gio::FileMonitorEvent ev);
253 
254     ActionConnection &connect_action(ActionID action_id, ToolID tool_id,
255                                      std::function<void(const ActionConnection &)> cb);
256 
257     void create_context_menu(Gtk::Menu *parent, const std::set<SelectableRef> &sel);
258     Gtk::MenuItem *create_context_menu_item(ActionToolID act);
259 
260     KeySequence keys_current;
261     KeyMatchResult keys_match(const KeySequence &keys) const;
262     bool handle_action_key(const GdkEventKey *ev);
263     void handle_tool_action(const ActionConnection &conn);
264     void handle_select_polygon(const ActionConnection &a);
265 
266     void handle_search();
267     void search_go(int dir);
268     std::list<Searcher::SearchResult> search_results;
269     unsigned int search_result_current = 0;
270     void update_search_markers();
271     void update_search_types_label();
272     void set_search_mode(bool enabled, bool focus = true);
273     std::map<Searcher::Type, Gtk::CheckButton *> search_check_buttons;
274 
275     class LogWindow *log_window = nullptr;
276     std::set<SelectableRef> selection_for_drag_move;
277     ToolID drag_tool;
278     Coordf cursor_pos_drag_begin;
279     Coordi cursor_pos_grid_drag_begin;
280 
281     std::map<ActionToolID, bool> action_sensitivity;
282     type_signal_action_sensitive s_signal_action_sensitive;
283 
284     bool property_panel_has_focus();
285 
286     sigc::connection initial_view_all_conn;
287 
288     bool sockets_broken = false;
289     void show_sockets_broken_dialog(const std::string &msg = "");
290     bool needs_autosave = false;
291     bool queue_autosave = false;
292 
293     void update_property_panels();
294     std::map<CanvasGL::SelectionTool, CanvasGL::SelectionQualifier> selection_qualifiers;
295     std::list<class ActionButtonBase *> action_buttons;
296 
297     Glib::RefPtr<Gio::SimpleAction> bottom_view_action;
298     Glib::RefPtr<Gio::SimpleAction> distraction_free_action;
299 
300     int left_panel_width = 0;
301 
302     void tool_bar_set_actions(const std::vector<ActionLabelInfo> &labels);
303     void tool_bar_append_action(InToolActionID action1, InToolActionID action2, const std::string &s);
304     void tool_bar_clear_actions();
305     InToolKeySequencesPreferences in_tool_key_sequeces_preferences;
306     std::vector<ActionLabelInfo> in_tool_action_label_infos;
307 
308     void show_preferences(std::optional<std::string> page = std::nullopt);
309 
310     void init_search();
311     void init_key();
312     void init_action();
313 
314     void handle_pan_action(const ActionConnection &c);
315     void handle_zoom_action(const ActionConnection &c);
316 
317     std::string get_complete_display_name(const SelectableRef &sr);
318 
319     void set_flip_view(bool flip);
320     void apply_arrow_keys();
321     void check_version();
322 
323     void update_cursor(ToolID tool_id);
324 
325     std::set<SelectableRef> last_canvas_selection;
326 };
327 } // namespace horizon
328