// Copyright (c) 2017 Informatibüro Daniel Schick // Description: Haupteinstiegsmaske ENI-2: Suche using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using bsmd.database; using System.Windows.Data; using log4net; using System.Windows.Media.Imaging; using System.Diagnostics; namespace ENI2 { /// /// Interaction logic for SucheControl.xaml /// public partial class SucheControl : UserControl { #region Fields private bool efMode = false; private List anmeldungen = new List(); private readonly object searchLock = new object(); private readonly ILog _log = LogManager.GetLogger("SucheControl"); private MenuItem cancelItem; #endregion #region Construction public SucheControl() { InitializeComponent(); Loaded += SucheControl_Loaded; } private void SucheControl_Loaded(object sender, RoutedEventArgs e) { this.dataGrid.ContextMenu = new ContextMenu(); this.dataGrid.CanUserAddRows = false; this.dataGrid.ContextMenuOpening += ContextMenu_ContextMenuOpening; MenuItem addItem = new MenuItem(); addItem.Header = Properties.Resources.textCopyClip; addItem.Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/documents.png")) }; addItem.Click += this.copyID; this.dataGrid.ContextMenu.Items.Add(addItem); MenuItem copyIMOItem = new MenuItem(); copyIMOItem.Header = Properties.Resources.textCopyIMO; copyIMOItem.Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/document_into.png")) }; copyIMOItem.Click += this.copyIMO; this.dataGrid.ContextMenu.Items.Add(copyIMOItem); cancelItem = new MenuItem(); cancelItem.Header = Properties.Resources.textUndoCancel; cancelItem.Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/delete.png")) }; cancelItem.Click += CancelItem_Click; cancelItem.Visibility = Visibility.Collapsed; this.dataGrid.ContextMenu.Items.Add(cancelItem); if (Keyboard.IsKeyDown(Key.LeftShift)) { efMode = true; logoImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/ef_logo.png")); } } #endregion public event MessageCore.MessageCoreSelectedHandler MessageCoreSelected; public bool AdminMode { get; set; } #region Context menu events private void ContextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e) { MessageCore selectedCore = this.dataGrid.SelectedItem as MessageCore; cancelItem.Visibility = (this.AdminMode && (selectedCore.Cancelled ?? false)) ? Visibility.Visible : Visibility.Collapsed; } private void CancelItem_Click(object sender, RoutedEventArgs e) { MessageCore selectedCore = this.dataGrid.SelectedItem as MessageCore; if(selectedCore.Cancelled ?? false) { if(MessageBox.Show("Undo cancel flag?", "Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) { selectedCore.Cancelled = false; DBManager.Instance.Save(selectedCore); } } } #endregion #region event handler searching private void Button_Click(object sender, RoutedEventArgs e) { // Eingabefelder und Ergebnis löschen textBoxHafen.Text = string.Empty; textBoxId.Text = string.Empty; textBoxIMO.Text = string.Empty; textBoxName.Text = string.Empty; textBoxTicketNr.Text = string.Empty; // dateTimePickerETAFrom.SelectedDate = null; // herausgenommen nach RM CH 21.2.18 // dateTimePickerETATo.SelectedDate = null; this.dataGrid.ItemsSource = null; this.searchResultLabel.Content = ""; } private void buttonSuche_Click(object sender, RoutedEventArgs e) { // filter auswerten Dictionary filterDict = new Dictionary(); bool latestIdsSearch = false; if (!this.textBoxHafen.Text.Trim().IsNullOrEmpty()) filterDict.Add(MessageCore.SearchFilterType.FILTER_PORT, this.textBoxHafen.Text.Trim()); if (!this.textBoxId.Text.Trim().IsNullOrEmpty()) filterDict.Add(MessageCore.SearchFilterType.FILTER_ID, this.textBoxId.Text.Trim()); if (!this.textBoxIMO.Text.Trim().IsNullOrEmpty()) filterDict.Add(MessageCore.SearchFilterType.FILTER_IMO, this.textBoxIMO.Text.Trim()); if (!this.textBoxName.Text.Trim().IsNullOrEmpty()) filterDict.Add(MessageCore.SearchFilterType.FILTER_SHIPNAME, this.textBoxName.Text.Trim()); if (!this.textBoxTicketNr.Text.Trim().IsNullOrEmpty()) filterDict.Add(MessageCore.SearchFilterType.FILTER_TICKETNO, this.textBoxTicketNr.Text.Trim()); uint? from = null, to = null; if(this.dateTimePickerETAFrom.SelectedDate.HasValue) { from = this.dateTimePickerETAFrom.SelectedDate.Value.ToUniversalTime().ToUnixTimeStamp(); } if(this.dateTimePickerETATo.SelectedDate.HasValue) { DateTime toTime = this.dateTimePickerETATo.SelectedDate.Value.ToUniversalTime().Add(new TimeSpan(23, 59, 59)); // search till the end of the "to" day (no time selection) to = toTime.ToUnixTimeStamp(); } if (from.HasValue || to.HasValue) filterDict.Add(MessageCore.SearchFilterType.FILTER_ETA, string.Format("{0}:{1}", from?.ToString() ?? "", to?.ToString() ?? "")); int? resultLimit = null; int? expectedResultNum; if (sender == this.buttonLast10Ids) { filterDict.Clear(); filterDict.Add(MessageCore.SearchFilterType.FILTER_LATESTIDS, null); filterDict.Add(MessageCore.SearchFilterType.FILTER_CREATEDBY, ReportingParty.CurrentReportingParty.Id.Value.ToString()); latestIdsSearch = true; resultLimit = 10; expectedResultNum = 10; } else { expectedResultNum = DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).GetNumCoresWithFilters(filterDict); if ((expectedResultNum ?? 0) > 100) resultLimit = 100; } Util.UIHelper.SetBusyState(); // suche auslösen this.anmeldungen = DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).GetMessageCoresWithFilters(filterDict, resultLimit); this.dataGrid.SelectedItem = null; BindingOperations.EnableCollectionSynchronization(this.anmeldungen, this.searchLock); // prevent sync lock exceptions (trat bei Sandra auf) if (App.UserId.HasValue) { // "locks" dazu abfragen LockingServiceReference.CoreLock[] coreLocks = null; bool retry = false; RESTART: try { coreLocks = App.LockingServiceClient.GetLocks(); } catch(Exception ex) { // wenn das System lang lief ist der Service deallokiert? Wirft hier eine Exception. Ich würde an der Stelle den Client neu // erzeugen und nochmal probieren, danach darüber laufen lassen.. if (!retry) { _log.ErrorFormat("LockingService:GetLocks(): {0}", ex.Message); _log.Info("trying to restart the locking service client"); retry = true; App.RestartLockingService(); goto RESTART; } } Dictionary coreLockUpdateDict = new Dictionary(); for (int i = 0; i < coreLocks.Length; i++) { bool lockState = coreLocks[i].UserId.Equals(App.UserId.Value); coreLockUpdateDict[coreLocks[i].CoreId] = lockState; } foreach (MessageCore core in this.anmeldungen) if (coreLockUpdateDict.ContainsKey(core.Id.Value)) core.Locked = coreLockUpdateDict[core.Id.Value]; } if(!latestIdsSearch) // 31.5.17: Komische Display ETA Vorsortierung this.anmeldungen.Sort(); // ergebnis anzeigen this.dataGrid.ItemsSource = this.anmeldungen; this.searchResultLabel.Content = ((expectedResultNum ?? 0) > 0) ? string.Format("{0} results found, {1} displayed.", expectedResultNum ?? 0, this.anmeldungen.Count) : "no results"; if(!latestIdsSearch && (expectedResultNum ?? 0) > 100) { // Messagebox damit es wirklich jeder merkt :\ string searchMessage = string.Format(Properties.Resources.textSearchExceededMessage, 100, expectedResultNum.Value); MessageBox.Show(searchMessage, Properties.Resources.textInfo, MessageBoxButton.OK, MessageBoxImage.Warning); } } private void etaValueChanged(object sender, EventArgs args) { bool valid = true; if ((this.dateTimePickerETAFrom.SelectedDate.HasValue) && (this.dateTimePickerETATo.SelectedDate.HasValue) && this.dateTimePickerETATo.SelectedDate.Value < this.dateTimePickerETAFrom.SelectedDate.Value) valid = false; this.dateTimePickerETAFrom.Background = valid ? SystemColors.ControlBrush : Brushes.Red; this.dateTimePickerETATo.Background = valid ? SystemColors.ControlBrush : Brushes.Red; } #endregion #region Selection event handling private void DisplayCore(MessageCore core) { if (core != null) { this.OnMessageCoreSelected(core); } } protected void OnMessageCoreSelected(MessageCore aMessageCore) { if ((this.MessageCoreSelected != null) && (aMessageCore != null)) { Util.UIHelper.SetBusyState(); this.MessageCoreSelected(aMessageCore); } } private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) { if (sender != null) { DataGrid grid = sender as DataGrid; if (grid?.SelectedItems?.Count == 1) { // DataGridRow dgr = grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem) as DataGridRow; MessageCore selectedCore = grid.SelectedItem as MessageCore; this.DisplayCore(selectedCore); } } } private void dataGrid_PreviewKeyDown(object sender, KeyEventArgs e) { if ((e.Key == Key.Return) || (e.Key == Key.Enter)) { MessageCore selectedCore = dataGrid.SelectedItem as MessageCore; this.DisplayCore(selectedCore); } else { base.OnPreviewKeyDown(e); } } private void copyID(object sender, RoutedEventArgs e) { if (dataGrid.SelectedItem is MessageCore selectedCore) { if (selectedCore.DisplayId != null) { Clipboard.SetText(selectedCore.DisplayId); } } } private void copyIMO(object sender, RoutedEventArgs e) { if (dataGrid.SelectedItem is MessageCore selectedCore) { Clipboard.SetText(selectedCore.IMO); } } #endregion private void logoImage_MouseUp(object sender, MouseButtonEventArgs e) { if (efMode) Process.Start("http://www.eintracht-frankfurt.de/home.html"); else Process.Start("http://www.eureport.de/"); } } }