using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Demos.Warden.Inspections; using System.ComponentModel; using System.Threading; using System.Reflection; using System.Windows.Data; using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Data; using System.IO; using MicrDraw = System.Drawing; using Forms = System.Windows.Forms; using Demos.Warden.StudyRelatedEntities; using Demos.DemosHelpers; using Demos.Warden.CustomizableFilter; using Demos.Warden.TagTextEditing; namespace Demos.Warden.UserInterface.MainWindow.GeneratedStudyDocuments { public partial class GeneratedStudyDocuments : Page { private StudentFilterWindow _studentFilterWindow; private StudentFilter _studentFilter = new StudentFilter(); private Oracle.ManagedDataAccess.Client.OracleConnection _connection = WardenStatic.WardenApplication.WardenConnectionHandler.Connection; private Student[] _selectedStudents; private FlowDocumentTagManager _documentManager = new FlowDocumentTagManager(); private int currentStudentIndex = 0; private Dictionary exportOptions = new Dictionary() { { "rtfSingle", "RTF zvolený student" }, { "rtfSeparate", "RTF samostatně" }, { "rtfBatch", "RTF společně" }, { "pdfSingle", "PDF zvolený student" }, { "pdfSeparate", "PDF samostatně" }, { "pdfBatch", "PDF společně" } }; private KeyValuePair[] _availableFonts = null; private Student CurrentStudent { get { if (this._selectedStudents == null || this._selectedStudents.Length == 0) { return null; } if (this.currentStudentIndex < 0) { return this._selectedStudents[0]; } else if (this.currentStudentIndex > this._selectedStudents.Length - 1) { return this._selectedStudents[this._selectedStudents.Length - 1]; } else { return this._selectedStudents[this.currentStudentIndex]; } } } private TagElementSelectionWindowSIS tagWindowSIS = null; private TagElementSelectionWindowGender tagWindowGender = null; private WardenGeneralWindow showStudentsWindow = null; private ConversionTypes _conversionDirection = ConversionTypes.ToActualValues; private FlowDocument _storedFdWhilePreviewing = null; public GeneratedStudyDocuments() { InitializeComponent(); this.prepareControls(); } #region GUI controls initialization private void prepareControls() { this.prepareStudentSelectionButton(); this.prepareExportOptionsCombobox(); this.prepareFontSelectionCombobox(); } private void prepareExportOptionsCombobox() { KeyValuePair[] items = new KeyValuePair[this.exportOptions.Count]; int i = 0; foreach (string k in this.exportOptions.Keys) { items[i] = new KeyValuePair(k, this.exportOptions[k]); i++; } this.cmbx_exportOptions.ItemsSource = items; this.cmbx_exportOptions.DisplayMemberPath = "Value"; this.cmbx_exportOptions.SelectedIndex = 0; } private void prepareStudentSelectionButton() { if (WardenStatic.WardenApplication.WardenConnectionHandler.Connection.State != ConnectionState.Open) { this.btn_SelectStudents.IsEnabled = false; } WardenStatic.WardenApplication.WardenConnectionHandler.ConnectionStateChange += ((object sender, EventArgs args) => { if (WardenStatic.WardenApplication.WardenConnectionHandler.Connection.State == ConnectionState.Open) { this.btn_SelectStudents.IsEnabled = true; } }); } private void prepareFontSelectionCombobox() { List> fonts = new List>(); foreach (MicrDraw.FontFamily font in MicrDraw.FontFamily.Families) { fonts.Add(new KeyValuePair(font.Name, font)); } this._availableFonts = fonts.ToArray(); this.tools_cmbx_fonts.ItemsSource = this._availableFonts; this.tools_cmbx_fonts.SelectedIndex = 0; this.tools_cmbx_fonts.DisplayMemberPath = "Key"; } #endregion #region selecting and retrieving students private Student[] GetStudentsFromFilter() { Student[] result = new Student[0]; string query; DataTable dbResult; try { query = this._studentFilter.GetQuery(); dbResult = OracleQueryHelperClass.GetResultsDataTable(query, this._connection); } catch { throw; } bool imperfectStudentInit = false; #if DEBUG imperfectStudentInit = true; #endif try { result = new Student[dbResult.Rows.Count]; for (int tracker = 0; tracker < dbResult.Rows.Count; tracker++) { result[tracker] = new Student(new StudentMinimalIdentity() { StudyID = dbResult.Rows[tracker]["sident"].ToInt32(GeneralHelperClass.ToInt32ConversionTypes.IntOrException) }, imperfectStudentInit); } } catch (Exception ex) { #if !DEBUG MessageBox.Show("Internal failure. Could not retrieve students."); #endif #if DEBUG throw; #endif } return result; } private void btn_SelectStudents_Click(object sender, RoutedEventArgs args) { _studentFilterWindow = new StudentFilterWindow(new StudentFilterWindowModel { InputValues = _studentFilter }); _studentFilterWindow.InputCompleted += processStudentFilterWindowInput; _studentFilterWindow.ShowDialog(); } private void processStudentFilterWindowInput(object sender, StudentFilterWindowModel args) { if (args.IsSuccess != true) { return; } this._studentFilter = args.Result.ReturnObject; this._selectedStudents = this.GetStudentsFromFilter(); this.currentStudentIndex = 0; this.setSelectedStudentsLabels(); } private void showSelectedStudents_Click(object sender, RoutedEventArgs args) { if (this._selectedStudents == null || this._selectedStudents.Length == 0) { MessageBox.Show("Žádní studenti nevybráni."); return; } else if (this.showStudentsWindow == null) { this.showStudentsWindow = new WardenGeneralWindow(); this.showStudentsWindow.Closed += (window, arg) => { this.showStudentsWindow = null; }; DataTable tab = new DataTable(); tab.Columns.Add("Jméno"); tab.Columns.Add("Obor"); tab.Columns.Add("Studijní stav"); tab.Columns.Add("Rok nástupu"); tab.Columns.Add("Studijní plán"); DataGrid gv = new DataGrid(); foreach (Student st in this._selectedStudents) { tab.Rows.Add( st.LastName + ", " + st.FirstName, st.FieldOfStudy, st.StudyStatus, st.YearOfInscription, st.StudyPlanID); } gv.ItemsSource = tab.DefaultView; this.showStudentsWindow.Content = gv; this.showStudentsWindow.Show(); } } #endregion #region Toolbar editting actions private void toolActions_Click(object sender, RoutedEventArgs args) { Button button = (Button)sender; switch (button.Name) { case "tools_btn_bold": this.formatBold(); break; case "tools_btn_italics": this.formatItalics(); break; case "tools_btn_underline": this.formatUnderline(); break; case "tools_btn_alignRight": this.formatAlign(TextAlignment.Right); break; case "tools_btn_alignCenter": this.formatAlign(TextAlignment.Center); break; case "tools_btn_alignJustify": this.formatAlign(TextAlignment.Justify); break; case "tools_btn_fontFamily": this.formatFont(); break; case "tools_btn_fontColor": this.setFontColor(); break; case "tools_btn_fontSize": this.setFontSize(); break; case "tools_btn_insertTagElementSIS": this.openInsertTagWindowSIS(); break; case "tools_btn_insertTagElementGender": this.openInsertTagWindowGender(); break; case "tools_btn_3colLayout": this.add3colLayoutTable(); break; case "tools_btn_insertImage": this.insertImage(); break; default: break; } } private void setFontColor() { TextSelection ts = this.richBox.Selection; if (ts == null) { return; } string userValue = this.tools_txtbox_fontcolor.Text; object outcome = null; try { outcome = ColorConverter.ConvertFromString("#" + userValue); } catch (Exception) { } if (outcome == null || !(outcome is Color)) { return; } ts.ApplyPropertyValue(ForegroundProperty, new SolidColorBrush((Color)outcome)); } private void setFontSize() { TextSelection ts = this.richBox.Selection; if (ts == null) { return; } string userValue = this.tools_txtbox_fontsize.Text; double value; if (!Double.TryParse(userValue, out value)) { this.tools_txtbox_fontsize.Text = "12"; return; } ts.ApplyPropertyValue(TextElement.FontSizeProperty, value); } private void formatBold() { TextSelection ts = this.richBox.Selection; if (ts == null) { return; } FontWeight? weight = null; object weightProperty = ts.GetPropertyValue(TextElement.FontWeightProperty); if (weightProperty is FontWeight) { weight = (FontWeight)ts.GetPropertyValue(TextElement.FontWeightProperty); } if (weightProperty == DependencyProperty.UnsetValue || (weight != FontWeights.Bold)) { ts.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold); } else { ts.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Normal); } } private void formatItalics() { TextSelection ts = this.richBox.Selection; if (ts == null) { return; } FontStyle? style = null; DependencyProperty depProperty = TextElement.FontStyleProperty; object styleProperty = ts.GetPropertyValue(depProperty); if (styleProperty is FontStyle) { style = (FontStyle)ts.GetPropertyValue(depProperty); } if (styleProperty == DependencyProperty.UnsetValue || (style != FontStyles.Italic)) { ts.ApplyPropertyValue(depProperty, FontStyles.Italic); } else { ts.ApplyPropertyValue(depProperty, FontStyles.Normal); } } private void formatUnderline() { TextSelection ts = this.richBox.Selection; if (ts == null) { return; } DependencyProperty depProperty = Inline.TextDecorationsProperty; object styleProperty = ts.GetPropertyValue(depProperty); if (styleProperty is TextDecorationCollection) { TextDecorationCollection propCol = (TextDecorationCollection)ts.GetPropertyValue(depProperty); if (propCol.Count > 0) { foreach (TextDecoration td in propCol) { if (td.Location == TextDecorationLocation.Underline) { this.richBox.Selection.ApplyPropertyValue(depProperty, null); } } } else { this.richBox.Selection.ApplyPropertyValue(depProperty, TextDecorations.Underline); } } } private void formatAlign(TextAlignment positionToSet) { TextSelection ts = this.richBox.Selection; if (ts == null) { return; } TextAlignment? style = null; DependencyProperty depProperty = Paragraph.TextAlignmentProperty; object propertyValue = ts.GetPropertyValue(depProperty); if (propertyValue is TextAlignment) { style = (TextAlignment)ts.GetPropertyValue(depProperty); } if (propertyValue == DependencyProperty.UnsetValue || (style != positionToSet)) { ts.ApplyPropertyValue(depProperty, positionToSet); } else { ts.ApplyPropertyValue(depProperty, TextAlignment.Left); } } private void formatFont() { System.Windows.Media.FontFamily font = null; try { MicrDraw.FontFamily fontD = ((KeyValuePair)this.tools_cmbx_fonts.SelectedItem).Value; font = new FontFamily(fontD.Name); } catch (Exception) { MessageBox.Show("Font se nepodařilo identifikovat."); return; } this.richBox.Selection.ApplyPropertyValue(FontFamilyProperty, font); } private void add3colLayoutTable() { ThreeColumnLayoutTable table = new ThreeColumnLayoutTable(); table.setLayout(); // not too cool, but sufficient... Paragraph insertionPara = this.richBox.CaretPosition.Paragraph; try { this.richBox.Document.Blocks.InsertAfter((Block)insertionPara, table); this.richBox.Document.Blocks.InsertAfter(table, new Paragraph()); } catch (Exception) { MessageBox.Show("Třídílné rozložení se nepodařilo vložit."); return; } } private void addTagElementAtCurrentPosition(TagTextEditing.TagBaseElement element) { if (element == null) { throw new ArgumentNullException(); } if (this.richBox.CaretPosition == null) { return; } TextPointer tp = this.richBox.CaretPosition; Paragraph currentParagraph = this.richBox.CaretPosition.Paragraph; // this is hacky af, but dunno, couldn't find much better ways... Run tempRun = new Run("ERROR", tp); Inline[] inlines = currentParagraph.Inlines.ToArray(); foreach (Inline curI in inlines) { currentParagraph.Inlines.Remove(curI); } foreach (Inline curI in inlines) { if (curI == tempRun) { currentParagraph.Inlines.Add(element); } else { currentParagraph.Inlines.Add(curI); } } Run extraSpace = new Run(" ", element.ContentEnd); this.richBox.CaretPosition = extraSpace.ContentEnd; } private void insertImage() { Forms.OpenFileDialog dia = new Forms.OpenFileDialog(); Forms.DialogResult result = dia.ShowDialog(); if (result != Forms.DialogResult.OK) { return; } if (!File.Exists(dia.FileName)) { MessageBox.Show("Soubor nenalezen."); return; } MicrDraw.Bitmap bmp = null; try { bmp = new MicrDraw.Bitmap(dia.FileName); } catch(Exception) { MessageBox.Show("Obrázek se nepodařilo vložit. Zvolili jste soubor: " + dia.FileName); return; } Clipboard.SetDataObject(bmp); this.richBox.Paste(); Clipboard.Clear(); } #endregion #region actions performed on prepared text public void actions_Click(object sender, RoutedEventArgs args) { Button button = (Button)sender; switch (button.Name) { case "btn_present": this.previewValuesForCurrentStudent(); break; case "btn_saveTemplate": this.saveTemplatetoFile(); break; case "btn_loadTemplate": this.loadTemplateFromFile(); break; case "btn_Export": this.export(); break; default: break; } } private void currentStudentChange_click(object sender, RoutedEventArgs args) { Button button = (Button)sender; switch (button.Name) { case "btn_previousStudent": if (this.currentStudentIndex != 0) { this.currentStudentIndex = this.currentStudentIndex - 1; } break; case "btn_nextStudent": if (this._selectedStudents != null && this._selectedStudents.Length > 0 && this.currentStudentIndex < this._selectedStudents.Length - 1) { this.currentStudentIndex = this.currentStudentIndex + 1; } break; } this.setSelectedStudentsLabels(); } private void previewValuesForCurrentStudent() { if (this._selectedStudents == null || this._selectedStudents.Length == 0) { MessageBox.Show("Není vybrán žádný student, nelze pokračovat."); return; } if (this._conversionDirection == ConversionTypes.ToActualValues) { this._storedFdWhilePreviewing = this.richBox.Document; FlowDocument newFd = this.getCopyOfDocument(this._storedFdWhilePreviewing); this.BindDataAccordingToModel(newFd, this.CurrentStudent); this._documentManager.Convert(newFd, ConversionTypes.ToActualValues); this.richBox.Document = newFd; this._conversionDirection = ConversionTypes.ToTagDefaultAppearance; } else { this.richBox.Document = this._storedFdWhilePreviewing; this._storedFdWhilePreviewing = null; this._conversionDirection = ConversionTypes.ToActualValues; } } private void saveTemplatetoFile() { Forms.SaveFileDialog dia = new Forms.SaveFileDialog(); Forms.DialogResult result = dia.ShowDialog(); if (result != Forms.DialogResult.OK) { return; } using (FileStream fs = new FileStream(dia.FileName, FileMode.Create)) { TextRange content = new TextRange(this.richBox.Document.ContentStart, this.richBox.Document.ContentEnd); content.Save(fs, DataFormats.XamlPackage, true); } } private void loadTemplateFromFile() { Forms.OpenFileDialog dia = new Forms.OpenFileDialog(); Forms.DialogResult result = dia.ShowDialog(); if (result != Forms.DialogResult.OK) { return; } if (!File.Exists(dia.FileName)) { MessageBox.Show("Soubor nenalezen."); return; } FlowDocument newFd = new FlowDocument(); try { using (FileStream fs = new FileStream(dia.FileName, FileMode.Open)) { TextRange content = new TextRange(newFd.ContentStart, newFd.ContentEnd); content.Load(fs, DataFormats.XamlPackage); this.richBox.Document = newFd; } } catch (Exception ex) { MessageBox.Show("Šablonu se nepodařilo načíst."); return; } } private void export() { try { string ExportOptionKey = ((KeyValuePair)this.cmbx_exportOptions.SelectedItem).Key; switch(ExportOptionKey) { case "rtfSingle": this.exportAsRTFSingle(); break; case "rtfSeparate": this.exportAsRTFSeparate(); break; case "rtfBatch": throw new NotImplementedException(); break; case "pdfSingle": this.exportAsPDF(new Student[] { this.CurrentStudent }, false); break; case "pdfSeparate": this.exportAsPDF(this._selectedStudents, false); break; case "pdfBatch": this.exportAsPDF(this._selectedStudents, true); break; default: throw new KeyNotFoundException(); } } catch (KeyNotFoundException) { MessageBox.Show("Chyba! Nepovedlo se rozpoznat typ exportu."); } catch (Exception) { MessageBox.Show("Chyba! Dokument se nepodařilo vyexportovat."); } } // RTF private void exportAsRTFSingle() { if (this._selectedStudents == null || this._selectedStudents.Length == 0) { MessageBox.Show("Pro tuto operaci je třeba vybrat alespoň jedno studium."); return; } Forms.FolderBrowserDialog dlg = new Forms.FolderBrowserDialog(); Forms.DialogResult res = dlg.ShowDialog(); if (res != Forms.DialogResult.OK) { return; } FlowDocument originalFd = this.getTaggedDocument(); Student student = this.CurrentStudent; FlowDocument cloneFd = this.getCopyOfDocument(originalFd); this._documentManager.setWidthOfThreeColLayouts(cloneFd, FlowDocumentTagManager.threeColLayoutWidths.A4); this.BindDataAccordingToModel(cloneFd, student); // this._documentManager.ReplaceTagsWithStaticActualValues(cloneFd); this._documentManager.Convert(cloneFd, ConversionTypes.ToActualValues); RichTextBox newRbx = new RichTextBox(); newRbx.Document = cloneFd; using (FileStream fs = new FileStream(String.Format("{0}//{1}", dlg.SelectedPath, this.getExportFilename(student, "rtf")), FileMode.OpenOrCreate, FileAccess.Write)) { //hmm can't i save FD directly? newRbx.SelectAll(); newRbx.Selection.Save(fs, DataFormats.Rtf); } } private void exportAsRTFSeparate() { if (this._selectedStudents == null || this._selectedStudents.Length == 0) { MessageBox.Show("Pro tuto operaci je třeba vybrat alespoň jedno studium."); return; } Forms.FolderBrowserDialog dlg = new Forms.FolderBrowserDialog(); Forms.DialogResult res = dlg.ShowDialog(); if (res != Forms.DialogResult.OK) { return; } FlowDocument originalFd = this.getTaggedDocument(); for (int x = 0; x < this._selectedStudents.Length; x++) { Student student = this._selectedStudents[x]; FlowDocument cloneFd = this.getCopyOfDocument(originalFd); this._documentManager.setWidthOfThreeColLayouts(cloneFd, FlowDocumentTagManager.threeColLayoutWidths.A4); this.BindDataAccordingToModel(cloneFd, student); //this._documentManager.ReplaceTagsWithStaticActualValues(cloneFd); this._documentManager.Convert(cloneFd, ConversionTypes.ToActualValues); RichTextBox newRbx = new RichTextBox(); newRbx.Document = cloneFd; using (FileStream fs = new FileStream(String.Format("{0}//{1}", dlg.SelectedPath, this.getExportFilename(student, "rtf")), FileMode.OpenOrCreate, FileAccess.Write)) { //hmm can't i save FD directly? newRbx.SelectAll(); newRbx.Selection.Save(fs, DataFormats.Rtf); } } } private void exportAsRTFBatch() { } // PDF private void exportAsPDF(Student[] students, bool batch) { if (students == null || students.Length == 0) { MessageBox.Show("Pro tuto operaci je třeba vybrat alespoň jedno studium."); return; } //FlowDocument doc = this.richBox.Document; FlowDocument cloneFd = this.getCopyOfDocument(this.richBox.Document); bool onlyProcessableElements = this._documentManager.CheckProcessableElements(cloneFd); if (!onlyProcessableElements) { MessageBox.Show("Nelze pokračovat, dokument obsahuje nepodporované prvky."); return; } Forms.FolderBrowserDialog dlg = new Forms.FolderBrowserDialog(); Forms.DialogResult res = dlg.ShowDialog(); if (res != Forms.DialogResult.OK) { return; } for (int x = 0; x < students.Length; x++) { Student student = students[x]; this.BindDataAccordingToModel(cloneFd, student); this._documentManager.Convert(cloneFd, ConversionTypes.ToActualValues); this._documentManager.PrepareSinglePDF(cloneFd, this.getExportFilename(student, "pdf")); } this._documentManager.SavePreparedPDFDocuments(dlg.SelectedPath, batch); this._documentManager.ClearPreparedPDFDocuments(); } #endregion #region supportive methods /// /// As opposed to the one being previewed. /// /// private FlowDocument getTaggedDocument() { if (this._storedFdWhilePreviewing != null) { return this._storedFdWhilePreviewing; } else { return this.richBox.Document; } } private void BindDataAccordingToModel(FlowDocument document, T model) { this._documentManager.BindModel(document, model); if (model is Student) { Student stud = model as Student; this._documentManager.BindGender(document, stud.Sex); } } private string getExportFilename(Student student, string extension) { string filename = String.Format("{0}_{1}_{2}.{3}", student.StudyID, student.FieldOfStudy, student.LastName, extension); return filename; } /// /// Beware! Returns deserialized FlowDocument copy. Inline objects'references may need be reset /// private FlowDocument getCopyOfDocument(FlowDocument document) { string xamlStream = System.Windows.Markup.XamlWriter.Save(this.richBox.Document); FlowDocument newFd = (FlowDocument)System.Windows.Markup.XamlReader.Parse(xamlStream); return newFd; } private void openInsertTagWindowSIS() { if (this.tagWindowSIS != null) { return; } this.tagWindowSIS = new TagElementSelectionWindowSIS(); this.tagWindowSIS.Initialize(); this.tagWindowSIS.Show(); this.tagWindowSIS.Closed += (object sender, EventArgs args) => { TagElementSelectionWindowSIS wnd = (TagElementSelectionWindowSIS)sender; if (wnd.IsSuccess) { this.addTagElementAtCurrentPosition(wnd.Result.ReturnObject); } this.tagWindowSIS = null; }; } private void openInsertTagWindowGender() { if (this.tagWindowGender != null) { return; } this.tagWindowGender = new TagElementSelectionWindowGender(); try { this.tagWindowGender.InputValues = this._documentManager.loadGenderTagsFromDbFile(); } catch (Exception ex) { } this.tagWindowGender.Initialize(); this.tagWindowGender.Show(); this.tagWindowGender.Closed += (object sender, EventArgs args) => { TagElementSelectionWindowGender wnd = (TagElementSelectionWindowGender)sender; if (wnd.IsSuccess) { this.addTagElementAtCurrentPosition(wnd.Result.ReturnObject[0]); } this.tagWindowGender = null; }; } private void setSelectedStudentsLabels() { if (this._selectedStudents != null && this._selectedStudents.Length > 0) { this.lbl_CurrentlySelectedStudentValue.Content = String.Format("{0}, {1} ({2})", this.CurrentStudent.LastName, this.CurrentStudent.FirstName, this.CurrentStudent.FieldOfStudy); this.lbl_NumberOfSelectedStudentsValue.Content = this._selectedStudents.Length; } else { this.currentStudentIndex = 0; this.lbl_CurrentlySelectedStudentValue.Content = "Není zvolený žádný student"; this.lbl_NumberOfSelectedStudentsValue.Content = "0"; } } #endregion } }