Exemple #1
0
// Manager event handler.
bool CustomizedGuiManager::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kCloseDisplayMessage:
      {
        // Execute the "Exit" command.
        Command* command = CommandsModule::instance()->getCommandByName(CommandId::Exit);
        UIContext::instance()->executeCommand(command);
      }
      break;

    case kDropFilesMessage:
      {
        // If the main window is not the current foreground one. We
        // discard the drop-files event.
        if (getForegroundWindow() != App::instance()->getMainWindow())
          break;

        const DropFilesMessage::Files& files = static_cast<DropFilesMessage*>(msg)->files();

        // Open all files
        Command* cmd_open_file =
          CommandsModule::instance()->getCommandByName(CommandId::OpenFile);
        Params params;

        UIContext* ctx = UIContext::instance();

        for (const auto& fn : files) {
          // If the document is already open, select it.
          Document* doc = static_cast<Document*>(ctx->documents().getByFileName(fn));
          if (doc) {
            DocumentView* docView = ctx->getFirstDocumentView(doc);
            if (docView)
              ctx->setActiveView(docView);
            else {
              ASSERT(false);    // Must be some DocumentView available
            }
          }
          // Load the file
          else {
            params.set("filename", fn.c_str());
            ctx->executeCommand(cmd_open_file, params);
          }
        }
      }
      break;

    case kKeyDownMessage: {
#ifdef _DEBUG
      // Left Shift+Ctrl+Q generates a crash (useful to test the anticrash feature)
      if (msg->ctrlPressed() &&
          msg->shiftPressed() &&
          static_cast<KeyMessage*>(msg)->scancode() == kKeyQ) {
        int* p = nullptr;
        *p = 0;
      }
#endif

      // Call base impl to check if there is a foreground window as
      // top level that needs keys. (In this way we just do not
      // process keyboard shortcuts for menus and tools).
      if (Manager::onProcessMessage(msg))
        return true;

      for (const Key* key : *KeyboardShortcuts::instance()) {
        if (key->isPressed(msg)) {
          // Cancel menu-bar loops (to close any popup menu)
          App::instance()->getMainWindow()->getMenuBar()->cancelMenuLoop();

          switch (key->type()) {

            case KeyType::Tool: {
              tools::Tool* current_tool = App::instance()->activeTool();
              tools::Tool* select_this_tool = key->tool();
              tools::ToolBox* toolbox = App::instance()->getToolBox();
              std::vector<tools::Tool*> possibles;

              // Collect all tools with the pressed keyboard-shortcut
              for (tools::Tool* tool : *toolbox) {
                Key* key = KeyboardShortcuts::instance()->tool(tool);
                if (key && key->isPressed(msg))
                  possibles.push_back(tool);
              }

              if (possibles.size() >= 2) {
                bool done = false;

                for (size_t i=0; i<possibles.size(); ++i) {
                  if (possibles[i] != current_tool &&
                      ToolBar::instance()->isToolVisible(possibles[i])) {
                    select_this_tool = possibles[i];
                    done = true;
                    break;
                  }
                }

                if (!done) {
                  for (size_t i=0; i<possibles.size(); ++i) {
                    // If one of the possibilities is the current tool
                    if (possibles[i] == current_tool) {
                      // We select the next tool in the possibilities
                      select_this_tool = possibles[(i+1) % possibles.size()];
                      break;
                    }
                  }
                }
              }

              ToolBar::instance()->selectTool(select_this_tool);
              return true;
            }

            case KeyType::Command: {
              Command* command = key->command();

              // Commands are executed only when the main window is
              // the current window running at foreground.
              UI_FOREACH_WIDGET(getChildren(), it) {
                Window* child = static_cast<Window*>(*it);

                // There are a foreground window executing?
                if (child->isForeground()) {
                  break;
                }
                // Is it the desktop and the top-window=
                else if (child->isDesktop() && child == App::instance()->getMainWindow()) {
                  // OK, so we can execute the command represented
                  // by the pressed-key in the message...
                  UIContext::instance()->executeCommand(
                    command, key->params());
                  return true;
                }
              }
              break;
            }

            case KeyType::Quicktool: {
              // Do nothing, it is used in the editor through the
              // KeyboardShortcuts::getCurrentQuicktool() function.
              break;
            }

          }
          break;
        }
      }
      break;
    }