My app allows the user to create and edit one or more presentations at a time. How can I tell if a presentation has any unsaved changes?
Could you please elaborate your query/requirements and provide more details on it? Additionally, kindly zip and attach sample presentation which has unsaved changes. If possible, please share some screenshots to demonstrate on how you could accomplish the task in PowerPoint options/commands manually. We will understand your needs precisely and then evaluate it.
I have a c# project which creates one or more presentations simultaneously based on interactive user selections. I need to be able to determine if any presentation has unsaved changes. I keep the presentations in a list and I need to know if any of them have changes that have not been saved before closing the application.
I can’t imagine what you mean when you ask for a sample presentation that has unsaved changes. That isn’t even possible.
In PowerPoint automation I would check the value of Presentation.Saved to determine whether the presenation has unsaved changes.
Thanks for providing further details.
I am afraid, there is no Presentation.Saved or relevant attribute in Aspose.Slides APIs. Anyways, we need to evaluate your requirements/issue in details. We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.
Issue ID(s): SLIDESNET-44300
You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.
Thank you. We currently use other Aspose products and are evaluating Aspose Slides.
It would also be very helpful for the Presentation class to have a FullFilePath property.
We need to evaluate if this can be supported. We have opened the following new ticket in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.
Issue ID(s): SLIDESNET-44301
Once we have an update on it, we will let you know.
The changes proposed by you will have a negative impact on the API. The point is that the Presentation
class does not represent the presentation file, but the presentation itself, so properties like FileName
and IsSaved
are irrelevant. Therefore, we can propose to you to use a wrapper over the Presentation
class that implements the logic of the presentation file, which implements all the properties required by you:
class PresentationFile : IDisposable
{
private string m_hash = "";
private bool m_disposed = false;
public Presentation Presentation { get; private set; }
public bool Saved { get { return GetHash() == m_hash; } } // SLIDESNET-44300
public string FileName { get { return Path.GetFileName(FullFileName); } } // SLIDESNET-44301
public string FullFileName { get; private set; } // SLIDESNET-44301
public PresentationFile()
{
FullFileName = m_hash = string.Empty;
Presentation = new Presentation();
}
public PresentationFile(string path)
{
if (File.Exists(path))
{
FullFileName = Path.GetFullPath(path);
Presentation = new Presentation(FullFileName);
m_hash = GetHash();
}
else
throw new ArgumentException();
}
public void Save()
{
if (!string.IsNullOrEmpty(FullFileName))
SaveAs(FullFileName);
else
throw new Exception();
}
public void SaveAs(string fileName)
{
FullFileName = Path.GetFullPath(fileName);
Presentation.Save(FullFileName, SaveFormat.Pptx);
m_hash = GetHash();
}
private string GetHash()
{
using (MemoryStream ms = new MemoryStream())
{
// md5 is not most efficient way, but simplest one
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
Presentation.Save(ms, SaveFormat.Pptx);
ms.Seek(0, SeekOrigin.Begin);
byte[] hash = md5.ComputeHash(ms);
return Convert.ToBase64String(hash);
}
}
}
public void Dispose()
{
if (!m_disposed && Presentation != null)
Presentation.Dispose();
m_disposed = true;
}
}
This test shows an example of how to use this wrapper:
public void PresentationFile_Test()
{
string path = "presentation.pptx";
string path2 = "presentation2.pptx";
// create new presentation
using (PresentationFile pres = new PresentationFile())
{
// initially presentation is not saved
Assert.IsFalse(pres.Saved);
// if you try to save - exception will be thrown, because file name not set
Assert.Throws<Exception>(() => pres.Save());
// right way to FIRST save
Assert.DoesNotThrow(() => pres.SaveAs(path));
// now we can get FileName, and FullFileName
Assert.AreEqual(path, pres.FileName);
// Save() works - file name is set
Assert.DoesNotThrow(() => pres.Save());
// Saved == true
Assert.IsTrue(pres.Saved);
// make some change in presentation
pres.Presentation.Slides.AddEmptySlide(pres.Presentation.LayoutSlides[0]);
// and now Saved == false
Assert.IsFalse(pres.Saved);
// you should save it
Assert.DoesNotThrow(() => pres.Save());
}
// open presentation
using (PresentationFile pres = new PresentationFile(path))
{
// initially presentation is saved
Assert.IsTrue(pres.Saved);
// Save() works - file name is set
Assert.DoesNotThrow(() => pres.Save());
// save as copy
Assert.DoesNotThrow(() => pres.SaveAs(path2));
Assert.AreEqual(path2, pres.FileName);
Assert.DoesNotThrow(() => pres.Save());
// Saved == true
Assert.IsTrue(pres.Saved);
// make some change in presentation
pres.Presentation.Slides.RemoveAt(0);
// and now Saved == false
Assert.IsFalse(pres.Saved);
// you should save it
Assert.DoesNotThrow(() => pres.Save());
}
}
Let us know if it works for your needs.
Thanks. I actually did implement something very similar to this.