| [8859b5] | 1 | /*
 | 
|---|
 | 2 |  * Project: MoleCuilder
 | 
|---|
 | 3 |  * Description: creates and alters molecular systems
 | 
|---|
 | 4 |  * Copyright (C)  2014 Frederik Heber. All rights reserved.
 | 
|---|
 | 5 |  *
 | 
|---|
 | 6 |  *
 | 
|---|
 | 7 |  *   This file is part of MoleCuilder.
 | 
|---|
 | 8 |  *
 | 
|---|
 | 9 |  *    MoleCuilder is free software: you can redistribute it and/or modify
 | 
|---|
 | 10 |  *    it under the terms of the GNU General Public License as published by
 | 
|---|
 | 11 |  *    the Free Software Foundation, either version 2 of the License, or
 | 
|---|
 | 12 |  *    (at your option) any later version.
 | 
|---|
 | 13 |  *
 | 
|---|
 | 14 |  *    MoleCuilder is distributed in the hope that it will be useful,
 | 
|---|
 | 15 |  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
 | 16 |  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
 | 17 |  *    GNU General Public License for more details.
 | 
|---|
 | 18 |  *
 | 
|---|
 | 19 |  *    You should have received a copy of the GNU General Public License
 | 
|---|
 | 20 |  *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
 | 
|---|
 | 21 |  */
 | 
|---|
 | 22 | 
 | 
|---|
 | 23 | /*
 | 
|---|
 | 24 |  * QtFavoriteActions.cpp
 | 
|---|
 | 25 |  *
 | 
|---|
 | 26 |  *  Created on: Sep 11, 2014
 | 
|---|
 | 27 |  *      Author: heber
 | 
|---|
 | 28 |  */
 | 
|---|
 | 29 | 
 | 
|---|
 | 30 | // include config.h
 | 
|---|
 | 31 | #ifdef HAVE_CONFIG_H
 | 
|---|
 | 32 | #include <config.h>
 | 
|---|
 | 33 | #endif
 | 
|---|
 | 34 | 
 | 
|---|
 | 35 | #include <Qt/qaction.h>
 | 
|---|
 | 36 | #include <Qt/qpainter.h>
 | 
|---|
 | 37 | #include <Qt/qpixmap.h>
 | 
|---|
 | 38 | #include <Qt/qsettings.h>
 | 
|---|
 | 39 | 
 | 
|---|
 | 40 | #include "UIElements/Views/Qt4/QtToolBar.hpp"
 | 
|---|
 | 41 | 
 | 
|---|
 | 42 | #include "CodePatterns/MemDebug.hpp"
 | 
|---|
 | 43 | 
 | 
|---|
 | 44 | #include <string>
 | 
|---|
 | 45 | 
 | 
|---|
 | 46 | #include "CodePatterns/Assert.hpp"
 | 
|---|
 | 47 | #include "CodePatterns/Log.hpp"
 | 
|---|
 | 48 | 
 | 
|---|
 | 49 | #include "Actions/Action.hpp"
 | 
|---|
 | 50 | #include "Actions/ActionQueue.hpp"
 | 
|---|
 | 51 | #include "Actions/ActionRegistry.hpp"
 | 
|---|
 | 52 | #include "Actions/ActionTraits.hpp"
 | 
|---|
 | 53 | #include "Actions/OptionTrait.hpp"
 | 
|---|
 | 54 | 
 | 
|---|
 | 55 | using namespace MoleCuilder;
 | 
|---|
 | 56 | 
 | 
|---|
| [b375e7] | 57 | const Observable::channels_t
 | 
|---|
 | 58 | QtToolBar::QtFavoriteActions::ActionQueuedChannels(1, ActionQueue::ActionQueued);
 | 
|---|
 | 59 | 
 | 
|---|
| [8859b5] | 60 | QtToolBar::QtFavoriteActions::QtFavoriteActions() :
 | 
|---|
 | 61 |   Observer("QtFavoriteActions"),
 | 
|---|
| [b375e7] | 62 |   LastActionCalled(
 | 
|---|
 | 63 |       ActionQueue::getPointer(),
 | 
|---|
 | 64 |       boost::bind(&QtToolBar::QtFavoriteActions::updateQueuedAction, boost::cref(this)),
 | 
|---|
 | 65 |       "QtFavoriteActions_QueuedAction",
 | 
|---|
 | 66 |       std::string(""),
 | 
|---|
 | 67 |       ActionQueuedChannels),
 | 
|---|
| [8859b5] | 68 |   ActionQueue_observing(false)
 | 
