/**
 * @brief Creates a map editor.
 * @param quest The quest containing the file.
 * @param path Path of the map data file to open.
 * @param parent The parent object or nullptr.
 * @throws EditorException If the file could not be opened.
 */
MapEditor::MapEditor(Quest& quest, const QString& path, QWidget* parent) :
  Editor(quest, path, parent),
  map_id(),
  map(nullptr),
  entity_creation_toolbar(nullptr),
  status_bar(nullptr),
  ignore_tileset_selection_changes(false) {

  ui.setupUi(this);
  build_entity_creation_toolbar();
  build_status_bar();

  // Get the map.
  ResourceType resource_type;
  QString map_id;
  quest.check_exists(path);
  if (!quest.is_resource_element(path, resource_type, map_id) ||
      resource_type != ResourceType::MAP) {
    throw EditorException(tr("File '%1' is not a map").arg(path));
  }
  this->map_id = map_id;

  // Editor properties.
  set_title(tr("Map %1").arg(get_file_name_without_extension()));
  set_icon(QIcon(":/images/icon_resource_map.png"));
  set_close_confirm_message(
        tr("Map '%1' has been modified. Save changes?").arg(map_id));
  set_select_all_supported(true);
  set_zoom_supported(true);
  get_view_settings().set_zoom(2.0);
  set_grid_supported(true);
  set_entity_type_visibility_supported(true);

  // Shortcuts.
  QAction* open_script_action = new QAction(this);
  open_script_action->setShortcut(tr("F4"));
  open_script_action->setShortcutContext(Qt::WindowShortcut);
  connect(open_script_action, SIGNAL(triggered(bool)),
          this, SLOT(open_script_requested()));
  addAction(open_script_action);

  // Open the file.
  map = new MapModel(quest, map_id, this);
  get_undo_stack().setClean();

  // Prepare the gui.
  const int side_width = 350;
  ui.splitter->setSizes({ side_width, width() - side_width });
  ui.map_side_splitter->setStretchFactor(0, 0);  // Don't expand the map properties view
  ui.map_side_splitter->setStretchFactor(1, 1);  // but only the tileset view.
  ui.tileset_field->set_resource_type(ResourceType::TILESET);
  ui.tileset_field->set_quest(quest);
  ui.music_field->set_resource_type(ResourceType::MUSIC);
  ui.music_field->set_quest(quest);
  ui.music_field->add_special_value("none", tr("<No music>"), 0);
  ui.music_field->add_special_value("same", tr("<Same as before>"), 1);
  ui.tileset_view->set_read_only(true);
  ui.map_view->set_map(map);
  ui.map_view->set_view_settings(get_view_settings());
  ui.map_view->set_common_actions(&get_common_actions());

  ui.size_field->config("x", 0, 99999, 8);
  ui.size_field->set_tooltips(
    tr("Width of the map in pixels"),
    tr("Height of the map in pixels"));

  ui.location_field->config(",", 0, 99999, 8);
  ui.location_field->set_tooltips(
    tr("Coordinates of the map in its world (useful to make adjacent scrolling maps)"),
    tr("Coordinates of the map in its world (useful to make adjacent scrolling maps)"));

  set_num_layers_visibility_supported(map->get_num_layers());

  load_settings();
  update();

  // Make connections.
  connect(&get_resources(), SIGNAL(element_description_changed(ResourceType, QString, QString)),
          this, SLOT(update_description_to_gui()));
  connect(ui.description_field, SIGNAL(editingFinished()),
          this, SLOT(set_description_from_gui()));

  connect(ui.size_field, SIGNAL(editing_finished()),
          this, SLOT(change_size_requested()));
  connect(map, SIGNAL(size_changed(QSize)),
          this, SLOT(update_size_field()));

  connect(ui.world_check_box, SIGNAL(stateChanged(int)),
          this, SLOT(world_check_box_changed()));
  connect(ui.world_field, SIGNAL(editingFinished()),
          this, SLOT(change_world_requested()));
  connect(map, SIGNAL(world_changed(QString)),
          this, SLOT(update_world_field()));

  connect(ui.floor_check_box, SIGNAL(stateChanged(int)),
          this, SLOT(floor_check_box_changed()));
  connect(ui.floor_field, SIGNAL(editingFinished()),
          this, SLOT(change_floor_requested()));
  connect(map, SIGNAL(floor_changed(int)),
          this, SLOT(update_floor_field()));

  connect(ui.location_field, SIGNAL(editing_finished()),
          this, SLOT(change_location_requested()));
  connect(map, SIGNAL(location_changed(QPoint)),
          this, SLOT(update_location_field()));

  connect(ui.tileset_field, SIGNAL(activated(QString)),
          this, SLOT(tileset_selector_activated()));
  connect(map, SIGNAL(tileset_id_changed(QString)),
          this, SLOT(tileset_id_changed(QString)));
  connect(ui.tileset_refresh_button, SIGNAL(clicked()),
          map, SLOT(tileset_modified()));
  connect(ui.tileset_edit_button, SIGNAL(clicked()),
          this, SLOT(open_tileset_requested()));

  connect(ui.music_field, SIGNAL(activated(QString)),
          this, SLOT(music_selector_activated()));
  connect(map, SIGNAL(music_id_changed(QString)),
          this, SLOT(update_music_field()));

  connect(ui.open_script_button, SIGNAL(clicked()),
          this, SLOT(open_script_requested()));

  connect(ui.map_view, SIGNAL(edit_entity_requested(EntityIndex, EntityModelPtr&)),
          this, SLOT(edit_entity_requested(EntityIndex, EntityModelPtr&)));
  connect(ui.map_view, SIGNAL(move_entities_requested(EntityIndexes, QPoint, bool)),
          this, SLOT(move_entities_requested(EntityIndexes, QPoint, bool)));
  connect(ui.map_view, SIGNAL(resize_entities_requested(QMap<EntityIndex, QRect>, bool)),
          this, SLOT(resize_entities_requested(QMap<EntityIndex, QRect>, bool)));
  connect(ui.map_view, SIGNAL(convert_tiles_requested(EntityIndexes)),
          this, SLOT(convert_tiles_requested(EntityIndexes)));
  connect(ui.map_view, SIGNAL(set_entities_direction_requested(EntityIndexes, int)),
          this, SLOT(set_entities_direction_requested(EntityIndexes, int)));
  connect(ui.map_view, SIGNAL(set_entities_layer_requested(EntityIndexes, int)),
          this, SLOT(set_entities_layer_requested(EntityIndexes, int)));
  connect(ui.map_view, SIGNAL(bring_entities_to_front_requested(EntityIndexes)),
          this, SLOT(bring_entities_to_front_requested(EntityIndexes)));
  connect(ui.map_view, SIGNAL(bring_entities_to_back_requested(EntityIndexes)),
          this, SLOT(bring_entities_to_back_requested(EntityIndexes)));
  connect(ui.map_view, SIGNAL(add_entities_requested(AddableEntities&)),
          this, SLOT(add_entities_requested(AddableEntities&)));
  connect(ui.map_view, SIGNAL(remove_entities_requested(EntityIndexes)),
          this, SLOT(remove_entities_requested(EntityIndexes)));

  connect(ui.map_view->get_scene(), SIGNAL(selectionChanged()),
          this, SLOT(map_selection_changed()));
}
Beispiel #2
0
GtkWidget *gui_build_interface(void)
{
	GtkWidget *vbox;
	GtkWidget *menubar;
	GtkActionGroup *action_group;
	GtkAccelGroup *accel_group;
	GError *error = NULL;
	gchar *icon_file;

	player_init();

	gmap = guimap_new();

	register_pixmaps();
	app_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	/* The name of the application */
	gtk_window_set_title(GTK_WINDOW(app_window), _("Pioneers"));

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_widget_show(vbox);
	gtk_container_add(GTK_CONTAINER(app_window), vbox);

	action_group = gtk_action_group_new("MenuActions");
	gtk_action_group_set_translation_domain(action_group, PACKAGE);
	gtk_action_group_add_actions(action_group, entries,
				     G_N_ELEMENTS(entries), app_window);
	gtk_action_group_add_toggle_actions(action_group, toggle_entries,
					    G_N_ELEMENTS(toggle_entries),
					    app_window);

	ui_manager = gtk_ui_manager_new();
	gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);

	accel_group = gtk_ui_manager_get_accel_group(ui_manager);
	gtk_window_add_accel_group(GTK_WINDOW(app_window), accel_group);

	error = NULL;
	if (!gtk_ui_manager_add_ui_from_string
	    (ui_manager, ui_description, -1, &error)) {
		g_message("building menus failed: %s", error->message);
		g_error_free(error);
		return NULL;
	}

	icon_file =
	    g_build_filename(DATADIR, "pixmaps", PIONEERS_ICON_FILE, NULL);
	if (g_file_test(icon_file, G_FILE_TEST_EXISTS)) {
		gtk_window_set_default_icon_from_file(icon_file, NULL);
	} else {
		/* Missing pixmap, main icon file */
		g_warning("Pixmap not found: %s", icon_file);
	}
	g_free(icon_file);

	color_chat_enabled =
	    config_get_int_with_default("settings/color_chat", TRUE);

	color_messages_enabled =
	    config_get_int_with_default("settings/color_messages", TRUE);
	log_set_func_message_color_enable(color_messages_enabled);

	set_color_summary(config_get_int_with_default
			  ("settings/color_summary", TRUE));

	set_silent_mode(config_get_int_with_default
			("settings/silent_mode", FALSE));
	set_announce_player(config_get_int_with_default
			    ("settings/announce_player", TRUE));

	legend_page_enabled =
	    config_get_int_with_default("settings/legend_page", FALSE);

	menubar = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
	gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
	toolbar = gtk_ui_manager_get_widget(ui_manager, "/MainToolbar");
	gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), build_main_interface(), TRUE,
			   TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), build_status_bar(), FALSE, FALSE,
			   0);

	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION
				     (gtk_ui_manager_get_action
				      (ui_manager,
				       "ui/MainMenu/SettingsMenu/ShowHideToolbar")),
				     config_get_int_with_default
				     ("settings/show_toolbar", TRUE));

	g_signal_connect(G_OBJECT(app_window), "key_press_event",
			 G_CALLBACK(hotkeys_handler), NULL);

	gtk_widget_show(app_window);

	frontend_gui_register_action(getAction(GUI_CONNECT), GUI_CONNECT);
	frontend_gui_register_action(getAction(GUI_DISCONNECT),
				     GUI_DISCONNECT);
