Package de.willuhn.jameica.hbci.gui.parts

Source Code of de.willuhn.jameica.hbci.gui.parts.SynchronizeList

/**********************************************************************
*
* Copyright (c) by Olaf Willuhn
* All rights reserved
*
**********************************************************************/

package de.willuhn.jameica.hbci.gui.parts;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TableItem;

import de.willuhn.jameica.gui.Action;
import de.willuhn.jameica.gui.GUI;
import de.willuhn.jameica.gui.formatter.TableFormatter;
import de.willuhn.jameica.gui.parts.Button;
import de.willuhn.jameica.gui.parts.ButtonArea;
import de.willuhn.jameica.gui.parts.TablePart;
import de.willuhn.jameica.gui.util.Font;
import de.willuhn.jameica.hbci.HBCI;
import de.willuhn.jameica.hbci.gui.action.Synchronize;
import de.willuhn.jameica.hbci.gui.dialogs.KontoAuswahlDialog;
import de.willuhn.jameica.hbci.gui.dialogs.SynchronizeOptionsDialog;
import de.willuhn.jameica.hbci.gui.filter.KontoFilter;
import de.willuhn.jameica.hbci.rmi.Konto;
import de.willuhn.jameica.hbci.synchronize.Synchronization;
import de.willuhn.jameica.hbci.synchronize.SynchronizeBackend;
import de.willuhn.jameica.hbci.synchronize.SynchronizeEngine;
import de.willuhn.jameica.hbci.synchronize.jobs.SynchronizeJob;
import de.willuhn.jameica.messaging.Message;
import de.willuhn.jameica.messaging.MessageConsumer;
import de.willuhn.jameica.messaging.QueryMessage;
import de.willuhn.jameica.messaging.StatusBarMessage;
import de.willuhn.jameica.services.BeanService;
import de.willuhn.jameica.system.Application;
import de.willuhn.jameica.system.OperationCanceledException;
import de.willuhn.logging.Logger;
import de.willuhn.util.ApplicationException;
import de.willuhn.util.I18N;
import de.willuhn.util.ProgressMonitor;

/**
* Vorgefertigte Liste mit den offenen Synchronisierungsaufgaben.
*/
public class SynchronizeList extends TablePart
{
  // Wir cachen die Liste der vom User explizit abgewaehlten Aufgaben waehrend der Sitzung
  private static Map<String,Boolean> uncheckedCache = new HashMap<String,Boolean>();
 
  private static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N();
  private MessageConsumer mcSync  = new SyncMessageConsumer();
  private MessageConsumer mcCache = new CacheMessageConsumer();
  private List<Synchronization> syncList = new ArrayList<Synchronization>();

  /**
   * ct.
   * @throws RemoteException
   */
  public SynchronizeList() throws RemoteException
  {
    super(new Configure());
    this.addColumn(i18n.tr("Offene Synchronisierungsaufgaben"),"name");
    this.setSummary(false);
    this.setCheckable(true);

    // BUGZILLA 583
    this.setFormatter(new TableFormatter() {
      public void format(TableItem item)
      {
        try
        {
          if (item == null)
            return;
          SynchronizeJob job = (SynchronizeJob) item.getData();
          if (job == null)
            return;
          item.setFont(job.isRecurring() ? Font.DEFAULT.getSWTFont() : Font.BOLD.getSWTFont());
        }
        catch (Exception e)
        {
          Logger.error("unable to format text",e);
        }
      }
    });
   
    // Vorm paint() nochmal machen, damit auch XP die Spaltenbreiten hinkriegt - die werden wohl scheinbar beim paint() ermittelt
    init();
  }
 
  /**
   * Initialisiert die Liste der Synchronisierungsaufgaben
   * @throws RemoteException
   */
  private void init() throws RemoteException
  {
    this.syncList.clear();
   
    this.removeAll(); // leer machen
   
    // Liste der Sync-Jobs hinzufuegen
    BeanService service = Application.getBootLoader().getBootable(BeanService.class);
    List<SynchronizeBackend> backends = service.get(SynchronizeEngine.class).getBackends();
    for (SynchronizeBackend backend:backends)
    {
      Synchronization sync = new Synchronization();
      sync.setBackend(backend);
      List<SynchronizeJob> jobs = backend.getSynchronizeJobs(null); // fuer alle Konten
      if (jobs != null)
      {
        for (SynchronizeJob job:jobs)
        {
          boolean checked = true;
          try
          {
            // nicht markiert, wenn das letzte Mal explizit abgewaehlt
            checked = !uncheckedCache.containsKey(job.getName());
          }
          catch (Exception e)
          {
            Logger.error("unable to determine if job was unchecked",e);
          }
          this.addItem(job,checked);

          sync.getJobs().add(job);
        }
      }
      this.syncList.add(sync);
    }
  }

