Quantcast

Added intelligent detection and handling of unsaved changes

Kevin Lyles [11-05-09 - 10:25]
Added intelligent detection and handling of unsaved changes
Filename
WeightsWatcher.xml
config.lua
diff --git a/WeightsWatcher.xml b/WeightsWatcher.xml
index 7aa8d06..e6e17c7 100644
--- a/WeightsWatcher.xml
+++ b/WeightsWatcher.xml
@@ -154,6 +154,22 @@
 						if self:GetNumber() ~= 0 or text:match("^[0.]+$") or text == "" then
 							self.number = text
 						end
+						if self:GetNumber() == ww_config.rightPanel.statList[self:GetParent().statName] or (self:GetNumber() == 0 and not ww_config.rightPanel.statList[self:GetParent().statName]) then
+							ww_config.rightPanel.changedStats[self] = nil
+							local changed = false
+							for _ in pairs(ww_config.rightPanel.changedStats) do
+								changed = true
+								break
+							end
+							if not changed then
+								ww_config.rightPanel.saveButton:Disable()
+								ww_config.rightPanel.resetButton:Disable()
+							end
+						else
+							ww_config.rightPanel.changedStats[self] = self:GetParent().statName
+							ww_config.rightPanel.saveButton:Enable()
+							ww_config.rightPanel.resetButton:Enable()
+						end
 					</OnTextChanged>
 					<OnChar>
 						if validateNumber(text, self:GetText()) then
@@ -262,7 +278,9 @@
 				</Frames>
 				<Scripts>
 					<OnClick>
-						configSelectWeight(self:GetParent())
+						configDiscardChanges(function()
+								configSelectWeight(self:GetParent())
+							end)
 					</OnClick>
 					<OnLoad>
 						self:SetFontString(self:CreateFontString(nil, "OVERLAY", "ww_defaultString"))
@@ -480,7 +498,9 @@
 				</Frames>
 				<Scripts>
 					<OnShow>
