public override void FinalizeReferenceLoad() { if (!m_bCacheUpdated || !CardMakerSettings.EnableGoogleCache) { return; } List <GoogleCacheItem> listCacheItems = new List <GoogleCacheItem>(); foreach (var zPair in m_dictionaryDataCache) { listCacheItems.Add(new GoogleCacheItem() { Reference = zPair.Key, Data = zPair.Value }); } var sLocalCacheFile = Path.Combine(CardMakerInstance.StartupPath, CardMakerConstants.GOOGLE_CACHE_FILE); if (!SerializationUtils.SerializeToXmlFile( sLocalCacheFile, listCacheItems, CardMakerConstants.XML_ENCODING)) { ProgressReporter.AddIssue("Failed to write cache file: {0}".FormatString(sLocalCacheFile)); } }
private void LoadCache() { if (!CardMakerSettings.EnableGoogleCache) { return; } var sLocalCacheFile = Path.Combine(CardMakerInstance.StartupPath, CardMakerConstants.GOOGLE_CACHE_FILE); List <GoogleCacheItem> listCacheItems = null; if (SerializationUtils.DeserializeFromXmlFile( sLocalCacheFile, CardMakerConstants.XML_ENCODING, ref listCacheItems)) { foreach (var zCacheItem in listCacheItems) { m_dictionaryDataCache.Add(zCacheItem.Reference, zCacheItem.Data); } } else { ProgressReporter.AddIssue("Failed to read cache file: {0}".FormatString(sLocalCacheFile)); } }
public PdfSharpExporter(int[] arrayLayoutIndices, string sExportFile, string sPageOrientation) : base(arrayLayoutIndices) { m_sExportFile = sExportFile; try { m_ePageOrientation = (PageOrientation)Enum.Parse(typeof(PageOrientation), sPageOrientation); } catch (Exception) { ProgressReporter.AddIssue(sPageOrientation + " is an unknown page orientation."); } m_zDocument = new PdfDocument(); }
/// <summary> /// Shows the read-only error (assumes the file is open in a viewer) /// </summary> private void DisplayError(string extraMessage = "") { var sMsg = "{0}The destination file may be open in a PDF viewer. Please close it before exporting." .FormatString( (string.IsNullOrWhiteSpace(extraMessage) ? "" : extraMessage + " -- " )); if (null != CardMakerInstance.ApplicationForm) { CardMakerInstance.ApplicationForm.InvokeAction(() => { MessageBox.Show(CardMakerInstance.ApplicationForm, sMsg, "PDF Write Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }); } else { ProgressReporter.AddIssue(sMsg); } }
public void GetData(string sPath, List <List <string> > listData, bool bLogNotFound, int nStartIdx, string nameAppend = "") { CSVFile zCSVParser = null; var bTryCopy = false; var sCombinedPath = Path.GetDirectoryName(sPath) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(sPath) + nameAppend + Path.GetExtension(sPath); if (!File.Exists(sCombinedPath)) { if (bLogNotFound) { var sMsg = "CSV File not found: " + sCombinedPath; ProgressReporter.AddIssue(sMsg); IssueManager.Instance.FireAddIssueEvent(sMsg); } return; } try { zCSVParser = new CSVFile(sCombinedPath, Encoding.UTF8); } catch (Exception) { bTryCopy = true; } // This is a ridiculous hack to work around excel locking the file from even being read if (bTryCopy) { var sTmpFile = sCombinedPath + "." + DateTime.Now.Millisecond + ".tmp"; File.Copy(sCombinedPath, sTmpFile); zCSVParser = new CSVFile(sTmpFile, Encoding.UTF8); File.Delete(sTmpFile); // remove the temp file } for (var nLine = nStartIdx; nLine < zCSVParser.Rows; nLine++) { listData.Add(zCSVParser.GetRow(nLine)); } }
public void GetData(GoogleSpreadsheetReference zReference, List <List <string> > listData, bool bRemoveFirstRow, string sNameAppend = "") { var sCacheKey = GetCacheKey(zReference.generateFullReference(), sNameAppend); List <List <string> > listCacheData; if (!CardMakerInstance.ForceDataCacheRefresh && m_dictionaryDataCache.TryGetValue(sCacheKey, out listCacheData)) { ProgressReporter.AddIssue("Loading {0} from local cache".FormatString(sCacheKey)); listData.AddRange(listCacheData); return; } var sSpreadsheetName = zReference.SpreadsheetName; var sSheetName = zReference.SheetName + sNameAppend; var bAuthorizationError = false; var bError = false; List <List <string> > listGoogleData = null; try { var zGoogleSpreadsheet = new GoogleSpreadsheet(CardMakerInstance.GoogleInitializerFactory); if (string.IsNullOrWhiteSpace(zReference.SpreadsheetId)) { ProgressReporter.AddIssue("WARNING: The reference {0}.{1} is missing the Spreadsheet ID. Please reconfigure this reference." .FormatString(zReference.SpreadsheetName, zReference.SheetName)); listGoogleData = zGoogleSpreadsheet.GetSheetContentsBySpreadsheetName(sSpreadsheetName, sSheetName); } else { listGoogleData = zGoogleSpreadsheet.GetSheetContentsBySpreadsheetId(zReference.SpreadsheetId, sSheetName); } // blank data just means an empty or non-existent sheet (generally okay) if (listGoogleData == null) { listGoogleData = new List <List <string> >(); } } catch (GoogleApiException e) { ProgressReporter.AddIssue("Google Spreadsheet access exception: " + e.Message); bAuthorizationError = GoogleApi.IsAuthorizationError(e); } catch (Exception e) { ProgressReporter.AddIssue("General exception: " + e.Message); listGoogleData = null; bError = true; } if (bAuthorizationError || bError || listGoogleData == null) { ProgressReporter.AddIssue("Failed to load any data from Google Spreadsheet." + "[" + sSpreadsheetName + "," + sSheetName + "]" + (bAuthorizationError ? " Google reported a problem with your credentials." : String.Empty)); } else { if (bRemoveFirstRow && listGoogleData.Count > 0) { listGoogleData.RemoveAt(0); } listData.AddRange(listGoogleData); if (m_dictionaryDataCache.ContainsKey(sCacheKey)) { m_dictionaryDataCache.Remove(sCacheKey); } m_dictionaryDataCache.Add(sCacheKey, listGoogleData); m_bCacheUpdated = true; } }
public override void ExportThread() { if (File.Exists(m_sExportFile)) { try { File.Delete(m_sExportFile); } catch (Exception) { ProgressReporter.AddIssue("Failed to delete PDF before export: {0}".FormatString(m_sExportFile)); } if (File.Exists(m_sExportFile)) { DisplayError(); ProgressReporter.Shutdown(); return; } } #if !MONO_BUILD Bitmap zBuffer = null; #endif var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); // always add a new page initially (necessary for ConfigurePointSizes) AddInitialPage(); Type zLastExporterType = null; foreach (var nIdx in ExportLayoutIndices) { ChangeExportLayoutIndex(nIdx); m_zExportData.Deck = CurrentDeck; if (CurrentDeck.EmptyReference) { // empty reference layouts are not exported ProgressReporter.ProgressStep(progressLayoutIdx); continue; } ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); var rectCrop = CurrentDeck.CardLayout.getExportCropDefinition(); // each layout has its own row export style (potentially) var zRowExporter = GetRowExporter(); // necessary tracking for which index of the layout is to be exported (this is NOT necessarily the index of the card due to the page back functionality) var nNextExportIndex = 0; // reconfigure the page per layout ConfigurePointSizes(CurrentDeck.CardLayout, rectCrop); if (nIdx == 0) { // only the page has been setup at this point, not the x-position zRowExporter.SetupNewRowXPosition(nNextExportIndex); } else { // after the first layout always evaluate whether a new page should be added // if the exporter type changes start a new page if (CardMakerSettings.PrintLayoutsOnNewPage || zLastExporterType != zRowExporter.GetType()) { AddPage(zRowExporter, nNextExportIndex); } else if (zRowExporter.IsLayoutForcedToNewRow() || zRowExporter.IsRowFull()) { MoveToNextRow(zRowExporter, nNextExportIndex); } } zLastExporterType = zRowExporter.GetType(); // When moving to the next row it should be a completely empty row. In the case of nesting only 2 layouts deep is supported at this // time - the first layout and one additional. Also note this is applied AFTER the above decisions above about moving to the next row. m_zExportData.NextRowYAdjust = Math.Max(m_zExportData.NextRowYAdjust, m_zExportData.LayoutPointHeight + m_zExportData.BufferY); #if !MONO_BUILD zBuffer?.Dispose(); zBuffer = createExportBuffer(CurrentDeck.CardLayout, rectCrop); var fOriginalXDpi = zBuffer.HorizontalResolution; var fOriginalYDpi = zBuffer.VerticalResolution; #endif foreach (var nCardIdx in GetExportIndices()) { CurrentDeck.CardPrintIndex = nCardIdx; #if MONO_BUILD // mono build won't support the optimization so re-create the buffer Bitmap zBuffer = createExportBuffer(CurrentDeck.CardLayout, rectCrop); #else // minor optimization, reuse the same bitmap (for drawing sake the DPI has to be reset) zBuffer.SetResolution(fOriginalXDpi, fOriginalYDpi); #endif // Draw the image into the buffer if (nCardIdx == -1) { Graphics.FromImage(zBuffer).FillRectangle(Brushes.White, 0, 0, zBuffer.Width, zBuffer.Height); // note: some oddities were observed where the buffer was not flood filling } else { CardRenderer.DrawPrintLineToGraphics(Graphics.FromImage(zBuffer), -rectCrop.X, -rectCrop.Y, true); // if cropping the border needs to be drawn to the cropped size if (rectCrop != Rectangle.Empty) { CardRenderer.DrawBorder(Graphics.FromImage(zBuffer), 0, 0, zBuffer.Width, zBuffer.Height, CurrentDeck.CardLayout, true); } } // apply any export rotation ProcessRotateExport(zBuffer, CurrentDeck.CardLayout, false); // before rendering to the PDF bump the DPI to the desired value zBuffer.SetResolution(CurrentDeck.CardLayout.dpi, CurrentDeck.CardLayout.dpi); var xImage = XImage.FromGdiPlusImage(zBuffer); // before drawing make sure there is space (will move to next row/page) EvaluateDrawLocation(nNextExportIndex, zRowExporter); m_zPageGfx.DrawImage(xImage, m_zExportData.DrawX, m_zExportData.DrawY); // any next row movement is dealt with independent of this call zRowExporter.MoveXToNextColumnPosition(); // undo any export rotation ProcessRotateExport(zBuffer, CurrentDeck.CardLayout, true); nNextExportIndex++; ProgressReporter.ProgressStep(progressCardIdx); } ProgressReporter.ProgressStep(progressLayoutIdx); } #if !MONO_BUILD zBuffer?.Dispose(); #endif try { m_zDocument.Save(m_sExportFile); ProgressReporter.ThreadSuccess = true; } catch (Exception ex) { DisplayError(ex.Message); ProgressReporter.ThreadSuccess = false; } ProgressReporter.Shutdown(); }
public override void ExportThread() { if (File.Exists(m_sExportFile)) { try { File.Delete(m_sExportFile); } catch (Exception) { ProgressReporter.AddIssue("Failed to delete PDF before export: {0}".FormatString(m_sExportFile)); } if (File.Exists(m_sExportFile)) { DisplayError(); ProgressReporter.Shutdown(); return; } } #if !MONO_BUILD Bitmap zBuffer = null; #endif var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); foreach (var nIdx in ExportLayoutIndices) { ChangeExportLayoutIndex(nIdx); if (CurrentDeck.EmptyReference) { // empty reference layouts are not exported ProgressReporter.ProgressStep(progressLayoutIdx); continue; } ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); var rectCrop = CurrentDeck.CardLayout.getExportCropDefinition(); ConfigurePointSizes(CurrentDeck.CardLayout, rectCrop); // necessary tracking for which index of the layout is to be exported (this is NOT necessarily the index of the card due to the page back functionality) var nNextExportIndex = 0; if (0 < nIdx) { if (CardMakerSettings.PrintLayoutsOnNewPage) { AddPage(); } if (CardMakerSettings.PrintAutoHorizontalCenter || (m_dDrawX + m_dLayoutPointWidth > m_dPageMarginEndX)) // this is the case where a layout won't fit in the remaining space of the row { MoveToNextRow(nNextExportIndex); } } // should be adjusted after the above move to next row m_dNextRowYAdjust = Math.Max(m_dNextRowYAdjust, m_dLayoutPointHeight + m_dBufferY); if (CardMakerSettings.PrintAutoHorizontalCenter) { CenterLayoutPositionOnNewRow(nNextExportIndex); } #if !MONO_BUILD zBuffer?.Dispose(); zBuffer = createExportBuffer(CurrentDeck.CardLayout, rectCrop); float fOriginalXDpi = zBuffer.HorizontalResolution; float fOriginalYDpi = zBuffer.VerticalResolution; #endif foreach (var nCardIdx in GetExportIndices()) { CurrentDeck.ResetDeckCache(); CurrentDeck.CardPrintIndex = nCardIdx; #if MONO_BUILD // mono build won't support the optimization so re-create the buffer Bitmap zBuffer = createExportBuffer(CurrentDeck.CardLayout, rectCrop); #endif #if !MONO_BUILD // minor optimization, reuse the same bitmap (for drawing sake the DPI has to be reset) zBuffer.SetResolution(fOriginalXDpi, fOriginalYDpi); #endif if (nCardIdx == -1) { Graphics.FromImage(zBuffer).FillRectangle(Brushes.White, 0, 0, zBuffer.Width, zBuffer.Height); // note: some oddities were observed where the buffer was not flood filling } else { CardRenderer.DrawPrintLineToGraphics(Graphics.FromImage(zBuffer), -rectCrop.X, -rectCrop.Y, true); // if cropping the border needs to be drawn to the cropped size if (rectCrop != Rectangle.Empty) { CardRenderer.DrawBorder(Graphics.FromImage(zBuffer), 0, 0, zBuffer.Width, zBuffer.Height, CurrentDeck.CardLayout, true); } } // apply any export rotation ProcessRotateExport(zBuffer, CurrentDeck.CardLayout, false); // before rendering to the PDF bump the DPI to the desired value zBuffer.SetResolution(CurrentDeck.CardLayout.dpi, CurrentDeck.CardLayout.dpi); var xImage = XImage.FromGdiPlusImage(zBuffer); EvaluatePagePosition(nNextExportIndex); m_zPageGfx.DrawImage(xImage, m_dDrawX, m_dDrawY); MoveToNextColumnPosition(); // undo any export rotation ProcessRotateExport(zBuffer, CurrentDeck.CardLayout, true); nNextExportIndex++; ProgressReporter.ProgressStep(progressCardIdx); } ProgressReporter.ProgressStep(progressLayoutIdx); } #if !MONO_BUILD zBuffer?.Dispose(); #endif try { m_zDocument.Save(m_sExportFile); ProgressReporter.ThreadSuccess = true; } catch (Exception ex) { DisplayError(ex.Message); ProgressReporter.ThreadSuccess = false; } ProgressReporter.Shutdown(); }
public void AddIssue(string sIssue) { ProgressReporter.AddIssue(sIssue); }
public override void ExportThread() { var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); foreach (var nIdx in ExportLayoutIndices) { ChangeExportLayoutIndex(nIdx); if (CurrentDeck.EmptyReference) { // empty reference layouts are not exported ProgressReporter.ProgressStep(progressLayoutIdx); continue; } var nPadSize = CurrentDeck.CardCount.ToString(CultureInfo.InvariantCulture).Length; ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); var exportWidth = CurrentDeck.CardLayout.exportWidth == 0 ? CurrentDeck.CardLayout.width : CurrentDeck.CardLayout.exportWidth; var exportHeight = CurrentDeck.CardLayout.exportHeight == 0 ? CurrentDeck.CardLayout.height : CurrentDeck.CardLayout.exportHeight; if (CurrentDeck.CardLayout.width > exportWidth || CurrentDeck.CardLayout.height > exportHeight) { Logger.AddLogLine( $"ERROR: Layout: [{CurrentDeck.CardLayout.Name}] exportWidth and/or exportHeight too small! (Skipping export)"); continue; } UpdateBufferBitmap(exportWidth, exportHeight); var zGraphics = Graphics.FromImage(m_zExportCardBuffer); var arrayCardIndices = GetCardIndicesArray(CurrentDeck); for (var nCardArrayIdx = 0; nCardArrayIdx < arrayCardIndices.Length; nCardArrayIdx++) { var nCardId = arrayCardIndices[nCardArrayIdx]; var nX = 0; var nY = 0; var nCardsExportedInImage = 0; zGraphics.Clear(CurrentDeck.CardLayout.exportTransparentBackground ? CardMakerConstants.NoColor : Color.White); do { CurrentDeck.ResetDeckCache(); // HACK - the printcard index is 0 based but all other uses of nCardId are 1 based (so ++ it!) CurrentDeck.CardPrintIndex = nCardId++; nCardsExportedInImage++; CardRenderer.DrawPrintLineToGraphics(zGraphics, nX, nY, !CurrentDeck.CardLayout.exportTransparentBackground); m_zExportCardBuffer.SetResolution(CurrentDeck.CardLayout.dpi, CurrentDeck.CardLayout.dpi); ProgressReporter.ProgressStep(progressCardIdx); int nMoveCount = 1; if (m_nSkipStitchIndex > 0) { var x = ((nCardsExportedInImage + 1) % m_nSkipStitchIndex); if (x == 0) { // shift forward an extra spot to ignore the dummy index nMoveCount = 2; } } var bOutOfSpace = false; for (int nShift = 0; nShift < nMoveCount; nShift++) { nX += CurrentDeck.CardLayout.width + CurrentDeck.CardLayout.buffer; if (nX + CurrentDeck.CardLayout.width > exportWidth) { nX = 0; nY += CurrentDeck.CardLayout.height + CurrentDeck.CardLayout.buffer; } if (nY + CurrentDeck.CardLayout.height > exportHeight) { // no more space bOutOfSpace = true; break; } } if (bOutOfSpace) { break; } } while (nCardArrayIdx < CurrentDeck.CardCount); string sFileName; // NOTE: nCardId at this point is 1 more than the actual index ... how convenient for export file names... if (!string.IsNullOrEmpty(m_sOverrideStringFormat)) { // check for the super override sFileName = CurrentDeck.TranslateFileNameString(m_sOverrideStringFormat, nCardId, nPadSize); } else if (!string.IsNullOrEmpty(CurrentDeck.CardLayout.exportNameFormat)) { // check for the per layout override sFileName = CurrentDeck.TranslateFileNameString(CurrentDeck.CardLayout.exportNameFormat, nCardId, nPadSize); } else // default { sFileName = CurrentDeck.CardLayout.Name + "_" + (nCardId).ToString(CultureInfo.InvariantCulture).PadLeft(nPadSize, '0'); } try { ProcessRotateExport(m_zExportCardBuffer, CurrentDeck.CardLayout, false); m_zExportCardBuffer.Save( m_sExportFolder + sFileName + "." + m_eImageFormat.ToString().ToLower(), m_eImageFormat); ProcessRotateExport(m_zExportCardBuffer, CurrentDeck.CardLayout, true); } catch (Exception ex) { ProgressReporter.AddIssue("Invalid Filename or IO error: " + sFileName + " :: " + ex.Message); ProgressReporter.ThreadSuccess = false; ProgressReporter.Shutdown(); return; } } ProgressReporter.ProgressStep(progressLayoutIdx); } ProgressReporter.ThreadSuccess = true; ProgressReporter.Shutdown(); }
public override void ExportThread() { var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); ChangeExportLayoutIndex(ExportLayoutIndices[0]); var nPadSize = CurrentDeck.CardCount.ToString(CultureInfo.InvariantCulture).Length; ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); UpdateBufferBitmap(CurrentDeck.CardLayout.width, CurrentDeck.CardLayout.height); var zGraphics = Graphics.FromImage(m_zExportCardBuffer); var nCardIdx = m_nImageExportIndex; zGraphics.Clear(CurrentDeck.CardLayout.exportTransparentBackground ? CardMakerConstants.NoColor : Color.White); CurrentDeck.ResetDeckCache(); CurrentDeck.CardPrintIndex = nCardIdx++; CardRenderer.DrawPrintLineToGraphics(zGraphics, 0, 0, !CurrentDeck.CardLayout.exportTransparentBackground); m_zExportCardBuffer.SetResolution(CurrentDeck.CardLayout.dpi, CurrentDeck.CardLayout.dpi); ProgressReporter.ProgressStep(progressCardIdx); string sFileName; // NOTE: nCardIdx at this point is 1 more than the actual index ... how convenient for export file names... if (!string.IsNullOrEmpty(m_sOverrideStringFormat)) { // check for the super override sFileName = CurrentDeck.TranslateFileNameString(m_sOverrideStringFormat, nCardIdx, nPadSize); } else if (!string.IsNullOrEmpty(CurrentDeck.CardLayout.exportNameFormat)) { // check for the per layout override sFileName = CurrentDeck.TranslateFileNameString(CurrentDeck.CardLayout.exportNameFormat, nCardIdx, nPadSize); } else // default { sFileName = CurrentDeck.CardLayout.Name + "_" + (nCardIdx).ToString(CultureInfo.InvariantCulture).PadLeft(nPadSize, '0'); } try { ProcessRotateExport(m_zExportCardBuffer, CurrentDeck.CardLayout, false); m_zExportCardBuffer.Save( m_sExportFolder + sFileName + "." + m_eImageFormat.ToString().ToLower(), m_eImageFormat); ProcessRotateExport(m_zExportCardBuffer, CurrentDeck.CardLayout, true); } catch (Exception e) { ProgressReporter.AddIssue("Invalid Filename or IO error: {0} {1}".FormatString(sFileName, e.Message)); ProgressReporter.ThreadSuccess = false; ProgressReporter.Shutdown(); return; } ProgressReporter.ProgressStep(progressLayoutIdx); ProgressReporter.ThreadSuccess = true; ProgressReporter.Shutdown(); }