Will do the numbers then.

The discinct message types are needed elsewhere, see the diff comment for 
details.

Diff comments:

> === modified file 'pics/message_archive.png'
> Binary files pics/message_archive.png 2010-01-14 18:22:23 +0000 and 
> pics/message_archive.png  2014-09-29 15:04:07 +0000 differ
> === modified file 'pics/message_archived.png'
> Binary files pics/message_archived.png        2010-01-14 18:22:23 +0000 and 
> pics/message_archived.png 2014-09-29 15:04:07 +0000 differ
> === added file 'pics/message_clear_selection.png'
> Binary files pics/message_clear_selection.png 1970-01-01 00:00:00 +0000 and 
> pics/message_clear_selection.png  2014-09-29 15:04:07 +0000 differ
> === modified file 'pics/message_restore.png'
> Binary files pics/message_restore.png 2010-01-14 18:22:23 +0000 and 
> pics/message_restore.png  2014-09-29 15:04:07 +0000 differ
> === added file 'pics/message_selection_invert.png'
> Binary files pics/message_selection_invert.png        1970-01-01 00:00:00 
> +0000 and pics/message_selection_invert.png 2014-09-29 15:04:07 +0000 differ
> === added file 'pics/messages_warfare.png'
> Binary files pics/messages_warfare.png        1970-01-01 00:00:00 +0000 and 
> pics/messages_warfare.png 2014-09-29 15:04:07 +0000 differ
> === modified file 'src/logic/building.cc'
> --- src/logic/building.cc     2014-09-18 18:56:20 +0000
> +++ src/logic/building.cc     2014-09-29 15:04:07 +0000
> @@ -879,7 +879,7 @@
>   */
>  void Building::send_message
>       (Game & game,
> -      const std::string & msgsender,
> +      const Message::Type msgtype,
>        const std::string & title,
>        const std::string & description,
>        bool link_to_building_lifetime,
> @@ -910,7 +910,7 @@
>       rt_description += "</p></rt>";
>  
>       Message * msg = new Message
> -             (msgsender, game.get_gametime(), title, rt_description,
> +             (msgtype, game.get_gametime(), title, rt_description,
>                get_position(), (link_to_building_lifetime ? m_serial : 0));
>  
>       if (throttle_time)
> 
> === modified file 'src/logic/building.h'
> --- src/logic/building.h      2014-09-14 11:31:58 +0000
> +++ src/logic/building.h      2014-09-29 15:04:07 +0000
> @@ -31,6 +31,7 @@
>  #include "logic/bill_of_materials.h"
>  #include "logic/buildcost.h"
>  #include "logic/immovable.h"
> +#include "logic/message.h"
>  #include "logic/soldier_counts.h"
>  #include "logic/wareworker.h"
>  #include "logic/widelands.h"
> @@ -259,7 +260,7 @@
>  
>       void send_message
>               (Game & game,
> -              const std::string & msgsender,
> +              const Message::Type msgtype,
>                const std::string & title,
>                const std::string & description,
>                bool link_to_building_lifetime = true,
> 
> === modified file 'src/logic/cmd_luacoroutine.cc'
> --- src/logic/cmd_luacoroutine.cc     2014-09-18 18:56:20 +0000
> +++ src/logic/cmd_luacoroutine.cc     2014-09-29 15:04:07 +0000
> @@ -50,7 +50,7 @@
>               for (int i = 1; i <= game.map().get_nrplayers(); i++) {
>                       Widelands::Message & msg =
>                               *new Widelands::Message
> -                             ("Game Logic", game.get_gametime(), "Lua 
> Coroutine Failed", e.what());
> +                             (Message::Type::gameLogic, game.get_gametime(), 
> "Lua Coroutine Failed", e.what());
>                       game.player(i).add_message(game, msg, true);
>               }
>               game.gameController()->setDesiredSpeed(0);
> 
> === modified file 'src/logic/message.h'
> --- src/logic/message.h       2014-09-15 10:17:53 +0000
> +++ src/logic/message.h       2014-09-29 15:04:07 +0000
> @@ -30,9 +30,29 @@
>  
>  struct Message {
>       enum Status {New, Read, Archived};
> +     enum class Type: uint8_t {
> +             noMessages,

I can give them the k prefix, no problem. The Google Style Guide is new to me, 
and I haven't done the bug about enum member renaming yet ;)

About the multiple names, they are needed elsewhere:

Geologist needs distinct message types, otherwise each geologist will only send 
1 message instead of 1 message for each resource type.

Militarysites need multiple message types to play special notification sounds 
for the site being attacked etc.

> +             allMessages,
> +             gameLogic,
> +             geologists,
> +             geologistsCoal,
> +             geologistsGold,
> +             geologistsGranite,
> +             geologistsIron,
> +             geologistsWater,
> +             scenario,
> +             seafaring,
> +             economy,      // economy
> +             siteOccupied, // economy
> +             warfare,     // everything starting from here is warfare
> +             siteDefeated,
> +             siteLost,
> +             underAttack
> +     };
> +
>       /**
>        * A new message to be displayed to the player
> -      * \param msgsender The message sender
> +      * \param msgtype The type of message (economy, geologists, etc.)
>        * \param sent_time The (game) time at which the message is sent
>        * \param t The message title
>        * \param b The message body
> @@ -43,7 +63,7 @@
>        * \param s The message status. Defaults to Status::New
>        */
>       Message
> -             (const std::string &       msgsender,
> +             (Message::Type             msgtype,
>                uint32_t                  sent_time,
>                const std::string &       t,
>                const std::string &       b,
> @@ -51,8 +71,8 @@
>                Widelands::Serial         ser = 0,
>                Status                    s = New)
>               :
> -             m_sender(msgsender),
> -             m_title(t),
> +             m_type    (msgtype),
> +             m_title   (t),
>               m_body    (b),
>               m_sent    (sent_time),
>               m_position(c),
> @@ -60,18 +80,35 @@
>               m_status  (s)
>       {}
>  
> -     const std::string & sender() const     {return m_sender;}
> -     uint32_t            sent    () const            {return m_sent;}
> -     const std::string & title() const      {return m_title;}
> -     const std::string & body () const               {return m_body;}
> -     Widelands::Coords   position() const            {return m_position;}
> -     Widelands::Serial   serial() const              {return m_serial;}
> -     Status              status  () const {return m_status;}
> -     Status set_status(Status const s) {return m_status = s;}
> +     Message::Type         type    () const   {return m_type;}
> +     uint32_t              sent    () const   {return m_sent;}
> +     const std::string &   title   () const   {return m_title;}
> +     const std::string &   body    () const   {return m_body;}
> +     Widelands::Coords     position() const   {return m_position;}
> +     Widelands::Serial     serial  () const   {return m_serial;}
> +     Status                status  () const   {return m_status;}
> +     Status set_status(Status const s)        {return m_status = s;}
> +
> +     /**
> +      * Returns the main type for the message's sub type
> +      */
> +     Message::Type message_type_category() const {
> +             if (m_type >=  Widelands::Message::Type::warfare) {
> +                     return Widelands::Message::Type::warfare;
> +
> +             } else if (m_type >= Widelands::Message::Type::economy &&
> +                                       m_type <= 
> Widelands::Message::Type::siteOccupied) {
> +                     return Widelands::Message::Type::economy;
> +             } else if (m_type >= Widelands::Message::Type::geologists &&
> +                                      m_type <= 
> Widelands::Message::Type::geologistsWater) {
> +               return Widelands::Message::Type::geologists;
> +       }
> +             return m_type;
> +     }
>  
>  private:
> -     std::string m_sender;
> -     std::string m_title;
> +     Message::Type     m_type;
> +     std::string       m_title;
>       std::string       m_body;
>       uint32_t          m_sent;
>       Widelands::Coords m_position;
> 
> === modified file 'src/logic/militarysite.cc'
> --- src/logic/militarysite.cc 2014-09-10 10:18:46 +0000
> +++ src/logic/militarysite.cc 2014-09-29 15:04:07 +0000
> @@ -248,7 +248,7 @@
>               if (upcast(Game, game, &egbase)) {
>                       send_message
>                               (*game,
> -                              "site_occupied",
> +                              Message::Type::siteOccupied,
>                                descr().descname(),
>                                descr().m_occupied_str,
>                                true);
> @@ -845,7 +845,7 @@
>               {
>                       send_message
>                               (game,
> -                              "site_lost",
> +                              Message::Type::siteLost,
>                                _("Militarysite lost!"),
>                                descr().m_defeated_enemy_str,
>                                false);
> @@ -899,7 +899,7 @@
>               // Of course we should inform the victorious player as well
>               newsite->send_message
>                       (game,
> -                      "site_defeated",
> +                      Message::Type::siteDefeated,
>                        _("Enemy at site defeated!"),
>                        newsite->descr().m_defeated_you_str,
>                        true);
> @@ -949,7 +949,7 @@
>       // radius <= 5 near the current location in the last 60 seconds
>       send_message
>               (game,
> -              "under_attack",
> +              Message::Type::underAttack,
>                _("You are under attack"),
>                discovered ? descr().m_aggressor_str : descr().m_attack_str,
>                false,
> 
> === modified file 'src/logic/player.cc'
> --- src/logic/player.cc       2014-09-18 18:56:20 +0000
> +++ src/logic/player.cc       2014-09-29 15:04:07 +0000
> @@ -292,15 +292,15 @@
>   * Plays the corresponding sound when a message is received and if sound is
>   * enabled.
>   */
> -void Player::play_message_sound(const std::string & sender) {
> -#define MAYBE_PLAY(a, b) if (sender == a) { \
> -     g_sound_handler.play_fx(b, 200, PRIO_ALWAYS_PLAY); \
> +void Player::play_message_sound(const Message::Type & msgtype) {
> +#define MAYBE_PLAY(type, file) if (msgtype == type) { \
> +     g_sound_handler.play_fx(file, 200, PRIO_ALWAYS_PLAY); \
>       return; \
>       }
>  
>       if (g_options.pull_section("global").get_bool("sound_at_message", 
> true)) {
> -             MAYBE_PLAY("site_occupied", "sound/military/site_occupied");
> -             MAYBE_PLAY("under_attack", "sound/military/under_attack");
> +             MAYBE_PLAY(Message::Type::siteOccupied, 
> "sound/military/site_occupied");
> +             MAYBE_PLAY(Message::Type::underAttack, 
> "sound/military/under_attack");
>  
>               g_sound_handler.play_fx("sound/message", 200, PRIO_ALWAYS_PLAY);
>       }
> @@ -321,7 +321,7 @@
>       // Sound & popup
>       if (InteractivePlayer * const iplayer = game.get_ipl()) {
>               if (&iplayer->player() == this) {
> -                     play_message_sound(message.sender());
> +                     play_message_sound(message.type());
>                       if (popup)
>                               iplayer->popup_message(id, message);
>               }
> @@ -339,7 +339,7 @@
>       Coords      const position = m   .position    ();
>       for (std::pair<MessageId, Message *>  tmp_message : messages()) {
>               if
> -                     (tmp_message.second->sender() == m.sender()      &&
> +                     (tmp_message.second->type() == m.type()      &&
>                        gametime < tmp_message.second->sent() + timeout &&
>                        map.calc_distance(tmp_message.second->position(), 
> position) <= radius)
>               {
> 
> === modified file 'src/logic/player.h'
> --- src/logic/player.h        2014-09-18 18:56:20 +0000
> +++ src/logic/player.h        2014-09-29 15:04:07 +0000
> @@ -524,7 +524,7 @@
>  private:
>       void update_building_statistics(Building &, NoteImmovable::Ownership 
> ownership);
>       void update_team_players();
> -     void play_message_sound(const std::string & sender);
> +     void play_message_sound(const Message::Type & msgtype);
>       void _enhance_or_dismantle
>               (Building *, BuildingIndex const index_of_new_building);
>  
> 
> === modified file 'src/logic/productionsite.cc'
> --- src/logic/productionsite.cc       2014-09-10 18:56:42 +0000
> +++ src/logic/productionsite.cc       2014-09-29 15:04:07 +0000
> @@ -924,7 +924,7 @@
>                       assert(!descr().out_of_resource_message().empty());
>                       send_message
>                               (game,
> -                                       "produce",
> +                              Message::Type::economy,
>                                descr().out_of_resource_title(),
>                                descr().out_of_resource_message(),
>                                true,
> 
> === modified file 'src/logic/ship.cc'
> --- src/logic/ship.cc 2014-09-18 18:56:20 +0000
> +++ src/logic/ship.cc 2014-09-29 15:04:07 +0000
> @@ -459,7 +459,7 @@
>                       // Send a message to the player, that a new port space 
> was found
>                       std::string msg_head = _("Port Space Found");
>                       std::string msg_body = _("An expedition ship found a 
> new port build space.");
> -                     send_message(game, "exp_port_space", msg_head, 
> msg_body, "port.png");
> +                     send_message(game, msg_head, msg_body, "port.png");
>               }
>               m_expedition->seen_port_buildspaces.swap(temp_port_buildspaces);
>       }
> @@ -568,7 +568,7 @@
>                                                       std::string msg_head = 
> _("Island Circumnavigated");
>                                                       std::string msg_body = 
> _("An expedition ship sailed around its"
>                                                                               
>  " island without any events.");
> -                                                     send_message(game, 
> "exp_island", msg_head, msg_body,
> +                                                     send_message(game, 
> msg_head, msg_body,
>                                                               
> "ship_explore_island_cw.png");
>                                                       m_ship_state = 
> EXP_WAITING;
>                                                       return 
> start_task_idle(game, descr().main_animation(), 1500);
> @@ -624,7 +624,7 @@
>                               std::string msg_head = _("Coast Reached");
>                               std::string msg_body =
>                                       _("An expedition ship reached a coast 
> and is waiting for further commands.");
> -                             send_message(game, "exp_coast", msg_head, 
> msg_body, "ship_explore_island_cw.png");
> +                             send_message(game, msg_head, msg_body, 
> "ship_explore_island_cw.png");
>                               return;
>                       }
>               }
> @@ -787,7 +787,7 @@
>       // Send a message to the player, that an expedition is ready to go
>       const std::string msg_head = _("Expedition Ready");
>       const std::string msg_body = _("An expedition ship is waiting for your 
> commands.");
> -     send_message(game, "exp_ready", msg_head, msg_body, 
> "start_expedition.png");
> +     send_message(game, msg_head, msg_body, "start_expedition.png");
>  }
>  
>  /// Initializes / changes the direction of scouting to @arg direction
> @@ -899,9 +899,7 @@
>   * \param picture picture name relative to the pics directory
>   */
>  void Ship::send_message
> -     (Game & game, const std::string & msgsender,
> -      const std::string & title, const std::string & description,
> -      const std::string & picture)
> +     (Game & game, const std::string & title, const std::string & 
> description, const std::string & picture)
>  {
>       std::string rt_description;
>       if (picture.size() > 3) {
> @@ -914,7 +912,7 @@
>       rt_description += "</p></rt>";
>  
>       Message * msg = new Message
> -             (msgsender, game.get_gametime(), title, rt_description, 
> get_position(), m_serial);
> +             (Message::Type::seafaring, game.get_gametime(), title, 
> rt_description, get_position(), m_serial);
>  
>       get_owner()->add_message(game, *msg);
>  }
> 
> === modified file 'src/logic/ship.h'
> --- src/logic/ship.h  2014-09-10 08:55:04 +0000
> +++ src/logic/ship.h  2014-09-29 15:04:07 +0000
> @@ -208,8 +208,7 @@
>       void init_fleet(EditorGameBase &);
>       void set_fleet(Fleet * fleet);
>  
> -     void send_message
> -             (Game &, const std::string &, const std::string &, const 
> std::string &, const std::string &);
> +     void send_message(Game &, const std::string &, const std::string &, 
> const std::string &);
>  
>       UI::Window * m_window;
>  
> 
> === modified file 'src/logic/soldier.cc'
> --- src/logic/soldier.cc      2014-09-18 18:56:20 +0000
> +++ src/logic/soldier.cc      2014-09-29 15:04:07 +0000
> @@ -1570,7 +1570,7 @@
>                                       owner().add_message
>                                               (game,
>                                                *new Message
> -                                                     ("game engine",
> +                                                     
> (Message::Type::gameLogic,
>                                                        game.get_gametime(),
>                                                        _("Logic error"),
>                                                        buffer,
> @@ -1579,7 +1579,7 @@
>                                       opponent.owner().add_message
>                                               (game,
>                                                *new Message
> -                                                     ("game engine",
> +                                                     
> (Message::Type::gameLogic,
>                                                        game.get_gametime(),
>                                                        _("Logic error"),
>                                                        buffer,
> 
> === modified file 'src/logic/warehouse.cc'
> --- src/logic/warehouse.cc    2014-09-10 10:18:46 +0000
> +++ src/logic/warehouse.cc    2014-09-29 15:04:07 +0000
> @@ -451,18 +451,30 @@
>                               (ref_cast<Game, EditorGameBase>(egbase), 4000);
>  
>               log("Message: adding (wh) (%s) %i \n", 
> to_string(descr().type()).c_str(), player.player_number());
> -             char message[2048];
> -             snprintf
> -                     (message, sizeof(message),
> -                      _("A new %s was added to your economy."),
> -                      descr().descname().c_str());
> -             send_message
> -                     (ref_cast<Game, EditorGameBase>(egbase),
> -                      "warehouse",
> -                      descr().descname(),
> -                      message,
> -                      true);
> +
> +             if (descr().name() == "port") {
> +                     send_message
> +                             (ref_cast<Game, EditorGameBase>(egbase),
> +                              Message::Type::seafaring,
> +                              descr().descname(),
> +                              _("A new port was added to your economy."),
> +                              true);
> +             } else if (descr().name() == "headquarters") {
> +                     send_message
> +                             (ref_cast<Game, EditorGameBase>(egbase),
> +                              Message::Type::economy,
> +                              descr().descname(),
> +                              _("A new headquarters was added to your 
> economy."),
> +                              true);
> +             } else {
> +                     send_message
> +                             (ref_cast<Game, EditorGameBase>(egbase),
> +                              Message::Type::economy,
> +                              descr().descname(),
> +                              _("A new warehouse was added to your 
> economy."),
> +                              true);
>               }
> +     }
>  
>       if (uint32_t const conquer_radius = descr().get_conquers())
>               egbase.conquer_area
> 
> === modified file 'src/logic/worker.cc'
> --- src/logic/worker.cc       2014-09-18 18:56:20 +0000
> +++ src/logic/worker.cc       2014-09-29 15:04:07 +0000
> @@ -941,12 +941,24 @@
>                                rdescr->name().c_str(),
>                                _("A geologist found resources."));
>  
> +                     Message::Type message_type = Message::Type::geologists;
> +                     if (rdescr->name() == "coal")
> +                             message_type = Message::Type::geologistsCoal;
> +                     else if (rdescr->name() == "gold")
> +                             message_type = Message::Type::geologistsGold;
> +                     else if (rdescr->name() == "granite")
> +                             message_type = Message::Type::geologistsGranite;
> +                     else if (rdescr->name() == "iron")
> +                             message_type = Message::Type::geologistsIron;
> +                     else if (rdescr->name() == "water")
> +                             message_type = Message::Type::geologistsWater;
> +
>                       //  We should add a message to the player's message 
> queue - but only,
>                       //  if there is not already a similar one in list.
>                       owner().add_message_with_timeout
>                               (game,
>                                *new Message
> -                                     ("geologist " + rdescr->name(), // e.g. 
> "geologist gold"
> +                                     (message_type,
>                                        game.get_gametime(),
>                                        rdescr->descname(),
>                                        message,
> @@ -1844,7 +1856,7 @@
>               owner().add_message
>                       (game,
>                        *new Message
> -                             ("game engine",
> +                             (Message::Type::gameLogic,
>                                game.get_gametime(),
>                                _("Worker got lost!"),
>                                buffer,
> 
> === modified file 'src/map_io/map_players_messages_packet.cc'
> --- src/map_io/map_players_messages_packet.cc 2014-09-18 18:56:20 +0000
> +++ src/map_io/map_players_messages_packet.cc 2014-09-29 15:04:07 +0000
> @@ -20,6 +20,7 @@
>  #include "map_io/map_players_messages_packet.h"
>  
>  #include "logic/game_data_error.h"
> +#include "logic/message.h"
>  #include "logic/player.h"
>  #include "map_io/coords_profile.h"
>  #include "map_io/map_object_loader.h"
> @@ -61,14 +62,14 @@
>                                                "added it to the queue. This 
> is only allowed during "
>                                                "simulation, not at load. The 
> following messge will be "
>                                                "removed when the queue is 
> reset:\n"
> -                                              "\tsender  : %s\n"
> +                                              "\tstype   : %u\n"
>                                                "\ttitle   : %s\n"
>                                                "\tsent    : %u\n"
>                                                "\tposition: (%i, %i)\n"
>                                                "\tstatus  : %u\n"
>                                                "\tbody    : %s\n",
>                                                p,
> -                                              begin->second->sender  
> ().c_str(),
> +                                              begin->second->type    (),
>                                                begin->second->title   
> ().c_str(),
>                                                begin->second->sent    (),
>                                                begin->second->position().x, 
> begin->second->position().y,
> @@ -120,7 +121,7 @@
>  
>                                       messages.add_message
>                                               (*new Message
> -                                                     (s->get_string     
> ("sender", ""),
> +                                                     
> (static_cast<Message::Type>(s->get_natural("type")),
>                                                        sent,
>                                                        s->get_name       (),
>                                                        
> s->get_safe_string("body"),
> @@ -156,11 +157,10 @@
>                       assert(message.sent() <= 
> static_cast<uint32_t>(egbase.get_gametime()));
>  
>                       Section & s = 
> prof.create_section_duplicate(message.title().c_str());
> -                     if (message.sender().size())
> -                             s.set_string("sender",    message.sender  ());
> -                     s.set_int      ("sent",      message.sent    ());
> -                     s.set_string   ("body",      message.body    ());
> -                     if (Coords const c =         message.position())
> +                     s.set_int    ("type",      
> static_cast<int32_t>(message.type()));
> +                     s.set_int    ("sent",      message.sent    ());
> +                     s.set_string ("body",      message.body    ());
> +                     if (Coords const c =       message.position())
>                               set_coords("position",  c, &s);
>                       switch (message.status()) {
>                       case Message::New:
> 
> === modified file 'src/scripting/lua_game.cc'
> --- src/scripting/lua_game.cc 2014-09-18 18:56:20 +0000
> +++ src/scripting/lua_game.cc 2014-09-29 15:04:07 +0000
> @@ -29,6 +29,7 @@
>  #include "logic/campaign_visibility.h"
>  #include "logic/constants.h"
>  #include "logic/game_controller.h"
> +#include "logic/message.h"
>  #include "logic/objective.h"
>  #include "logic/path.h"
>  #include "logic/player.h"
> @@ -277,9 +278,6 @@
>                       'archived'. Default: "new"
>               :type status: :class:`string`
>  
> -             :arg sender: sender name of this string. Default: 
> "ScriptingEngine"
> -             :type sender: :class:`string`
> -
>               :arg popup: should the message window be opened for this 
> message or not.
>                       Default: :const:`false`
>               :type popup: :class:`boolean`
> @@ -293,7 +291,6 @@
>       std::string body = luaL_checkstring(L, 3);
>       Coords c = Coords::Null();
>       Message::Status st = Message::New;
> -     std::string sender = "ScriptingEngine";
>       bool popup = false;
>  
>       if (n == 4) {
> @@ -313,11 +310,6 @@
>               }
>               lua_pop(L, 1);
>  
> -             lua_getfield(L, 4, "sender");
> -             if (!lua_isnil(L, -1))
> -                     sender = luaL_checkstring(L, -1);
> -             lua_pop(L, 1);
> -
>               lua_getfield(L, 4, "popup");
>               if (!lua_isnil(L, -1))
>                       popup = luaL_checkboolean(L, -1);
> @@ -331,7 +323,7 @@
>               plr.add_message
>                       (game,
>                        *new Message
> -                             (sender,
> +                             (Message::Type::scenario,
>                                game.get_gametime(),
>                                title,
>                                body,
> @@ -1049,7 +1041,6 @@
>       {nullptr, nullptr},
>  };
>  const PropertyType<LuaMessage> LuaMessage::Properties[] = {
> -     PROP_RO(LuaMessage, sender),
>       PROP_RO(LuaMessage, title),
>       PROP_RO(LuaMessage, body),
>       PROP_RO(LuaMessage, sent),
> @@ -1079,15 +1070,7 @@
>   PROPERTIES
>   ==========================================================
>   */
> -/* RST
> -     .. attribute:: sender
>  
> -             (RO) The name of the sender of this message
> -*/
> -int LuaMessage::get_sender(lua_State * L) {
> -     lua_pushstring(L, get(L, get_game(L)).sender());
> -     return 1;
> -}
>  /* RST
>       .. attribute:: title
>  
> 
> === modified file 'src/scripting/lua_game.h'
> --- src/scripting/lua_game.h  2014-09-18 18:56:20 +0000
> +++ src/scripting/lua_game.h  2014-09-29 15:04:07 +0000
> @@ -161,7 +161,6 @@
>       /*
>        * Properties
>        */
> -     int get_sender(lua_State * L);
>       int get_sent(lua_State * L);
>       int get_title(lua_State * L);
>       int get_body(lua_State * L);
> 
> === modified file 'src/wui/game_message_menu.cc'
> --- src/wui/game_message_menu.cc      2014-09-10 14:48:40 +0000
> +++ src/wui/game_message_menu.cc      2014-09-29 15:04:07 +0000
> @@ -20,6 +20,7 @@
>  #include "wui/game_message_menu.h"
>  
>  #include <boost/bind.hpp>
> +#include <boost/format.hpp>
>  
>  #include "base/deprecated.h"
>  #include "base/time_string.h"
> @@ -46,11 +47,12 @@
>               (&plr, "messages", &registry, 580, 375, _("Messages: Inbox")),
>       message_body
>               (this,
> -              5, 150, 570, 220,
> +              5, 154, 570, 216,
>                "", UI::Align_Left, 1),
>       mode(Inbox)
>  {
> -     list = new UI::Table<uintptr_t>(this, 5, 35, 570, 110);
> +
> +     list = new UI::Table<uintptr_t>(this, 5, message_body.get_y() - 110, 
> 570, 110);
>       list->selected.connect(boost::bind(&GameMessageMenu::selected, this, 
> _1));
>       
> list->double_clicked.connect(boost::bind(&GameMessageMenu::double_clicked, 
> this, _1));
>       list->add_column (60, _("Select"), "", UI::Align_HCenter, true);
> @@ -58,39 +60,105 @@
>       list->add_column(330, _("Title"));
>       list->add_column(120, _("Time sent"));
>  
> +     // Buttons for message types
> +     m_geologistsbtn =
> +                     new UI::Button
> +                             (this, "filter_geologists_messages",
> +                              5, 5, 34, 34,
> +                              g_gr->images().get("pics/but0.png"),
> +                              g_gr->images().get("pics/menu_geologist.png"),
> +                              "",
> +                              true);
> +     m_geologistsbtn->sigclicked.connect
> +                     (boost::bind(&GameMessageMenu::filter_messages, this, 
> Widelands::Message::Type::geologists));
> +
> +     m_economybtn =
> +                     new UI::Button
> +                             (this, "filter_economy_messages",
> +                              2 * 5 + 34, 5, 34, 34,
> +                              g_gr->images().get("pics/but0.png"),
> +                              g_gr->images().get("pics/menu_build_flag.png"),
> +                              "",
> +                              true);
> +     m_economybtn->sigclicked.connect
> +                     (boost::bind(&GameMessageMenu::filter_messages, this, 
> Widelands::Message::Type::economy));
> +
> +     m_seafaringbtn =
> +                     new UI::Button
> +                             (this, "filter_seafaring_messages",
> +                              3 * 5 + 2 * 34, 5, 34, 34,
> +                              g_gr->images().get("pics/but0.png"),
> +                              
> g_gr->images().get("pics/start_expedition.png"),
> +                              "",
> +                              true);
> +     m_seafaringbtn->sigclicked.connect
> +                     (boost::bind(&GameMessageMenu::filter_messages, this, 
> Widelands::Message::Type::seafaring));
> +
> +     m_warfarebtn =
> +                     new UI::Button
> +                             (this, "filter_warfare_messages",
> +                              4 * 5 + 3 * 34, 5, 34, 34,
> +                              g_gr->images().get("pics/but0.png"),
> +                              
> g_gr->images().get("pics/messages_warfare.png"),
> +                              "",
> +                              true);
> +     m_warfarebtn->sigclicked.connect
> +                     (boost::bind(&GameMessageMenu::filter_messages, this, 
> Widelands::Message::Type::warfare));
> +
> +     m_scenariobtn =
> +                     new UI::Button
> +                             (this, "filter_scenario_messages",
> +                              5 * 5 + 4 * 34, 5, 34, 34,
> +                              g_gr->images().get("pics/but0.png"),
> +                              g_gr->images().get("pics/menu_objectives.png"),
> +                              "",
> +                              true);
> +     m_scenariobtn->sigclicked.connect
> +                     (boost::bind(&GameMessageMenu::filter_messages, this, 
> Widelands::Message::Type::scenario));
> +
> +     m_message_filter = Widelands::Message::Type::allMessages;
> +     set_filter_messages_tooltips();
> +     // End: Buttons for message types
> +
>       UI::Button * clearselectionbtn =
>               new UI::Button
>                       (this, "clear_selection",
> -                      5, 5, 140, 25,
> -                      g_gr->images().get("pics/but0.png"),
> -                      _("Clear"), _("Clear selection"));
> +                      5 * 5 + 6 * 34 + 17, 5, 34, 34,
> +                      g_gr->images().get("pics/but2.png"),
> +                      g_gr->images().get("pics/message_clear_selection.png"),
> +                      _("Clear selection"));
>       clearselectionbtn->sigclicked.connect
>               (boost::bind(&GameMessageMenu::do_clear_selection, this));
>  
>       UI::Button * invertselectionbtn =
>               new UI::Button
>                       (this, "invert_selection",
> -                      150, 5, 140, 25,
> -                      g_gr->images().get("pics/but0.png"),
> -                      _("Invert"), _("Invert selection"));
> +                      6 * 5 + 7 * 34 + 17, 5, 34, 34,
> +                      g_gr->images().get("pics/but2.png"),
> +                      
> g_gr->images().get("pics/message_selection_invert.png"),
> +                      _("Invert selection"));
>       invertselectionbtn->sigclicked.connect
>               (boost::bind(&GameMessageMenu::do_invert_selection, this));
>  
>       m_archivebtn =
>               new UI::Button
>                       (this, "archive_or_restore_selected_messages",
> -                      295, 5, 25, 25,
> +                      6 * 5 + 9 * 34 + 34, 5, 34, 34,
>                        g_gr->images().get("pics/but2.png"),
>                        g_gr->images().get("pics/message_archive.png"),
> -                      _("Archive selected messages"));
> +                      /** TRANSLATORS: %s is a tooltip, Del is the 
> corresponding hotkey */
> +                      (boost::format(_("Del: %s"))
> +                       /** TRANSLATORS: Tooltip in the messages window */
> +                       % _("Archive selected messages")).str());
>       m_archivebtn->sigclicked.connect
>               (boost::bind(&GameMessageMenu::archive_or_restore, this));
>  
>       m_togglemodebtn =
>               new UI::Button
>                       (this, "toggle_between_inbox_or_archive",
> -                      325, 5, 190, 25,
> +                      7 * 5 + 10 * 34 + 34, 5, 34, 34,
>                        g_gr->images().get("pics/but2.png"),
> +                      g_gr->images().get("pics/message_archived.png"),
>                        _("Show Archive"));
>       m_togglemodebtn->sigclicked.connect
>               (boost::bind(&GameMessageMenu::toggle_mode, this));
> @@ -98,13 +166,24 @@
>       m_centerviewbtn =
>               new UI::Button
>                       (this, "center_main_mapview_on_location",
> -                      550, 5, 25, 25,
> +                      580 - 5 - 34, 5, 34, 34,
>                        g_gr->images().get("pics/but2.png"),
>                        g_gr->images().get("pics/menu_goto.png"),
> -                      _("center main mapview on location"),
> +                      /** TRANSLATORS: %s is a tooltip, G is the 
> corresponding hotkey */
> +                      (boost::format(_("G: %s"))
> +                       /** TRANSLATORS: Tooltip in the messages window */
> +                       % _("Center main mapview on location")).str(),
>                        false);
>       
> m_centerviewbtn->sigclicked.connect(boost::bind(&GameMessageMenu::center_view,
>  this));
>  
> +
> +     m_display_message_type_label =
> +             new UI::MultilineTextarea
> +                     (this,
> +                      5, 375 - 5 - 34, 5 * 34, 40,
> +                      "<rt image=pics/message_new.png></rt>",
> +                      UI::Align::Align_BottomLeft, false);
> +
>       if (get_usedefaultpos())
>               center_to_parent();
>  
> @@ -183,6 +262,19 @@
>               }
>       }
>  
> +     // Filter message type
> +     if (m_message_filter != Message::Type::allMessages) {
> +             set_display_message_type_label(m_message_filter);
> +             for (uint32_t j = list->size(); j; --j) {
> +                     MessageId m_id((*list)[j - 1]);
> +                     if (Message const * const message = mq[m_id]) {
> +                             if (message->message_type_category() != 
> m_message_filter) {
> +                                     list->remove(j - 1);
> +                             }
> +                     }
> +             }
> +     }
> +
>       if (list->size()) {
>               if (!list->has_selection())
>                       list->select(0);
> @@ -192,6 +284,7 @@
>       } else {
>               m_centerviewbtn->set_enabled(false);
>               message_body.set_text(std::string());
> +             
> set_display_message_type_label(Widelands::Message::Type::noMessages);
>       }
>  }
>  
> @@ -226,6 +319,7 @@
>                       }
>                       m_centerviewbtn->set_enabled(message->position());
>                       message_body.set_text(message->body    ());
> +                     
> set_display_message_type_label(message->message_type_category());
>                       return;
>               }
>       }
> @@ -247,12 +341,31 @@
>  {
>       if (down) {
>               switch (code.sym) {
> +             // Don't forget to change the tooltips if any of these get 
> reassigned
>               case SDLK_g:
>                       if (m_centerviewbtn->enabled())
>                               center_view();
>                       return true;
> -
> +             case SDLK_a:
> +                     filter_messages(Widelands::Message::Type::allMessages);
> +                     return true;
> +             case SDLK_l:
> +                     filter_messages(Widelands::Message::Type::geologists);
> +                     return true;
> +             case SDLK_e:
> +                     filter_messages(Widelands::Message::Type::economy);
> +                     return true;
> +             case SDLK_f:
> +                     filter_messages(Widelands::Message::Type::seafaring);
> +                     return true;
> +             case SDLK_w:
> +                     filter_messages(Widelands::Message::Type::warfare);
> +                     return true;
> +             case SDLK_r:
> +                     filter_messages(Widelands::Message::Type::scenario);
> +                     return true;
>               case SDLK_KP_PERIOD:
> +
>                       if (code.mod & KMOD_NUM)
>                               break;
>                       /* no break */
> @@ -336,6 +449,141 @@
>  }
>  
>  /**
> + * Show only messages of a certain type
> + * @param msgtype the types of messages to show
> + */
> +void GameMessageMenu::filter_messages(Widelands::Message::Type const 
> msgtype) {
> +     switch (msgtype) {
> +             case Widelands::Message::Type::geologists:
> +                     toggle_filter_messages_button(*m_geologistsbtn, 
> msgtype);
> +                     break;
> +             case Widelands::Message::Type::economy:
> +                     toggle_filter_messages_button(*m_economybtn, msgtype);
> +                     break;
> +             case Widelands::Message::Type::seafaring:
> +                     toggle_filter_messages_button(*m_seafaringbtn, msgtype);
> +                     break;
> +             case Widelands::Message::Type::warfare:
> +                     toggle_filter_messages_button(*m_warfarebtn, msgtype);
> +                     break;
> +             case Widelands::Message::Type::scenario:
> +                     toggle_filter_messages_button(*m_scenariobtn, msgtype);
> +                     break;
> +             default:
> +                     set_filter_messages_tooltips();
> +                     m_message_filter = 
> Widelands::Message::Type::allMessages;
> +                     m_geologistsbtn->set_perm_pressed(false);
> +                     m_economybtn->set_perm_pressed(false);
> +                     m_seafaringbtn->set_perm_pressed(false);
> +                     m_warfarebtn->set_perm_pressed(false);
> +                     m_scenariobtn->set_perm_pressed(false);
> +     }
> +     think();
> +}
> +
> +/**
> + * Helper for filter_messages
> + */
> +void GameMessageMenu::toggle_filter_messages_button(UI::Button & button, 
> Widelands::Message::Type msgtype) {
> +     set_filter_messages_tooltips();
> +     if (button.get_perm_pressed()) {
> +             button.set_perm_pressed(false);
> +             m_message_filter = Widelands::Message::Type::allMessages;
> +     } else {
> +             m_geologistsbtn->set_perm_pressed(false);
> +             m_economybtn->set_perm_pressed(false);
> +             m_seafaringbtn->set_perm_pressed(false);
> +             m_warfarebtn->set_perm_pressed(false);
> +             m_scenariobtn->set_perm_pressed(false);
> +             button.set_perm_pressed(true);
> +             m_message_filter = msgtype;
> +             /** TRANSLATORS: %1% is a tooltip, %2% is the corresponding 
> hotkey */
> +             button.set_tooltip((boost::format(_("%1% (Hotkey: %2%)"))
> +                                                               /** 
> TRANSLATORS: Tooltip in the messages window */
> +                                                               % _("Show all 
> messages")
> +                                                               % "A").str());
> +     }
> +}
> +
> +/**
> + * Helper for filter_messages
> + */
> +void GameMessageMenu::set_filter_messages_tooltips() {
> +     m_geologistsbtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)"))
> +                                                                             
>         /** TRANSLATORS: Tooltip in the messages window */
> +                                                                             
>         % _("Show geologists' messages only")
> +                                                                             
>         % "L").str());
> +     m_economybtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)"))
> +                                                                             
> /** TRANSLATORS: Tooltip in the messages window */
> +                                                                             
> % _("Show economy messages only")
> +                                                                             
> % "E").str());
> +     m_seafaringbtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)"))
> +                                                                             
>   /** TRANSLATORS: Tooltip in the messages window */
> +                                                                             
>   % _("Show seafaring messages only")
> +                                                                             
>   % "F").str());
> +     m_warfarebtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)"))
> +                                                                             
> /** TRANSLATORS: Tooltip in the messages window */
> +                                                                             
> % _("Show warfare messages only")
> +                                                                             
> % "W").str());
> +     m_scenariobtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)"))
> +                                                                             
>  /** TRANSLATORS: Tooltip in the messages window */
> +                                                                             
>  % _("Show scenario messages only")
> +                                                                             
>  % "R").str());
> +}
> +
> +/**
> + * Update image and tooltip for message category label
> + */
> +void 
> GameMessageMenu::set_display_message_type_label(Widelands::Message::Type 
> msgtype) {
> +     std::string message_type_tooltip = "";
> +     std::string message_type_image = "";
> +
> +     switch (msgtype) {
> +             case Widelands::Message::Type::geologists:
> +                     /** TRANSLATORS: This is a message's type */
> +                     message_type_tooltip =  _("Geologists");
> +                     message_type_image =  "<rt 
> image=pics/menu_geologist.png></rt>";
> +                     break;
> +             case Widelands::Message::Type::economy:
> +                     /** TRANSLATORS: This is a message's type */
> +                     message_type_tooltip =  _("Economy");
> +                     message_type_image =  "<rt 
> image=pics/menu_build_flag.png></rt>";
> +                     break;
> +             case Widelands::Message::Type::seafaring:
> +                     /** TRANSLATORS: This is a message's type */
> +                     message_type_tooltip =  _("Seafaring");
> +                     message_type_image =  "<rt 
> image=pics/start_expedition.png></rt>";
> +                     break;
> +             case Widelands::Message::Type::warfare:
> +                     /** TRANSLATORS: This is a message's type */
> +                     message_type_tooltip =  _("Warfare");
> +                     message_type_image =  "<rt 
> image=pics/messages_warfare.png></rt>";
> +                     break;
> +             case Widelands::Message::Type::scenario:
> +                     /** TRANSLATORS: This is a message's type */
> +                     message_type_tooltip =  _("Scenario");
> +                     message_type_image =  "<rt 
> image=pics/menu_objectives.png></rt>";
> +                     break;
> +             case Widelands::Message::Type::noMessages:
> +                     /** TRANSLATORS: This show up instead of a message's 
> type when there are no messages found */
> +                     message_type_tooltip =  _("No message found");
> +                     break;
> +             default:
> +                     /** TRANSLATORS: This is the default message type */
> +                     message_type_tooltip = _("General");
> +                     message_type_image =  "<rt 
> image=pics/message_new.png></rt>";
> +     }
> +
> +     m_display_message_type_label->set_tooltip(
> +                              /** TRANSLATORS: %s is a message's type */
> +                              (boost::format(_("Type of this message: %s"))
> +                               /** TRANSLATORS: Tooltip in the messages 
> window */
> +                               % message_type_tooltip).str());
> +     m_display_message_type_label->set_text(message_type_image);
> +}
> +
> +
> +/**
>   * Clear the current selection of messages.
>   */
>  void GameMessageMenu::do_clear_selection()
> @@ -359,15 +607,23 @@
>               mode = Archive;
>               set_title(_("Messages: Archive"));
>               
> m_archivebtn->set_pic(g_gr->images().get("pics/message_restore.png"));
> -             m_archivebtn->set_tooltip(_("Restore selected messages"));
> -             m_togglemodebtn->set_title(_("Show Inbox"));
> +             /** TRANSLATORS: %s is a tooltip, Del is the corresponding 
> hotkey */
> +             m_archivebtn->set_tooltip((boost::format(_("Del: %s"))
> +                                                                             
>         /** TRANSLATORS: Tooltip in the messages window */
> +                                                                             
>         % _("Restore selected messages")).str());
> +             
> m_togglemodebtn->set_pic(g_gr->images().get("pics/message_new.png"));
> +             m_togglemodebtn->set_tooltip(_("Show Inbox"));
>               break;
>       case Archive:
>               mode = Inbox;
>               set_title(_("Messages: Inbox"));
>               
> m_archivebtn->set_pic(g_gr->images().get("pics/message_archive.png"));
> -             m_archivebtn->set_tooltip(_("Archive selected messages"));
> -             m_togglemodebtn->set_title(_("Show Archive"));
> +             /** TRANSLATORS: %s is a tooltip, Del is the corresponding 
> hotkey */
> +             m_archivebtn->set_tooltip((boost::format(_("Del: %s"))
> +                                                                             
>         /** TRANSLATORS: Tooltip in the messages window */
> +                                                                             
>         % _("Archive selected messages")).str());
> +             
> m_togglemodebtn->set_pic(g_gr->images().get("pics/message_archived.png"));
> +             m_togglemodebtn->set_tooltip(_("Show Archive"));
>               break;
>       default:
>               assert(false); // there is nothing but Archive and Inbox
> 
> === modified file 'src/wui/game_message_menu.h'
> --- src/wui/game_message_menu.h       2014-09-10 14:48:40 +0000
> +++ src/wui/game_message_menu.h       2014-09-29 15:04:07 +0000
> @@ -22,6 +22,7 @@
>  
>  #include "base/deprecated.h"
>  #include "base/i18n.h"
> +#include "logic/message.h"
>  #include "logic/message_queue.h"
>  #include "ui_basic/button.h"
>  #include "ui_basic/multilinetextarea.h"
> @@ -49,6 +50,7 @@
>  
>  private:
>       enum Cols {ColSelect, ColStatus, ColTitle, ColTimeSent};
> +     enum class ReadUnread: uint8_t {allMessages, readMessages, newMessages};
>  
>       InteractivePlayer & iplayer() const;
>       void selected(uint32_t);
> @@ -60,6 +62,10 @@
>       void archive_or_restore();
>       void toggle_mode();
>       void center_view();
> +     void filter_messages(Widelands::Message::Type);
> +     void toggle_filter_messages_button(UI::Button &, 
> Widelands::Message::Type);
> +     void set_filter_messages_tooltips();
> +     void set_display_message_type_label(Widelands::Message::Type);
>       void update_record(UI::Table<uintptr_t>::EntryRecord & er, const 
> Widelands::Message &);
>  
>       UI::Table<uintptr_t> * list;
> @@ -68,6 +74,14 @@
>       UI::Button * m_togglemodebtn;
>       UI::Button * m_centerviewbtn;
>       Mode mode;
> +     // Buttons for message types
> +     UI::Button * m_geologistsbtn;
> +     UI::Button * m_economybtn;
> +     UI::Button * m_seafaringbtn;
> +     UI::Button * m_warfarebtn;
> +     UI::Button * m_scenariobtn;
> +     Widelands::Message::Type m_message_filter;
> +     UI::MultilineTextarea * m_display_message_type_label;
>  };
>  
>  #endif  // end of include guard: WL_WUI_GAME_MESSAGE_MENU_H
> 
> === modified file 
> 'test/maps/lua_persistence.wmf/scripting/test_persistence.lua'
> --- test/maps/lua_persistence.wmf/scripting/test_persistence.lua      
> 2014-08-01 15:30:12 +0000
> +++ test/maps/lua_persistence.wmf/scripting/test_persistence.lua      
> 2014-09-29 15:04:07 +0000
> @@ -49,7 +49,7 @@
>     objective.done = true
>  
>     p:send_message("dummy msg1", "dummy msg 1")
> -   msg = p:send_message("hello nice", "World", {sender="blah", field = field 
> })
> +   msg = p:send_message("hello nice", "World", {field = field })
>     player_slot = map.player_slots[1]
>  
>     myset = Set:new{
> @@ -118,7 +118,6 @@
>     assert_table(msg)
>     assert_equal("hello nice", msg.title)
>     assert_equal("World", msg.body)
> -   assert_equal("blah", msg.sender)
>     assert_equal(field, msg.field)
>  
>     assert_table(map)
> 
> === modified file 'test/maps/lua_testsuite.wmf/scripting/messages.lua'
> --- test/maps/lua_testsuite.wmf/scripting/messages.lua        2014-09-09 
> 08:24:10 +0000
> +++ test/maps/lua_testsuite.wmf/scripting/messages.lua        2014-09-29 
> 15:04:07 +0000
> @@ -13,7 +13,6 @@
>     local m = player1:send_message("Hallo", "World!")
>     assert_equal("Hallo", m.title)
>     assert_equal("World!", m.body)
> -   assert_equal("ScriptingEngine", m.sender)
>     assert_equal(0, m.sent)
>     assert_equal(0, m.sent)
>     assert_equal(nil, m.field)
> @@ -32,10 +31,6 @@
>        player1:send_message("Hallo", "World!", {status="nono"})
>     end)
>  end
> -function messages_tests:test_sender()
> -   local m = player1:send_message("Hallo", "World!", {sender="i am you"})
> -   assert_equal("i am you", m.sender)
> -end
>  function messages_tests:test_field()
>     local f = map:get_field(23,28)
>     local m = player1:send_message("Hallo", "World!", {field = f})
> 
> === modified file 'txts/README.lua'
> --- txts/README.lua   2014-09-18 16:41:26 +0000
> +++ txts/README.lua   2014-09-29 15:04:07 +0000
> @@ -78,8 +78,14 @@
>     ) .. p(_
>  [[In the message window, the following additional shortcuts are available:]]
>     ) .. p(
> -_ "G: jumps to the location corresponding to the current message" .. "<br>"
> -.. _"DELETE: archives the current message"
> +_ "A: shows all messages" .. "<br>"
> +.. _ "L: shows geologists' messages only" .. "<br>"
> +.. _ "E: shows economy messages only" .. "<br>"
> +.. _ "F: shows seafaring messages only" .. "<br>"
> +.. _ "W: shows warfare messages only" .. "<br>"
> +.. _ "R: shows scenario messages only" .. "<br>"
> +.. _ "G: jumps to the location corresponding to the current message" .. 
> "<br>"
> +.. _"DELETE: archives/restores the current message"
>     ) .. h2(_
>  [[Online Help]]
>     ) .. p( _
> 


-- 
https://code.launchpad.net/~widelands-dev/widelands/bug-987510/+merge/236231
Your team Widelands Developers is requested to review the proposed merge of 
lp:~widelands-dev/widelands/bug-987510 into lp:widelands.

_______________________________________________
Mailing list: https://launchpad.net/~widelands-dev
Post to     : widelands-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~widelands-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to