Author: sveinung
Date: Thu Sep 10 12:31:05 2015
New Revision: 29848

URL: http://svn.gna.org/viewcvs/freeciv?rev=29848&view=rev
Log:
Qt client: Go to and... unit sub menu

Auto generated a "Go to and..." menu based on what the unit legally can do.
Since it's a goto it shouldn’t (by default) forbid what may become legal
when a unit reaches its target. (Example: Join the city that will be built
at the target tile next turn)

Keep the existing goto and do X orders in the old locations even if this
leads to duplication. They can be removed when the users are used to the new
locations.

Motivations:
* Allow the user to specify the order before the unit moves into harms way.
* The orders system can handle a lot more than the QT client currently
  sends.
* Make it easy to find a "Go to and..." unit order.

Putting it in an easy to discover context menu isn't in scope of this patch.
Neither is adding menu items for non action enabler controlled actions and
stuff like "nothing" (move) or "something" (action move).

See patch #6339

Modified:
    trunk/client/gui-qt/menu.cpp
    trunk/client/gui-qt/menu.h

Modified: trunk/client/gui-qt/menu.cpp
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-qt/menu.cpp?rev=29848&r1=29847&r2=29848&view=diff
==============================================================================
--- trunk/client/gui-qt/menu.cpp        (original)
+++ trunk/client/gui-qt/menu.cpp        Thu Sep 10 12:31:05 2015
@@ -63,6 +63,9 @@
 {
   /* PORTME */
   gov_menu::create_all();
+
+  /* A new ruleset may have been loaded. */
+  go_act_menu::reset_all();
 }
 
 /**************************************************************************
@@ -74,6 +77,7 @@
   if (C_S_RUNNING == client_state()) {
     gui()->menu_bar->menus_sensitive();
     gov_menu::update_all();
+    go_act_menu::update_all();
   }
 }
 
@@ -277,6 +281,161 @@
 void gov_menu::update_all()
 {
   foreach (gov_menu *m, instances) {
+    m->update();
+  }
+}
+
+/**************************************************************************
+  Instantiate a new goto and act sub menu.
+**************************************************************************/
+go_act_menu::go_act_menu(QWidget* parent)
+  : QMenu(_("Go to and..."), parent)
+{
+  go_act_mapper = new QSignalMapper(this);
+
+  /* Will need auto updates etc. */
+  instances << this;
+}
+
+/**************************************************************************
+  Destructor.
+**************************************************************************/
+go_act_menu::~go_act_menu()
+{
+  /* Updates are no longer needed. */
+  instances.remove(this);
+}
+
+/**************************************************************************
+  Reset the goto and act menu so it will be recreated.
+**************************************************************************/
+void go_act_menu::reset()
+{
+  QAction *action;
+
+  /* Clear out each existing menu item. */
+  foreach(action, QWidget::actions()) {
+    removeAction(action);
+    action->deleteLater();
+  }
+
+  /* Clear menu item to action ID mapping. */
+  items.clear();
+
+  /* Reset the Qt signal mapper */
+  go_act_mapper->deleteLater();
+  go_act_mapper = new QSignalMapper(this);
+}
+
+/**************************************************************************
+  Fill the new goto and act sub menu with menu items.
+**************************************************************************/
+void go_act_menu::create()
+{
+  QAction *item;
+  int tgt_kind_group;
+
+  /* Group goto and perform action menu items by target kind. */
+  for (tgt_kind_group = 0; tgt_kind_group < ATK_COUNT; tgt_kind_group++) {
+    action_iterate(action_id) {
+      if (action_get_actor_kind(action_id) != AAK_UNIT) {
+        /* This action isn't performed by a unit. */
+        continue;
+      }
+
+      if (action_get_target_kind(action_id) != tgt_kind_group) {
+        /* Wrong group. */
+        continue;
+      }
+
+      if (action_requires_details(action_id)) {
+        /* The order system doesn't support actions that requires the
+         * player to specify details. */
+        continue;
+      }
+
+      /* Create and add the menu item. It will be hidden or shown based on
+       * unit type.  */
+      item = addAction(action_get_ui_name(action_id));
+      items.insert(item, action_id);
+      connect(item, SIGNAL(triggered()),
+              go_act_mapper, SLOT(map()));
+      go_act_mapper->setMapping(item, action_id);
+    } action_iterate_end;
+  }
+
+  connect(go_act_mapper, SIGNAL(mapped(int)), this, SLOT(start_go_act(int)));
+}
+
+/**************************************************************************
+  Update the goto and act menu based on the selected unit(s)
+**************************************************************************/
+void go_act_menu::update()
+{
+  bool can_do_something = false;
+
+  if (!actions_are_ready()) {
+    /* Nothing to do. */
+    return;
+  }
+
+  if (items.isEmpty()) {
+    /* The goto and act menu needs menu items. */
+    create();
+  }
+
+  /* Enable a menu item if it is theoretically possible that one of the
+   * selected units can perform it. Checking if the action can be performed
+   * at the current tile is pointless since it should be performed at the
+   * target tile. */
+  foreach(QAction *item, items.keys()) {
+    if (units_can_do_action(get_units_in_focus(),
+                            items.value(item), TRUE)) {
+      item->setVisible(true);
+      can_do_something = true;
+    } else {
+      item->setVisible(false);
+    }
+  }
+
+  if (can_do_something) {
+    /* At least one menu item is enabled for one of the selected units. */
+    setEnabled(true);
+  } else {
+    /* No menu item is enabled any of the selected units. */
+    setEnabled(false);
+  }
+}
+
+/**************************************************************************
+  Activate the goto system
+**************************************************************************/
+void go_act_menu::start_go_act(int action_id)
+{
+  request_unit_goto(ORDER_PERFORM_ACTION, action_id);
+}
+
+/**************************************************************************
+  Store all goto and act menu items so they can be updated etc
+**************************************************************************/
+QSet<go_act_menu *> go_act_menu::instances;
+
+/**************************************************************************
+  Reset all goto and act menu instances.
+**************************************************************************/
+void go_act_menu::reset_all()
+{
+  foreach (go_act_menu *m, instances) {
+    m->reset();
+  }
+}
+
+/**************************************************************************
+  Update all goto and act menu instances
+**************************************************************************/
+void go_act_menu::update_all()
+{
+  foreach (go_act_menu *m, instances) {
     m->update();
   }
 }
