jens-maus/yam

View on GitHub
src/mui/MainWindow.c

Summary

Maintainability
Test Coverage
/***************************************************************************

 YAM - Yet Another Mailer
 Copyright (C) 1995-2000 Marcel Beck
 Copyright (C) 2000-2022 YAM Open Source Team

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 YAM Official Support Site :  http://www.yam.ch
 YAM OpenSource project    :  http://sourceforge.net/projects/yamos/

 $Id$

 Superclass:  MUIC_Window
 Description: Mainwindow class carrying all main GUI elements of YAM

***************************************************************************/

#include "MainWindow_cl.h"

#include <proto/muimaster.h>
#include <libraries/iffparse.h>
#include <mui/NBalance_mcc.h>

#include "YAM.h"
#include "YAM_error.h"

#include "mui/MainMailListGroup.h"
#include "mui/QuickSearchBar.h"
#include "mui/ReadMailGroup.h"

#include "Busy.h"
#include "Config.h"
#include "Locale.h"
#include "MailList.h"
#include "MUIObjects.h"
#include "Requesters.h"

#include "Debug.h"

/* INCLUDE
#include "YAM_find.h"
*/

/* Overloaded Methods */
/// OVERLOAD(OM_SET)
OVERLOAD(OM_SET)
{
  IPTR result = 0;
  struct TagItem *tags = inittags(msg), *tag;

  ENTER();

  while((tag = NextTagItem((APTR)&tags)) != NULL)
  {
    switch(tag->ti_Tag)
    {
      case MUIA_Window_DefaultObject:
      {
        // if the user clicks somewhere where the default
        // object would be set to NULL we make sure we set
        // it back to the default object of the readmail group
        if((Object *)tag->ti_Data == NULL)
          tag->ti_Data = xget(G->MA->GUI.PG_MAILLIST, MUIA_MainMailListGroup_ActiveListviewObject);
      }
      break;
    }
  }

  result = DoSuperMethodA(cl, obj, msg);

  RETURN(result);
  return result;
}

///
/// OVERLOAD(MUIM_Window_Snapshot)
OVERLOAD(MUIM_Window_Snapshot)
{
  struct MUIP_Window_Snapshot *snap = (struct MUIP_Window_Snapshot *)msg;
  IPTR result;

  ENTER();

  // remember the weights for snapshot operations, but not for unsnapshot operations
  if(snap->flags != 0)
  {
    // get the weights according to their GUI elements
    G->Weights[0] = xget(G->MA->GUI.LV_FOLDERS,  MUIA_HorizWeight);
    G->Weights[1] = xget(G->MA->GUI.GR_MAILVIEW, MUIA_HorizWeight);

    // if the embedded read pane objects are currently active we save their weight values
    if(C->EmbeddedReadPane == TRUE)
    {
      G->Weights[6] = xget(G->MA->GUI.GR_MAILLIST, MUIA_VertWeight);
      G->Weights[7] = xget(G->MA->GUI.MN_EMBEDDEDREADPANE, MUIA_VertWeight);
      G->Weights[8] = xget(G->MA->GUI.MN_EMBEDDEDREADPANE, MUIA_ReadMailGroup_HGVertWeight);
      G->Weights[9] = xget(G->MA->GUI.MN_EMBEDDEDREADPANE, MUIA_ReadMailGroup_TGVertWeight);
    }

    // save the FolderListtree order
    FO_SaveTree();

    // make sure the layout is saved
    SaveLayout(TRUE);
  }

  result = DoSuperMethodA(cl, obj, msg);

  RETURN(result);
  return result;
}

///

/* Private Functions */

/* Public Methods */
/// DECLARE(ShowErrors)
// show the error window
DECLARE(ShowErrors)
{
  ENTER();

  ER_NewError(NULL);

  RETURN(0);
  return 0;
}