  /**
   * @see de.willuhn.jameica.gui.parts.TablePart#paint(org.eclipse.swt.widgets.Composite)
   */
  public synchronized void paint(Composite parent) throws RemoteException
  {
    Application.getMessagingFactory().getMessagingQueue(SynchronizeBackend.QUEUE_STATUS).registerMessageConsumer(this.mcSync);
    Application.getMessagingFactory().getMessagingQueue("jameica.gui.view.unbind").registerMessageConsumer(this.mcCache);
    parent.addDisposeListener(new DisposeListener() {
      public void widgetDisposed(DisposeEvent e)
      {
        Application.getMessagingFactory().getMessagingQueue(SynchronizeBackend.QUEUE_STATUS).unRegisterMessageConsumer(mcSync);
        Application.getMessagingFactory().getMessagingQueue("jameica.gui.view.unbind").unRegisterMessageConsumer(mcCache);
      }
    });

    final Button start = new Button(i18n.tr("S&ynchronisierung starten"),new SyncStart(),null,true,"mail-send-receive.png");
   
    // Button deaktivieren, wenn alle Sync-Aufgaben abgeschaltet sind
    this.addSelectionListener(new Listener() {
      public void handleEvent(Event event)
      {
        try
        {
          List<SynchronizeJob> selected = getItems(true);
          start.setEnabled(selected != null && selected.size() > 0);
        }
        catch (Exception e)
        {
          Logger.error("unable to determine selected items",e);
          Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Fehler beim Ermitteln der Synchronisierungsaufgaben"),StatusBarMessage.TYPE_ERROR));
        }
      }
    });
   
    super.paint(parent);
   
    // Erst nach dem paint() machen, damit der initiale Checked-State aus dem Cache beachtet wird
    this.init();
   
    ButtonArea b = new ButtonArea();
    b.addButton(i18n.tr("Optionen..."),new Options(),null,false,"document-properties.png"); // BUGZILLA 226
    b.addButton(start);
    b.paint(parent);
  }
 
  /**
   * Cached die Liste der abgewaehlten Aufgaben.
   */
  private void cacheUnchecked()
  {
    try
    {
      uncheckedCache.clear();
      List<SynchronizeJob> selected = getItems(true);
      List<SynchronizeJob> all      = getItems(false);
      for (SynchronizeJob j:all)
      {
        if (!selected.contains(j))
        {
          // abgewaehlt
          uncheckedCache.put(j.getName(),Boolean.TRUE);
        }
      }
    }
    catch (Exception e)
    {
      Logger.error("unable to cache unchecked items",e);
    }
  }
 
  /**
   * Oeffnet den Dialog mit den Synchronisierungsoptionen.
   */
  private class Options implements Action
  {
    /**
     * @see de.willuhn.jameica.gui.Action#handleAction(java.lang.Object)
     */
    public void handleAction(Object context) throws ApplicationException
    {
      try
      {
        Konto k  = null;
        Object o = getSelection();
        if (o instanceof SynchronizeJob)
          k = ((SynchronizeJob)o).getKonto();
       
        // Konto erfragen
        if (k == null)
        {
          KontoAuswahlDialog d1 = new KontoAuswahlDialog(null,KontoFilter.SYNCED,KontoAuswahlDialog.POSITION_CENTER);
          d1.setText(i18n.tr("Bitte w�hlen Sie das Konto, f�r welches Sie die " +
                             "Synchronisierungsoptionen �ndern m�chten."));
          k = (Konto) d1.open();
        }
       
        if (k == null)
          return;

        SynchronizeOptionsDialog d = new SynchronizeOptionsDialog(k,SynchronizeOptionsDialog.POSITION_CENTER);
        d.open();
       
        // So, jetzt muessen wir die Liste der Sync-Jobs neu befuellen
        init();
      }
      catch (OperationCanceledException oce)
      {
        // ignore
      }
      catch (ApplicationException ae)
      {
        throw ae;
      }
      catch (Exception e)
      {
        Logger.error("unable to configure synchronize options");
        GUI.getStatusBar().setErrorText(i18n.tr("Fehler beim Konfigurieren der Synchronisierungsoptionen: {0}",e.getMessage()));
      }
    }
  }
 