-						changeFocus(self.scrollFrame.stats[#(self.scrollFrame.stats)])
+						if not ww_config.popup then
+							changeFocus(self.scrollFrame.stats[#(self.scrollFrame.stats)])
+						end
 					</OnShow>
 				</Scripts>
 			</Frame>
@@ -500,7 +520,13 @@
 				</Anchors>
 				<Scripts>
 					<OnClick>
-						StaticPopup_Show("WW_CONFIRM_RESTORE_DEFAULTS")
+						if ww_config.rightPanel.weightFrame and defaultVars.weightsList[ww_config.rightPanel.weightFrame.category.class][ww_config.rightPanel.weightFrame.name] then
+							StaticPopup_Show("WW_CONFIRM_RESTORE_DEFAULTS")
+						else
+							configDiscardChanges(function()
+									StaticPopup_Show("WW_CONFIRM_RESTORE_DEFAULTS")
+								end)
+						end
 					</OnClick>
 				</Scripts>
 			</Button>
@@ -523,6 +549,23 @@
 			<OnLoad>
 				table.insert(UISpecialFrames, self:GetName());
 			</OnLoad>
+			<OnHide>
+				if self.reallyClose then
+					self.reallyClose = nil
+				else
+					self.popup = true
+					self:Show()
+					configDiscardChanges(function()
+							self.reallyClose = true
+							<!-- Safe because configDiscardChanges will save the weight first -->
+							if self.rightPanel:IsShown() then
+								configResetWeight()
+							end
+							self:Hide()
+						end)
+					self.popup = nil
+				end
+			</OnHide>
 		</Scripts>
 	</Frame>
 	<Frame name="ww_newWeight" parent="UIParent" hidden="true" frameStrata="DIALOG">
diff --git a/config.lua b/config.lua
index 8dd43fa..142a090 100644
--- a/config.lua
+++ b/config.lua
@@ -2,6 +2,24 @@ if not WeightsWatcher then
 	WeightsWatcher = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceHook-2.1")
 end

+StaticPopupDialogs["WW_CONFIRM_DISCARD_CHANGES"] = {
+	text = "You have unsaved changes for this weight.",
+	button1 = "Discard",
+	button3 = "Save",
+	button2 = "Cancel",
+	OnAccept = function(self, func)
+			func()
+		end,
+	OnAlt = function(self, func)
+			configSaveWeight()
+			func()
+		end,
+	showAlert = true,
+	timeout = 0,
+	whileDead = true,
+	hideOnEscape = true,
+}
+
 StaticPopupDialogs["WW_CONFIRM_WEIGHT_DELETE"] = {
 	text = "Are you sure you want to delete the %s weight named \"%s\"?",
 	button1 = "Delete",
@@ -156,6 +174,17 @@ function changeFocus(currentStatFrame)
 	end
 end

+function configDiscardChanges(func)
+	if ww_config.rightPanel:IsShown() and ww_config.rightPanel.changedStats then
+		for _, _ in pairs(ww_config.rightPanel.changedStats) do
+			local popup = StaticPopup_Show("WW_CONFIRM_DISCARD_CHANGES")
+			popup.data = func
+			return
+		end
+	end
+	func()
+end
+
 function selectWeight(class, name)
 	for _, classFrame in ipairs(ww_config.leftPanel.scrollFrame.categories) do
 		if classFrame.class == class then
@@ -177,6 +206,7 @@ function configSelectWeight(weightFrame)

 	ww_config.rightPanel.weightFrame = weightFrame
 	ww_config.rightPanel.statList = ww_vars.weightsList[weightFrame.category.class][weightFrame.name]
+	ww_config.rightPanel.changedStats = {}

 	-- Fills the right panel with the current weight's stats
 	configResetWeight()
@@ -202,16 +232,33 @@ end

 function configResetWeight()
 	local value
+	local changed = false

-	for _, frame in pairs(ww_config.rightPanel.scrollFrame.stats) do
-		if frame.statName then
-			value = ww_config.rightPanel.statList[frame.statName]
+	if ww_config.rightPanel.changedStats then
+		for statValue, statName in pairs(ww_config.rightPanel.changedStats) do
+			changed = true
+			value = ww_config.rightPanel.statList[statName]
 			if not value then
 				value = ""
 			end
-			frame.statValue:SetText(value)
+			statValue:SetText(value)
 		end
 	end
+	if not changed then
+		for _, frame in pairs(ww_config.rightPanel.scrollFrame.stats) do
+			if frame.statName then
+				value = ww_config.rightPanel.statList[frame.statName]
+				if not value then
+					value = ""
+				end
+				frame.statValue:SetText(value)
+			end
+		end
+	end
+
+	ww_config.rightPanel.changedStats = {}
+	ww_config.rightPanel.saveButton:Disable()
+	ww_config.rightPanel.resetButton:Disable()
 end

 function configDeleteWeight()
@@ -230,15 +277,17 @@ function configSaveWeight()
 		ww_weightIdealCache[weightFrame.category.class][weightFrame.name] = {}
 	end

-	for _, frame in pairs(ww_config.rightPanel.scrollFrame.stats) do
-		if frame.statName then
-			number = frame.statValue:GetNumber()
-			if number == 0 then
-				number = nil
-			end
-			ww_config.rightPanel.statList[frame.statName] = number
+	for statValue, statName in pairs(ww_config.rightPanel.changedStats) do
+		number = statValue:GetNumber()
+		if number == 0 then
+			number = nil
 		end
+		ww_config.rightPanel.statList[statName] = number
 	end
+
+	ww_config.rightPanel.changedStats = {}
+	ww_config.rightPanel.saveButton:Disable()
+	ww_config.rightPanel.resetButton:Disable()
 end

 function deleteWeight()
@@ -306,19 +355,21 @@ function deleteWeight()
 end

 function configNewWeight(class, weight, statList)
-	-- Need to call show first to re-initialize the dropdown
-	ww_newWeight:Show()
-	if class then
-		UIDropDownMenu_SetSelectedValue(ww_newWeight.dropdown, class, false)
-	end
-	ww_newWeight.editBox:SetText("")
-	if weight then
-		ww_newWeight.editBox:SetText(weight)
-	end
-	if not statList then
-		statList = {}
-	end
-	ww_newWeight.statList = statList
+	configDiscardChanges(function()
+			-- Need to call show first to re-initialize the dropdown
+			ww_newWeight:Show()
+			if class then
+				UIDropDownMenu_SetSelectedValue(ww_newWeight.dropdown, class, false)
+			end
+			ww_newWeight.editBox:SetText("")
+			if weight then
+				ww_newWeight.editBox:SetText(weight)
+			end
+			if not statList then
+				statList = {}
+			end
+			ww_newWeight.statList = statList
+		end)
 end

 function setWeight(class, weight, statList)