Changeset 1727


Ignore:
Timestamp:
Jul 5, 2010, 3:51:42 PM (11 years ago)
Author:
Paul Lelgemann
Message:

+ P2PEditor can display the status of jobs, if available; Participating displays overlay while loading workspace data
+ KeySearcher can upload status for P2PEditor display

Location:
trunk
Files:
10 added
24 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/CrypP2P/P2PSettings.Designer.cs

    r1696 r1727  
    122122        [global::System.Configuration.UserScopedSettingAttribute()]
    123123        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    124         [global::System.Configuration.DefaultSettingValueAttribute("10")]
     124        [global::System.Configuration.DefaultSettingValueAttribute("60")]
    125125        public int DistributedJobListRefreshInterval {
    126126            get {
  • trunk/CrypP2P/P2PSettings.settings

    r1696 r1727  
    2828    </Setting>
    2929    <Setting Name="DistributedJobListRefreshInterval" Type="System.Int32" Scope="User">
    30       <Value Profile="(Default)">10</Value>
     30      <Value Profile="(Default)">60</Value>
    3131    </Setting>
    3232    <Setting Name="UseLocalAddressDetection" Type="System.Boolean" Scope="User">
  • trunk/CrypP2P/app.config

    r1696 r1727  
    3333            </setting>
    3434            <setting name="DistributedJobListRefreshInterval" serializeAs="String">
    35                 <value>10</value>
     35                <value>60</value>
    3636            </setting>
    3737            <setting name="UseLocalAddressDetection" serializeAs="String">
  • trunk/CrypPlugins/KeySearcher/KeySearcher.cs

    r1707 r1727  
    3838        private readonly Mutex maxThreadMutex = new Mutex();
    3939
     40        public bool IsKeySearcherRunning;
    4041        private KeyQualityHelper keyQualityHelper;
    4142        private readonly P2PQuickWatchPresentation p2PQuickWatchPresentation;
     
    215216        public KeySearcher()
    216217        {
     218            IsKeySearcherRunning = false;
    217219            settings = new KeySearcherSettings(this);
    218220            QuickWatchPresentation = new QuickWatch();
     
    261263        public virtual void Execute()
    262264        {
     265            IsKeySearcherRunning = true;
     266
    263267            //either byte[] CStream input or CryptoolStream Object input
    264268            if (encryptedData != null || csEncryptedData != null) //to prevent execution on initialization
     
    283287        public void Stop()
    284288        {
     289            IsKeySearcherRunning = false;
    285290            stop = true;
    286291        }
  • trunk/CrypPlugins/KeySearcher/KeySearcher.csproj

    r1707 r1727  
    116116    <Compile Include="P2P\Presentation\StatisticsGenerator.cs" />
    117117    <Compile Include="P2P\Presentation\StatusContainer.cs" />
     118    <Compile Include="P2P\Storage\StatusUpdater.cs" />
    118119    <Compile Include="Presentation\Controls\LocalQuickWatchPresentation.xaml.cs">
    119120      <DependentUpon>LocalQuickWatchPresentation.xaml</DependentUpon>
     
    151152      <Private>False</Private>
    152153    </ProjectReference>
     154    <ProjectReference Include="..\P2PEditor\P2PEditor.csproj">
     155      <Project>{59DEB752-BEB6-4B2B-86A9-78B150537529}</Project>
     156      <Name>P2PEditor</Name>
     157      <Private>False</Private>
     158    </ProjectReference>
    153159  </ItemGroup>
    154160  <ItemGroup>
  • trunk/CrypPlugins/KeySearcher/KeySearcherSettings.cs

    r1701 r1727  
    11using System;
    22using System.Numerics;
     3using System.Windows;
     4using Cryptool.P2P;
    35using Cryptool.PluginBase;
    46using System.ComponentModel;
    57using System.Collections.ObjectModel;
    68using KeySearcher.KeyPattern;
     9using KeySearcher.P2P.Storage;
    710
    811namespace KeySearcher
     
    132135        }
    133136
     137        [TaskPane("Copy status key", "Copy status key to clipboard. The key can than be used to upload it together with the job using the P2PEditor.", GroupPeerToPeer, 4, true, DisplayLevel.Professional, ControlType.Button)]
     138        public void StatusKeyButton()
     139        {
     140            if (!keysearcher.IsKeySearcherRunning)
     141            {
     142                keysearcher.GuiLogMessage("KeySearcher must be running to copy the status key.", NotificationLevel.Error);
     143                return;
     144            }
     145
     146            var generator = new StorageKeyGenerator(keysearcher, this);
     147            var statusKey = generator.GenerateStatusKey();
     148
     149            Clipboard.SetDataObject(statusKey, true);
     150            keysearcher.GuiLogMessage("Status key '" + statusKey + "' has been copied to clipboard.",
     151                                      NotificationLevel.Info);
     152        }
     153
    134154        private ObservableCollection<string> coresAvailable = new ObservableCollection<string>();
    135155        public ObservableCollection<string> CoresAvailable
  • trunk/CrypPlugins/KeySearcher/P2P/DistributedBruteForceManager.cs

    r1708 r1727  
    6262            {
    6363                keySearcher.GuiLogMessage("Unable to use peer-to-peer system.", NotificationLevel.Error);
     64                status.CurrentOperation = "Unable to use peer-to-peer system";
    6465                return;
    6566            }
     
    8081                status.IsCurrentProgressIndeterminate = true;
    8182
     83                BigInteger displayablePatternId;
    8284                try
    8385                {
     
    8890                        break;
    8991                    }
     92                    displayablePatternId = currentLeaf.PatternId() + 1;
    9093                }
    9194                catch (AlreadyCalculatedException)
     
    9699                }
    97100
    98                 status.CurrentOperation = "Calculating global statistics";
    99                 StatisticsGenerator.CalculateGlobalStatistics(currentLeaf.PatternId());
    100101                if (!currentLeaf.ReserveLeaf())
    101102                {
    102103                    keySearcher.GuiLogMessage(
    103                         "Pattern #" + currentLeaf.PatternId() +
     104                        "Pattern #" + displayablePatternId +
    104105                        " was reserved before it could be reserved for this CrypTool instance.",
    105106                        NotificationLevel.Info);
     
    109110
    110111                keySearcher.GuiLogMessage(
    111                     "Running pattern #" + (currentLeaf.PatternId() + 1) + " of " + patternPool.Length,
     112                    "Running pattern #" + displayablePatternId + " of " + patternPool.Length,
    112113                    NotificationLevel.Info);
    113                 status.CurrentChunk = currentLeaf.PatternId() + 1;
     114                status.CurrentChunk = displayablePatternId;
    114115                status.CurrentOperation = "Calculating pattern " + status.CurrentChunk;
    115116
     
    127128                        KeyPoolTree.ProcessCurrentPatternCalculationResult(currentLeaf, result);
    128129                        StatisticsGenerator.ProcessPatternResults(result);
    129                        
     130
     131                        status.CurrentOperation = "Calculating global statistics";
     132                        StatisticsGenerator.CalculateGlobalStatistics(displayablePatternId);
     133
    130134                        status.LocalFinishedChunks++;
    131135                        keySearcher.GuiLogMessage(
    132136                            string.Format("Best match: {0} with {1}", result.First.Value.key, result.First.Value.value),
    133137                            NotificationLevel.Info);
     138
     139                        status.CurrentOperation = "Updating status in DHT";
     140                        keyPoolTree.UpdateStatus(currentLeaf);
    134141                    }
    135142                    else
     
    161168                keySearcher.showProgress(keySearcher.costList, 1, 1, 1);
    162169                keySearcher.GuiLogMessage("Calculation complete.", NotificationLevel.Info);
     170                keyPoolTree.UpdateStatusForFinishedCalculation();
    163171               
    164172            }
  • trunk/CrypPlugins/KeySearcher/P2P/Presentation/StatisticsGenerator.cs

    r1709 r1727  
    1515    class StatisticsGenerator
    1616    {
     17        public readonly BigInteger TotalAmountOfChunks;
    1718        private readonly StatusContainer status;
    1819        private readonly P2PQuickWatchPresentation quickWatch;
    1920        private readonly KeySearcher keySearcher;
    2021        private readonly DistributedBruteForceManager distributedBruteForceManager;
    21         private readonly BigInteger totalAmountOfChunks;
    2222        private readonly Stopwatch stopWatch;
    2323        private readonly Timer elapsedTimeTimer;
    2424        private readonly Timer trafficUpdateTimer;
    2525
     26        public BigInteger HighestChunkCalculated;
    2627        private DateTime lastDateOfGlobalStatistics;
    27         private BigInteger highestChunkCalculated;
    2828        private BigInteger totalRequestsAtStartOfNodeSearch;
    2929
     
    3636
    3737            lastDateOfGlobalStatistics = DateTime.Now;
    38             highestChunkCalculated = -1;
     38            HighestChunkCalculated = -1;
    3939            stopWatch = new Stopwatch();
    4040
     
    4444            var keyPatternPool = new KeyPatternPool(keyPattern, new BigInteger(keysPerChunk));
    4545
    46             totalAmountOfChunks = keyPatternPool.Length;
     46            TotalAmountOfChunks = keyPatternPool.Length;
    4747
    4848            status.PropertyChanged += StatusPropertyChanged;
     
    142142        public void CalculateGlobalStatistics(BigInteger nextChunk)
    143143        {
    144             if (highestChunkCalculated == -1) highestChunkCalculated = nextChunk;
    145             if (nextChunk <= highestChunkCalculated) return;
    146 
    147             var totalAmountOfParticipants = nextChunk - highestChunkCalculated;
     144            if (HighestChunkCalculated == -1) HighestChunkCalculated = nextChunk;
     145            if (nextChunk <= HighestChunkCalculated) return;
     146
     147            var totalAmountOfParticipants = nextChunk - HighestChunkCalculated;
    148148            status.TotalAmountOfParticipants = totalAmountOfParticipants;
    149149
    150150            var timeUsedForLatestProgress = DateTime.Now.Subtract(lastDateOfGlobalStatistics);
    151151            var secondsForOneChunk = timeUsedForLatestProgress.TotalSeconds/(double) totalAmountOfParticipants;
    152             var remainingChunks = totalAmountOfChunks - nextChunk;
     152            var remainingChunks = TotalAmountOfChunks - nextChunk;
    153153            var secondsRemaining = (double) remainingChunks*secondsForOneChunk;
    154154
     
    168168            lastDateOfGlobalStatistics = DateTime.Now;
    169169
    170             highestChunkCalculated = nextChunk;
    171             var globalProgressValue = (double) highestChunkCalculated/(double) totalAmountOfChunks;
    172             keySearcher.ProgressChanged(globalProgressValue, 1);
     170            HighestChunkCalculated = nextChunk;
     171            status.GlobalProgress = (double) HighestChunkCalculated/(double) TotalAmountOfChunks;
     172            keySearcher.ProgressChanged(status.GlobalProgress, 1);
    173173        }
    174174
  • trunk/CrypPlugins/KeySearcher/P2P/Presentation/StatusContainer.cs

    r1705 r1727  
    5252        }
    5353
     54        private double globalProgress;
     55        public double GlobalProgress
     56        {
     57            get { return globalProgress; }
     58            set
     59            {
     60                globalProgress = value;
     61                OnPropertyChanged("GlobalProgress");
     62            }
     63        }
     64
    5465        private bool isCurrentProgressIndeterminate;
    5566        public bool IsCurrentProgressIndeterminate
  • trunk/CrypPlugins/KeySearcher/P2P/Storage/StorageKeyGenerator.cs

    r1706 r1727  
    5454            return BitConverter.ToString(hash).Replace("-", "");
    5555        }
     56
     57        public string GenerateStatusKey()
     58        {
     59            return Generate() + "-status";
     60        }
    5661    }
    5762}
  • trunk/CrypPlugins/KeySearcher/P2P/Tree/KeyPoolTree.cs

    r1709 r1727  
    11using System;
    22using System.Collections.Generic;
     3using Cryptool.P2PEditor.Distributed;
    34using Cryptool.PluginBase;
    45using KeySearcher.Helper;
     
    1819        private readonly StorageHelper storageHelper;
    1920        private readonly string identifier;
     21        private readonly StatusUpdater statusUpdater;
     22        private readonly int updateIntervalMod;
    2023
    2124        private NodeBase currentNode;
     
    3134
    3235            storageHelper = new StorageHelper(keySearcher, statisticsGenerator, statusContainer);
     36            statusUpdater = new StatusUpdater(statusContainer, identifierGenerator.GenerateStatusKey());
     37            UpdateStatusForNewCalculation();
    3338            skippedReservedNodes = false;
     39            updateIntervalMod = 5;
    3440
    3541            statisticsGenerator.MarkStartOfNodeSearch();
     
    128134            currentLeaf.HandleResults(result);
    129135        }
     136
     137        private void UpdateStatusForNewCalculation()
     138        {
     139            statusUpdater.SendUpdate(DistributedJobStatus.Status.New);
     140        }
     141
     142        public void UpdateStatusForFinishedCalculation()
     143        {
     144            statusUpdater.SendUpdate(DistributedJobStatus.Status.Finished);
     145        }
     146
     147        public void UpdateStatus(Leaf currentLeaf)
     148        {
     149            var isHigherPatternThanBefore = (currentLeaf.PatternId() + 1) >= statisticsGenerator.HighestChunkCalculated;
     150            var isLastPattern = currentLeaf.PatternId() == statisticsGenerator.TotalAmountOfChunks - 1;
     151            var patternIdQualifiesForUpdate = currentLeaf.PatternId() % updateIntervalMod == 0;
     152
     153            if ((!isHigherPatternThanBefore || !patternIdQualifiesForUpdate) && !isLastPattern) return;
     154            statusUpdater.SendUpdate();
     155            keySearcher.GuiLogMessage("Updating status in DHT", NotificationLevel.Info);
     156        }
    130157    }
    131158}
  • trunk/CrypPlugins/P2PEditor/Converters/TrueToVisibleOrCollapsedConverter.cs

    r1716 r1727  
    44using System.Windows.Data;
    55
    6 namespace KeySearcherConverter
     6namespace Cryptool.P2PEditor.Converters
    77{
    88    [ValueConversion(typeof (bool), typeof (Visibility))]
  • trunk/CrypPlugins/P2PEditor/Converters/UtcDateTimeToLocalConverter.cs

    r1717 r1727  
    66namespace Cryptool.P2PEditor.Converters
    77{
    8     public class DateTimeConverter : IValueConverter
     8    public class UtcDateTimeToLocalConverter : IValueConverter
    99    {
    1010        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    1111        {
    12             return ((DateTime)value).ToString("g", Thread.CurrentThread.CurrentCulture);
     12            var startTimeUtc = DateTime.SpecifyKind((DateTime) value, DateTimeKind.Utc);
     13            var localTime = startTimeUtc.ToLocalTime();
     14
     15            if (startTimeUtc == DateTime.MinValue) return "-";
     16
     17            return localTime.ToString("g", Thread.CurrentThread.CurrentCulture);
    1318        }
    1419
  • trunk/CrypPlugins/P2PEditor/Distributed/DistributedJob.cs

    r1703 r1727  
    66namespace Cryptool.P2PEditor.Distributed
    77{
    8     [Serializable]
    98    public class DistributedJob : INotifyPropertyChanged
    109    {
    11         [NonSerialized]
    12         private String localFilePath;
    13 
    1410        public DistributedJob()
    1511        {
    16             JobGuid = Guid.NewGuid();
    17             JobOwner = P2PSettings.Default.PeerName;
    18             JobDate = DateTime.Now;
     12            Guid = Guid.NewGuid();
     13            Owner = P2PSettings.Default.PeerName;
     14            CreateDate = DateTime.UtcNow;
    1915        }
    2016
    21         public Guid JobGuid { get; private set; }
     17        public Guid Guid { get; set; }
    2218
    23         public String JobName { get; set; }
     19        public String Name { get; set; }
    2420
    25         public String JobDescription { get; set; }
     21        public String Description { get; set; }
    2622
    27         public String JobOwner { get; set; }
     23        public String Owner { get; set; }
    2824
    29         public DateTime JobDate { get; set; }
     25        public DateTime CreateDate { get; set; }
    3026
    31         public String FileName { get; private set; }
     27        public String FileName { get; set; }
    3228
     29        private DistributedJobStatus status;
     30        public DistributedJobStatus Status
     31        {
     32            get { return status; }
     33            set
     34            {
     35                if (value == status) return;
     36                status = value;
     37                OnPropertyChanged("Status");
     38            }
     39        }
     40
     41        private int downloads;
     42        public int Downloads
     43        {
     44            get { return downloads; }
     45            set
     46            {
     47                if (value == downloads) return;
     48                downloads = value;
     49                OnPropertyChanged("Downloads");
     50            }
     51        }
     52
     53        private DateTime lastDownload;
     54        public DateTime LastDownload
     55        {
     56            get { return lastDownload; }
     57            set
     58            {
     59                if (value == lastDownload) return;
     60                lastDownload = value;
     61                OnPropertyChanged("LastDownload");
     62            }
     63        }
     64
     65        private String localFilePath;
    3366        public String LocalFilePath
    3467        {
     
    4376        }
    4477
    45         #region INotifyPropertyChanged Members
    46 
    47         [field: NonSerialized]
    48         public event PropertyChangedEventHandler PropertyChanged;
    49 
    50         #endregion
     78        private String statusKey;
     79        public String StatusKey
     80        {
     81            get { return statusKey; }
     82            set
     83            {
     84                if (value == statusKey) return;
     85                statusKey = value;
     86                OnPropertyChanged("StatusKey");
     87            }
     88        }
    5189
    5290        public void ConvertRawWorkspaceToLocalFile(byte[] rawWorkspaceData)
    5391        {
    54             string workspacePath = P2PSettings.Default.WorkspacePath;
     92            var workspacePath = P2PSettings.Default.WorkspacePath;
    5593            if (String.IsNullOrEmpty(workspacePath) || !Directory.Exists(workspacePath))
    5694            {
     
    6098            // Avoid overwriting previous versions of this workspace or workspaces with common names by adding an integer prefix
    6199            var originalFileName = FileName;
    62             LocalFilePath = Path.Combine(workspacePath, JobOwner + "_" + originalFileName);
     100            LocalFilePath = Path.Combine(workspacePath, Owner + "_" + originalFileName);
    63101            var counter = 0;
    64102            while (File.Exists(LocalFilePath))
    65103            {
    66                 LocalFilePath = Path.Combine(workspacePath, counter++ + "_" + JobOwner + "_" + originalFileName);
     104                LocalFilePath = Path.Combine(workspacePath, counter++ + "_" + Owner + "_" + originalFileName);
    67105            }
    68106
     
    75113        }
    76114
     115        #region INotifyPropertyChanged Members
     116
     117        public event PropertyChangedEventHandler PropertyChanged;
     118
    77119        private void OnPropertyChanged(string propertyName)
    78120        {
     
    80122                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    81123        }
     124
     125        #endregion
     126
     127        #region Equals and HashCode
    82128
    83129        public override bool Equals(object obj)
     
    98144            }
    99145
    100             return obj.JobGuid == JobGuid;
     146            return obj.Guid == Guid;
    101147        }
    102148
    103149        public override int GetHashCode()
    104150        {
    105             return JobGuid.GetHashCode();
     151            return Guid.GetHashCode();
    106152        }
     153
     154        #endregion
    107155    }
    108156}
  • trunk/CrypPlugins/P2PEditor/Distributed/JobListManager.cs

    r1665 r1727  
    1 using System;
     1using System;
    22using System.Collections.Generic;
    33using System.IO;
    4 using System.Runtime.Serialization.Formatters.Binary;
    54using Cryptool.P2P;
     5using Cryptool.P2P.Internal;
    66using Cryptool.PluginBase;
    77
     
    1212        private const string JoblistKey = "Cryptool.P2PEditor.JobList";
    1313        private const string WorkspaceKeyPrefix = "Workspace";
    14         private readonly P2PEditor _p2PEditor;
     14        private readonly P2PEditor p2PEditor;
    1515
    1616        public JobListManager(P2PEditor p2PEditor)
    1717        {
    18             _p2PEditor = p2PEditor;
     18            this.p2PEditor = p2PEditor;
    1919        }
    2020
    21         public List<DistributedJob> JobList()
     21        public ICollection<DistributedJob> JobList()
    2222        {
    23             _p2PEditor.GuiLogMessage("Fetching DHT job list...", NotificationLevel.Debug);
     23            p2PEditor.GuiLogMessage("Fetching DHT job list...", NotificationLevel.Debug);
    2424
    2525            if (!P2PManager.IsConnected)
    2626            {
    27                 _p2PEditor.GuiLogMessage("P2P not connected, cannot fetch job list.", NotificationLevel.Error);
     27                p2PEditor.GuiLogMessage("P2P not connected, cannot fetch job list.", NotificationLevel.Error);
    2828                return new List<DistributedJob>();
    2929            }
     
    3333            {
    3434                // no job list in DHT, create empty list
    35                 _p2PEditor.GuiLogMessage("No list in DHT, creating empty list.", NotificationLevel.Debug);
     35                p2PEditor.GuiLogMessage("No list in DHT, creating empty list.", NotificationLevel.Debug);
    3636                return new List<DistributedJob>();
    3737            }
    3838
    39             var memoryStream = new MemoryStream(serialisedJobList);
    40 
    41             var bformatter = new BinaryFormatter();
    42             bformatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
    43             return (List<DistributedJob>) bformatter.Deserialize(memoryStream);
     39            return ByteArrayToJobList(serialisedJobList);
    4440        }
    4541
    4642        public void AddDistributedJob(DistributedJob distributedJob)
    4743        {
    48             _p2PEditor.GuiLogMessage("Distributing new job...", NotificationLevel.Debug);
     44            p2PEditor.GuiLogMessage("Distributing new job...", NotificationLevel.Debug);
    4945
    5046            if (!P2PManager.IsConnected)
    5147            {
    52                 _p2PEditor.GuiLogMessage("P2P not connected, cannot distribute job.", NotificationLevel.Error);
     48                p2PEditor.GuiLogMessage("P2P not connected, cannot distribute job.", NotificationLevel.Error);
    5349                return;
    5450            }
     
    5753            currentJobList.Add(distributedJob);
    5854
    59             var memoryStream = new MemoryStream();
    60             var bformatter = new BinaryFormatter();
    61             bformatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
    62 
    63             bformatter.Serialize(memoryStream, currentJobList);
    64             P2PManager.Store(JoblistKey, memoryStream.ToArray());
     55            var serializedJobList = JobListToByteArray(currentJobList);
     56            P2PManager.Store(JoblistKey, serializedJobList);
    6557
    6658            var workspaceData = File.ReadAllBytes(distributedJob.LocalFilePath);
    67             _p2PEditor.GuiLogMessage(
     59            p2PEditor.GuiLogMessage(
    6860                "Workspace size: " + workspaceData.Length + ", storing at " + GenerateWorkspaceKey(distributedJob),
    6961                NotificationLevel.Debug);
    7062            P2PManager.Store(GenerateWorkspaceKey(distributedJob), workspaceData);
    7163
    72             _p2PEditor.GuiLogMessage("Distributed job " + distributedJob.JobName, NotificationLevel.Info);
     64            p2PEditor.GuiLogMessage("Distributed job " + distributedJob.Name, NotificationLevel.Info);
    7365        }
    7466
    7567        public void DeleteDistributedJob(DistributedJob distributedJobToDelete)
    7668        {
    77             _p2PEditor.GuiLogMessage("Deleting job...", NotificationLevel.Debug);
     69            p2PEditor.GuiLogMessage("Deleting job...", NotificationLevel.Debug);
    7870
    7971            if (!P2PManager.IsConnected)
    8072            {
    81                 _p2PEditor.GuiLogMessage("P2P not connected, cannot distribute job.", NotificationLevel.Error);
     73                p2PEditor.GuiLogMessage("P2P not connected, cannot distribute job.", NotificationLevel.Error);
    8274                return;
    8375            }
     
    8678            currentJobList.Remove(distributedJobToDelete);
    8779
    88             var memoryStream = new MemoryStream();
    89             var bformatter = new BinaryFormatter();
    90             bformatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
    91 
    92             bformatter.Serialize(memoryStream, currentJobList);
    93             P2PManager.Store(JoblistKey, memoryStream.ToArray());
     80            var serializedJobList = JobListToByteArray(currentJobList);
     81            P2PManager.Store(JoblistKey, serializedJobList);
    9482
    9583            // Retrieve job first to satify versioned DHT
     
    9785            P2PManager.Remove(GenerateWorkspaceKey(distributedJobToDelete));
    9886
    99             _p2PEditor.GuiLogMessage("Deleted distributed job " + distributedJobToDelete.JobName, NotificationLevel.Info);
     87            p2PEditor.GuiLogMessage("Deleted distributed job " + distributedJobToDelete.Name, NotificationLevel.Info);
    10088        }
    10189
     
    10593        }
    10694
     95        public void RetrieveDownloadCount(DistributedJob distributedJob)
     96        {
     97            var result = P2PManager.Retrieve(GenerateDownloadCounterKey(distributedJob));
     98           
     99            if (result.Status == RequestResultType.KeyNotFound)
     100            {
     101                distributedJob.Downloads = 0;
     102                return;
     103            }
     104
     105            var binaryReader = new BinaryReader(new MemoryStream(result.Data));
     106            distributedJob.Downloads = binaryReader.ReadInt32();
     107            distributedJob.LastDownload = DateTime.FromBinary(binaryReader.ReadInt64());
     108        }
     109
     110        public void RetrieveCurrentStatus(DistributedJob distributedJob)
     111        {
     112            if (string.IsNullOrEmpty(distributedJob.StatusKey)) return;
     113
     114            var result = P2PManager.Retrieve(distributedJob.StatusKey);
     115            if (result.Status != RequestResultType.Success) return;
     116
     117            var status = DistributedJobSerializer.StatusFromReader(new BinaryReader(new MemoryStream(result.Data)));
     118            distributedJob.Status = status;
     119        }
     120
     121        public void IncreaseDownloadCount(DistributedJob distributedJob)
     122        {
     123            RetrieveDownloadCount(distributedJob);
     124            distributedJob.Downloads++;
     125
     126            var memoryStream = new MemoryStream();
     127            var binaryWriter = new BinaryWriter(memoryStream);
     128            binaryWriter.Write(distributedJob.Downloads);
     129            binaryWriter.Write(DateTime.UtcNow.ToBinary());
     130
     131            P2PManager.Store(GenerateDownloadCounterKey(distributedJob), memoryStream.ToArray());
     132        }
     133
    107134        private static string GenerateWorkspaceKey(DistributedJob distributedJob)
    108135        {
    109             return string.Format("{0}.{1}.{2}", JoblistKey, WorkspaceKeyPrefix, distributedJob.JobGuid);
     136            return string.Format("{0}.{1}.{2}", JoblistKey, WorkspaceKeyPrefix, distributedJob.Guid);
     137        }
     138
     139        private static string GenerateDownloadCounterKey(DistributedJob distributedJob)
     140        {
     141            return string.Format("{0}.{1}.{2}.{3}", JoblistKey, WorkspaceKeyPrefix, distributedJob.Guid, "downloads");
     142        }
     143
     144        private static byte[] JobListToByteArray(ICollection<DistributedJob> distributedJobList)
     145        {
     146            var memoryStream = new MemoryStream();
     147            var binaryWriter = new BinaryWriter(memoryStream);
     148            binaryWriter.Write(distributedJobList.Count);
     149
     150            foreach (var distributedJob in distributedJobList)
     151            {
     152                DistributedJobSerializer.ToWriter(distributedJob, binaryWriter);
     153            }
     154
     155            return memoryStream.ToArray();
     156        }
     157
     158        private ICollection<DistributedJob> ByteArrayToJobList(byte[] rawData)
     159        {
     160            var distributedJobList = new List<DistributedJob>();
     161            var binaryReader = new BinaryReader(new MemoryStream(rawData));
     162
     163            var numberOfJobs = binaryReader.ReadInt32();
     164            for (var i = 0; i < numberOfJobs; i++)
     165            {
     166                distributedJobList.Add(DistributedJobSerializer.FromReader(binaryReader));
     167            }
     168
     169            return distributedJobList;
    110170        }
    111171    }
  • trunk/CrypPlugins/P2PEditor/GUI/Controls/JobCreation.xaml

    r1563 r1727  
    77    <Grid>
    88        <Grid.ColumnDefinitions>
    9             <ColumnDefinition Width="284*" />
    10             <ColumnDefinition Width="197*" />
     9            <ColumnDefinition Width="75" />
     10            <ColumnDefinition Width="*" />
    1111        </Grid.ColumnDefinitions>
    12         <Label Content="Name:" Height="28" HorizontalAlignment="Left" VerticalAlignment="Top" />
    13         <TextBox Text="{Binding JobName}" Height="26" VerticalAlignment="Top" Grid.ColumnSpan="2" Margin="74,0,0,0" />
    14         <TextBox Text="{Binding LocalFilePath}" Margin="74,33,34,0" Name="LocalFilePath" Grid.ColumnSpan="2" Height="28" VerticalAlignment="Top" />
    15         <Button Content="..." Click="BrowseFileButton_OnClick"  Height="28" HorizontalAlignment="Right" Margin="0,34,0,0" Name="BrowseFileButton" VerticalAlignment="Top" Width="28" Grid.Column="1" />
    16         <Label Content="Workspace:" Height="28" HorizontalAlignment="Left" Margin="0,34,0,0" VerticalAlignment="Top" />
    17         <Label Content="Description:" Height="28" HorizontalAlignment="Left" Margin="-2,68,0,0" VerticalAlignment="Top" />
    18         <TextBox Text="{Binding JobDescription}" Margin="74,70,0,36" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" Grid.ColumnSpan="2" />
    19         <Button Content="Share" Click="ShareButton_Click"  Margin="0,0,0,7" Name="ShareButton" HorizontalAlignment="Right" Width="80" Grid.Column="1" Height="23" VerticalAlignment="Bottom" />
     12        <Grid.RowDefinitions>
     13            <RowDefinition Height="28"/>
     14            <RowDefinition Height="28" />
     15            <RowDefinition Height="28" />
     16            <RowDefinition Height="*" />
     17            <RowDefinition Height="28" />
     18        </Grid.RowDefinitions>
     19       
     20        <Label Content="_Name:" Target="{Binding ElementName=NameField}" Grid.Row="0" Grid.Column="0" />
     21        <Label Content="Status _key:" Target="{Binding ElementName=StatusKeyField}" Grid.Row="1" Grid.Column="0" />
     22        <Label Content="_Workspace:" Target="{Binding ElementName=LocalFilePathButton}" Grid.Row="2" Grid.Column="0" />
     23        <Label Content="_Description:" Target="{Binding ElementName=DescriptionField}" Grid.Row="3" Grid.Column="0" />
     24       
     25        <TextBox Text="{Binding Name}" x:Name="NameField" Grid.Row="0" Grid.Column="1" Height="24" />
     26        <TextBox Text="{Binding StatusKey}" x:Name="StatusKeyField" Grid.Row="1" Grid.Column="1" Height="24" />
     27        <Grid Grid.Row="2" Grid.Column="1" Height="24">
     28            <TextBox Text="{Binding LocalFilePath}" Margin="0,0,34,0" />
     29            <Button Content="..." Click="BrowseFileButton_OnClick" HorizontalAlignment="Right" Width="28" x:Name="LocalFilePathButton" />
     30        </Grid>
     31        <TextBox Text="{Binding Description}" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" Grid.Row="3" Grid.Column="1" Margin="0,2,0,0" x:Name="DescriptionField" />
     32        <Button Content="_Share" Click="ShareButton_Click" HorizontalAlignment="Right" Width="80" Grid.Row="4" Grid.Column="1" Height="24" />
    2033    </Grid>
    2134</GUI:P2PUserControl>
  • trunk/CrypPlugins/P2PEditor/GUI/Controls/JobCreation.xaml.cs

    r1563 r1727  
    66using Cryptool.P2PEditor.Worker;
    77using Cryptool.PluginBase;
     8using Clipboard = System.Windows.Clipboard;
     9using TextDataFormat = System.Windows.TextDataFormat;
    810
    911namespace Cryptool.P2PEditor.GUI.Controls
    1012{
    11     /// <summary>
    12     /// Interaction logic for JobCreation.xaml
    13     /// </summary>
    1413    public partial class JobCreation
    1514    {
    16         private DistributedJob _newDistributedJob;
     15        private DistributedJob newDistributedJob;
    1716
    1817        public JobCreation()
     
    2423        {
    2524            DataContext = new DistributedJob();
     25
     26            if (!Clipboard.ContainsText(TextDataFormat.Text)) return;
     27            var clipboardData = Clipboard.GetText(TextDataFormat.Text);
     28            if (clipboardData.EndsWith("-status"))
     29            {
     30                ((DistributedJob)DataContext).StatusKey = clipboardData;
     31            }
    2632        }
    2733
     
    4753        {
    4854            // Validate input
    49             _newDistributedJob = (DistributedJob) DataContext;
     55            newDistributedJob = (DistributedJob) DataContext;
    5056
    51             if (_newDistributedJob.JobDescription == null || _newDistributedJob.JobName == null)
     57            if (newDistributedJob.Description == null || newDistributedJob.Name == null)
    5258            {
    5359                P2PEditor.GuiLogMessage("Please fill all fields.", NotificationLevel.Error);
     
    5561            }
    5662
    57             if (!File.Exists(_newDistributedJob.LocalFilePath))
     63            if (!File.Exists(newDistributedJob.LocalFilePath))
    5864            {
    5965                // TODO validate that selected file contains a workspace
     
    6268            }
    6369
    64             var backgroundCreationWorker = new JobCreationWorker(JobListManager, _newDistributedJob);
     70            var backgroundCreationWorker = new JobCreationWorker(JobListManager, newDistributedJob);
    6571            backgroundCreationWorker.RunWorkerCompleted += BackgroundCreationWorkerCompleted;
    6672            backgroundCreationWorker.RunWorkerAsync();
     
    6975        private void BackgroundCreationWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    7076        {
    71             P2PEditor.GuiLogMessage("Distributed job " + _newDistributedJob.JobGuid, NotificationLevel.Debug);
     77            P2PEditor.GuiLogMessage("Distributed job " + newDistributedJob.Guid, NotificationLevel.Debug);
    7278            DataContext = new DistributedJob();
    7379
  • trunk/CrypPlugins/P2PEditor/GUI/Controls/JobDisplay.xaml

    r1701 r1727  
    1212        </ResourceDictionary>
    1313    </GUI:P2PUserControl.Resources>
    14         <Grid Background="White">
    15         <ListBox x:Name="JobListBox" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Jobs, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" ItemTemplate="{StaticResource jobDisplayTemplate}" Style="{StaticResource jobListDisplayStyle}" KeyUp="JobListBox_KeyUp" Margin="0,0,0,35">
    16             <ListBox.ItemContainerStyle>
    17                 <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
    18                     <EventSetter Event="MouseDoubleClick" Handler="ParticipateItemHandler"/>
    19                 </Style>
    20             </ListBox.ItemContainerStyle>
    21         </ListBox>
    22         <Grid DataContext="{Binding SelectedItem,ElementName=JobListBox}">
    23             <Button Content="Participate" HorizontalAlignment="Right" Margin="0,0,0,6" Name="ParticipateButton" Width="75" Height="23" VerticalAlignment="Bottom" Click="ParticipateButton_Click" />
    24             <Button Content="Refresh" Click="RefreshButton_Click" Margin="0,0,0,6" Name="RefreshButton" Height="23" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="75" />
    25             <Button Content="Delete" Click="DeleteButton_Click" Margin="0,0,81,6" Name="DeleteButton" HorizontalAlignment="Right" Width="75" Height="23" VerticalAlignment="Bottom" />
    26         </Grid>
    27     </Grid>
     14    <AdornerDecorator>
     15        <DockPanel Name="mainPane">
     16            <Grid Background="White">
     17                <ListBox x:Name="JobListBox" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Jobs, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" ItemTemplate="{StaticResource jobDisplayTemplate}" Style="{StaticResource jobListDisplayStyle}" KeyUp="JobListBox_KeyUp" Margin="0,0,0,35">
     18                    <ListBox.ItemContainerStyle>
     19                        <Style TargetType="{x:Type ListBoxItem}">
     20                            <EventSetter Event="MouseDoubleClick" Handler="ParticipateItemHandler"/>
     21                        </Style>
     22                    </ListBox.ItemContainerStyle>
     23                </ListBox>
     24                <Grid DataContext="{Binding SelectedItem,ElementName=JobListBox}">
     25                    <Button Content="Participate" HorizontalAlignment="Right" Margin="0,0,0,6" Name="ParticipateButton" Width="75" Height="23" VerticalAlignment="Bottom" Click="ParticipateButton_Click" />
     26                    <Button Content="Refresh" Click="RefreshButton_Click" Margin="0,0,0,6" Name="RefreshButton" Height="23" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="75" />
     27                    <Button Content="Delete" Click="DeleteButton_Click" Margin="0,0,81,6" Name="DeleteButton" HorizontalAlignment="Right" Width="75" Height="23" VerticalAlignment="Bottom" />
     28                </Grid>
     29            </Grid>
     30        </DockPanel>
     31    </AdornerDecorator>
    2832</GUI:P2PUserControl>
  • trunk/CrypPlugins/P2PEditor/GUI/Controls/JobDisplay.xaml.cs

    r1701 r1727  
    22using System.Collections.Generic;
    33using System.ComponentModel;
     4using System.Threading;
    45using System.Timers;
    56using System.Windows;
     7using System.Windows.Data;
     8using System.Windows.Documents;
    69using System.Windows.Input;
     10using System.Windows.Media;
    711using System.Windows.Threading;
    812using Cryptool.P2P;
     13using Cryptool.P2PEditor.Converters;
    914using Cryptool.P2PEditor.Distributed;
    1015using Cryptool.P2PEditor.Worker;
    1116using Cryptool.PluginBase;
     17using Timer = System.Timers.Timer;
    1218
    1319namespace Cryptool.P2PEditor.GUI.Controls
     
    1622    /// Interaction logic for JobDisplay.xaml
    1723    /// </summary>
    18     public partial class JobDisplay
     24    public partial class JobDisplay : INotifyPropertyChanged
    1925    {
    20         public static DependencyProperty JobsProperty = DependencyProperty.Register("Jobs",
     26        public static readonly DependencyProperty JobsProperty = DependencyProperty.Register("Jobs",
    2127                                                                                    typeof (List<DistributedJob>),
    2228                                                                                    typeof (JobDisplay));
    23 
    24         private Timer _refreshListTimer;
     29        public ICollection<DistributedJob> Jobs
     30        {
     31            get { return (List<DistributedJob>)GetValue(JobsProperty); }
     32            set { SetValue(JobsProperty, value); }
     33        }
     34
     35        private Timer refreshListTimer;
     36        private readonly DispatcherTimer updateJobDetailsTimer;
     37        private JobListDetailsUpdateWorker updateTask;
     38
     39        private bool participating;
     40        public bool Participating
     41        {
     42            get { return participating; }
     43            set
     44            {
     45                participating = value;
     46                OnPropertyChanged("Participating");
     47            }
     48        }
    2549
    2650        public JobDisplay()
     
    3054
    3155            P2PManager.ConnectionManager.OnP2PConnectionStateChangeOccurred += P2PManager_OnP2PConnectionStateChangeOccurred;
     56
     57            updateJobDetailsTimer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(5)};
     58            updateJobDetailsTimer.Tick += UpdateJobDetailsTimerElapsed;
     59            updateJobDetailsTimer.Start();
     60
     61            AttachLoadingAdorner();
     62        }
     63
     64        private void AttachLoadingAdorner()
     65        {
     66            ParticipateAdorner participateAdorner = new ParticipateAdorner(mainPane);
     67           /* participateAdorner.FontSize = 15;
     68            loading.OverlayedText = "loading...";
     69            loading.Typeface = new Typeface(FontFamily, FontStyles.Italic,
     70                FontWeights.Bold, FontStretch);*/
     71            Binding bind = new Binding("Participating");
     72            bind.Source = this;
     73            bind.Converter = new TrueToVisibleOrCollapsedConverter();
     74            participateAdorner.SetBinding(VisibilityProperty, bind);
     75            AdornerLayer.GetAdornerLayer(mainPane).Add(participateAdorner);
     76        }
     77
     78        void UpdateJobDetailsTimerElapsed(object sender, EventArgs eventArgs)
     79        {
     80            if (!P2PManager.IsConnected || !IsVisible) return;
     81            if (updateTask != null) return;
     82
     83            updateTask = new JobListDetailsUpdateWorker(Jobs, JobListManager);
     84            updateTask.RunWorkerCompleted += UpdateTaskRunWorkerCompleted;
     85            updateTask.RunWorkerAsync();
     86            P2PEditor.GuiLogMessage("Running update task.", NotificationLevel.Debug);
     87        }
     88
     89        void UpdateTaskRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
     90        {
     91            updateTask = null;
    3292        }
    3393
     
    3999        private void UpdateRefreshTimerSettings(bool isConnected)
    40100        {
    41             if (P2PSettings.Default.DistributedJobListRefreshInterval == 0)
    42             {
    43                 return;
    44             }
    45 
    46             if (_refreshListTimer == null)
    47             {
    48                 _refreshListTimer = new Timer(P2PSettings.Default.DistributedJobListRefreshInterval * 1000);
    49                 _refreshListTimer.Elapsed += RefreshListTimerElapsed;
     101            if (P2PSettings.Default.DistributedJobListRefreshInterval == 0) return;
     102
     103            if (refreshListTimer == null)
     104            {
     105                refreshListTimer = new Timer(P2PSettings.Default.DistributedJobListRefreshInterval * 1000);
     106                refreshListTimer.Elapsed += RefreshListTimerElapsed;
    50107            }
    51108
    52109            if (isConnected)
    53             {
    54                 _refreshListTimer.Start();
    55             }
    56             else
    57             {
    58                 _refreshListTimer.Stop();
    59             }
     110                refreshListTimer.Start();
     111            else
     112                refreshListTimer.Stop();
    60113        }
    61114
    62115        void RefreshListTimerElapsed(object sender, ElapsedEventArgs e)
    63116        {
    64             if (!IsVisible)
    65             {
    66                 return;
    67             }
    68 
     117            if (!IsVisible) return;
    69118            Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(UpdateJobList));
    70119        }
    71120
    72         public List<DistributedJob> Jobs
    73         {
    74             get { return (List<DistributedJob>) GetValue(JobsProperty); }
    75             set { SetValue(JobsProperty, value); }
    76         }
    77 
    78121        private void RefreshButton_Click(object sender, RoutedEventArgs e)
    79122        {
     
    83126        public void UpdateJobList()
    84127        {
    85             if (!P2PManager.IsConnected)
    86             {
    87                 return;
    88             }
     128            if (!P2PManager.IsConnected) return;
    89129
    90130            P2PEditor.GuiLogMessage("Requesting new job list...", NotificationLevel.Debug);
     
    105145            Jobs = updateWorker.RefreshedJobList;
    106146
    107             if (Jobs != null)
    108                 Jobs.Reverse();
     147            UpdateJobDetailsTimerElapsed(null, null);
    109148        }
    110149
     
    121160        private void ParticipateInSelectedJob()
    122161        {
     162            Participating = true;
     163
    123164            var jobToParticipateIn = (DistributedJob) JobListBox.SelectedItem;
    124165
    125             if (jobToParticipateIn == null)
    126             {
    127                 return;
    128             }
     166            if (jobToParticipateIn == null) return;
    129167
    130168            P2PEditor.GuiLogMessage(
    131                 string.Format("Participating in job {0} ({1}).", jobToParticipateIn.JobName, jobToParticipateIn.JobGuid),
     169                string.Format("Preparing to participate in job {0} ({1}).", jobToParticipateIn.Name,
     170                              jobToParticipateIn.Guid),
    132171                NotificationLevel.Info);
    133172            new JobParticipationWorker(P2PEditor, JobListManager, jobToParticipateIn, Dispatcher).RunWorkerAsync();
     
    157196            var jobToDelete = (DistributedJob)JobListBox.SelectedItem;
    158197
    159             if (jobToDelete == null || jobToDelete.JobOwner != P2PSettings.Default.PeerName)
    160             {
    161                 return;
    162             }
     198            if (jobToDelete == null || jobToDelete.Owner != P2PSettings.Default.PeerName) return;
    163199
    164200            P2PEditor.GuiLogMessage(
    165                 string.Format("Deleting job {0} ({1}).", jobToDelete.JobName, jobToDelete.JobGuid),
     201                string.Format("Deleting job {0} ({1}).", jobToDelete.Name, jobToDelete.Guid),
    166202                NotificationLevel.Info);
    167203
     
    175211            P2PEditorPresentation.ShowActiveJobs();
    176212        }
     213
     214        #region INotifyPropertyChanged Members
     215
     216        public event PropertyChangedEventHandler PropertyChanged;
     217
     218        private void OnPropertyChanged(string propertyName)
     219        {
     220            if (PropertyChanged != null)
     221                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     222        }
     223
     224        #endregion
    177225    }
    178226}
  • trunk/CrypPlugins/P2PEditor/GUI/Controls/JobDisplayTemplate.xaml

    r1701 r1727  
    33    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Distributed="clr-namespace:Cryptool.P2PEditor.Distributed" xmlns:Converters="clr-namespace:Cryptool.P2PEditor.Converters">
    44
    5         <Converters:DateTimeConverter x:Key="DateTimeConverter" />
     5    <Converters:StatusToColorConverter x:Key="StatusToColorConverter" />
     6        <Converters:StringEmptyToVisibilityConverter x:Key="StringEmptyToVisibilityConverter" />
     7        <Converters:TrueToVisibleOrCollapsedConverter x:Key="TrueToVisibleOrCollapsedConverter" />
     8    <Converters:UtcDateTimeToLocalConverter x:Key="UtcDateTimeToLocalConverter" />
    69        <DataTemplate DataType="{x:Type Distributed:DistributedJob}" x:Key="jobDisplayTemplate">
    7         <Grid>
    8             <Grid.ColumnDefinitions>
    9                 <ColumnDefinition Width="75" />
    10                 <ColumnDefinition Width="*" />
    11                 <ColumnDefinition Width="130" />
    12             </Grid.ColumnDefinitions>
    13             <StackPanel Grid.Column="0">
    14                 <Label Content="Name" FontWeight="Bold" Height="24" />
    15                 <Label Content="Author:" FontWeight="Bold" FontSize="10" Height="23" />
    16                 <Label Content="Workspace:" FontWeight="Bold" FontSize="10" Height="23" />
     10        <Border BorderBrush="Silver" BorderThickness="0,0,0,1">
     11            <StackPanel>
     12                <Grid>
     13                    <Grid.ColumnDefinitions>
     14                        <ColumnDefinition Width="300*" />
     15                        <ColumnDefinition Width="300" />
     16                        <ColumnDefinition Width="140" />
     17                    </Grid.ColumnDefinitions>
     18                    <Label Content="{Binding Name}" FontSize="16" Grid.Column="0" />
     19
     20                    <Ellipse Fill="{Binding Status.CurrentStatus, Converter={StaticResource StatusToColorConverter}}" Height="18" Width="18" StrokeThickness="1" Stroke="DarkGray" Margin="0,5,105,5" Grid.Column="1" HorizontalAlignment="Right" />
     21                    <ProgressBar Value="{Binding Status.Progress}" Maximum="1" Width="100" Height="20" Grid.Column="1" HorizontalAlignment="Right" />
     22
     23                    <Label Content="{Binding CreateDate, Converter={StaticResource UtcDateTimeToLocalConverter}}" FontSize="16" Grid.Column="2" HorizontalAlignment="Right" Foreground="DarkGray" />
     24                </Grid>
     25                <Grid Visibility="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Converter={StaticResource TrueToVisibleOrCollapsedConverter}}">
     26                    <Grid.ColumnDefinitions>
     27                        <ColumnDefinition Width="75" />
     28                        <ColumnDefinition Width="*" />
     29                    </Grid.ColumnDefinitions>
     30                    <StackPanel Grid.Column="0">
     31                        <Label Content="Author:" FontSize="10" Height="23" />
     32                        <Label Content="Workspace:" FontSize="10" Height="23" />
     33                        <Label Content="Downloads:" FontSize="10" Height="23" />
     34                        <Label Content="Participants:" FontSize="10" Height="23" />
     35                        <Label Content="Start date:" FontSize="10" Height="23" />
     36                        <Label Content="Description:" FontSize="10" Height="23" />
     37                    </StackPanel>
     38                    <StackPanel Grid.Column="1">
     39                        <Label Content="{Binding Owner}" Height="23" FontSize="10" />
     40                        <Label Content="{Binding FileName}" Height="23" FontSize="10" />
     41                        <Label Content="{Binding Downloads}" Height="23" FontSize="10" />
     42                        <Label Content="{Binding Status.Participants}" Height="23" FontSize="10" />
     43                        <Label Content="{Binding Status.StartDate, Converter={StaticResource UtcDateTimeToLocalConverter}}" Height="23" FontSize="10" />
     44                        <Label Content="{Binding Description}" Height="23" FontSize="10" />
     45                    </StackPanel>
     46                </Grid>
    1747            </StackPanel>
    18             <StackPanel Grid.Column="1">
    19                 <Label Content="{Binding JobName}" Height="24" />
    20                 <Label Content="{Binding JobOwner}" Height="23" FontSize="10" />
    21                 <Label Content="{Binding FileName}" Height="23" FontSize="10" />
    22             </StackPanel>
    23             <StackPanel Grid.Column="2" HorizontalAlignment="Right">
    24                 <Label Content="{Binding JobDate, Converter={StaticResource DateTimeConverter}}" VerticalAlignment="Top" FontSize="10" Height="23" />
    25                 <Label Content="" VerticalAlignment="Top" FontSize="10" Height="23" />
    26             </StackPanel>
    27         </Grid>
     48        </Border>
    2849    </DataTemplate>
    2950   
  • trunk/CrypPlugins/P2PEditor/P2PEditor.csproj

    r1701 r1727  
    7070  <ItemGroup>
    7171    <Compile Include="Converters\ConnectivityToVisibilityConverter.cs" />
     72    <Compile Include="Converters\StatusToColorConverter.cs" />
     73    <Compile Include="Converters\StringEmptyToVisibilityConverter.cs" />
     74    <Compile Include="Converters\StringNotEmptyToVisibilityConverter.cs" />
     75    <Compile Include="Converters\UtcDateTimeToLocalConverter.cs" />
    7276    <Compile Include="Converters\DateTimeConverter.cs" />
     77    <Compile Include="Converters\TrueToVisibleOrCollapsedConverter.cs" />
     78    <Compile Include="Distributed\DistributedJobSerializer.cs" />
     79    <Compile Include="Distributed\DistributedJobStatus.cs" />
    7380    <Compile Include="GUI\Controls\ConnectTab.xaml.cs">
    7481      <DependentUpon>ConnectTab.xaml</DependentUpon>
    7582    </Compile>
    7683    <Compile Include="GUI\P2PUserControl.cs" />
     84    <Compile Include="GUI\ParticipateAdorner.cs" />
     85    <Compile Include="Helper\DistributedStatusUpdater.cs" />
    7786    <Compile Include="P2PEditorSettings.cs" />
    7887    <Compile Include="DetailedDescription\Description.xaml.cs">
     
    97106      <AutoGen>True</AutoGen>
    98107      <DesignTime>True</DesignTime>
     108    </Compile>
     109    <Compile Include="Worker\JobListDetailsUpdateWorker.cs">
     110      <SubType>Component</SubType>
    99111    </Compile>
    100112    <Compile Include="Worker\JobListUpdateWorker.cs">
  • trunk/CrypPlugins/P2PEditor/P2PEditorSettings.cs

    r1696 r1727  
    2424    internal class P2PEditorSettings : ISettings
    2525    {
    26         private readonly P2PEditor _p2PEditor;
    27         private readonly P2PSettings _settings;
     26        private readonly P2PEditor p2PEditor;
     27        private readonly P2PSettings settings;
    2828
    2929        private const string GroupExperienced = "experienced_settings";
     
    3232        public P2PEditorSettings(P2PEditor p2PEditor)
    3333        {
    34             _p2PEditor = p2PEditor;
    35             _settings = P2PSettings.Default;
     34            this.p2PEditor = p2PEditor;
     35            settings = P2PSettings.Default;
    3636        }
    3737
     
    5151        public string PeerName
    5252        {
    53             get { return _settings.PeerName; }
    54             set
    55             {
    56                 if (value != _settings.PeerName)
    57                 {
    58                     _settings.PeerName = value;
     53            get { return settings.PeerName; }
     54            set
     55            {
     56                if (value != settings.PeerName)
     57                {
     58                    settings.PeerName = value;
    5959                    OnPropertyChanged("PeerName");
    6060                    HasChanges = true;
     
    6666        public string WorldName
    6767        {
    68             get { return _settings.WorldName; }
    69             set
    70             {
    71                 if (value != _settings.WorldName)
    72                 {
    73                     _settings.WorldName = value;
     68            get { return settings.WorldName; }
     69            set
     70            {
     71                if (value != settings.WorldName)
     72                {
     73                    settings.WorldName = value;
    7474                    OnPropertyChanged("WorldName");
    7575                    HasChanges = true;
     
    8282        public string WorkspacePath
    8383        {
    84             get { return _settings.WorkspacePath; }
    85             set
    86             {
    87                 if (value != _settings.WorkspacePath)
    88                 {
    89                     _settings.WorkspacePath = value;
     84            get { return settings.WorkspacePath; }
     85            set
     86            {
     87                if (value != settings.WorkspacePath)
     88                {
     89                    settings.WorkspacePath = value;
    9090                    OnPropertyChanged("WorkspacePath");
    9191                    HasChanges = true;
     
    101101                P2PManager.Connect();
    102102                OnPropertyChanged("ButtonStart");
    103                 _p2PEditor.GuiLogMessage(Resources.Attributes.start_launched, NotificationLevel.Info);
     103                p2PEditor.GuiLogMessage(Resources.Attributes.start_launched, NotificationLevel.Info);
    104104            } else
    105105            {
    106                 _p2PEditor.GuiLogMessage(Resources.Attributes.start_failed, NotificationLevel.Warning);
     106                p2PEditor.GuiLogMessage(Resources.Attributes.start_failed, NotificationLevel.Warning);
    107107            }
    108108        }
     
    115115                P2PManager.Disconnect();
    116116                OnPropertyChanged("ButtonStop");
    117                 _p2PEditor.GuiLogMessage(Resources.Attributes.stop_launched, NotificationLevel.Info);
     117                p2PEditor.GuiLogMessage(Resources.Attributes.stop_launched, NotificationLevel.Info);
    118118            }
    119119            else
    120120            {
    121                 _p2PEditor.GuiLogMessage(Resources.Attributes.stop_failed, NotificationLevel.Warning);
     121                p2PEditor.GuiLogMessage(Resources.Attributes.stop_failed, NotificationLevel.Warning);
    122122            }
    123123        }
     
    127127        public int DistributedJobListRefreshInterval
    128128        {
    129             get { return _settings.DistributedJobListRefreshInterval; }
    130             set
    131             {
    132                 if (value != _settings.DistributedJobListRefreshInterval)
    133                 {
    134                     _settings.DistributedJobListRefreshInterval = value;
     129            get { return settings.DistributedJobListRefreshInterval; }
     130            set
     131            {
     132                if (value != settings.DistributedJobListRefreshInterval)
     133                {
     134                    settings.DistributedJobListRefreshInterval = value;
    135135                    OnPropertyChanged("DistributedJobListRefreshInterval");
    136136                    HasChanges = true;
     
    143143        public bool ConnectOnStartup
    144144        {
    145             get { return _settings.ConnectOnStartup; }
    146             set
    147             {
    148                 if (value != _settings.ConnectOnStartup)
    149                 {
    150                     _settings.ConnectOnStartup = value;
     145            get { return settings.ConnectOnStartup; }
     146            set
     147            {
     148                if (value != settings.ConnectOnStartup)
     149                {
     150                    settings.ConnectOnStartup = value;
    151151                    OnPropertyChanged("ConnectOnStartup");
    152152                    HasChanges = true;
     
    159159        public int LinkManager
    160160        {
    161             get { return (int) _settings.LinkManager; }
    162             set
    163             {
    164                 if ((P2PLinkManagerType) value != _settings.LinkManager)
    165                 {
    166                     _settings.LinkManager = (P2PLinkManagerType) value;
     161            get { return (int) settings.LinkManager; }
     162            set
     163            {
     164                if ((P2PLinkManagerType) value != settings.LinkManager)
     165                {
     166                    settings.LinkManager = (P2PLinkManagerType) value;
    167167                    OnPropertyChanged("LinkManager");
    168168                    HasChanges = true;
     
    175175        public int Bootstrapper
    176176        {
    177             get { return (int) _settings.Bootstrapper; }
    178             set
    179             {
    180                 if ((P2PBootstrapperType) value != _settings.Bootstrapper)
    181                 {
    182                     _settings.Bootstrapper = (P2PBootstrapperType) value;
     177            get { return (int) settings.Bootstrapper; }
     178            set
     179            {
     180                if ((P2PBootstrapperType) value != settings.Bootstrapper)
     181                {
     182                    settings.Bootstrapper = (P2PBootstrapperType) value;
    183183                    OnPropertyChanged("Bootstrapper");
    184184                    HasChanges = true;
     
    191191        public int Architecture
    192192        {
    193             get { return (int)_settings.Architecture; }
    194             set
    195             {
    196                 if ((P2PArchitecture)value != _settings.Architecture)
    197                 {
    198                     _settings.Architecture = (P2PArchitecture)value;
     193            get { return (int)settings.Architecture; }
     194            set
     195            {
     196                if ((P2PArchitecture)value != settings.Architecture)
     197                {
     198                    settings.Architecture = (P2PArchitecture)value;
    199199                    OnPropertyChanged("Architecture");
    200200                    HasChanges = true;
     
    207207        public int TransportProtocol
    208208        {
    209             get { return (int)_settings.TransportProtocol; }
    210             set
    211             {
    212                 if ((P2PTransportProtocol)value != _settings.TransportProtocol)
    213                 {
    214                     _settings.TransportProtocol = (P2PTransportProtocol)value;
     209            get { return (int)settings.TransportProtocol; }
     210            set
     211            {
     212                if ((P2PTransportProtocol)value != settings.TransportProtocol)
     213                {
     214                    settings.TransportProtocol = (P2PTransportProtocol)value;
    215215                    OnPropertyChanged("TransportProtocol");
    216216                    HasChanges = true;
     
    223223        public int LocalPort
    224224        {
    225             get { return _settings.LocalReceivingPort; }
    226             set
    227             {
    228                 if (value != _settings.LocalReceivingPort)
    229                 {
    230                     _settings.LocalReceivingPort = value;
     225            get { return settings.LocalReceivingPort; }
     226            set
     227            {
     228                if (value != settings.LocalReceivingPort)
     229                {
     230                    settings.LocalReceivingPort = value;
    231231                    OnPropertyChanged("LocalPort");
    232232                    HasChanges = true;
     
    239239        public bool UseLocalAddressDetection
    240240        {
    241             get { return _settings.UseLocalAddressDetection; }
    242             set
    243             {
    244                 if (value != _settings.UseLocalAddressDetection)
    245                 {
    246                     _settings.UseLocalAddressDetection = value;
     241            get { return settings.UseLocalAddressDetection; }
     242            set
     243            {
     244                if (value != settings.UseLocalAddressDetection)
     245                {
     246                    settings.UseLocalAddressDetection = value;
    247247                    OnPropertyChanged("UseLocalAddressDetection");
    248248                    HasChanges = true;
     
    255255        public bool Log2Monitor
    256256        {
    257             get { return _settings.Log2Monitor; }
    258             set
    259             {
    260                 if (value != _settings.Log2Monitor)
    261                 {
    262                     _settings.Log2Monitor = value;
     257            get { return settings.Log2Monitor; }
     258            set
     259            {
     260                if (value != settings.Log2Monitor)
     261                {
     262                    settings.Log2Monitor = value;
    263263                    OnPropertyChanged("Log2Monitor");
    264264                    HasChanges = true;
  • trunk/CrypPlugins/P2PEditor/Worker/JobCreationWorker.cs

    r1527 r1727  
    66    public class JobCreationWorker : BackgroundWorker
    77    {
    8         private readonly JobListManager _jobListManager;
    9         private readonly DistributedJob _jobToDistribute;
     8        private readonly JobListManager jobListManager;
     9        private readonly DistributedJob jobToDistribute;
    1010
    1111        public JobCreationWorker(JobListManager jobListManager, DistributedJob jobToDistribute)
    1212        {
    13             _jobListManager = jobListManager;
    14             _jobToDistribute = jobToDistribute;
     13            this.jobListManager = jobListManager;
     14            this.jobToDistribute = jobToDistribute;
    1515
    1616            DoWork += JobCreationWorker_DoWork;
     
    1919        private void JobCreationWorker_DoWork(object sender, DoWorkEventArgs e)
    2020        {
    21             _jobListManager.AddDistributedJob(_jobToDistribute);
     21            jobListManager.AddDistributedJob(jobToDistribute);
    2222        }
    2323    }
  • trunk/CrypPlugins/P2PEditor/Worker/JobDeletionWorker.cs

    r1563 r1727  
    66    public class JobDeletionWorker : BackgroundWorker
    77    {
    8         private readonly JobListManager _jobListManager;
    9         private readonly DistributedJob _jobToDistribute;
     8        private readonly JobListManager jobListManager;
     9        private readonly DistributedJob jobToDistribute;
    1010
    1111        public JobDeletionWorker(JobListManager jobListManager, DistributedJob jobToDistribute)
    1212        {
    13             _jobListManager = jobListManager;
    14             _jobToDistribute = jobToDistribute;
     13            this.jobListManager = jobListManager;
     14            this.jobToDistribute = jobToDistribute;
    1515
    1616            DoWork += JobCreationWorker_DoWork;
     
    1919        private void JobCreationWorker_DoWork(object sender, DoWorkEventArgs e)
    2020        {
    21             _jobListManager.DeleteDistributedJob(_jobToDistribute);
     21            jobListManager.DeleteDistributedJob(jobToDistribute);
    2222        }
    2323    }
  • trunk/CrypPlugins/P2PEditor/Worker/JobListUpdateWorker.cs

    r1616 r1727  
    77    public class JobListUpdateWorker : BackgroundWorker
    88    {
    9         private readonly JobListManager _jobListManager;
    10         public List<DistributedJob> RefreshedJobList;
     9        private readonly JobListManager jobListManager;
     10        public ICollection<DistributedJob> RefreshedJobList;
    1111
    1212        public JobListUpdateWorker(JobListManager jobListManager)
    1313        {
    14             _jobListManager = jobListManager;
     14            this.jobListManager = jobListManager;
    1515
    1616            DoWork += JobCreationWorker_DoWork;
     
    1919        private void JobCreationWorker_DoWork(object sender, DoWorkEventArgs e)
    2020        {
    21             RefreshedJobList = _jobListManager.JobList();
     21            RefreshedJobList = jobListManager.JobList();
    2222        }
    2323    }
  • trunk/CrypPlugins/P2PEditor/Worker/JobParticipationWorker.cs

    r1643 r1727  
    99    public class JobParticipationWorker : BackgroundWorker
    1010    {
    11         private readonly P2PEditor _p2PEditor;
    12         private readonly JobListManager _jobListManager;
    13         private readonly DistributedJob _jobToParticipateIn;
    14         private readonly Dispatcher _dispatcher;
     11        private readonly P2PEditor p2PEditor;
     12        private readonly JobListManager jobListManager;
     13        private readonly DistributedJob jobToParticipateIn;
     14        private readonly Dispatcher dispatcher;
    1515
    1616        public JobParticipationWorker(P2PEditor p2PEditor, JobListManager jobListManager, DistributedJob jobToParticipateIn, Dispatcher dispatcher)
    1717        {
    18             _p2PEditor = p2PEditor;
    19             _jobListManager = jobListManager;
    20             _jobToParticipateIn = jobToParticipateIn;
    21             _dispatcher = dispatcher;
     18            this.p2PEditor = p2PEditor;
     19            this.jobListManager = jobListManager;
     20            this.jobToParticipateIn = jobToParticipateIn;
     21            this.dispatcher = dispatcher;
    2222
    2323            DoWork += JobParticipationWorker_DoWork;
     
    2828            try
    2929            {
    30                 _jobListManager.CompleteDistributedJob(_jobToParticipateIn);
    31             } catch(Exception ex)
     30                jobListManager.CompleteDistributedJob(jobToParticipateIn);
     31            }
     32            catch (Exception ex)
    3233            {
    33                 _p2PEditor.GuiLogMessage("Error completing job: " + ex.Message, NotificationLevel.Error);
     34                p2PEditor.GuiLogMessage("Error completing job: " + ex.Message, NotificationLevel.Error);
    3435                return;
    3536            }
    3637
    37             _p2PEditor.GuiLogMessage("Local workspace: " + _jobToParticipateIn.LocalFilePath, NotificationLevel.Debug);
    38             _p2PEditor.GuiLogMessage(
     38            p2PEditor.GuiLogMessage("Local workspace: " + jobToParticipateIn.LocalFilePath, NotificationLevel.Debug);
     39            p2PEditor.GuiLogMessage(
    3940                string.Format("Workspace {0} ready to participate, dispatching with CrypTool...",
    40                               _jobToParticipateIn.JobName),
     41                              jobToParticipateIn.Name),
    4142                NotificationLevel.Info);
    4243
    43             _dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(DispatchOpenFileEvent));
     44            try
     45            {
     46                jobListManager.IncreaseDownloadCount(jobToParticipateIn);
     47            } catch(Exception)
     48            {
     49               
     50            }
     51
     52            dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(DispatchOpenFileEvent));
    4453        }
    4554
    4655        private void DispatchOpenFileEvent()
    4756        {
    48             _p2PEditor.SendOpenProjectFileEvent(_jobToParticipateIn.LocalFilePath);
     57            p2PEditor.SendOpenProjectFileEvent(jobToParticipateIn.LocalFilePath);
    4958        }
    5059    }
Note: See TracChangeset for help on using the changeset viewer.