  /**
   * Startet die Synchronisierung der Konten.
   */
  private class SyncStart implements Action
  {
    /**
     * @see de.willuhn.jameica.gui.Action#handleAction(java.lang.Object)
     */
    @Override
    public void handleAction(Object context) throws ApplicationException
    {
      try
      {
        cacheUnchecked();
       
        Logger.info("Collecting synchronize jobs");
        List<SynchronizeJob> selected = getItems(true);

        // Iterieren ueber die Synchronisationen und die rauswerfen, die nicht markiert sind
        List<Synchronization> result = new ArrayList<Synchronization>();
        for (Synchronization s:syncList)
        {
          List<SynchronizeJob> jobs = s.getJobs(); // komplette Liste der Jobs
          List<SynchronizeJob> toExecute = new ArrayList<SynchronizeJob>();
          for (SynchronizeJob job:jobs)
          {
            if (selected.contains(job)) // in den selektierten enthalten?
              toExecute.add(job);
          }
         
          // Gar kein Job in dem Backend ausgewaehlt
          if (toExecute.size() == 0)
            continue;
         
          Synchronization rs = new Synchronization();
          rs.setBackend(s.getBackend());
          rs.setJobs(toExecute);
          result.add(rs);
        }
       
        Synchronize sync = new Synchronize();
        sync.handleAction(result);
      }
      catch (OperationCanceledException oce)
      {
        // ignore
      }
      catch (ApplicationException ae)
      {
        throw ae;
      }
      catch (RemoteException re)
      {
        Logger.error("error while synchronizing",re);
        throw new ApplicationException(i18n.tr("Synchronisierung fehlgeschlagen: {0}",re.getMessage()));
      }
    }
  }

  /**
   * Hilfsklasse zum Reagieren auf Doppelklicks in der Liste.
   * Dort stehen naemlich ganz verschiedene Datensaetze drin.
   * Daher muss der Datensatz selbst entscheiden, was beim
   * Klick auf ihn gesehen soll.
   */
  private static class Configure implements Action
  {

    /**
     * @see de.willuhn.jameica.gui.Action#handleAction(java.lang.Object)
     */
    public void handleAction(Object context) throws ApplicationException
    {
      if (!(context instanceof SynchronizeJob))
        return;
     
      ((SynchronizeJob)context).configure();
    }
  }
 
  /**
   * Hilfsklasse zum Abfragen der Status-Codes der SynchronizeEngine.
   */
  private class SyncMessageConsumer implements MessageConsumer
  {
    /**
     * @see de.willuhn.jameica.messaging.MessageConsumer#autoRegister()
     */
    public boolean autoRegister()
    {
      return false;
    }

    /**
     * @see de.willuhn.jameica.messaging.MessageConsumer#getExpectedMessageTypes()
     */
    public Class[] getExpectedMessageTypes()
    {
      return new Class[]{QueryMessage.class};
    }

    /**
     * @see de.willuhn.jameica.messaging.MessageConsumer#handleMessage(de.willuhn.jameica.messaging.Message)
     */
    public void handleMessage(final Message message) throws Exception
    {
      GUI.getDisplay().asyncExec(new Runnable()
      {
        public void run()
        {
          try
          {
            QueryMessage msg = (QueryMessage) message;
            Integer status = (Integer) msg.getData();
            if (status == null)
              return;

            if (status.intValue() == ProgressMonitor.STATUS_RUNNING)
              return; // laeuft noch
           
            // Liste der Jobs aktualisieren
            init();
          }
          catch (Exception e)
          {
            Logger.error("unable to reload sync jobs",e);
          }
        }
      });
    }
  }
 
  /**
   * Wird beim unbind der View benachrichtigt und speichert die aktuelle Auswahl
   * der abgewaehlten Sync-Aufgaben.
   */
  private class CacheMessageConsumer implements MessageConsumer
  {
    /**
     * @see de.willuhn.jameica.messaging.MessageConsumer#autoRegister()
     */
    public boolean autoRegister()
    {
      return false;
    }
   
    /**
     * @see de.willuhn.jameica.messaging.MessageConsumer#getExpectedMessageTypes()
     */
    public Class[] getExpectedMessageTypes()
    {
      return new Class[]{QueryMessage.class};
    }
   
    /**
     * @see de.willuhn.jameica.messaging.MessageConsumer#handleMessage(de.willuhn.jameica.messaging.Message)
     */
    public void handleMessage(Message message) throws Exception
    {
      cacheUnchecked();
    }
  }

}
TOP

Related Classes of de.willuhn.jameica.hbci.gui.parts.SynchronizeList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.