#ifdef ADMIN_GTK
	/** @todo RC 2005-05-26 Admin interface: Not tested */
	frontend_gui_register_action(gtk_ui_manager_get_action
				     (manager,
				      "ui/MainMenu/GameMenu/GameAdmin"),
				     GUI_ADMIN);
#endif
	frontend_gui_register_action(getAction(GUI_CHANGE_NAME),
				     GUI_CHANGE_NAME);
	frontend_gui_register_action(getAction(GUI_ROLL), GUI_ROLL);
	frontend_gui_register_action(getAction(GUI_TRADE), GUI_TRADE);
	frontend_gui_register_action(getAction(GUI_UNDO), GUI_UNDO);
	frontend_gui_register_action(getAction(GUI_FINISH), GUI_FINISH);
	frontend_gui_register_action(getAction(GUI_ROAD), GUI_ROAD);
	frontend_gui_register_action(getAction(GUI_SHIP), GUI_SHIP);
	frontend_gui_register_action(getAction(GUI_MOVE_SHIP),
				     GUI_MOVE_SHIP);
	frontend_gui_register_action(getAction(GUI_BRIDGE), GUI_BRIDGE);
	frontend_gui_register_action(getAction(GUI_SETTLEMENT),
				     GUI_SETTLEMENT);
	frontend_gui_register_action(getAction(GUI_CITY), GUI_CITY);
	frontend_gui_register_action(getAction(GUI_BUY_DEVELOP),
				     GUI_BUY_DEVELOP);
	frontend_gui_register_action(getAction(GUI_CITY_WALL),
				     GUI_CITY_WALL);
#if 0
	frontend_gui_register_destroy(gtk_ui_manager_get_action
				      (manager, "GameQuit"), GUI_QUIT);
#endif

	gui_toolbar_show_button("BuildShip", FALSE);
	gui_toolbar_show_button("MoveShip", FALSE);
	gui_toolbar_show_button("BuildBridge", FALSE);

	gui_toolbar_show_accelerators(config_get_int_with_default
				      ("settings/toolbar_show_accelerators",
				       TRUE));

	gtk_ui_manager_ensure_update(ui_manager);
	gtk_widget_show(app_window);
	g_signal_connect(G_OBJECT(app_window), "delete_event",
			 G_CALLBACK(quit_cb), NULL);

	return app_window;
}