///
/// DECLARE(Relayout)
// relayout the main window after a configuration change
DECLARE(Relayout)
{
  ENTER();

  if(DoMethod(G->MA->GUI.GR_MAIN, MUIM_Group_InitChange))
  {
    BOOL showbar = TRUE;

    switch(C->InfoBarPos)
    {
      case IB_POS_TOP:
      {
        DoMethod(G->MA->GUI.GR_MAIN, MUIM_Group_Sort, G->MA->GUI.IB_INFOBAR,
                                                      G->MA->GUI.GR_TOP,
                                                      G->MA->GUI.GR_HIDDEN,
                                                      G->MA->GUI.GR_BOTTOM,
                                                      NULL);
      }
      break;

      case IB_POS_CENTER:
      {
        DoMethod(G->MA->GUI.GR_MAIN, MUIM_Group_Sort, G->MA->GUI.GR_TOP,
                                                      G->MA->GUI.GR_HIDDEN,
                                                      G->MA->GUI.IB_INFOBAR,
                                                      G->MA->GUI.GR_BOTTOM,
                                                      NULL);
      }
      break;

      case IB_POS_BOTTOM:
      {
        DoMethod(G->MA->GUI.GR_MAIN, MUIM_Group_Sort, G->MA->GUI.GR_TOP,
                                                      G->MA->GUI.GR_HIDDEN,
                                                      G->MA->GUI.GR_BOTTOM,
                                                      G->MA->GUI.IB_INFOBAR,
                                                      NULL);
      }
      break;

      default:
      {
        showbar = FALSE;
      }
    }

    // if the InfoBar is enabled by the user we make sure we show it
    set(G->MA->GUI.IB_INFOBAR, MUIA_ShowMe, showbar);

    DoMethod(G->MA->GUI.GR_MAIN, MUIM_Group_ExitChange);
  }

  if(DoMethod(G->MA->GUI.GR_MAILLIST, MUIM_Group_InitChange))
  {
    BOOL showbar = TRUE;

    switch(C->QuickSearchBarPos)
    {
      case QSB_POS_TOP:
      {
        DoMethod(G->MA->GUI.GR_MAILLIST, MUIM_Group_Sort, G->MA->GUI.GR_QUICKSEARCHBAR,
                                                          G->MA->GUI.PG_MAILLIST,
                                                          NULL);
      }
      break;

      case QSB_POS_BOTTOM:
      {
        DoMethod(G->MA->GUI.GR_MAILLIST, MUIM_Group_Sort, G->MA->GUI.PG_MAILLIST,
                                                          G->MA->GUI.GR_QUICKSEARCHBAR,
                                                          NULL);
      }
      break;

      default:
      {
        showbar = FALSE;
      }
      break;
    }

    // if the QuickSearchBar is enabled by the user we make sure we show it
    set(G->MA->GUI.GR_QUICKSEARCHBAR, MUIA_ShowMe, showbar);

    DoMethod(G->MA->GUI.GR_MAILLIST, MUIM_Group_ExitChange);
  }

  // check whether the embedded read pane object is already embeeded in our main
  // window so that we know what to do now
  if(G->MA->GUI.MN_EMBEDDEDREADPANE != NULL && C->EmbeddedReadPane == FALSE)
  {
    // the user want to have the embedded read pane removed from the main
    // window, so lets do it now
    if(DoMethod(G->MA->GUI.GR_MAILVIEW, MUIM_Group_InitChange))
    {
      DoMethod(G->MA->GUI.GR_MAILVIEW, OM_REMMEMBER, G->MA->GUI.MN_EMBEDDEDREADPANE);
      DoMethod(G->MA->GUI.GR_MAILVIEW, OM_REMMEMBER, G->MA->GUI.BL_MAILVIEW);

      // clear all contents of the currenly displayed mail
      DoMethod(G->MA->GUI.MN_EMBEDDEDREADPANE, MUIM_ReadMailGroup_Clear, MUIF_NONE);

      // dispose the objects now that we don't need them anymore
      MUI_DisposeObject(G->MA->GUI.MN_EMBEDDEDREADPANE);
      MUI_DisposeObject(G->MA->GUI.BL_MAILVIEW);

      // and nullify it to make it readdable again
      G->MA->GUI.MN_EMBEDDEDREADPANE = NULL;
      G->MA->GUI.BL_MAILVIEW = NULL;

      DoMethod(G->MA->GUI.GR_MAILVIEW, MUIM_Group_ExitChange);
    }
  }
  else if(G->MA->GUI.MN_EMBEDDEDREADPANE == NULL && C->EmbeddedReadPane == TRUE)
  {
    // the user want to have the embedded read pane added to the main
    // window, so lets do it now and create the object
    if((G->MA->GUI.BL_MAILVIEW = NBalanceObject,
      MUIA_ObjectID, MAKE_ID('B','0','0','2'),
      MUIA_Balance_Quiet, TRUE,
    End) != NULL)
    {
      if((G->MA->GUI.MN_EMBEDDEDREADPANE = ReadMailGroupObject,
        MUIA_ContextMenu, TRUE,
        MUIA_VertWeight, G->Weights[7],
        MUIA_ReadMailGroup_HGVertWeight, G->Weights[8],
        MUIA_ReadMailGroup_TGVertWeight, G->Weights[9],
      End) != NULL)
      {
        if(DoMethod(G->MA->GUI.GR_MAILVIEW, MUIM_Group_InitChange))
        {
          set(G->MA->GUI.GR_MAILLIST, MUIA_VertWeight, G->Weights[6]);

          DoMethod(G->MA->GUI.GR_MAILVIEW, OM_ADDMEMBER, G->MA->GUI.BL_MAILVIEW);
          DoMethod(G->MA->GUI.GR_MAILVIEW, OM_ADDMEMBER, G->MA->GUI.MN_EMBEDDEDREADPANE);

          DoMethod(G->MA->GUI.GR_MAILVIEW, MUIM_Group_ExitChange);
        }
        else
        {
          MUI_DisposeObject(G->MA->GUI.MN_EMBEDDEDREADPANE);
          G->MA->GUI.MN_EMBEDDEDREADPANE = NULL;
          MUI_DisposeObject(G->MA->GUI.BL_MAILVIEW);
          G->MA->GUI.BL_MAILVIEW = NULL;
        }
      }
      else
      {
        MUI_DisposeObject(G->MA->GUI.BL_MAILVIEW);
        G->MA->GUI.BL_MAILVIEW = NULL;
      }
    }
  }

  RETURN(0);
  return 0;
}