@@ -608,6 +767,10 @@
   act->setShortcut(QKeySequence(tr("g")));
   menu_list.insertMulti(STANDARD, act);
   connect(act, SIGNAL(triggered()), this, SLOT(slot_unit_goto()));
+
+  /* The goto and act sub menu is handled as a separate object. */
+  menu->addMenu(new go_act_menu());
+
   act = menu->addAction(_("Go to Nearest City"));
   act->setShortcut(QKeySequence(tr("shift+g")));
   menu_list.insertMulti(GOTO_CITY, act);

Modified: trunk/client/gui-qt/menu.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-qt/menu.h?rev=29848&r1=29847&r2=29848&view=diff
==============================================================================
--- trunk/client/gui-qt/menu.h  (original)
+++ trunk/client/gui-qt/menu.h  Thu Sep 10 12:31:05 2015
@@ -134,6 +134,32 @@
   void update();
 };
 
+/****************************************************************************
+  Go to and... menu.
+****************************************************************************/
+class go_act_menu : public QMenu
+{
+  Q_OBJECT
+  static QSet<go_act_menu *> instances;
+
+  QSignalMapper *go_act_mapper;
+  QMap<QAction *, int> items;
+
+public:
+  go_act_menu(QWidget* parent = 0);
+  virtual ~go_act_menu();
+
+  static void reset_all();
+  static void update_all();
+
+public slots:
+  void start_go_act(int action_id);
+
+  void reset();
+  void create();
+  void update();
+};
+
 /**************************************************************************
   Class representing global menus in gameview
 **************************************************************************/


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to