|---|
 | 69 | {
 | 
|---|
 | 70 |   // initialize counts from settings
 | 
|---|
 | 71 |   QSettings settings;
 | 
|---|
 | 72 |   settings.beginGroup("FavoriteActions");
 | 
|---|
 | 73 |   const ActionQueue::ActionTokens_t actions = ActionQueue::getInstance().getListOfActions();
 | 
|---|
 | 74 |   for (ActionQueue::ActionTokens_t::const_iterator tokeniter = actions.begin();
 | 
|---|
 | 75 |       tokeniter != actions.end(); ++tokeniter) {
 | 
|---|
 | 76 | #ifndef NDEBUG
 | 
|---|
 | 77 |     std::pair<ActionCounts_t::iterator, bool> inserter =
 | 
|---|
 | 78 | #endif
 | 
|---|
 | 79 |     ActionCounts.insert( std::make_pair(
 | 
|---|
 | 80 |         *tokeniter,
 | 
|---|
 | 81 |         settings.value(QString(tokeniter->c_str()), 0).toInt())
 | 
|---|
 | 82 |     );
 | 
|---|
 | 83 |     ASSERT( inserter.second,
 | 
|---|
 | 84 |         "QtFavoriteActions::QtFavoriteActions() - encountered action token"
 | 
|---|
 | 85 |         +*tokeniter+" twice.");
 | 
|---|
 | 86 |   }
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 | //  resize(settings.value("size", QSize(400, 400)).toSize());
 | 
|---|
 | 89 |   settings.endGroup();
 | 
|---|
 | 90 | 
 | 
|---|
 | 91 |   // sign in
 | 
|---|
 | 92 |   ActionQueue::getInstance().signOn(this, ActionQueue::ActionQueued);
 | 
|---|
 | 93 |   ActionQueue_observing = true;
 | 
|---|
 | 94 | }
 | 
|---|
 | 95 | 
 | 
|---|
| [b375e7] | 96 | std::string QtToolBar::QtFavoriteActions::updateQueuedAction() const
 | 
|---|
 | 97 | {
 | 
|---|
 | 98 |   const Action *lastcalledaction =
 | 
|---|
 | 99 |       ActionQueue::getInstance().lastChanged<Action>();
 | 
|---|
 | 100 |   if (lastcalledaction != NULL)
 | 
|---|
 | 101 |     return lastcalledaction->getName();
 | 
|---|
 | 102 |   else
 | 
|---|
 | 103 |     return std::string("");
 | 
|---|
 | 104 | }
 | 
|---|
 | 105 | 
 | 
|---|
 | 106 | void QtToolBar::QtFavoriteActions::resetQueuedAction()
 | 
|---|
 | 107 | {
 | 
|---|
 | 108 |   const std::string name = LastActionCalled.get();
 | 
|---|
 | 109 |   if (!name.empty())
 | 
|---|
 | 110 |     ++ActionCounts[name];
 | 
|---|
 | 111 | }
 | 
|---|
 | 112 | 
 | 
|---|
| [8859b5] | 113 | QtToolBar::QtFavoriteActions::~QtFavoriteActions()
 | 
|---|
 | 114 | {
 | 
|---|
 | 115 |   // sign off
 | 
|---|
 | 116 |   if (ActionQueue_observing)
 | 
|---|
 | 117 |     ActionQueue::getInstance().signOff(this, ActionQueue::ActionQueued);
 | 
|---|
 | 118 | 
 | 
|---|
 | 119 |   // store all known counts
 | 
|---|
 | 120 |   QSettings settings;
 | 
|---|
 | 121 |   settings.beginGroup("FavoriteActions");
 | 
|---|
 | 122 |   ActionQueue::ActionTokens_t actions = ActionQueue::getInstance().getListOfActions();
 | 
|---|
 | 123 |   for (ActionQueue::ActionTokens_t::const_iterator tokeniter = actions.begin();
 | 
|---|
 | 124 |       tokeniter != actions.end(); ++tokeniter) {
 | 
|---|
 | 125 |     settings.setValue(QString(tokeniter->c_str()), ActionCounts[*tokeniter]);
 | 
|---|
 | 126 |   }
 | 
|---|
 | 127 |   settings.endGroup();
 | 
|---|
 | 128 | }
 | 
|---|
 | 129 | 
 | 
|---|
 | 130 | void QtToolBar::QtFavoriteActions::update(Observable *publisher)
 | 
|---|
 | 131 | {
 | 
|---|
 | 132 |   ASSERT(0, "QtFavoriteActions::update() - this should never be called, we are only subscribed to channels.");
 | 
|---|
 | 133 | }
 | 
|---|
 | 134 | 
 | 
|---|
 | 135 | void QtToolBar::QtFavoriteActions::subjectKilled(Observable *publisher)
 | 
|---|
 | 136 | {
 | 
|---|
 | 137 |   ActionQueue_observing = false;
 | 
|---|
 | 138 | }
 | 
|---|
 | 139 | 
 | 
|---|
 | 140 | void QtToolBar::QtFavoriteActions::recieveNotification(Observable *publisher, Notification_ptr notification)
 | 
|---|
 | 141 | {
 | 
|---|
 | 142 |   if (dynamic_cast<ActionQueue *>(publisher) != NULL) {
 | 
|---|
| [b375e7] | 143 |     resetQueuedAction();
 | 
|---|
| [8859b5] | 144 |   } else {
 | 
|---|
 | 145 |     ASSERT(0, "QtFavoriteActions::update() - cannot get here, we are only subscribed to ActionQueue.");
 | 
|---|
 | 146 |   }
 | 
|---|
 | 147 | }
 | 
|---|
 | 148 | 
 | 
|---|
 | 149 | void
 | 