///
/// DECLARE(DoEditAction)
// delegate an edit action (i.e. cut/copy/paste, etc) to certain subobjects
DECLARE(DoEditAction) // enum EditAction action
{
  BOOL matched = FALSE;

  ENTER();

  // check if the quicksearchbar (if enabled) reacts on our
  // edit action
  if(C->QuickSearchBarPos != QSB_POS_OFF)
    matched = DoMethod(G->MA->GUI.GR_QUICKSEARCHBAR, MUIM_QuickSearchBar_DoEditAction, msg->action);

  // if we have an active embedded read pane we
  // have to forward the request to the readmail group object
  // first and see if it matches
  if(matched == FALSE && C->EmbeddedReadPane == TRUE)
    matched = DoMethod(G->MA->GUI.MN_EMBEDDEDREADPANE, MUIM_ReadMailGroup_DoEditAction, msg->action, TRUE);

  RETURN(0);
  return 0;
}

///
/// DECLARE(ApplyFilters)
DECLARE(ApplyFilters) // enum ApplyFilterMode mode, ULONG qualifier, struct FilterResult *result
{
  struct Folder *folder;
  struct FilterResult filterResult;

  ENTER();

  D(DBF_FILTER, "About to apply SPAM and user defined filters in mode %ld...", msg->mode);

  memset(&filterResult, 0, sizeof(filterResult));

  folder = (msg->mode == APPLY_AUTO) ? FO_GetFolderByType(FT_INCOMING, NULL) : GetCurrentFolder();

  if(folder != NULL && (C->SpamFilterEnabled == FALSE || FO_GetFolderByType(FT_SPAM, NULL) != NULL))
  {
    struct MailList *mlist = NULL;
    BOOL processAllMails = TRUE;

    // query how many mails are currently selected/marked
    if(msg->mode == APPLY_USER || msg->mode == APPLY_RX || msg->mode == APPLY_RX_ALL || msg->mode == APPLY_SPAM)
    {
      ULONG minselected = isAnyFlagSet(msg->qualifier, (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) ? 1 : 2;

      if((mlist = MA_CreateMarkedList(G->MA->GUI.PG_MAILLIST, msg->mode == APPLY_RX)) != NULL)
      {
        if(mlist->count < minselected)
        {
          W(DBF_FILTER, "number of selected mails < required minimum (%ld < %ld)", mlist->count, minselected);

          DeleteMailList(mlist);
          mlist = NULL;
        }
        else
          processAllMails = FALSE;
      }
    }

    // if we haven't got any mail list, we
    // go and create one over all mails in the folder
    if(mlist == NULL)
      mlist = MA_CreateFullList(folder, (msg->mode == APPLY_AUTO || msg->mode == APPLY_RX));

    // check that we can continue
    if(mlist != NULL)
    {
      BOOL applyFilters = TRUE;

      // if this function was called manually by the user we ask him
      // if he really wants to apply the filters or not.
      if(msg->mode == APPLY_USER)
      {
        char buf[SIZE_LARGE];

        if(processAllMails == TRUE)
          snprintf(buf, sizeof(buf), tr(MSG_MA_CONFIRMFILTER_ALL), folder->Name);
        else
          snprintf(buf, sizeof(buf), tr(MSG_MA_CONFIRMFILTER_SELECTED), folder->Name);

        if(MUI_Request(_app(obj), obj, MUIF_NONE, tr(MSG_MA_ConfirmReq), tr(MSG_YesNoReq), buf) == 0)
          applyFilters = FALSE;
      }

      // the user has not cancelled the filter process
      if(applyFilters == TRUE)
      {
        FilterMails(mlist, msg->mode, &filterResult);

        if(filterResult.Checked != 0 && msg->mode == APPLY_USER)
        {
          if(C->ShowFilterStats == TRUE)
          {
            char buf[SIZE_LARGE];

            if(C->SpamFilterEnabled == TRUE)
            {
              // include the number of spam classified mails
              snprintf(buf, sizeof(buf), tr(MSG_MA_FILTER_STATS_SPAM), filterResult.Checked,
                                                                       filterResult.Forwarded,
                                                                       filterResult.Moved,
                                                                       filterResult.Deleted,
                                                                       filterResult.Spam);
            }
            else
            {
              snprintf(buf, sizeof(buf), tr(MSG_MA_FilterStats), filterResult.Checked,
                                                                 filterResult.Forwarded,
                                                                 filterResult.Moved,
                                                                 filterResult.Deleted);
            }

            MUI_Request(_app(obj), obj, MUIF_NONE, NULL, tr(MSG_OkayReq), buf);
          }
        }
      }
      else
        D(DBF_FILTER, "filtering rejected by user.");

      DeleteMailList(mlist);
    }
    else
      W(DBF_FILTER, "folder empty or error on creating list of mails.");
  }

  // copy the results if anybody is interested in them
  if(msg->result != NULL)
    memcpy(msg->result, &filterResult, sizeof(filterResult));

  RETURN(0);
  return 0;
}

///