|---|
 | 150 | QtToolBar::QtFavoriteActions::addToolBarActions(
 | 
|---|
 | 151 |     QtToolBar &_toolbar,
 | 
|---|
 | 152 |     const unsigned int _max) const
 | 
|---|
 | 153 | {
 | 
|---|
 | 154 |   // invert map
 | 
|---|
 | 155 |   std::multimap<unsigned int, std::string> InvertedCounts;
 | 
|---|
 | 156 |   for (ActionCounts_t::const_iterator countiter = ActionCounts.begin();
 | 
|---|
 | 157 |       countiter != ActionCounts.end(); ++countiter) {
 | 
|---|
 | 158 |     InvertedCounts.insert( std::make_pair( countiter->second, countiter->first) );
 | 
|---|
 | 159 |   }
 | 
|---|
 | 160 | 
 | 
|---|
 | 161 |   // then use last _max entries
 | 
|---|
 | 162 |   std::multimap<unsigned int, std::string>::const_reverse_iterator iter =
 | 
|---|
 | 163 |       InvertedCounts.rbegin();
 | 
|---|
 | 164 |   ActionQueue &AQ = ActionQueue::getInstance();
 | 
|---|
 | 165 |   const present_actions_t &present_actions = _toolbar.getPresentActions();
 | 
|---|
 | 166 |   for (size_t added = 0; added<_max; ++iter) {
 | 
|---|
 | 167 |     const std::string &token = iter->second;
 | 
|---|
 | 168 |     present_actions_t::const_iterator actioniter =
 | 
|---|
 | 169 |         present_actions.find(token);
 | 
|---|
 | 170 |     if (actioniter == present_actions.end()) {
 | 
|---|
 | 171 |       const ActionTrait &traits = AQ.getActionsTrait(token);
 | 
|---|
 | 172 |       const std::string icon_name = traits.getMenuName() + std::string("-") + token;
 | 
|---|
 | 173 |       const std::string description = traits.getDescription();
 | 
|---|
 | 174 |       QIcon icon = getIcon(token, icon_name);
 | 
|---|
 | 175 |       _toolbar.addActionItem(
 | 
|---|
 | 176 |           token,
 | 
|---|
 | 177 |           description,
 | 
|---|
 | 178 |           icon_name);
 | 
|---|
 | 179 |       ++added;
 | 
|---|
 | 180 |     }
 | 
|---|
 | 181 |   }
 | 
|---|
 | 182 | }
 | 
|---|
 | 183 | 
 | 
|---|
 | 184 | QIcon
 | 
|---|
 | 185 | QtToolBar::QtFavoriteActions::createIconPlaceholder(
 | 
|---|
 | 186 |     const std::string &_token
 | 
|---|
 | 187 |     ) const
 | 
|---|
 | 188 | {
 | 
|---|
 | 189 |   LOG(2, "DEBUG: Creating icon with text " << _token);
 | 
|---|
 | 190 |   QPixmap pixmap(100,100);
 | 
|---|
 | 191 |   pixmap.fill(QColor("white"));
 | 
|---|
 | 192 | 
 | 
|---|
 | 193 |   QPainter painter( &pixmap  );
 | 
|---|
 | 194 |   QRect rectangle( QPoint(0,0), QPoint(100,100));
 | 
|---|
 | 195 |   QRect boundingbox = QRect(1,1, 98, 98 );
 | 
|---|
 | 196 |   painter.drawRect( boundingbox );
 | 
|---|
 | 197 |   QFont font = QFont("Arial");
 | 
|---|
 | 198 |   font.setPixelSize(30);
 | 
|---|
 | 199 |   painter.setFont( font );
 | 
|---|
 | 200 |   QString icon_text(_token.c_str());
 | 
|---|
 | 201 |   icon_text.replace(QString("-"), QString("\n"));
 | 
|---|
 | 202 |   painter.drawText( rectangle, Qt::TextWordWrap, icon_text, &boundingbox );
 | 
|---|
 | 203 | 
 | 
|---|
 | 204 |   QIcon PlaceholderIcon(pixmap);
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 |   return PlaceholderIcon;
 | 
|---|
 | 207 | }
 | 
|---|
 | 208 | 
 | 
|---|
 | 209 | QIcon
 | 
|---|
 | 210 | QtToolBar::QtFavoriteActions::getIcon(
 | 
|---|
 | 211 |     const std::string &_token,
 | 
|---|
 | 212 |     const std::string &_icon_name
 | 
|---|
 | 213 |     ) const
 | 
|---|
 | 214 | {
 | 
|---|
 | 215 |   LOG(2, "DEBUG: Obtaining icon with text " << _token);
 | 
|---|
 | 216 |   // TODO: look up _icon_name from QIcon::fromTheme or someplace
 | 
|---|
 | 217 |   if (QIcon::hasThemeIcon(QString(_icon_name.c_str())))
 | 
|---|
 | 218 |     return QIcon::fromTheme(QString(_icon_name.c_str()));
 | 
|---|
 | 219 |   else
 | 
|---|
 | 220 |     return createIconPlaceholder(_token);
 | 
|---|
 | 221 | }
 | 
|---|