summaryrefslogtreecommitdiff
path: root/plugins/MyDetails
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MyDetails')
-rw-r--r--plugins/MyDetails/Docs/Skins/Default/MyDetails.msk399
-rw-r--r--plugins/MyDetails/Docs/Skins/Pidgin/MyDetails.msk59
-rw-r--r--plugins/MyDetails/Docs/langpack_MyDetails.txt85
-rw-r--r--plugins/MyDetails/Docs/mydetails.gifbin0 -> 80764 bytes
-rw-r--r--plugins/MyDetails/Docs/mydetails_changelog.txt228
-rw-r--r--plugins/MyDetails/Docs/mydetails_readme.txt41
-rw-r--r--plugins/MyDetails/Docs/mydetails_version.txt1
-rw-r--r--plugins/MyDetails/commons.h148
-rw-r--r--plugins/MyDetails/data.cpp1063
-rw-r--r--plugins/MyDetails/data.h183
-rw-r--r--plugins/MyDetails/frame.cpp2428
-rw-r--r--plugins/MyDetails/frame.h38
-rw-r--r--plugins/MyDetails/mydetails.cpp992
-rw-r--r--plugins/MyDetails/mydetails.h42
-rw-r--r--plugins/MyDetails/mydetails.vcproj642
-rw-r--r--plugins/MyDetails/options.cpp189
-rw-r--r--plugins/MyDetails/options.h83
-rw-r--r--plugins/MyDetails/res/leftarrow.icobin0 -> 2550 bytes
-rw-r--r--plugins/MyDetails/res/listening_to.icobin0 -> 2038 bytes
-rw-r--r--plugins/MyDetails/res/mail.icobin0 -> 2550 bytes
-rw-r--r--plugins/MyDetails/res/rightarrow.icobin0 -> 2550 bytes
-rw-r--r--plugins/MyDetails/resource.h72
-rw-r--r--plugins/MyDetails/resource.rc326
23 files changed, 7019 insertions, 0 deletions
diff --git a/plugins/MyDetails/Docs/Skins/Default/MyDetails.msk b/plugins/MyDetails/Docs/Skins/Default/MyDetails.msk
new file mode 100644
index 0000000000..93c46b457a
--- /dev/null
+++ b/plugins/MyDetails/Docs/Skins/Default/MyDetails.msk
@@ -0,0 +1,399 @@
+function configure()
+{
+ // Options for this skin
+
+ opts.align_right.description = "Align to right"
+ opts.align_right.type = CHECKBOX
+ opts.align_right.value = false
+
+ opts.show_avatar.description = "Show avatar"
+ opts.show_avatar.type = CHECKBOX
+ opts.show_avatar.value = true
+
+ opts.avatar_allow_grow.description = "Allow avatar to grow (be bigger than original image)"
+ opts.avatar_allow_grow.type = CHECKBOX
+ opts.avatar_allow_grow.value = false
+
+ opts.avatar_use_fixed_size.description = "Use fixed size avatar"
+ opts.avatar_use_fixed_size.type = CHECKBOX
+ opts.avatar_use_fixed_size.value = false
+
+ opts.avatar_fixed_size.description = "Avatar fixed size (pixels)"
+ opts.avatar_fixed_size.type = NUMBER
+ opts.avatar_fixed_size.value = 30
+ opts.avatar_fixed_size.min = 1
+ opts.avatar_fixed_size.max = 255
+
+ opts.show_protocol.description = "Show protocol"
+ opts.show_protocol.type = CHECKBOX
+ opts.show_protocol.value = true
+
+ opts.show_email.description = "Show unread mail count"
+ opts.show_email.type = CHECKBOX
+ opts.show_email.value = true
+
+ opts.show_status.description = "Show status"
+ opts.show_status.type = CHECKBOX
+ opts.show_status.value = true
+
+ opts.show_status_msg.description = "Show status message"
+ opts.show_status_msg.type = CHECKBOX
+ opts.show_status_msg.value = true
+
+ opts.show_listening.description = "Show listening to"
+ opts.show_listening.type = CHECKBOX
+ opts.show_listening.value = true
+
+ opts.show_protocol_cycle.description = "Show protocol cycle buttons"
+ opts.show_protocol_cycle.type = CHECKBOX
+ opts.show_protocol_cycle.value = false
+
+ opts.use_under_avatar.description = "Use free space (under avatar) to other texts"
+ opts.use_under_avatar.type = CHECKBOX
+ opts.use_under_avatar.value = true
+
+ opts.border_left.description = "Left border"
+ opts.border_left.type = NUMBER
+ opts.border_left.value = 8
+ opts.border_left.min = 0
+ opts.border_left.max = 100
+
+ opts.border_top.description = "Top border"
+ opts.border_top.type = NUMBER
+ opts.border_top.value = 8
+ opts.border_top.min = 0
+ opts.border_top.max = 100
+
+ opts.border_right.description = "Right border"
+ opts.border_right.type = NUMBER
+ opts.border_right.value = 8
+ opts.border_right.min = 0
+ opts.border_right.max = 100
+
+ opts.border_bottom.description = "Bottom border"
+ opts.border_bottom.type = NUMBER
+ opts.border_bottom.value = 8
+ opts.border_bottom.min = 0
+ opts.border_bottom.max = 100
+
+ // Default fonts
+
+ nickname.font.face = "Tahoma"
+ nickname.font.size = 13
+ nickname.font.bold = true
+ nickname.font.color = RGB(0,0,0)
+
+ protocol.font.face = "Tahoma"
+ protocol.font.size = 8
+ protocol.font.color = RGB(0,0,0)
+
+ email.font.face = "Tahoma"
+ email.font.size = 8
+ email.font.color = RGB(0,0,0)
+
+ status_name.font.face = "Tahoma"
+ status_name.font.size = 8
+ status_name.font.color = RGB(0,0,0)
+
+ status_msg.font.face = "Tahoma"
+ status_msg.font.size = 8
+ status_msg.font.italic = true
+ status_msg.font.color = RGB(150,150,150)
+
+ listening.font.face = "Tahoma"
+ listening.font.size = 8
+ listening.font.italic = true
+ listening.font.color = RGB(150,150,150)
+}
+
+function valign_center(top)
+{
+ var height = 0
+ for(var i = 1; i < arguments.length; i++)
+ height = Math.max(height, arguments[i].height)
+ for(var i = 1; i < arguments.length; i++)
+ arguments[i].top = top + (height - arguments[i].height)/2
+ return top + height
+}
+
+// Resize a field, keeping its aspect ratio
+function resize(field, maxWidth, maxHeight, allowGrow)
+{
+ if (allowGrow == null)
+ allowGrow = true
+
+ var factor = Math.min(maxWidth / field.width, maxHeight / field.height)
+ if (!allowGrow && factor >= 1)
+ return
+
+ field.width *= factor
+ field.height *= factor
+}
+
+function draw()
+{
+ // Default texts
+ if (nickname.enabled && nickname.text == "")
+ nickname.text = "<no nickname>"
+ if (status_msg.enabled && status_msg.text == "")
+ status_msg.text = "<no status message>"
+ if (listening.enabled && listening.text == "")
+ listening.text = "<nothing playing>"
+
+ if (info.protocol.locked)
+ status_name.text += " (locked)"
+
+
+ // ToolTips
+ nickname.toolTip = nickname.text
+ protocol.toolTip = protocol.text
+ status_icon.toolTip = status_name.toolTip = status_name.text
+ status_msg.toolTip = status_msg.text
+ listening_icon.toolTip = listening.toolTip = listening.text
+ next_proto.toolTip = "Show next protocol"
+ prev_proto.toolTip = "Show previous protocol"
+ email_icon.toolTip = email.toolTip = "Unread Email Count: " + email.text
+
+
+ // Borders
+ window.borders.left = opts.border_left
+ window.borders.top = opts.border_top
+ window.borders.right = opts.border_right
+ window.borders.bottom = opts.border_bottom
+
+
+ // Visible
+ nickname.visible = true
+ prev_proto.visible = next_proto.visible = opts.show_protocol_cycle && !IsEmpty(next_proto, prev_proto)
+ avatar.visible = opts.show_avatar && avatar.enabled && !IsEmpty(avatar)
+ protocol.visible = opts.show_protocol && protocol.enabled
+ status_icon.visible = status_name.visible = opts.show_status && status_name.enabled
+ status_msg.visible = opts.show_status_msg && !IsEmpty(status_msg)
+ listening_icon.visible = listening.visible = opts.show_listening && !IsEmpty(listening_icon, listening)
+ email_icon.visible = email.visible = opts.show_email && email.enabled && !IsEmpty(email_icon, email) && email.text > 0
+
+
+ // Space to draw the frame around
+ var BORDER_SPACE = 2
+ nickname.borders = BORDER_SPACE
+ protocol.borders = BORDER_SPACE
+ status_icon.borders = BORDER_SPACE
+ status_name.borders = BORDER_SPACE
+ status_msg.borders = BORDER_SPACE
+ listening_icon.borders = BORDER_SPACE
+ listening.borders = BORDER_SPACE
+ email_icon.borders = BORDER_SPACE
+ email.borders = BORDER_SPACE
+
+
+ if (avatar.visible)
+ {
+ if (opts.avatar_use_fixed_size)
+ resize(avatar, opts.avatar_fixed_size, opts.avatar_fixed_size, opts.avatar_allow_grow)
+ else
+ resize(avatar, window.width/2.5, window.height - (!info.resize_frame && prev_proto.visible ? prev_proto.height : 0), opts.avatar_allow_grow)
+ }
+
+ if (!info.resize_frame && prev_proto.visible)
+ {
+ prev_proto.left = 0
+ prev_proto.bottom = window.height
+
+ next_proto.right = window.width
+ next_proto.bottom = window.height
+ }
+
+ var avatar_bottom = avatar.bottom
+ if (opts.show_avatar && opts.avatar_use_fixed_size)
+ avatar_bottom = opts.avatar_fixed_size
+
+ var top = 0
+
+ if (opts.align_right)
+ {
+ // Align
+ nickname.hAlign = RIGHT
+ protocol.hAlign = RIGHT
+ status_name.hAlign = RIGHT
+ status_msg.hAlign = RIGHT
+ listening.hAlign = RIGHT
+
+
+ var right = window.right
+
+ function updateTopRight(val)
+ {
+ top = val
+ if (opts.use_under_avatar && top > avatar_bottom)
+ right = window.right
+ }
+
+ if (avatar.visible)
+ {
+ avatar.right = window.right
+ avatar.top = 0
+
+ right = avatar.left - 6
+ }
+
+ if (opts.show_avatar && opts.avatar_use_fixed_size)
+ right = window.right - opts.avatar_fixed_size - 6
+
+ nickname.right = right
+ nickname.top = top
+
+ updateTopRight(nickname.bottom)
+
+ if (protocol.visible)
+ {
+ protocol.right = right
+ protocol.top = top
+
+ if (email.visible)
+ {
+ email_icon.right = protocol.left - 10
+ email.right = email_icon.left
+
+ var bottom = valign_center(top, protocol, email_icon, email)
+ updateTopRight(bottom)
+ }
+ else
+ updateTopRight(protocol.bottom)
+ }
+ else if (email.visible)
+ {
+ email_icon.borders.left = 0
+ email_icon.right = right
+
+ email.right = email_icon.left
+
+ var bottom = valign_center(top, email_icon, email)
+ updateTopRight(bottom)
+ }
+
+ if (status_name.visible)
+ {
+ status_icon.right = right
+ status_name.right = status_icon.left
+
+ var bottom = valign_center(top, status_icon, status_name)
+ updateTopRight(bottom)
+ }
+
+ if (status_msg.visible)
+ {
+ status_msg.right = right
+ status_msg.top = top
+
+ updateTopRight(status_msg.bottom)
+ }
+
+ if (listening.visible)
+ {
+ listening_icon.borders.left = 0
+ listening_icon.right = right
+
+ listening.right = listening_icon.left
+
+ var bottom = valign_center(top, listening_icon, listening)
+ updateTopRight(bottom)
+ }
+ }
+ else
+ {
+ var left = 0
+
+ function updateTopLeft(val)
+ {
+ top = val
+ if (opts.use_under_avatar && top > avatar_bottom)
+ left = 0
+ }
+
+ if (avatar.visible)
+ {
+ avatar.left = 0
+ avatar.top = 0
+
+ left = avatar.right + 6
+ }
+
+ if (opts.show_avatar && opts.avatar_use_fixed_size)
+ left = opts.avatar_fixed_size + 6
+
+ nickname.left = left
+ nickname.top = top
+
+ updateTopLeft(nickname.bottom)
+
+ if (protocol.visible)
+ {
+ protocol.left = left
+ protocol.top = top
+
+ if (email.visible)
+ {
+ email_icon.left = protocol.right + 10
+ email.left = email_icon.right
+
+ var bottom = valign_center(top, protocol, email_icon, email)
+ updateTopLeft(bottom)
+ }
+ else
+ updateTopLeft(protocol.bottom)
+ }
+ else if (email.visible)
+ {
+ email_icon.borders.right = 0
+ email_icon.left = left
+
+ email.left = email_icon.right
+
+ var bottom = valign_center(top, email_icon, email)
+ updateTopLeft(bottom)
+ }
+
+ if (status_name.visible)
+ {
+ status_icon.left = left
+ status_name.left = status_icon.right
+
+ var bottom = valign_center(top, status_icon, status_name)
+ updateTopLeft(bottom)
+ }
+
+ if (status_msg.visible)
+ {
+ status_msg.left = left
+ status_msg.top = top
+
+ updateTopLeft(status_msg.bottom)
+ }
+
+ if (listening.visible)
+ {
+ listening_icon.borders.right = 0
+ listening_icon.left = left
+
+ listening.borders.left = 0
+ listening.left = listening_icon.right
+
+ var bottom = valign_center(top, listening_icon, listening)
+ updateTopLeft(bottom)
+ }
+ }
+
+ if (info.resize_frame)
+ {
+ if (prev_proto.visible)
+ {
+ top = Math.max(avatar.bottom, top)
+
+ prev_proto.left = 0
+ prev_proto.top = top
+
+ next_proto.right = window.width
+ next_proto.top = top
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/MyDetails/Docs/Skins/Pidgin/MyDetails.msk b/plugins/MyDetails/Docs/Skins/Pidgin/MyDetails.msk
new file mode 100644
index 0000000000..89295899f8
--- /dev/null
+++ b/plugins/MyDetails/Docs/Skins/Pidgin/MyDetails.msk
@@ -0,0 +1,59 @@
+function configure()
+{
+ // Default fonts
+
+ status_msg.font.face = "Tahoma"
+ status_msg.font.size = 8
+ status_msg.font.color = RGB(0,0,0)
+}
+
+function draw()
+{
+ if (status_msg.text == "")
+ status_msg.text = status_name.text
+
+ // ToolTips
+ status_icon.toolTip = protocol.text + " : " + status_name.text
+ if (info.protocol.locked)
+ status_icon.toolTip += " (locked)"
+ if (email.text > 0)
+ status_icon.toolTip += " [" + email.text + " emails]"
+
+ status_msg.toolTip = status_msg.text
+
+ // Borders
+ window.borders = 10
+
+ // Visible
+ status_msg.visible = true
+ avatar.visible = true
+ status_icon.visible = true
+
+ status_name.visible = false
+ protocol.visible = false
+ nickname.visible = false
+ prev_proto.visible = next_proto.visible = false
+ listening_icon.visible = listening.visible = false
+ email_icon.visible = email.visible = false
+
+ // Space to draw the frame around
+ var BORDER_SPACE = 2
+ status_icon.borders = BORDER_SPACE
+ status_msg.borders = BORDER_SPACE
+ status_name.borders = BORDER_SPACE
+
+ // Positions
+ var HEIGHT = 45
+
+ avatar.right = window.right
+ avatar.top = 0
+ avatar.width = HEIGHT
+ avatar.height = HEIGHT
+
+ status_icon.left = 0
+ status_icon.top = (HEIGHT - status_icon.height) / 2
+
+ status_msg.left = status_icon.right + 5
+ status_msg.top = (HEIGHT - status_msg.height) / 2
+ status_msg.right = avatar.left - 5
+}
diff --git a/plugins/MyDetails/Docs/langpack_MyDetails.txt b/plugins/MyDetails/Docs/langpack_MyDetails.txt
new file mode 100644
index 0000000000..01c61de1b4
--- /dev/null
+++ b/plugins/MyDetails/Docs/langpack_MyDetails.txt
@@ -0,0 +1,85 @@
+; My Details
+; Author: Pescuma
+; http://forums.miranda-im.org/showthread.php?t=5643
+
+[My Details]
+
+; Group in options
+[Customize]
+
+; Options
+
+[ General ]
+[Cycle through protocols every:]
+[seconds]
+[RTL]
+[Auto-resize frame]
+[Replace Smileys]
+[Align text to right]
+[Use contact lest smileys]
+[Resize Smileys]
+[Global on avatar]
+[Global on nickname]
+[Global on status]
+[Global on status message]
+
+[ Frame Options ]
+[Top:]
+[Bottom:]
+[Left:]
+[Right:]
+[Background Color:]
+
+[ Avatar ]
+[Custom size:]
+[pixels]
+[Allow it to grow]
+[Draw border on avatar]
+[Border Color:]
+[Round corners of avatars]
+[Custom corner size:]
+[Use free space (under avatar) to other texts]
+
+[ Protocol ]
+[Show protocol name]
+[Show protocol cycle button]
+
+
+; Default values
+[<no nickname>]
+[<no status name>]
+
+
+; Without multiwindows
+[Show My Details]
+[Hide My Details]
+
+
+; Menus
+[Set My Avatar...]
+[Set My Nickname...]
+[Set My Status Message...]
+[Set My Avatar for %s...]
+[Set My Nickname for %s...]
+[Set My Status Message for %s...]
+[Show next protocol]
+[Show previous protocol]
+[Cycle through protocols]
+[Don't cycle through protocols]
+
+
+; Dialogs
+[Set My Nickname]
+[Set My Nickname for %s]
+[Nickname:]
+
+[Set My Status Message for All Status]
+[Set My Status Message for %s]
+[Status Message:]
+
+[OK]
+[Cancel]
+
+; Clist Modern BAckground
+[Main Window/Backgrnd]
+[MyDetails/Backgrnd]
diff --git a/plugins/MyDetails/Docs/mydetails.gif b/plugins/MyDetails/Docs/mydetails.gif
new file mode 100644
index 0000000000..8e4d04e583
--- /dev/null
+++ b/plugins/MyDetails/Docs/mydetails.gif
Binary files differ
diff --git a/plugins/MyDetails/Docs/mydetails_changelog.txt b/plugins/MyDetails/Docs/mydetails_changelog.txt
new file mode 100644
index 0000000000..011a1c63b3
--- /dev/null
+++ b/plugins/MyDetails/Docs/mydetails_changelog.txt
@@ -0,0 +1,228 @@
+My Details
+
+Changelog:
+
+. 0.0.2.6
+ + Added support for clist modern skin engine
+ + Added pidgin style skin
+ * Fix for last shown protocol
+ * Updated updater to use googlecode
+
+. 0.0.2.5
+ + Use account name and ordering
+ * Better handling status messages
+ * Fix for jabber status names
+ * Bug fixes
+
+. 0.0.2.3
+ * Moved background color to font service settings
+ + Better simple away support
+
+. 0.0.2.2
+ * Fix for email count
+ * Better handling of hover
+ * Better handling of small sizes
+ * If fixed avatar size is set, use it even if no avatar present
+ + If windows uses RTL, it is selected by default
+
+. 0.0.2.1
+ + Show lock icon over status
+ + Show unread mail count
+ * Resize frame is working again
+ * Still work in progress
+
+. 0.0.2.0
+ + Now uses skins plugin to position elements (work in progress)
+
+. 0.0.1.11
+ * Fix for arrows: always draw then at right side
+
+. 0.0.1.10
+ + Added arrows to change protocols (Drugwash patch)
+ * Use icolib to show icons (uses listening to icon from contact list)
+
+. 0.0.1.9
+ + Created 2 services: MyDetails/HideFrame and MyDetails/ShowFrame
+ * MyDetails/ShowHideMyDetails changed to work with frames too (it toggles the frame)
+
+. 0.0.1.8
+ * Fix for crash when using main menu options
+
+. 0.0.1.7
+ * Fix for crash when no protocol found
+ + Added 2 keys to allow themes to show/hide frame: MyDetails\ForceHideFrame and MyDetails\ForceShowFrame (BYTE). Both are deleted after use.
+
+. 0.0.1.6
+ + Added uid for 0.8
+
+. 0.0.1.5:
+ + Added option to set status message per protocol
+
+. 0.0.1.4
+ * Fixed crash on protocol connection
+ + Support for new version of ersatz
+
+. 0.0.1.3
+ + Support for ersatz plugin by TioDuke. When it is finished, status message will be shown correctly always :)
+
+. 0.0.1.2
+ + Added listening to info
+
+. 0.0.1.1
+ * Fix for crash on exit (thanks ghazan)
+ - Removed clist modern mod support
+
+. 0.0.1.0
+ * Fix in call to NAS service
+ + Ready to FL
+
+. 0.0.0.42
+ * Fixed code to open only one dialog
+ + CTRL-Enter on status message dialog
+
+. 0.0.0.41
+ + Added support to new NAS services
+ + Open only one dialog (for dialogs that t handles - does not include NAS / avs)
+ * Bigger buffer for status messages
+ + First release build (dll is 200k smaller)
+
+. 0.0.0.40
+ * Changed text [Top: ] to [Top:]
+ + Added langpack_MyDetails.txt
+
+. 0.0.0.39
+ * Reverted to show menus on key up
+ + Using miranda lists now. This version only works with newer versions of miranda
+ * Fixed call to NAS with parsed variables
+
+. 0.0.0.38
+ * Fix for international languages
+ + Translateble options dialog
+ + Show some menus on key down (but it still not work as desired, i'll have to figure it)
+
+. 0.0.0.37
+ * Bugfix in status menu
+ + Better support for updater
+
+. 0.0.0.36
+ + Change to better support NAS
+ + Change to know when info changed (may flick a little less the screen and the tooltip, but may be losing changes)
+
+. 0.0.0.35
+ + Try to discover the default nick
+ + Global on avatar
+ * Fixed order of fields in options dialog
+
+. 0.0.0.34
+ * Fixed issue with mTooltip
+ + Changed tooltip timeout to 10h (is it long enougth? :P )
+
+. 0.0.0.33
+ + Added timer to refresh status messages. It isnt in options dialog, but can be changed at DB, in key MyDetails\RefreshStatusMessageTimer (0 disables it, default to 12 s)
+ * Fixed input box in set my nickname
+
+. 0.0.0.32
+ * Fix for crash on startup
+ * Fix for drawing function
+
+. 0.0.0.31
+ * Fix for status message with NAS
+
+. 0.0.0.30
+ * Try to fix bug when setting name (Again)
+ * Fix for multi line in status message and nickname
+ + Setting to call global functions on left click
+ + Calling service to get max nickname length from protocol (no proto support it right now)
+
+. 0.0.0.29
+ * Fix in status message code
+
+. 0.0.0.28
+ + Multiline popup
+ + More options in context menu
+ * Try to fix bug when setting name
+
+. 0.0.0.27
+ + Better support for core away system (it set the message in the DB, inside SRAway module)
+
+. 0.0.0.26
+ + Added tooltips
+ + Added background collor
+ + Added XStatus support
+ + Added in the zip: avatar service (unicode and non-unicode) and folder service
+
+. 0.0.0.25
+ + Added support to set avatars (needs modified version of avatar service - is inside zip)
+ + Added in the zip: avatar service and folder service
+
+. 0.0.0.23
+ * Bugfix in new status menu code
+
+. 0.0.0.22
+ + Using clist status menus when possible (this should add support to all away system always)
+ + Show global status menu on right click
+ * Fixed space in status
+
+. 0.0.0.21
+ * Bugfixes
+
+. 0.0.0.20
+ + Compatibility with KeepStatus -> code is too ugly :'(
+ + Show status messages only for supported statuses
+ + Show SimpleAway dialog only to supported protocols
+
+. 0.0.0.19
+ + Better support to SimpleAway
+ + Set what protocol to show by clicking in proto name
+ * Bug fixes
+
+. 0.0.0.18
+ + Set status message after status change (should work with gadu-gadu, but it isn't the best solution at all)
+
+. 0.0.0.17
+ + Popups with more actions
+ + Option to grow avatar
+ + An attempt to set status messages withou NAS
+
+. 0.0.0.16
+ * Fixed leak of GDI objects
+ * Fixed resizing of avatar
+
+. 0.0.0.15
+ * Bug fixes
+
+. 0.0.0.14
+ + Resize frame
+ + Use space bellow avatar
+
+. 0.0.0.13
+ - Change to try to get more updates from status message changes
+ * Fix in avatar refresh
+
+. 0.0.0.12
+ * Updater works
+ * Fix drawing protocol name
+
+. 0.0.0.11
+ * Fixed bug on drawing status name
+ + Added custom avatar size
+ + Will not cicle when changing status
+
+. 0.0.0.9
+ * Fixed crash on Set My Nickname from status menu
+ + Added cache to data (should draw faster, but have to see if the data shown is correct)
+ + Added visual things
+ + Option to set status
+ - Changed to set things with left click of mouse
+
+. 0.0.0.7
+ * Fix in NAS fetching code (again)
+
+. 0.0.0.6
+ * Fix in NAS fetching code
+ + RTL
+ + Smileys
+
+. 0.0.0.5
+ + Added option dialog
+ + Added option to not cicle throught protocols \ No newline at end of file
diff --git a/plugins/MyDetails/Docs/mydetails_readme.txt b/plugins/MyDetails/Docs/mydetails_readme.txt
new file mode 100644
index 0000000000..c9e58d0136
--- /dev/null
+++ b/plugins/MyDetails/Docs/mydetails_readme.txt
@@ -0,0 +1,41 @@
+My Details plugin
+-----------------
+
+What it does:
+- Show your current configuration, per protocol, for avatar, nickname, status and away message
+- It shows each protocol at a time, cicling throught then
+- Allows to set nickname (per protocol or for all protocols) and away messages (per protocol or for all protocols - need NewAwaySystem, SimpleAway or core module)
+
+Some comments:
+1. SimpleAway does not show a dialog to set a message for all protocols. Someones it does not show the dialog (I requested it in the thread http://forums.miranda-im.org/showthread.php?p=47157).
+2. For core away system, only some protocols works (probabily the same as SimpleAway). But for the ones that it works, the message in the frame is the old message. I know, it sucks... But if you use ersatz plugin this problem doesn't happen: http://pescuma.mirandaim.ru/miranda/ersatz.zip
+
+To request support to other away system: If someone wants to use another away system, please request in its thread to add support for 2 services:
+1. Get current status message for a protocol, given its name
+2. Set current status message for a protocol, given its name and the message
+
+
+To use skin engine of clist modern: the following glyphs are used:
+- MyDetails,ID=Background : background of frame
+- MyDetails,ID=MouseOver : base mouse over background (for all fields)
+- MyDetails,ID=MouseOverNick : base mouse over background for nick (drawn over the base one)
+- MyDetails,ID=MouseOverProto : base mouse over background for protocol (drawn over the base one)
+- MyDetails,ID=MouseOverStatus : base mouse over status name/icon for nick (drawn over the base one)
+- MyDetails,ID=MouseOverStatusMsg : base mouse over background for status message (drawn over the base one)
+- MyDetails,ID=MouseOverListening : base mouse over background for listening info (drawn over the base one)
+
+To report bugs/make suggestions, go to the forum thread: http://forums.miranda-im.org/showthread.php?t=5643
+
+Dependencies:
+- If you want integration with clist, an frame enabled clist, such as clist_modern or clist_nicer+
+- Away systens supported: Core, NewAwaySystem or SimpleAway
+
+Todo:
+- Global page
+- Add custom presets
+- Resize on mouse hover
+- clist_modern_layered integration -> try this: http://forums.miranda-im.org/showthread.php?t=6597
+- New drawing code (please, do not request things like order of items or spacing, it is in TODO list, but will take time to be made)
+- Options to XStatus setup
+- Icons instead of ... on mouse over
+- Options to show/hide itens
diff --git a/plugins/MyDetails/Docs/mydetails_version.txt b/plugins/MyDetails/Docs/mydetails_version.txt
new file mode 100644
index 0000000000..e078af1e48
--- /dev/null
+++ b/plugins/MyDetails/Docs/mydetails_version.txt
@@ -0,0 +1 @@
+My Details 0.0.2.6 \ No newline at end of file
diff --git a/plugins/MyDetails/commons.h b/plugins/MyDetails/commons.h
new file mode 100644
index 0000000000..ca1849c826
--- /dev/null
+++ b/plugins/MyDetails/commons.h
@@ -0,0 +1,148 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __COMMONS_H__
+# define __COMMONS_H__
+
+
+#define _WIN32_WINNT 0x0501
+#include <windows.h>
+#include <win2k.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <vector>
+
+#define MIRANDA_VER 0x800
+#include <newpluginapi.h>
+#include <m_clist.h>
+#include <m_skin.h>
+#include <m_system.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_database.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_awaymsg.h>
+#include <m_contacts.h>
+#include <m_options.h>
+#include <m_clui.h>
+#include <m_clc.h>
+#include <m_proto_listeningto.h>
+#include <m_listeningto.h>
+
+#include <m_NewAwaySys.h>
+#include <m_updater.h>
+#include <m_fontservice.h>
+#include <m_variables.h>
+#include <m_avatars.h>
+#include <m_statusplugins.h>
+#include <m_ersatz.h>
+#include <m_icq.h>
+#include <m_icolib.h>
+#include "m_cluiframes.h"
+#include "m_simpleaway.h"
+
+#include <richedit.h>
+#include <m_smileyadd.h>
+
+#include <io.h>
+
+#include "../skins/m_skins_cpp.h"
+
+#include "resource.h"
+
+
+#define MODULE_NAME "MyDetails"
+
+#define SETTING_FRAME_VISIBLE "FrameVisible"
+#define SETTING_DEFAULT_NICK "DefaultNick"
+
+
+extern HINSTANCE hInst;
+extern PLUGINLINK *pluginLink;
+
+extern long nickname_dialog_open;
+extern long status_msg_dialog_open;
+
+extern SkinDialog *dialog;
+
+
+#include "m_mydetails.h"
+#include "data.h"
+#include "options.h"
+#include "frame.h"
+#include "../utils/mir_smileys.h"
+#include "../utils/mir_memory.h"
+#include "../utils/mir_options.h"
+#include "../utils/mir_icons.h"
+#include "../utils/tstring.h"
+
+
+#define PS_SETMYAVATAR "/SetMyAvatar"
+#define PS_GETMYAVATAR "/GetMyAvatar"
+#define PS_GETMYAVATARMAXSIZE "/GetMyAvatarMaxSize"
+#define PS_GETUNREADEMAILCOUNT "/GetUnreadEmailCount"
+
+#define PS_SETMYNICKNAME "/SetNickname"
+
+#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength"
+
+#define WAYD_UNICODE 1 // return Unicode texts
+#if defined( _UNICODE )
+ #define WAYD_TCHAR WAYD_UNICODE
+#else
+ #define WAYD_TCHAR 0
+#endif
+
+// Get the max length that a WAYD message can have
+// wParam=(WPARAM)0
+// lParam=(LPARAM)0
+// Returns the max length
+#define PS_GET_MY_WAYD_MAXLENGTH "/GetMyWAYDMaxLength"
+
+// Get the WAYD message for the user
+// wParam=(WPARAM)WAYD_xxx
+// lParam=(LPARAM)0
+// Returns the text or NULL if there is none. Remember to mir_free the return value.
+#define PS_GET_MY_WAYD "/GetMyWAYD"
+
+// Sets the WAYD message for the user
+// wParam=(WPARAM)WAYD_xxx
+// lParam=(LPARAM)(WCHAR * or char *)The text to set
+// Returns 0 on success, nonzero on failure
+#define PS_SET_MY_WAYD "/SetMyWAYD"
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+// See if a protocol service exists
+__inline static int ProtoServiceExists(const char *szModule,const char *szService)
+{
+ char str[MAXMODULELABELLENGTH];
+ strcpy(str,szModule);
+ strcat(str,szService);
+ return ServiceExists(str);
+}
+
+
+
+
+
+#endif // __COMMONS_H__
diff --git a/plugins/MyDetails/data.cpp b/plugins/MyDetails/data.cpp
new file mode 100644
index 0000000000..eccd72e0e7
--- /dev/null
+++ b/plugins/MyDetails/data.cpp
@@ -0,0 +1,1063 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+#include "data.h"
+#include <algorithm>
+
+
+static char *StatusModeToDbSetting(int status,const char *suffix);
+
+
+static bool IsValid(const char *proto)
+{
+ if (proto == NULL || proto[0] == 0)
+ return false;
+
+ int caps = CallProtoService(proto, PS_GETCAPS, PFLAGNUM_1, 0);
+ return (caps & PF1_IM) == PF1_IM && strcmp(proto, "MetaContacts") != 0;
+}
+
+static bool AccOrderComp(PROTOACCOUNT *p1, PROTOACCOUNT *p2)
+{
+ return p1->iOrder < p2->iOrder;
+}
+
+static void GetAccounts(std::vector<PROTOACCOUNT *> *result)
+{
+ int count;
+ PROTOACCOUNT **protos;
+ ProtoEnumAccounts(&count, &protos);
+
+ for (int i = 0; i < count; i++)
+ {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (!IsAccountEnabled(protos[i]))
+ continue;
+
+ if (!IsValid(protos[i]->szModuleName))
+ continue;
+
+ result->push_back(protos[i]);
+ }
+
+ std::sort(result->begin(), result->begin(), AccOrderComp);
+}
+
+
+void GetProtocols(std::vector<Protocol> *result)
+{
+ std::vector<PROTOACCOUNT *> accs;
+ GetAccounts(&accs);
+
+ unsigned int accsSize = accs.size();
+ for (unsigned int i = 0; i < accsSize ; ++i)
+ result->push_back(Protocol(accs[i]->szModuleName));
+}
+
+
+int GetProtocolIndexByName(const char *moduleName)
+{
+ std::vector<PROTOACCOUNT *> protos;
+ GetAccounts(&protos);
+
+ int protosSize = (int) protos.size();
+ for(int i = 0; i < protosSize; ++i)
+ {
+ if (strcmp(protos[i]->szModuleName, moduleName) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+
+int GetNumProtocols()
+{
+ std::vector<PROTOACCOUNT *> protos;
+ GetAccounts(&protos);
+ return protos.size();
+}
+
+
+struct ProtoCache
+{
+ Protocol *proto;
+ int index;
+
+ void Free()
+ {
+ delete proto;
+ proto = NULL;
+ index = -1;
+ }
+};
+
+static ProtoCache current = { NULL, -1 };
+
+
+void SetCurrentProtocol(int index)
+{
+ current.Free();
+
+ int protosSize = GetNumProtocols();
+ if (protosSize > 0)
+ current.index = (index % protosSize + protosSize) % protosSize;
+
+ DBWriteContactSettingWord(NULL, "MyDetails", "ProtocolNumber", current.index);
+}
+
+Protocol * GetCurrentProtocol(bool createIfDontExist)
+{
+ if (createIfDontExist && current.index >= 0 && current.proto == NULL)
+ {
+ std::vector<PROTOACCOUNT *> protos;
+ GetAccounts(&protos);
+
+ int protosSize = protos.size();
+ if (current.index >= protosSize)
+ {
+ current.index = -1;
+ return NULL;
+ }
+
+ current.proto = new Protocol(protos[current.index]->szModuleName);
+ }
+
+ return current.proto;
+}
+
+int GetCurrentProtocolIndex()
+{
+ return current.index;
+}
+
+
+Protocol GetProtocolByIndex(int index)
+{
+ std::vector<PROTOACCOUNT *> protos;
+ GetAccounts(&protos);
+ int protosSize = protos.size();
+
+ if (protosSize < 1)
+ return Protocol(NULL);
+
+ index = (index % protosSize + protosSize) % protosSize;
+ return Protocol(protos[index]->szModuleName);
+}
+
+
+Protocol GetProtocolByName(const char *moduleName)
+{
+ std::vector<PROTOACCOUNT *> protos;
+ GetAccounts(&protos);
+
+ int protosSize = (int) protos.size();
+ for(int i = 0; i < protosSize; ++i)
+ {
+ if (strcmp(protos[i]->szModuleName, moduleName) == 0)
+ return Protocol(protos[i]->szModuleName);
+ }
+
+ return Protocol(NULL);
+}
+
+
+ProtocolArray *protocols = NULL;
+
+
+void InitProtocolData()
+{
+ protocols = new ProtocolArray();
+}
+
+
+void DeInitProtocolData()
+{
+ current.Free();
+
+ delete protocols;
+ protocols = NULL;
+}
+
+
+// Protocol Class ///////////////////////////////////////////////////////////////////////////////////////////
+
+
+Protocol::Protocol(const char *aName)
+{
+ if (aName)
+ name = aName;
+
+ avatar_bmp = NULL;
+ status = 0;
+ custom_status = 0;
+ locked = false;
+ emails = 0;
+
+ // Initial value
+ UpdateAll();
+}
+
+Protocol::~Protocol()
+{
+}
+
+
+bool Protocol::IsValid()
+{
+ return !name.empty();
+}
+
+
+Protocol::operator bool ()
+{
+ return IsValid();
+}
+
+
+void Protocol::UpdateAll()
+{
+ status_initialized = false;
+ status_message_initialized = false;
+ nickname_initialized = false;
+ avatar_initialized = false;
+ locked_initialized = false;
+ emails_initialized = false;
+ listening_to_initialized = false;
+}
+
+
+int Protocol::Call(const char *service, WPARAM wParam, LPARAM lParam)
+{
+ return CallProtoService(name.c_str(), service, wParam, lParam);
+}
+
+
+bool Protocol::CanCall(const char *service)
+{
+ return ProtoServiceExists(name.c_str(), service) != 0;
+}
+
+
+std::string Protocol::GetDBSettingString(const char *key, const char *def)
+{
+ std::string result = def;
+
+ DBVARIANT dbv;
+ if (!DBGetContactSettingTString(0, name.c_str(), key, &dbv))
+ {
+ if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0)
+ result = dbv.ptszVal;
+
+ DBFreeVariant(&dbv);
+ }
+
+ return result;
+}
+
+
+const char * Protocol::GetName()
+{
+ return name.c_str();
+}
+
+
+const char * Protocol::GetDescription()
+{
+ if (description.empty())
+ {
+ PROTOACCOUNT *acc = ProtoGetAccount(name.c_str());
+
+ if (acc == NULL || acc->tszAccountName == NULL || acc->tszAccountName[0] == 0)
+ {
+ char tmp[1024];
+ Call(PS_GETNAME, sizeof(tmp), (LPARAM) tmp);
+ description = tmp;
+ }
+ else
+ {
+ if (mir_is_unicode())
+ {
+ char *tmp = mir_u2a((const wchar_t *) acc->tszAccountName);
+ description = tmp;
+ mir_free(tmp);
+ }
+ else
+ {
+ description = acc->tszAccountName;
+ }
+ }
+ }
+
+ return description.c_str();
+}
+
+void Protocol::UpdateStatus()
+{
+ status_initialized = true;
+
+ status = Call(PS_GETSTATUS);
+
+ if (status > ID_STATUS_OFFLINE && CanCall(PS_ICQ_GETCUSTOMSTATUS))
+ {
+ char *name_key = NULL;
+ char *message_key = NULL;
+
+ custom_status = Call(PS_ICQ_GETCUSTOMSTATUS, (WPARAM) &name_key, (LPARAM) &message_key);
+
+ // Fix fo jabber, that returns 0xbaadf00d here
+ if (custom_status < 0)
+ custom_status = 0;
+
+ custom_status_name_key = (name_key ? name_key : "");
+ custom_status_message_key = (message_key ? message_key : "");
+ }
+ else
+ {
+ custom_status = 0;
+ custom_status_name_key = "";
+ custom_status_message_key = "";
+ }
+
+ if (custom_status == 0)
+ {
+ status_name = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, status, GCMDF_TCHAR);
+ }
+ else
+ {
+ status_name = "";
+
+ if (!custom_status_name_key.empty())
+ status_name = GetDBSettingString(custom_status_name_key.c_str());
+
+ if (!custom_status_message_key.empty())
+ {
+ std::string tmp = GetDBSettingString(custom_status_message_key.c_str());
+ if (!tmp.empty())
+ {
+ status_name += ": ";
+ status_name += tmp;
+ }
+ }
+ }
+
+ if (status_name.empty())
+ status_name = TranslateTS("<no status name>");
+}
+
+const char * Protocol::GetStatusName()
+{
+ if (!status_initialized)
+ UpdateStatus();
+
+ return status_name.c_str();
+}
+
+const char * Protocol::GetCustomStatusNameKey()
+{
+ if (!status_initialized)
+ UpdateStatus();
+
+ return custom_status_name_key.c_str();
+}
+
+const char * Protocol::GetCustomStatusMessageKey()
+{
+ if (!status_initialized)
+ UpdateStatus();
+
+ return custom_status_message_key.c_str();
+}
+
+int Protocol::GetStatus()
+{
+ if (!status_initialized)
+ UpdateStatus();
+
+ return status;
+}
+
+int Protocol::GetCustomStatus()
+{
+ if (!status_initialized)
+ UpdateStatus();
+
+ return custom_status;
+}
+
+
+void Protocol::SetStatus(int aStatus)
+{
+ char status_msg[256];
+
+ if (ServiceExists(MS_CS_SETSTATUSEX))
+ {
+ // :'(
+
+ // BEGIN From commomstatus.cpp (KeepStatus)
+ int i, count, pCount;
+ PROTOCOLDESCRIPTOR **protos;
+
+ pCount = 0;
+ CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&count,(LPARAM)&protos);
+ for(i=0;i<count;i++) {
+ if(protos[i]->type!=PROTOTYPE_PROTOCOL || CallProtoService(protos[i]->szName,PS_GETCAPS,PFLAGNUM_2,0)==0) continue;
+ pCount += 1;
+ }
+ // END From commomstatus.cpp (KeepStatus)
+
+
+ PROTOCOLSETTINGEX **pse = (PROTOCOLSETTINGEX **) mir_alloc0(pCount * sizeof(PROTOCOLSETTINGEX *));
+
+ for(i = 0; i < pCount; i++)
+ {
+ pse[i] = (PROTOCOLSETTINGEX *) mir_alloc0(sizeof(PROTOCOLSETTINGEX));
+ pse[i]->szName = "";
+ }
+
+ pse[0]->cbSize = sizeof(PROTOCOLSETTINGEX);
+ pse[0]->status = aStatus;
+ pse[0]->szName = (char *) name.c_str();
+
+ GetStatusMsg(aStatus, status_msg, sizeof(status_msg));
+ pse[0]->szMsg = status_msg;
+
+ CallService(MS_CS_SETSTATUSEX, (WPARAM) &pse, 0);
+
+ for(i = 0; i < pCount; i++)
+ mir_free(pse[i]);
+ mir_free(pse);
+ }
+ else
+ {
+ Call(PS_SETSTATUS, aStatus);
+
+ if (CanSetStatusMsg(aStatus))
+ {
+ char status_msg[MS_MYDETAILS_GETMYSTATUSMESSAGE_BUFFER_SIZE];
+ GetStatusMsg(aStatus, status_msg, sizeof(status_msg));
+ SetStatusMsg(aStatus, status_msg);
+ }
+ }
+}
+
+
+bool Protocol::CanGetStatusMsg()
+{
+ return CanGetStatusMsg(GetStatus());
+}
+
+bool Protocol::CanGetStatusMsg(int aStatus)
+{
+ return (Call(PS_GETCAPS, PFLAGNUM_1) & PF1_MODEMSGSEND) != 0
+ && (Call(PS_GETCAPS, (WPARAM)PFLAGNUM_3) & Proto_Status2Flag(aStatus));
+}
+
+
+bool Protocol::CanSetStatusMsg()
+{
+ return CanSetStatusMsg(GetStatus()) // <- Simple away handled by this one
+ || ServiceExists(MS_NAS_INVOKESTATUSWINDOW);
+
+}
+
+bool Protocol::CanSetStatusMsg(int aStatus)
+{
+ return CanGetStatusMsg(aStatus);
+}
+
+void Protocol::GetStatusMsg(int aStatus, char *msg, size_t msg_size)
+{
+ if (!CanGetStatusMsg())
+ {
+ lstrcpyn(msg, "", msg_size);
+ return;
+ }
+
+ bool isCurrentStatus = (aStatus == GetStatus());
+
+ if (isCurrentStatus && CanCall(PS_GETMYAWAYMSG))
+ {
+ char *tmp = (char *) Call(PS_GETMYAWAYMSG);
+ lstrcpyn(msg, tmp == NULL ? "" : tmp, msg_size);
+ }
+ else if (isCurrentStatus && ServiceExists(MS_SA_ISSARUNNING) && CallService(MS_SA_ISSARUNNING, 0, 0))
+ {
+ char *tmp = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) ID_STATUS_CURRENT, (LPARAM) name.c_str());
+
+ if (tmp != NULL)
+ {
+ lstrcpyn(msg, tmp, msg_size);
+ mir_free(tmp);
+ }
+ else lstrcpyn(msg, "", msg_size);
+
+ }
+ else if (ServiceExists(MS_NAS_GETSTATE))
+ {
+ NAS_PROTOINFO pi;
+
+ ZeroMemory(&pi, sizeof(pi));
+ pi.cbSize = sizeof(NAS_PROTOINFO);
+ pi.szProto = (char *) name.c_str();
+ pi.status = (isCurrentStatus ? 0 : aStatus);
+ pi.szMsg = NULL;
+
+ if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
+ {
+ if (pi.szMsg == NULL)
+ {
+ pi.szProto = NULL;
+
+ if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
+ {
+ if (pi.szMsg != NULL)
+ {
+ lstrcpyn(msg, pi.szMsg, msg_size);
+ mir_free(pi.szMsg);
+ }
+ else lstrcpyn(msg, "", msg_size);
+ }
+ else lstrcpyn(msg, "", msg_size);
+ }
+ else // if (pi.szMsg != NULL)
+ {
+ lstrcpyn(msg, pi.szMsg, msg_size);
+ mir_free(pi.szMsg);
+ }
+ }
+ else lstrcpyn(msg, "", msg_size);
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ char *tmp = variables_parse(msg, NULL, NULL);
+ lstrcpyn(msg, tmp, msg_size);
+ variables_free(tmp);
+ }
+ }
+ // TODO: Remove when removing old NAS services support
+ else if (ServiceExists("NewAwaySystem/GetState"))
+ {
+ NAS_PROTOINFO pi, *pii;
+
+ ZeroMemory(&pi, sizeof(pi));
+ pi.cbSize = sizeof(NAS_PROTOINFO);
+ pi.szProto = (char *) name.c_str();
+ pi.status = (isCurrentStatus ? 0 : aStatus);
+ pi.szMsg = NULL;
+
+ pii = &pi;
+
+ if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
+ {
+ if (pi.szMsg == NULL)
+ {
+ pi.szProto = NULL;
+
+ if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
+ {
+ if (pi.szMsg != NULL)
+ {
+ lstrcpyn(msg, pi.szMsg, msg_size);
+ mir_free(pi.szMsg);
+ }
+ else lstrcpyn(msg, "", msg_size);
+ }
+ else lstrcpyn(msg, "", msg_size);
+ }
+ else // if (pi.szMsg != NULL)
+ {
+ lstrcpyn(msg, pi.szMsg, msg_size);
+ mir_free(pi.szMsg);
+ }
+ }
+ else lstrcpyn(msg, "", msg_size);
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ char *tmp = variables_parse(msg, NULL, NULL);
+ lstrcpyn(msg, tmp, msg_size);
+ variables_free(tmp);
+ }
+ }
+ else if (ServiceExists(MS_AWAYMSG_GETSTATUSMSG))
+ {
+ char *tmp = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM)aStatus, 0);
+
+ if (tmp != NULL)
+ {
+ lstrcpyn(msg, tmp, msg_size);
+ mir_free(tmp);
+ }
+ else lstrcpyn(msg, "", msg_size);
+ }
+}
+
+void Protocol::UpdateStatusMsg()
+{
+ status_message_initialized = true;
+
+ TCHAR tmp[1024];
+ GetStatusMsg(GetStatus(), tmp, sizeof(tmp));
+
+ status_message = tmp;
+}
+
+const char * Protocol::GetStatusMsg()
+{
+ if (!status_message_initialized)
+ UpdateStatusMsg();
+
+ return status_message.c_str();
+}
+
+void Protocol::SetStatusMsg(const char *message)
+{
+ SetStatusMsg(GetStatus(), message);
+}
+
+void Protocol::SetStatusMsg(int aStatus, const char *message)
+{
+ if (!CanSetStatusMsg(aStatus))
+ return;
+
+ if (ServiceExists(MS_NAS_SETSTATE))
+ {
+ NAS_PROTOINFO pi = {0}, *pii;
+
+ pi.cbSize = sizeof(pi);
+ pi.szProto = (char *) name.c_str();
+ pi.szMsg = mir_strdup(message);
+ pi.status = aStatus;
+
+ pii = &pi;
+
+ CallService(MS_NAS_SETSTATE, (WPARAM) &pii, 1);
+ }
+ else
+ {
+ Call(PS_SETAWAYMSG, (WPARAM) aStatus, (LPARAM) message);
+ }
+}
+
+bool Protocol::HasAvatar()
+{
+ if (!avatar_initialized)
+ UpdateAvatar();
+
+ return avatar_bmp != NULL;
+}
+
+bool Protocol::CanGetAvatar()
+{
+ int caps = Call(PS_GETCAPS, PFLAGNUM_4);
+
+ if ((caps & PF4_AVATARS) == 0)
+ return false;
+
+ if (!ServiceExists(MS_AV_GETMYAVATAR))
+ return false;
+
+ return true;
+}
+
+void Protocol::UpdateAvatar()
+{
+ avatar_initialized = true;
+ avatar_file = "";
+ avatar_bmp = NULL;
+
+ // See if can get one
+ if (!CanGetAvatar())
+ return;
+
+ // Get HBITMAP from cache
+ AVATARCACHEENTRY *ace = (avatarCacheEntry *) CallService(MS_AV_GETMYAVATAR, 0, (LPARAM) name.c_str());
+ if (ace != NULL)
+ {
+ avatar_file = ace->szFilename;
+ avatar_bmp = ace->hbmPic;
+ }
+}
+
+const char * Protocol::GetAvatarFile()
+{
+ if (!avatar_initialized)
+ UpdateAvatar();
+
+ return avatar_file.c_str();
+}
+
+HBITMAP Protocol::GetAvatarImage()
+{
+ if (!avatar_initialized)
+ UpdateAvatar();
+
+ return avatar_bmp;
+}
+
+
+bool Protocol::CanGetNick()
+{
+ return ServiceExists(MS_CONTACT_GETCONTACTINFO) != FALSE;
+}
+
+int Protocol::GetNickMaxLength()
+{
+ if (CanCall(PS_GETMYNICKNAMEMAXLENGTH))
+ {
+ int ret = Call(PS_GETMYNICKNAMEMAXLENGTH);
+ if (ret <= 0)
+ ret = MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE;
+ return ret;
+ }
+ else
+ return MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE;
+}
+
+void Protocol::UpdateNick()
+{
+ nickname_initialized = true;
+ nickname = "";
+
+ // See if can get one
+ if (!CanGetNick())
+ return;
+
+ // Get it
+ CONTACTINFO ci;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = NULL;
+ ci.szProto = (char *) name.c_str();
+ ci.dwFlag = CNF_DISPLAY;
+
+#ifdef UNICODE
+ ci.dwFlag |= CNF_UNICODE;
+#endif
+
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci))
+ {
+ // CNF_DISPLAY always returns a string type
+ nickname = ci.pszVal;
+ mir_free(ci.pszVal);
+ }
+}
+
+const char * Protocol::GetNick()
+{
+ if (!nickname_initialized)
+ UpdateNick();
+
+ return nickname.c_str();
+}
+
+
+bool Protocol::CanSetNick()
+{
+ return CanCall(PS_SETMYNICKNAME) != 0;
+}
+
+
+void Protocol::SetNick(const char *nick)
+{
+ // See if can get one
+ if (!CanSetNick())
+ return;
+
+ if (nick == NULL)
+ return;
+
+ // Get it
+ Call(PS_SETMYNICKNAME, NULL, (LPARAM) nick);
+}
+
+
+bool Protocol::CanSetAvatar()
+{
+ return ServiceExists(MS_AV_SETMYAVATAR) != FALSE && ServiceExists(MS_AV_CANSETMYAVATAR) != FALSE &&
+ CallService(MS_AV_CANSETMYAVATAR, (WPARAM) name.c_str(), 0);
+}
+
+void Protocol::SetAvatar(const char *file_name)
+{
+ if (!CanSetAvatar())
+ return;
+
+ CallService(MS_AV_SETMYAVATAR, (WPARAM) name.c_str(), (LPARAM) file_name);
+}
+
+bool Protocol::CanGetListeningTo()
+{
+ return CanCall(PS_SET_LISTENINGTO) != 0;
+}
+
+bool Protocol::CanSetListeningTo()
+{
+ return CanGetListeningTo() && ServiceExists(MS_LISTENINGTO_ENABLE);
+}
+
+bool Protocol::ListeningToEnabled()
+{
+ return CanSetListeningTo() && CallService(MS_LISTENINGTO_ENABLED, (WPARAM) name.c_str(), 0) != 0;
+}
+
+void Protocol::UpdateListeningTo()
+{
+ listening_to_initialized = true;
+ listening_to = "";
+
+ if (!CanGetListeningTo())
+ return;
+
+ listening_to = GetDBSettingString("ListeningTo");
+}
+
+const char * Protocol::GetListeningTo()
+{
+ if (!listening_to_initialized)
+ UpdateListeningTo();
+
+ return listening_to.c_str();
+}
+
+void Protocol::UpdateLocked()
+{
+ locked_initialized = true;
+
+ locked = (DBGetContactSettingByte(NULL, name.c_str(), "LockMainStatus", 0) != 0);
+}
+
+bool Protocol::IsLocked()
+{
+ if (!locked_initialized)
+ UpdateLocked();
+
+ return locked;
+}
+
+bool Protocol::CanGetEmailCount()
+{
+ return CanCall(PS_GETUNREADEMAILCOUNT) != 0
+ && GetStatus() > ID_STATUS_OFFLINE;
+}
+
+void Protocol::UpdateEmailCount()
+{
+ emails_initialized = true;
+
+ if (!CanGetEmailCount())
+ emails = 0;
+ else
+ emails = max(0, Call(PS_GETUNREADEMAILCOUNT));
+}
+
+int Protocol::GetEmailCount()
+{
+ if (!emails_initialized)
+ UpdateEmailCount();
+
+ return emails;
+}
+
+
+// ProtocolDataArray Class /////////////////////////////////////////////////////////////////////////////
+
+
+ProtocolArray::ProtocolArray()
+{
+ GetDefaultNick();
+ GetDefaultAvatar();
+}
+
+int ProtocolArray::GetGlobalStatus()
+{
+ int status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
+ if (status == ID_STATUS_CONNECTING)
+ status = ID_STATUS_OFFLINE;
+
+ return status;
+}
+
+bool ProtocolArray::CanSetAvatars()
+{
+ return ServiceExists(MS_AV_SETMYAVATAR) != FALSE;
+}
+
+void ProtocolArray::SetAvatars(const char *file_name)
+{
+ if (!CanSetAvatars())
+ return;
+
+ CallService(MS_AV_SETMYAVATAR, NULL, (WPARAM) file_name);
+}
+
+
+void ProtocolArray::SetNicks(const char *nick)
+{
+ if (nick == NULL || nick[0] == '\0')
+ return;
+
+ lstrcpyn(default_nick, nick, sizeof(default_nick));
+
+ DBWriteContactSettingString(0, MODULE_NAME, SETTING_DEFAULT_NICK, nick);
+
+ std::vector<Protocol> protos;
+ GetProtocols(&protos);
+
+ unsigned int protosSize = protos.size();
+ for (int i = 0; i < protosSize; ++i)
+ protos[i].SetNick(default_nick);
+}
+
+
+void ProtocolArray::SetStatus(int aStatus)
+{
+ CallService(MS_CLIST_SETSTATUSMODE, aStatus, 0);
+}
+
+void ProtocolArray::SetStatusMsgs(const char *message)
+{
+ for (int i = ID_STATUS_OFFLINE ; i <= ID_STATUS_IDLE; i++)
+ {
+ SetStatusMsgs(i, message);
+ }
+}
+
+void ProtocolArray::SetStatusMsgs(int status, const char *message)
+{
+ DBWriteContactSettingString(NULL,"SRAway",StatusModeToDbSetting(status,"Msg"),message);
+ if (!DBGetContactSettingByte(NULL,"SRAway",StatusModeToDbSetting(status,"UsePrev"),0))
+ {
+ // Save default also
+ DBWriteContactSettingString(NULL,"SRAway",StatusModeToDbSetting(status,"Default"),message);
+ }
+
+ std::vector<Protocol> protos;
+ GetProtocols(&protos);
+
+ unsigned int protosSize = protos.size();
+ for (int i = 0; i < protosSize; ++i)
+ {
+ if (protos[i].GetStatus() == status)
+ protos[i].SetStatusMsg(status, message);
+ }
+}
+
+
+void ProtocolArray::GetDefaultNick()
+{
+ DBVARIANT dbv;
+
+ if (!DBGetContactSettingTString(0, MODULE_NAME, SETTING_DEFAULT_NICK, &dbv))
+ {
+ lstrcpyn(default_nick, dbv.pszVal, sizeof(default_nick));
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ default_nick[0] = '\0';
+ }
+}
+
+void ProtocolArray::GetDefaultAvatar()
+{
+ DBVARIANT dbv;
+
+ if (!DBGetContactSettingTString(0, "ContactPhoto", "File", &dbv))
+ {
+ lstrcpyn(default_avatar_file, dbv.pszVal, sizeof(default_avatar_file));
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ default_avatar_file[0] = '\0';
+ }
+}
+
+char * ProtocolArray::GetDefaultStatusMsg()
+{
+ return GetDefaultStatusMsg(CallService(MS_CLIST_GETSTATUSMODE, 0, 0));
+}
+
+char * ProtocolArray::GetDefaultStatusMsg(int status)
+{
+ default_status_message[0] = '\0';
+
+ if (ServiceExists(MS_AWAYMSG_GETSTATUSMSG))
+ {
+ if (status == ID_STATUS_CONNECTING)
+ {
+ status = ID_STATUS_OFFLINE;
+ }
+
+ char *tmp = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM)status, 0);
+
+ if (tmp != NULL)
+ {
+ lstrcpyn(default_status_message, tmp, sizeof(default_status_message));
+ mir_free(tmp);
+ }
+ }
+
+ return default_status_message;
+}
+
+bool ProtocolArray::CanSetListeningTo()
+{
+ return ServiceExists(MS_LISTENINGTO_ENABLE) != 0;
+}
+
+bool ProtocolArray::ListeningToEnabled()
+{
+ return CanSetListeningTo() && CallService(MS_LISTENINGTO_ENABLED, 0, 0) != 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+// Helper functions
+
+static char *StatusModeToDbSetting(int status,const char *suffix)
+{
+ char *prefix;
+ static char str[64];
+
+ switch(status) {
+ case ID_STATUS_AWAY: prefix="Away"; break;
+ case ID_STATUS_NA: prefix="Na"; break;
+ case ID_STATUS_DND: prefix="Dnd"; break;
+ case ID_STATUS_OCCUPIED: prefix="Occupied"; break;
+ case ID_STATUS_FREECHAT: prefix="FreeChat"; break;
+ case ID_STATUS_ONLINE: prefix="On"; break;
+ case ID_STATUS_OFFLINE: prefix="Off"; break;
+ case ID_STATUS_INVISIBLE: prefix="Inv"; break;
+ case ID_STATUS_ONTHEPHONE: prefix="Otp"; break;
+ case ID_STATUS_OUTTOLUNCH: prefix="Otl"; break;
+ case ID_STATUS_IDLE: prefix="Idl"; break;
+ default: return NULL;
+ }
+ lstrcpyA(str,prefix); lstrcatA(str,suffix);
+ return str;
+}
+
+
diff --git a/plugins/MyDetails/data.h b/plugins/MyDetails/data.h
new file mode 100644
index 0000000000..9c458b50dd
--- /dev/null
+++ b/plugins/MyDetails/data.h
@@ -0,0 +1,183 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __DATA_H__
+# define __DATA_H__
+
+
+//#include "protocol_config.h"
+
+class Protocol
+{
+ // Attributes ////////////
+ std::string name;
+
+ std::string description;
+
+ bool avatar_initialized;
+ std::string avatar_file;
+ HBITMAP avatar_bmp;
+
+ bool status_message_initialized;
+ std::string status_message;
+
+ bool nickname_initialized;
+ std::string nickname;
+
+ bool locked_initialized;
+ bool locked;
+
+ bool emails_initialized;
+ int emails;
+
+ bool listening_to_initialized;
+ std::string listening_to;
+
+ bool status_initialized;
+ std::string status_name;
+ std::string custom_status_name_key;
+ std::string custom_status_message_key;
+ int status;
+ int custom_status;
+
+public:
+ Protocol(const char *name);
+ ~Protocol();
+
+ bool IsValid();
+ operator bool ();
+
+ void UpdateAll();
+
+ const char * GetName();
+ const char * GetDescription();
+
+ const char * GetStatusName();
+ const char * GetCustomStatusNameKey();
+ const char * GetCustomStatusMessageKey();
+ int GetStatus();
+ int GetCustomStatus();
+ void SetStatus(int aStatus);
+
+ bool HasAvatar();
+ bool CanGetAvatar();
+ const char * GetAvatarFile();
+ HBITMAP GetAvatarImage();
+
+ bool CanSetAvatar();
+ void SetAvatar(const TCHAR *file_name);
+
+ bool CanGetNick();
+ const char * GetNick();
+ int GetNickMaxLength();
+ bool CanSetNick();
+ void SetNick(const TCHAR *nick);
+
+ bool CanGetListeningTo();
+ bool CanSetListeningTo();
+ bool ListeningToEnabled();
+ const char * GetListeningTo();
+
+ bool CanGetStatusMsg();
+ bool CanGetStatusMsg(int aStatus);
+ void GetStatusMsg(int aStatus, TCHAR *msg, size_t msg_size);
+ const char * GetStatusMsg();
+
+ bool CanSetStatusMsg();
+ bool CanSetStatusMsg(int aStatus);
+ void SetStatusMsg(const TCHAR *message);
+ void SetStatusMsg(int aStatus, const TCHAR *message);
+
+ bool IsLocked();
+
+ bool CanGetEmailCount();
+ int GetEmailCount();
+
+ int Call(const char *service, WPARAM wParam = 0, LPARAM lParam = 0);
+ bool CanCall(const char *service);
+
+ std::string GetDBSettingString(const char *key, const char *def = "");
+
+private:
+ void UpdateStatus();
+ void UpdateAvatar();
+ void UpdateNick();
+ void UpdateListeningTo();
+ void UpdateStatusMsg();
+ void UpdateLocked();
+ void UpdateEmailCount();
+};
+
+
+
+class ProtocolArray
+{
+public:
+ TCHAR default_nick[256];
+ TCHAR default_avatar_file[256];
+ TCHAR default_status_message[256];
+
+ // Methods ///////////////
+
+ ProtocolArray();
+
+ bool CanSetAvatars();
+ void SetAvatars(const TCHAR *file);
+
+ void SetNicks(const TCHAR *nick);
+
+ void SetStatus(int aStatus);
+
+ void SetStatusMsgs(const TCHAR *message);
+ void SetStatusMsgs(int status, const TCHAR *message);
+
+ int GetGlobalStatus();
+
+ void GetDefaultNick(); // Copy to cache
+ void GetDefaultAvatar(); // Copy to cache
+ TCHAR * GetDefaultStatusMsg(); // Copy to cache
+ TCHAR * GetDefaultStatusMsg(int status);
+
+ bool CanSetListeningTo();
+ bool ListeningToEnabled();
+};
+
+extern ProtocolArray *protocols;
+
+
+void SetCurrentProtocol(int index);
+Protocol * GetCurrentProtocol(bool createIfDontExist = true);
+int GetCurrentProtocolIndex();
+
+void GetProtocols(std::vector<Protocol> *result);
+int GetProtocolIndexByName(const char *moduleName);
+int GetNumProtocols();
+Protocol GetProtocolByIndex(int index);
+Protocol GetProtocolByName(const char *proto);
+
+void InitProtocolData();
+void DeInitProtocolData();
+
+
+
+
+
+
+#endif // __DATA_H__
diff --git a/plugins/MyDetails/frame.cpp b/plugins/MyDetails/frame.cpp
new file mode 100644
index 0000000000..d5b609a4e9
--- /dev/null
+++ b/plugins/MyDetails/frame.cpp
@@ -0,0 +1,2428 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+#include "frame.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include <m_skin_eng.h>
+
+
+// Prototypes /////////////////////////////////////////////////////////////////////////////////////
+
+
+#define WINDOW_NAME_PREFIX "mydetails_window"
+#define WINDOW_CLASS_NAME "MyDetailsFrame"
+#define CONTAINER_CLASS_NAME "MyDetailsFrameContainer"
+
+#define ID_FRAME_TIMER 1011
+#define ID_RECALC_TIMER 1012
+#define ID_STATUSMESSAGE_TIMER 1013
+
+#define RECALC_TIME 500
+
+#define IDC_HAND MAKEINTRESOURCE(32649)
+
+
+// Messages
+#define MWM_REFRESH (WM_USER+10)
+#define MWM_REFRESH_DATA (WM_USER+18)
+
+
+HWND hwnd_frame = NULL;
+HWND hwnd_container = NULL;
+
+int frame_id = -1;
+
+HANDLE hMenuShowHideFrame = 0;
+
+int CreateFrame();
+void FixMainMenu();
+void UpdateFrameData();
+void RedrawFrame();
+
+
+// used when no multiwindow functionality available
+BOOL MyDetailsFrameVisible();
+void SetMyDetailsFrameVisible(BOOL visible);
+int ShowHideMenuFunc(WPARAM wParam, LPARAM lParam);
+int ShowFrameFunc(WPARAM wParam, LPARAM lParam);
+int HideFrameFunc(WPARAM wParam, LPARAM lParam);
+int ShowHideFrameFunc(WPARAM wParam, LPARAM lParam);
+
+
+
+LRESULT CALLBACK FrameContainerWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK FrameWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+void SetCycleTime();
+void SetCycleTime(HWND hwnd);
+void SetStatusMessageRefreshTime();
+void SetStatusMessageRefreshTime(HWND hwnd);
+int SettingsChangedHook(WPARAM wParam, LPARAM lParam);
+int AvatarChangedHook(WPARAM wParam, LPARAM lParam);
+int ProtoAckHook(WPARAM wParam, LPARAM lParam);
+int SmileyAddOptionsChangedHook(WPARAM wParam,LPARAM lParam);
+int ListeningtoEnableStateChangedHook(WPARAM wParam,LPARAM lParam);
+int AccListChanged(WPARAM wParam, LPARAM lParam);
+
+
+void ExternalRect(RECT &ret, const RECT r1, const RECT r2);
+bool InsideRect(const POINT &p, const RECT &r);
+
+
+int operator==(const RECT& left, const RECT& right)
+{
+ return left.left == right.left && left.right == right.right
+ && left.top == right.top && left.bottom == right.bottom;
+}
+
+class ToolTipArea
+{
+public:
+ ToolTipArea() : hwndTT(0), hwndParent(0) { memset(&rc, 0, sizeof(rc)); }
+ ~ToolTipArea() { removeTooltip(); }
+
+ void createTooltip(HWND hwnd, const RECT &rc, const TCHAR *text)
+ {
+ if (text == NULL || text[0] == 0)
+ {
+ removeTooltip();
+ return;
+ }
+
+ this->text = text;
+
+ if (this->rc == rc && hwndParent == hwnd && hwndTT != NULL)
+ return;
+
+ removeTooltip();
+
+ this->rc = rc;
+ this->hwndParent = hwnd;
+ this->hwndTT = CreateTooltip(this->hwndParent, this->rc);
+ }
+
+ void removeTooltip()
+ {
+ if (hwndTT == NULL)
+ return;
+
+ DestroyWindow(hwndTT);
+ hwndTT = NULL;
+ hwndParent = NULL;
+ }
+
+ const TCHAR * getTextFor(HWND hwndFrom)
+ {
+ if (hwndTT == NULL || hwndTT != hwndFrom)
+ return NULL;
+ return text.c_str();
+ }
+
+
+private:
+
+ HWND hwndTT;
+ RECT rc;
+ HWND hwndParent;
+ std::tstring text;
+
+ HWND CreateTooltip(HWND hwnd, RECT &rect)
+ {
+ // struct specifying control classes to register
+ INITCOMMONCONTROLSEX iccex;
+ HWND hwndTT; // handle to the ToolTip control
+ // struct specifying info about tool in ToolTip control
+ TOOLINFO ti;
+ unsigned int uid = 0; // for ti initialization
+
+ // Load the ToolTip class from the DLL.
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_BAR_CLASSES;
+
+ if(!InitCommonControlsEx(&iccex))
+ return NULL;
+
+ /* CREATE A TOOLTIP WINDOW */
+ hwndTT = CreateWindowEx(WS_EX_TOPMOST,
+ TOOLTIPS_CLASS,
+ NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ hwnd,
+ NULL,
+ hInst,
+ NULL
+ );
+
+ /* Gives problem with mToolTip
+ SetWindowPos(hwndTT,
+ HWND_TOPMOST,
+ 0,
+ 0,
+ 0,
+ 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ */
+
+ /* INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE */
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = hwnd;
+ ti.hinst = hInst;
+ ti.uId = uid;
+ ti.lpszText = LPSTR_TEXTCALLBACK;
+ // ToolTip control will cover the whole window
+ ti.rect.left = rect.left;
+ ti.rect.top = rect.top;
+ ti.rect.right = rect.right;
+ ti.rect.bottom = rect.bottom;
+
+ /* SEND AN ADDTOOL MESSAGE TO THE TOOLTIP CONTROL WINDOW */
+ SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ SendMessage(hwndTT, TTM_SETDELAYTIME, (WPARAM) (DWORD) TTDT_AUTOPOP, (LPARAM) MAKELONG(24 * 60 * 60 * 1000, 0));
+
+ return hwndTT;
+ }
+};
+
+
+struct SimpleItem
+{
+ RECT rc;
+ bool draw;
+ bool mouseOver;
+ ToolTipArea tt;
+ bool alignRight;
+
+ SimpleItem() : draw(FALSE), mouseOver(FALSE), alignRight(FALSE)
+ {
+ memset(&rc, 0, sizeof(rc));
+ }
+ virtual ~SimpleItem() {}
+
+ virtual void hide()
+ {
+ draw = false;
+ mouseOver = false;
+ tt.removeTooltip();
+ }
+
+ virtual void update(HWND hwnd, SkinFieldState *item)
+ {
+ draw = item->isVisible();
+ alignRight = ( item->getHorizontalAlign() == SKN_HALIGN_RIGHT );
+
+ if (draw)
+ {
+ rc = item->getRect();
+ tt.createTooltip(hwnd, rc, item->getToolTip());
+ }
+ else
+ {
+ tt.removeTooltip();
+ }
+ }
+
+ virtual bool hitTest(const POINT &p)
+ {
+ return draw && InsideRect(p, rc);
+ }
+
+ virtual const TCHAR * getToolTipFor(HWND hwndFrom)
+ {
+ return tt.getTextFor(hwndFrom);
+ }
+
+ bool setMouseOver(POINT *mousePos)
+ {
+ bool over = (mousePos != NULL && hitTest(*mousePos));
+
+ if (mouseOver == over)
+ return FALSE;
+
+ mouseOver = over;
+ return TRUE;
+ }
+
+};
+
+struct IconAndItem : public SimpleItem
+{
+ RECT rcIcon;
+ RECT rcItem;
+ BOOL drawIcon;
+ BOOL drawItem;
+ ToolTipArea ttIcon;
+
+ IconAndItem() : drawIcon(FALSE), drawItem(FALSE)
+ {
+ memset(&rcIcon, 0, sizeof(rcIcon));
+ memset(&rcItem, 0, sizeof(rcItem));
+ }
+ virtual ~IconAndItem() {}
+
+ virtual void hide()
+ {
+ SimpleItem::hide();
+ drawIcon = FALSE;
+ drawItem = FALSE;
+ }
+
+ virtual void update(HWND hwnd, SkinIconFieldState *icon, SkinTextFieldState *item)
+ {
+ drawIcon = icon->isVisible();
+ drawItem = item->isVisible();
+ alignRight = ( item->getHorizontalAlign() == SKN_HALIGN_RIGHT );
+
+ draw = drawIcon || drawItem;
+ if (draw)
+ {
+ if (drawIcon)
+ rcIcon = icon->getRect();
+ if (drawItem)
+ rcItem = item->getRect();
+
+ if (drawIcon && drawItem)
+ ExternalRect(rc, rcIcon, rcItem);
+ else if (drawIcon)
+ rc = rcIcon;
+ else // if (drawItem)
+ rc = rcItem;
+ }
+
+ if (drawItem)
+ tt.createTooltip(hwnd, rcItem, item->getToolTip());
+ else
+ tt.removeTooltip();
+
+ if (drawIcon)
+ ttIcon.createTooltip(hwnd, rcIcon, icon->getToolTip());
+ else
+ ttIcon.removeTooltip();
+ }
+
+ virtual const TCHAR * getToolTipFor(HWND hwndFrom)
+ {
+ const TCHAR * ret = tt.getTextFor(hwndFrom);
+
+ if (ret == NULL)
+ ret = ttIcon.getTextFor(hwndFrom);
+
+ return ret;
+ }
+};
+
+
+struct MyDetailsFrameData
+{
+ std::vector<SimpleItem*> items;
+ SimpleItem proto;
+ SimpleItem proto_cycle_next;
+ SimpleItem proto_cycle_prev;
+ SimpleItem avatar;
+ SimpleItem nick;
+ IconAndItem status;
+ SimpleItem away_msg;
+ IconAndItem listening_to;
+ IconAndItem email;
+
+ bool showing_menu;
+
+ bool tracking_exit;
+
+ MyDetailsFrameData()
+ : showing_menu(false)
+ , tracking_exit(false)
+ {
+ items.push_back(&proto);
+ items.push_back(&proto_cycle_next);
+ items.push_back(&proto_cycle_prev);
+ items.push_back(&avatar);
+ items.push_back(&nick);
+ items.push_back(&status);
+ items.push_back(&away_msg);
+ items.push_back(&listening_to);
+ items.push_back(&email);
+ }
+};
+
+
+
+// Functions //////////////////////////////////////////////////////////////////////////////////////
+
+void InitFrames()
+{
+ InitContactListSmileys();
+
+ CreateFrame();
+
+ HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingsChangedHook);
+ HookEvent(ME_AV_MYAVATARCHANGED, AvatarChangedHook);
+ HookEvent(ME_PROTO_ACK, ProtoAckHook);
+ HookEvent(ME_SMILEYADD_OPTIONSCHANGED,SmileyAddOptionsChangedHook);
+ HookEvent(ME_LISTENINGTO_ENABLE_STATE_CHANGED,ListeningtoEnableStateChangedHook);
+ HookEvent(ME_PROTO_ACCLISTCHANGED, AccListChanged);
+}
+
+
+void DeInitFrames()
+{
+ if(ServiceExists(MS_CLIST_FRAMES_REMOVEFRAME) && frame_id != -1)
+ {
+ CallService(MS_CLIST_FRAMES_REMOVEFRAME, (WPARAM)frame_id, 0);
+ }
+
+ if (hwnd_frame != NULL) DestroyWindow(hwnd_frame);
+ if (hwnd_container != NULL) DestroyWindow(hwnd_container);
+}
+
+int SmileyAddOptionsChangedHook(WPARAM wParam,LPARAM lParam)
+{
+ UpdateFrameData();
+ return 0;
+}
+
+int SkinEngineDrawCallback(HWND hWnd, HDC hDC, RECT * rcPaint, HRGN rgn, DWORD dFlags, void * CallBackData);
+
+int CreateFrame()
+{
+ WNDCLASS wndclass;
+ wndclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; //CS_PARENTDC | CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = FrameWindowProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInst;
+ wndclass.hIcon = NULL;
+ wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wndclass.hbrBackground = 0; //(HBRUSH)(COLOR_3DFACE+1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = WINDOW_CLASS_NAME;
+ RegisterClass(&wndclass);
+
+ if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ {
+ hwnd_frame = CreateWindow(WINDOW_CLASS_NAME, Translate("My Details"),
+ WS_CHILD | WS_VISIBLE,
+ 0,0,10,10, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), NULL, hInst, NULL);
+
+ CLISTFrame Frame = {0};
+
+ Frame.cbSize = sizeof(Frame);
+ Frame.name = "My Details";
+ Frame.TBname = Translate("My Details");
+ Frame.hWnd = hwnd_frame;
+ Frame.align = alTop;
+ Frame.Flags = F_VISIBLE | F_SHOWTB | F_SHOWTBTIP | F_NOBORDER | F_NO_SUBCONTAINER;
+ Frame.height = 100;
+
+ frame_id = CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0);
+
+ if (ServiceExists(MS_SKINENG_REGISTERPAINTSUB))
+ {
+ CallService(MS_BACKGROUNDCONFIG_REGISTER,(WPARAM)"My Details Background/MyDetails", 0);
+ CallService(MS_SKINENG_REGISTERPAINTSUB, (WPARAM) Frame.hWnd, (LPARAM) SkinEngineDrawCallback);
+ }
+
+ if (DBGetContactSettingByte(NULL, "MyDetails", "ForceHideFrame", 0))
+ {
+ int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
+ if(flags & F_VISIBLE)
+ CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
+
+ DBDeleteContactSetting(NULL, "MyDetails", "ForceHideFrame");
+ }
+
+ if (DBGetContactSettingByte(NULL, "MyDetails", "ForceShowFrame", 0))
+ {
+ int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
+ if(!(flags & F_VISIBLE))
+ CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
+
+ DBDeleteContactSetting(NULL, "MyDetails", "ForceShowFrame");
+ }
+ }
+ else
+ {
+ wndclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;//CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = FrameContainerWindowProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInst;
+ wndclass.hIcon = NULL;
+ wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wndclass.hbrBackground = 0; //(HBRUSH)(COLOR_3DFACE+1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = CONTAINER_CLASS_NAME;
+ RegisterClass(&wndclass);
+
+ hwnd_container = CreateWindowEx(WS_EX_TOOLWINDOW, CONTAINER_CLASS_NAME, Translate("My Details"),
+ (WS_THICKFRAME | WS_CAPTION | WS_SYSMENU) & ~WS_VISIBLE,
+ 0,0,200,130, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), NULL, hInst, NULL);
+
+ hwnd_frame = CreateWindow(WINDOW_CLASS_NAME, Translate("My Details"),
+ WS_CHILD | WS_VISIBLE,
+ 0,0,10,10, hwnd_container, NULL, hInst, NULL);
+
+ SetWindowLong(hwnd_container, GWL_USERDATA, (LONG)hwnd_frame);
+ SendMessage(hwnd_container, WM_SIZE, 0, 0);
+
+ // Create menu item
+
+ CLISTMENUITEM menu = {0};
+
+ menu.cbSize=sizeof(menu);
+ menu.flags = CMIM_ALL;
+ menu.popupPosition = -0x7FFFFFFF;
+ menu.pszPopupName = Translate("My Details");
+ menu.position = 1; // 500010000
+ menu.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ menu.pszName = Translate("Show My Details");
+ menu.pszService= MODULE_NAME "/ShowHideMyDetails";
+ hMenuShowHideFrame = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menu);
+
+ if(DBGetContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 1) == 1)
+ {
+ ShowWindow(hwnd_container, SW_SHOW);
+ FixMainMenu();
+ }
+ }
+
+ CreateServiceFunction(MS_MYDETAILS_SHOWFRAME, ShowFrameFunc);
+ CreateServiceFunction(MS_MYDETAILS_HIDEFRAME, HideFrameFunc);
+ CreateServiceFunction(MS_MYDETAILS_SHOWHIDEFRAME, ShowHideFrameFunc);
+
+ return 0;
+}
+
+
+BOOL FrameIsFloating()
+{
+ if (frame_id == -1)
+ {
+ return true; // no frames, always floating
+ }
+
+ return (CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLOATING, frame_id), 0) != 0);
+}
+
+
+LRESULT CALLBACK FrameContainerWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ switch(msg)
+ {
+ case WM_SHOWWINDOW:
+ {
+ if ((BOOL)wParam)
+ Utils_RestoreWindowPosition(hwnd, 0, MODULE_NAME, WINDOW_NAME_PREFIX);
+ else
+ Utils_SaveWindowPosition(hwnd, 0, MODULE_NAME, WINDOW_NAME_PREFIX);
+ break;
+ }
+
+ case WM_ERASEBKGND:
+ {
+ HWND child = (HWND)GetWindowLong(hwnd, GWL_USERDATA);
+
+ SendMessage(child, WM_ERASEBKGND, wParam, lParam);
+ break;
+ }
+
+ case WM_SIZE:
+ {
+ HWND child = (HWND)GetWindowLong(hwnd, GWL_USERDATA);
+ RECT r;
+ GetClientRect(hwnd, &r);
+
+ SetWindowPos(child, 0, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
+ InvalidateRect(child, NULL, TRUE);
+
+ return TRUE;
+ }
+
+ case WM_CLOSE:
+ {
+ DBWriteContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 0);
+ ShowWindow(hwnd, SW_HIDE);
+ FixMainMenu();
+ return TRUE;
+ }
+ }
+
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+
+
+BOOL ScreenToClient(HWND hWnd, LPRECT lpRect)
+{
+ BOOL ret;
+
+ POINT pt;
+
+ pt.x = lpRect->left;
+ pt.y = lpRect->top;
+
+ ret = ScreenToClient(hWnd, &pt);
+
+ if (!ret) return ret;
+
+ lpRect->left = pt.x;
+ lpRect->top = pt.y;
+
+
+ pt.x = lpRect->right;
+ pt.y = lpRect->bottom;
+
+ ret = ScreenToClient(hWnd, &pt);
+
+ lpRect->right = pt.x;
+ lpRect->bottom = pt.y;
+
+ return ret;
+}
+
+
+BOOL MoveWindow(HWND hWnd, const RECT &rect, BOOL bRepaint)
+{
+ return MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, bRepaint);
+}
+
+
+RECT GetInnerRect(const RECT &rc, const RECT &clipping)
+{
+ RECT rc_ret = rc;
+
+ rc_ret.left = max(rc.left, clipping.left);
+ rc_ret.top = max(rc.top, clipping.top);
+ rc_ret.right = min(rc.right, clipping.right);
+ rc_ret.bottom = min(rc.bottom, clipping.bottom);
+
+ return rc_ret;
+}
+
+
+
+
+
+void ExternalRect(RECT &ret, const RECT r1, const RECT r2)
+{
+ ret.left = min(r1.left, r2.left);
+ ret.right = max(r1.right, r2.right);
+ ret.top = min(r1.top, r2.top);
+ ret.bottom = max(r1.bottom, r2.bottom);
+}
+
+
+HBITMAP CreateBitmap32(int cx, int cy)
+{
+ BITMAPINFO RGB32BitsBITMAPINFO;
+ UINT * ptPixels;
+ HBITMAP DirectBitmap;
+
+ ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
+ RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ RGB32BitsBITMAPINFO.bmiHeader.biWidth=cx;//bm.bmWidth;
+ RGB32BitsBITMAPINFO.bmiHeader.biHeight=cy;//bm.bmHeight;
+ RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;
+ RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;
+
+ DirectBitmap = CreateDIBSection(NULL,
+ (BITMAPINFO *)&RGB32BitsBITMAPINFO,
+ DIB_RGB_COLORS,
+ (void **)&ptPixels,
+ NULL, 0);
+ return DirectBitmap;
+}
+
+
+BOOL UseLayeredMode()
+{
+ return isLayeredEnabled() && !FrameIsFloating();
+}
+
+
+void EraseBackground(HWND hwnd, HDC hdc)
+{
+ RECT r;
+ GetClientRect(hwnd, &r);
+
+ if (isSkinEngineEnabled())
+ {
+ if (FrameIsFloating())
+ {
+ HBRUSH hB = CreateSolidBrush(opts.bkg_color);
+ FillRect(hdc, &r, hB);
+ DeleteObject(hB);
+ }
+ else
+ {
+ SkinDrawWindowBack(hwnd, hdc, &r, "Main,ID=Background");
+ }
+
+ SkinDrawGlyph(hdc, &r, &r,"MyDetails,ID=Background");
+ }
+ else
+ {
+ HBRUSH hB = CreateSolidBrush(opts.bkg_color);
+ FillRect(hdc, &r, hB);
+ DeleteObject(hB);
+ }
+}
+
+static int Width(const RECT &rc)
+{
+ return rc.right - rc.left;
+}
+
+static int Height(const RECT &rc)
+{
+ return rc.bottom - rc.top;
+}
+
+static HICON CreateOverlayedIcon(HICON icon, HICON overlay)
+{
+ HIMAGELIST il = ImageList_Create(
+ GetSystemMetrics(SM_CXICON),
+ GetSystemMetrics(SM_CYICON),
+ ILC_COLOR32|ILC_MASK, 2, 2);
+ ImageList_AddIcon(il, icon);
+ ImageList_AddIcon(il, overlay);
+ HIMAGELIST newImage = ImageList_Merge(il,0,il,1,0,0);
+ ImageList_Destroy(il);
+ HICON hIcon = ImageList_GetIcon(newImage, 0, 0);
+ ImageList_Destroy(newImage);
+ return hIcon; // the result should be destroyed by DestroyIcon()
+}
+
+void Draw(HDC hdc, SkinIconFieldState &state)
+{
+ if (!state.isVisible())
+ return;
+
+ RECT rc = state.getInsideRect();
+ HRGN rgn = CreateRectRgnIndirect(&rc);
+ SelectClipRgn(hdc, rgn);
+
+ rc = state.getInsideRect(true);
+
+ skin_DrawIconEx(hdc, rc.left, rc.top, state.getIcon(), Width(rc), Height(rc), 0, NULL, DI_NORMAL);
+
+ SelectClipRgn(hdc, NULL);
+ DeleteObject(rgn);
+}
+
+void Draw(HDC hdc, SkinTextFieldState &state, BOOL replace_smileys = FALSE, const char *protocol = NULL)
+{
+ if (!state.isVisible())
+ return;
+
+ RECT rc = state.getInsideRect();
+ HRGN rgn = CreateRectRgnIndirect(&rc);
+ SelectClipRgn(hdc, rgn);
+
+ HGDIOBJ oldFont = SelectObject(hdc, state.getFont());
+ COLORREF oldColor = SetTextColor(hdc, state.getFontColor());
+
+ UINT uFormat = DT_NOPREFIX | DT_END_ELLIPSIS | (opts.draw_text_rtl ? DT_RTLREADING : 0);
+
+ switch(state.getHorizontalAlign())
+ {
+ case SKN_HALIGN_RIGHT:
+ uFormat |= DT_RIGHT;
+ break;
+ case SKN_HALIGN_CENTER:
+ uFormat |= DT_CENTER;
+ break;
+ case SKN_HALIGN_LEFT:
+ uFormat |= DT_LEFT;
+ break;
+ }
+
+ if (replace_smileys && opts.replace_smileys)
+ {
+ uFormat |= DT_SINGLELINE;
+
+ // Draw only first line of text
+ char *tmp = strdup(state.getText());
+ char *pos = strchr(tmp, '\r');
+ if (pos != NULL)
+ pos[0] = '\0';
+ pos = strchr(tmp, '\n');
+ if (pos != NULL)
+ pos[0] = '\0';
+
+ Smileys_DrawText(hdc, tmp, -1, &rc, uFormat | (opts.resize_smileys ? DT_RESIZE_SMILEYS : 0),
+ opts.use_contact_list_smileys ? "clist" : protocol, NULL);
+ }
+ else
+ {
+ skin_DrawText(hdc, state.getText(), -1, &rc, uFormat);
+ }
+
+
+ SelectObject(hdc, oldFont);
+ SetTextColor(hdc, oldColor);
+
+ SelectClipRgn(hdc, NULL);
+ DeleteObject(rgn);
+}
+
+
+void DrawMouseOver(HDC hdc, RECT *lprc, const char *place)
+{
+ if (isSkinEngineEnabled())
+ {
+ SkinDrawGlyph(hdc, lprc, lprc, "MyDetails,ID=MouseOver");
+
+ char glyph[1024];
+ mir_snprintf(glyph, MAX_REGS(glyph), "MyDetails,ID=MouseOver%s", place);
+ SkinDrawGlyph(hdc, lprc, lprc, glyph);
+ }
+ else
+ {
+ FrameRect(hdc, lprc, (HBRUSH) GetStockObject(GRAY_BRUSH));
+ }
+}
+
+
+void Draw(HWND hwnd, HDC hdc_orig)
+{
+ MyDetailsFrameData *data = (MyDetailsFrameData *) GetWindowLong(hwnd, GWL_USERDATA);
+
+ Protocol *proto = GetCurrentProtocol();
+ if (proto == NULL)
+ {
+ EraseBackground(hwnd, hdc_orig);
+ return;
+ }
+
+ if (ServiceExists(MS_CLIST_FRAMES_SETFRAMEOPTIONS) && frame_id != -1)
+ {
+ int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
+ if(flags & F_UNCOLLAPSED)
+ {
+ RECT rf;
+ GetClientRect(hwnd, &rf);
+
+ if (rf.bottom - rf.top != 0)
+ {
+ if (FrameIsFloating())
+ {
+ HWND parent = GetParent(hwnd);
+
+ if (parent != NULL)
+ {
+ RECT rp_client, rp_window, r_window;
+ GetClientRect(parent, &rp_client);
+ GetWindowRect(parent, &rp_window);
+ GetWindowRect(hwnd, &r_window);
+ int diff = (rp_window.bottom - rp_window.top) - (rp_client.bottom - rp_client.top);
+ if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ diff += (r_window.top - rp_window.top);
+
+ SetWindowPos(parent, 0, 0, 0, rp_window.right - rp_window.left, diff, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
+ }
+ }
+ }
+
+ for (size_t i = 0; i < data->items.size(); ++i)
+ data->items[i]->hide();
+
+ return;
+ }
+ }
+
+
+ RECT r_full;
+ GetClientRect(hwnd, &r_full);
+
+ HDC hdc;
+ HBITMAP hBmp;
+ BOOL useLayeredMode = UseLayeredMode();
+ if (useLayeredMode)
+ {
+ hdc = hdc_orig;
+ hBmp = NULL;
+ }
+ else
+ {
+ hdc = CreateCompatibleDC(hdc_orig);
+ hBmp = CreateBitmap32(Width(r_full), Height(r_full));
+ SelectObject(hdc, hBmp);
+ }
+
+ int old_bk_mode = SetBkMode(hdc, TRANSPARENT);
+ HFONT old_font = (HFONT) GetCurrentObject(hdc, OBJ_FONT);
+ COLORREF old_color = GetTextColor(hdc);
+ SetStretchBltMode(hdc, HALFTONE);
+
+
+ HICON hStatusIcon;
+ bool freeStatusIcon = false;
+ if (proto->GetCustomStatus() != 0 && proto->CanCall(PS_ICQ_GETCUSTOMSTATUSICON))
+ hStatusIcon = (HICON) proto->Call(PS_ICQ_GETCUSTOMSTATUSICON, proto->GetCustomStatus(), LR_SHARED);
+ else
+ hStatusIcon = LoadSkinnedProtoIcon(proto->GetName(), proto->GetStatus());
+
+ if (proto->IsLocked())
+ {
+ HICON hLockOverlay = LoadSkinnedIcon(SKINICON_OTHER_STATUS_LOCKED);
+ if (hLockOverlay != NULL)
+ {
+ freeStatusIcon = true;
+ hStatusIcon = CreateOverlayedIcon(hStatusIcon, hLockOverlay);
+ }
+ }
+
+
+ HICON hListeningIcon = IcoLib_LoadIcon("LISTENING_TO_ICON");
+ HICON hEmailIcon = IcoLib_LoadIcon("MYDETAILS_EMAIL");
+ HICON hNextIcon = IcoLib_LoadIcon("MYDETAILS_NEXT_PROTOCOL");
+ HICON hPrevIcon = IcoLib_LoadIcon("MYDETAILS_PREV_PROTOCOL");
+
+ {
+ dialog->setInfoBool("resize_frame", opts.resize_frame);
+ dialog->setInfoBool("protocol.locked", proto->IsLocked());
+
+
+ if (opts.resize_frame)
+ dialog->setSize(Width(r_full), 0x1FFFFFFF);
+ else
+ dialog->setSize(Width(r_full), Height(r_full));
+
+
+
+ SkinImageField avatar = dialog->getImageField("avatar");
+ if (proto->CanGetAvatar() && proto->GetAvatarImage() != NULL)
+ {
+ avatar.setEnabled(TRUE);
+ avatar.setImage(proto->GetAvatarImage());
+ }
+ else
+ {
+ avatar.setEnabled(FALSE);
+ avatar.setImage(NULL);
+ }
+
+ SkinTextField nickname = dialog->getTextField("nickname");
+ nickname.setText(proto->GetNick());
+
+ SkinTextField protocol = dialog->getTextField("protocol");
+ protocol.setText(proto->GetDescription());
+
+ SkinIconField status_icon = dialog->getIconField("status_icon");
+ status_icon.setIcon(hStatusIcon);
+
+ SkinTextField status_name = dialog->getTextField("status_name");
+ status_name.setText(proto->GetStatusName());
+
+ SkinTextField status_msg = dialog->getTextField("status_msg");
+ if (proto->CanGetStatusMsg())
+ {
+ status_msg.setEnabled(TRUE);
+ status_msg.setText(proto->GetStatusMsg());
+ }
+ else
+ {
+ status_msg.setEnabled(FALSE);
+ status_msg.setText(_T(""));
+ }
+
+ SkinIconField listening_icon = dialog->getIconField("listening_icon");
+ SkinTextField listening = dialog->getTextField("listening");
+ if (proto->ListeningToEnabled() && proto->GetStatus() > ID_STATUS_OFFLINE
+ && proto->GetListeningTo()[0] != 0)
+ {
+ listening_icon.setEnabled(TRUE);
+ listening.setEnabled(TRUE);
+ listening_icon.setIcon(hListeningIcon);
+ listening.setText(proto->GetListeningTo());
+ }
+ else
+ {
+ listening_icon.setEnabled(FALSE);
+ listening.setEnabled(FALSE);
+ listening_icon.setIcon(NULL);
+ listening.setText(_T(""));
+ }
+
+ SkinIconField email_icon = dialog->getIconField("email_icon");
+ SkinTextField email = dialog->getTextField("email");
+ if (proto->CanGetEmailCount())
+ {
+ email_icon.setEnabled(TRUE);
+ email.setEnabled(TRUE);
+ email_icon.setIcon(hEmailIcon);
+
+ TCHAR tmp[64];
+ _sntprintf(tmp, MAX_REGS(tmp), _T("%d"), proto->GetEmailCount());
+ email.setText(tmp);
+ }
+ else
+ {
+ email_icon.setEnabled(FALSE);
+ email.setEnabled(FALSE);
+ email_icon.setIcon(NULL);
+ email.setText(_T(""));
+ }
+
+ SkinIconField next_proto = dialog->getIconField("next_proto");
+ SkinIconField prev_proto = dialog->getIconField("prev_proto");
+ prev_proto.setIcon(hPrevIcon);
+ next_proto.setIcon(hNextIcon);
+ }
+
+ SkinDialogState state = dialog->run();
+ SkinImageFieldState avatar = state.getImageField("avatar");
+ SkinTextFieldState nickname = state.getTextField("nickname");
+ SkinTextFieldState protocol = state.getTextField("protocol");
+ SkinIconFieldState status_icon = state.getIconField("status_icon");
+ SkinTextFieldState status_name = state.getTextField("status_name");
+ SkinTextFieldState status_msg = state.getTextField("status_msg");
+ SkinIconFieldState listening_icon = state.getIconField("listening_icon");
+ SkinTextFieldState listening = state.getTextField("listening");
+ SkinIconFieldState email_icon = state.getIconField("email_icon");
+ SkinTextFieldState email = state.getTextField("email");
+ SkinIconFieldState next_proto = state.getIconField("next_proto");
+ SkinIconFieldState prev_proto = state.getIconField("prev_proto");
+
+
+ {
+ data->proto.update(hwnd, &protocol);
+ data->proto_cycle_next.update(hwnd, &next_proto);
+ data->proto_cycle_prev.update(hwnd, &prev_proto);
+ data->avatar.update(hwnd, &avatar);
+ data->nick.update(hwnd, &nickname);
+ data->status.update(hwnd, &status_icon, &status_name);
+ data->away_msg.update(hwnd, &status_msg);
+ data->listening_to.update(hwnd, &listening_icon, &listening);
+ data->email.update(hwnd, &email_icon, &email);
+
+
+ POINT p = {0};
+ GetCursorPos(&p);
+ ScreenToClient(hwnd, &p);
+
+ for(size_t i = 0; i < data->items.size(); ++i)
+ data->items[i]->setMouseOver(&p);
+ }
+
+ // Erase
+ EraseBackground(hwnd, hdc);
+
+ // Draw items
+
+ UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS
+ | (opts.draw_text_rtl ? DT_RTLREADING : 0);
+
+ // Image
+ if (avatar.isVisible() && proto->CanGetAvatar() && proto->GetAvatarImage() != NULL)
+ {
+ RECT rc = avatar.getInsideRect();
+ HRGN rgn = CreateRectRgnIndirect(&rc);
+ SelectClipRgn(hdc, rgn);
+
+ rc = avatar.getInsideRect(true);
+
+ int width = Width(rc);
+ int height = Height(rc);
+
+ int round_radius;
+ if (opts.draw_avatar_round_corner)
+ {
+ if (opts.draw_avatar_use_custom_corner_size)
+ round_radius = opts.draw_avatar_custom_corner_size;
+ else
+ round_radius = min(width, height) / 6;
+ }
+ else
+ {
+ round_radius = 0;
+ }
+
+
+ AVATARDRAWREQUEST adr = {0};
+
+ adr.cbSize = sizeof(AVATARDRAWREQUEST);
+ adr.hTargetDC = hdc;
+ adr.rcDraw = rc;
+
+ adr.dwFlags = AVDRQ_OWNPIC | AVDRQ_HIDEBORDERONTRANSPARENCY |
+ (opts.draw_avatar_border ? AVDRQ_DRAWBORDER : 0 ) |
+ (opts.draw_avatar_round_corner ? AVDRQ_ROUNDEDCORNER : 0 );
+
+ if (useLayeredMode)
+ adr.dwFlags |= AVDRQ_AERO;
+
+ adr.clrBorder = opts.draw_avatar_border_color;
+ adr.radius = round_radius;
+ adr.alpha = 255;
+ adr.szProto = (char *) proto->GetName();
+
+ CallService(MS_AV_DRAWAVATAR, 0, (LPARAM) &adr);
+
+ // Clipping rgn
+ SelectClipRgn(hdc, NULL);
+ DeleteObject(rgn);
+ }
+
+ // Nick
+ if (data->nick.draw && data->nick.mouseOver && proto->CanSetNick())
+ DrawMouseOver(hdc, &nickname.getRect(), "Nick");
+
+ Draw(hdc, nickname, TRUE, proto->GetName());
+
+
+ // Protocol
+ if (data->proto.draw && data->proto.mouseOver)
+ DrawMouseOver(hdc, &data->proto.rc, "Proto");
+
+ Draw(hdc, protocol);
+
+
+ // Status
+ if (data->status.draw && data->status.mouseOver)
+ DrawMouseOver(hdc, &data->status.rc, "Status");
+
+ Draw(hdc, status_icon);
+ Draw(hdc, status_name);
+
+
+ // Away message
+ if (data->away_msg.draw && data->away_msg.mouseOver && proto->CanSetStatusMsg())
+ DrawMouseOver(hdc, &data->away_msg.rc, "StatusMsg");
+
+ Draw(hdc, status_msg, TRUE, proto->GetName());
+
+
+ // Listening to
+ Draw(hdc, listening_icon);
+ Draw(hdc, listening);
+
+ if (data->listening_to.draw && data->listening_to.mouseOver && protocols->CanSetListeningTo())
+ DrawMouseOver(hdc, &data->listening_to.rc, "Listening");
+
+
+ // Unread email count
+ Draw(hdc, email_icon);
+ Draw(hdc, email);
+
+ // Protocol cycle icon
+ Draw(hdc, next_proto);
+ Draw(hdc, prev_proto);
+
+
+ SelectObject(hdc, old_font);
+ SetTextColor(hdc, old_color);
+ SetBkMode(hdc, old_bk_mode);
+
+ if (!useLayeredMode)
+ {
+ BitBlt(hdc_orig, r_full.left, r_full.top, r_full.right - r_full.left,
+ r_full.bottom - r_full.top, hdc, r_full.left, r_full.top, SRCCOPY);
+ DeleteDC(hdc);
+ DeleteObject(hBmp);
+ }
+
+ if (freeStatusIcon)
+ DestroyIcon(hStatusIcon);
+ IcoLib_ReleaseIcon(hListeningIcon);
+ IcoLib_ReleaseIcon(hEmailIcon);
+ IcoLib_ReleaseIcon(hPrevIcon);
+ IcoLib_ReleaseIcon(hNextIcon);
+
+ if (opts.resize_frame && ServiceExists(MS_CLIST_FRAMES_SETFRAMEOPTIONS) && frame_id != -1)
+ {
+ RECT rf;
+ GetClientRect(hwnd, &rf);
+
+ int currentSize = Height(r_full);
+
+ int expectedSize = 0;
+ for(size_t i = 0; i < data->items.size(); ++i)
+ {
+ SimpleItem *item = data->items[i];
+ if (!item->draw)
+ continue;
+
+ expectedSize = max(expectedSize, item->rc.bottom);
+ }
+ expectedSize += state.getBorders().bottom;
+
+ if (expectedSize != currentSize)
+ {
+ if (FrameIsFloating())
+ {
+ HWND parent = GetParent(hwnd);
+
+ if (parent != NULL)
+ {
+ RECT rp_client, rp_window, r_window;
+ GetClientRect(parent, &rp_client);
+ GetWindowRect(parent, &rp_window);
+ GetWindowRect(hwnd, &r_window);
+ int diff = (rp_window.bottom - rp_window.top) - (rp_client.bottom - rp_client.top);
+ if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ diff += (r_window.top - rp_window.top);
+
+ SetWindowPos(parent, 0, 0, 0, rp_window.right - rp_window.left, expectedSize + diff, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
+ }
+ }
+ else if (IsWindowVisible(hwnd) && ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ {
+ int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
+ if(flags & F_VISIBLE)
+ {
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, frame_id), (LPARAM) expectedSize);
+ CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)frame_id, (LPARAM)(FU_TBREDRAW | FU_FMREDRAW | FU_FMPOS));
+ }
+ }
+ }
+ }
+}
+
+int SkinEngineDrawCallback(HWND hWnd, HDC hDC, RECT * rcPaint, HRGN rgn, DWORD dFlags, void * CallBackData)
+{
+ Draw(hWnd, hDC);
+ return 0;
+}
+
+bool InsideRect(const POINT &p, const RECT &r)
+{
+ return p.x >= r.left && p.x < r.right && p.y >= r.top && p.y < r.bottom;
+}
+
+int ShowPopupMenu(HWND hwnd, HMENU submenu, SimpleItem &item)
+{
+ POINT p;
+ if (item.alignRight)
+ p.x = item.rc.right;
+ else
+ p.x = item.rc.left;
+ p.y = item.rc.bottom+1;
+ ClientToScreen(hwnd, &p);
+
+ return TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD
+ | (item.alignRight ? TPM_RIGHTALIGN : TPM_LEFTALIGN), p.x, p.y, 0, hwnd, NULL);
+}
+
+
+void ShowGlobalStatusMenu(HWND hwnd, MyDetailsFrameData *data, Protocol *proto, POINT &p)
+{
+ HMENU submenu = (HMENU) CallService(MS_CLIST_MENUGETSTATUS,0,0);
+
+ int ret = ShowPopupMenu(hwnd, submenu, data->status);
+ if(ret)
+ CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(ret),MPCF_MAINMENU),(LPARAM)NULL);
+}
+
+void ShowProtocolStatusMenu(HWND hwnd, MyDetailsFrameData *data, Protocol *proto, POINT &p)
+{
+ HMENU menu = (HMENU) CallService(MS_CLIST_MENUGETSTATUS,0,0);
+ HMENU submenu = NULL;
+
+ if (menu != NULL)
+ {
+ // Find the correct menu item
+ int count = GetMenuItemCount(menu);
+ for (int i = 0 ; i < count && submenu == NULL; i++)
+ {
+ MENUITEMINFO mii = {0};
+
+ mii.cbSize = sizeof(mii);
+
+ if(!IsWinVer98Plus())
+ {
+ mii.fMask = MIIM_TYPE;
+ }
+ else
+ {
+ mii.fMask = MIIM_STRING;
+ }
+
+ GetMenuItemInfo(menu, i, TRUE, &mii);
+
+ if (mii.cch != 0)
+ {
+ mii.cch++;
+ mii.dwTypeData = (char *)malloc(sizeof(char) * mii.cch);
+ GetMenuItemInfo(menu, i, TRUE, &mii);
+
+ if (strcmp(mii.dwTypeData, proto->GetDescription()) == 0)
+ {
+ submenu = GetSubMenu(menu, i);
+ }
+
+ free(mii.dwTypeData);
+ }
+ }
+
+ if (submenu == NULL && GetNumProtocols() == 1)
+ {
+ submenu = menu;
+ }
+ }
+
+ if (submenu != NULL)
+ {
+ int ret = ShowPopupMenu(hwnd, submenu, data->status);
+ if(ret)
+ CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(ret),MPCF_MAINMENU),(LPARAM)NULL);
+ }
+ else
+ {
+ // Well, lets do it by hand
+ static int statusModePf2List[]={0xFFFFFFFF,PF2_ONLINE,PF2_SHORTAWAY,PF2_LONGAWAY,PF2_LIGHTDND,PF2_HEAVYDND,PF2_FREECHAT,PF2_INVISIBLE,PF2_ONTHEPHONE,PF2_OUTTOLUNCH};
+
+ menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
+ submenu = GetSubMenu(menu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
+
+ DWORD flags = proto->Call(PS_GETCAPS, PFLAGNUM_2);
+ for ( int i = GetMenuItemCount(submenu) -1 ; i >= 0 ; i-- )
+ {
+ if (!(flags & statusModePf2List[i]))
+ {
+ // Hide menu
+ RemoveMenu(submenu, i, MF_BYPOSITION);
+ }
+ }
+
+ int ret = ShowPopupMenu(hwnd, submenu, data->status);
+ DestroyMenu(menu);
+
+ if(ret)
+ proto->SetStatus(ret);
+ }
+}
+
+void ShowListeningToMenu(HWND hwnd, MyDetailsFrameData *data, Protocol *proto, POINT &p)
+{
+ HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
+ HMENU submenu = GetSubMenu(menu, 5);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
+
+ // Add this proto to menu
+ char tmp[128];
+ mir_snprintf(tmp, sizeof(tmp), Translate("Enable Listening To for %s"), proto->GetDescription());
+
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+ mii.fType = MFT_STRING;
+ mii.fState = proto->ListeningToEnabled() ? MFS_CHECKED : 0;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 1;
+
+ if (!proto->CanSetListeningTo())
+ {
+ mii.fState |= MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STATE;
+ mii.fState = protocols->ListeningToEnabled() ? MFS_CHECKED : 0;
+
+ if (!protocols->CanSetListeningTo())
+ {
+ mii.fState |= MFS_DISABLED;
+ }
+
+ SetMenuItemInfo(submenu, ID_LISTENINGTOPOPUP_SENDLISTENINGTO, FALSE, &mii);
+
+ int ret = ShowPopupMenu(hwnd, submenu, data->listening_to);
+
+ DestroyMenu(menu);
+
+ switch(ret)
+ {
+ case 1:
+ {
+ CallService(MS_LISTENINGTO_ENABLE, (LPARAM) proto->GetName(), !proto->ListeningToEnabled());
+ break;
+ }
+ case ID_LISTENINGTOPOPUP_SENDLISTENINGTO:
+ {
+ CallService(MS_LISTENINGTO_ENABLE, 0, !protocols->ListeningToEnabled());
+ break;
+ }
+ }
+
+}
+
+
+LRESULT CALLBACK FrameWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_CREATE:
+ {
+ MyDetailsFrameData *data = new MyDetailsFrameData();
+ SetWindowLong(hwnd, GWL_USERDATA, (LONG) data);
+
+ SetCurrentProtocol(DBGetContactSettingWord(NULL, "MyDetails", "ProtocolNumber", 0));
+
+ SetCycleTime(hwnd);
+
+ SetStatusMessageRefreshTime(hwnd);
+
+ return TRUE;
+ }
+
+
+ case WM_ERASEBKGND:
+ {
+ //EraseBackground(hwnd, (HDC)wParam);
+ //Draw(hwnd, (HDC)wParam);
+ return TRUE;
+ }
+
+ /*
+ case WM_PRINTCLIENT:
+ {
+ Draw(hwnd, (HDC)wParam);
+ return TRUE;
+ }
+ */
+
+ case WM_PAINT:
+ {
+ if (UseLayeredMode())
+ {
+ CallService(MS_SKINENG_INVALIDATEFRAMEIMAGE, (WPARAM) hwnd, 0);
+ ValidateRect(hwnd, NULL);
+ }
+ else
+ {
+ RECT r;
+ if(GetUpdateRect(hwnd, &r, FALSE))
+ {
+ PAINTSTRUCT ps;
+
+ HDC hdc = BeginPaint(hwnd, &ps);
+ Draw(hwnd, hdc);
+ EndPaint(hwnd, &ps);
+ }
+ }
+
+ return TRUE;
+ }
+
+ case WM_SIZE:
+ {
+ //InvalidateRect(hwnd, NULL, FALSE);
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+ RedrawFrame();
+ break;
+ }
+
+ case WM_TIMER:
+ {
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+
+ if (wParam == ID_FRAME_TIMER)
+ {
+ if (!data->showing_menu)
+ CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
+ }
+ else if (wParam == ID_RECALC_TIMER)
+ {
+ KillTimer(hwnd, ID_RECALC_TIMER);
+
+ PostMessage(hwnd, MWM_REFRESH_DATA, 0, 0);
+ }
+ else if (wParam == ID_STATUSMESSAGE_TIMER)
+ {
+ SetStatusMessageRefreshTime(hwnd);
+
+ PostMessage(hwnd, MWM_REFRESH_DATA, 0, 0);
+ }
+
+ return TRUE;
+ }
+
+ case WM_LBUTTONUP:
+ {
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+ Protocol *proto = GetCurrentProtocol();
+ if (proto == NULL)
+ break;
+
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+
+ // In proto cycle button?
+ if (data->proto_cycle_next.hitTest(p))
+ {
+ CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
+ }
+ else if (data->proto_cycle_prev.hitTest(p))
+ {
+ CallService(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, 0, 0);
+ }
+ // In image?
+ else if (data->avatar.hitTest(p) && proto->CanSetAvatar())
+ {
+ if (opts.global_on_avatar)
+ CallService(MS_MYDETAILS_SETMYAVATARUI, 0, 0);
+ else
+ CallService(MS_MYDETAILS_SETMYAVATARUI, 0, (LPARAM) proto->GetName());
+ }
+ // In nick?
+ else if (data->nick.hitTest(p) && proto->CanSetNick())
+ {
+ if (opts.global_on_nickname)
+ CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, 0);
+ else
+ CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, (LPARAM) proto->GetName());
+ }
+ // In status message?
+ else if (data->away_msg.hitTest(p) && proto->CanSetStatusMsg())
+ {
+ if (opts.global_on_status_message)
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, 0);
+ else
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, (LPARAM) proto->GetName());
+ }
+ // In status?
+ else if (data->status.hitTest(p))
+ {
+ data->showing_menu = true;
+
+ if (opts.global_on_status)
+ ShowGlobalStatusMenu(hwnd, data, proto, p);
+ else
+ ShowProtocolStatusMenu(hwnd, data, proto, p);
+
+ data->showing_menu = false;
+ }
+ // In listening to?
+ else if (data->listening_to.hitTest(p) && protocols->CanSetListeningTo())
+ {
+ ShowListeningToMenu(hwnd, data, proto, p);
+ }
+ // In protocol?
+ else if (data->proto.hitTest(p))
+ {
+ data->showing_menu = true;
+
+ HMENU menu = CreatePopupMenu();
+
+ std::vector<Protocol> protos;
+ GetProtocols(&protos);
+
+ int current = GetCurrentProtocolIndex();
+
+ int protosSize = (int) protos.size();
+ for (int i = protosSize - 1 ; i >= 0 ; i--)
+ {
+ Protocol &proto = protos[i];
+
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = (char *) proto.GetDescription();
+ mii.cch = strlen(mii.dwTypeData);
+ mii.wID = i + 1;
+
+ if (i == current)
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(menu, 0, TRUE, &mii);
+ }
+
+ int ret = ShowPopupMenu(hwnd, menu, data->proto);
+
+ DestroyMenu(menu);
+
+ if (ret != 0)
+ PluginCommand_ShowProtocol(NULL, (WPARAM) GetProtocolByIndex(ret - 1).GetName());
+
+ data->showing_menu = false;
+ }
+
+ break;
+ }
+
+ case WM_MEASUREITEM:
+ {
+ return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+ }
+ case WM_DRAWITEM:
+ {
+ return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+ }
+
+ case WM_CONTEXTMENU:
+ {
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+ Protocol *proto = GetCurrentProtocol();
+ if (proto == NULL)
+ break;
+
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+
+ ScreenToClient(hwnd, &p);
+
+ data->showing_menu = true;
+
+ // In proto cycle button?
+ if (data->proto_cycle_next.hitTest(p))
+ {
+ CallService(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, 0, 0);
+ }
+ else if (data->proto_cycle_prev.hitTest(p))
+ {
+ CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
+ }
+ // In image?
+ else if (data->avatar.hitTest(p))
+ {
+ HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
+ HMENU submenu = GetSubMenu(menu, 4);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
+
+ // Add this proto to menu
+ char tmp[128];
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Avatar for %s..."), proto->GetDescription());
+
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 1;
+
+ if (!proto->CanSetAvatar())
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ ClientToScreen(hwnd, &p);
+
+ int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
+ DestroyMenu(menu);
+
+ switch(ret)
+ {
+ case 1:
+ {
+ CallService(MS_MYDETAILS_SETMYAVATARUI, 0, (LPARAM) proto->GetName());
+ break;
+ }
+ case ID_AVATARPOPUP_SETMYAVATAR:
+ {
+ CallService(MS_MYDETAILS_SETMYAVATARUI, 0, 0);
+ break;
+ }
+ }
+ }
+ // In nick?
+ else if (data->nick.hitTest(p))
+ {
+ HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
+ HMENU submenu = GetSubMenu(menu, 2);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
+
+ // Add this proto to menu
+ char tmp[128];
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Nickname for %s..."), proto->GetDescription());
+
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 1;
+
+ if (!proto->CanSetNick())
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ ClientToScreen(hwnd, &p);
+
+ int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
+ DestroyMenu(menu);
+
+ switch(ret)
+ {
+ case 1:
+ {
+ CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, (LPARAM) proto->GetName());
+ break;
+ }
+ case ID_NICKPOPUP_SETMYNICKNAME:
+ {
+ CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, 0);
+ break;
+ }
+ }
+ }
+ // In status message?
+ else if (data->away_msg.hitTest(p))
+ {
+ char tmp[128];
+
+ HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
+ HMENU submenu = GetSubMenu(menu, 3);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
+
+ // Add this proto to menu
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."),
+ proto->GetDescription());
+
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 1;
+
+ if (!proto->CanSetStatusMsg())
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ {
+ // Add this to menu
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, proto->GetStatus(), 0));
+
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 2;
+
+ if (proto->GetStatus() == ID_STATUS_OFFLINE)
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+ }
+
+ ClientToScreen(hwnd, &p);
+
+ int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
+ DestroyMenu(menu);
+
+ switch(ret)
+ {
+ case 1:
+ {
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, (LPARAM) proto->GetName());
+ break;
+ }
+ case 2:
+ {
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, (WPARAM) proto->GetStatus(), 0);
+ break;
+ }
+ case ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE:
+ {
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, 0);
+ break;
+ }
+ }
+ }
+ // In status?
+ else if (data->status.hitTest(p))
+ {
+ if (opts.global_on_status)
+ ShowProtocolStatusMenu(hwnd, data, proto, p);
+ else
+ ShowGlobalStatusMenu(hwnd, data, proto, p);
+ }
+ // In listening to?
+ else if (data->listening_to.hitTest(p) && protocols->CanSetListeningTo())
+ {
+ ShowListeningToMenu(hwnd, data, proto, p);
+ }
+ // In protocol?
+ else if (data->proto.hitTest(p))
+ {
+ }
+ // Default context menu
+ else
+ {
+ HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
+ HMENU submenu = GetSubMenu(menu, 1);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
+
+ if (opts.cycle_through_protocols)
+ RemoveMenu(submenu, ID_CYCLE_THROUGH_PROTOS, MF_BYCOMMAND);
+ else
+ RemoveMenu(submenu, ID_DONT_CYCLE_THROUGH_PROTOS, MF_BYCOMMAND);
+
+ // Add this proto to menu
+ char tmp[128];
+ MENUITEMINFO mii = {0};
+
+ mir_snprintf(tmp, sizeof(tmp), Translate("Enable Listening To for %s"), proto->GetDescription());
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+ mii.fType = MFT_STRING;
+ mii.fState = proto->ListeningToEnabled() ? MFS_CHECKED : 0;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 5;
+
+ if (!proto->CanSetListeningTo())
+ {
+ mii.fState |= MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ // Add this to menu
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, proto->GetStatus(), 0));
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 4;
+
+ if (proto->GetStatus() == ID_STATUS_OFFLINE)
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ // Add this proto to menu
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."), proto->GetDescription());
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 3;
+
+ if (!proto->CanSetStatusMsg())
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Nickname for %s..."), proto->GetDescription());
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 2;
+
+ if (!proto->CanSetNick())
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Avatar for %s..."), proto->GetDescription());
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = tmp;
+ mii.cch = strlen(tmp);
+ mii.wID = 1;
+
+ if (!proto->CanSetAvatar())
+ {
+ mii.fMask |= MIIM_STATE;
+ mii.fState = MFS_DISABLED;
+ }
+
+ InsertMenuItem(submenu, 0, TRUE, &mii);
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STATE;
+ mii.fState = protocols->ListeningToEnabled() ? MFS_CHECKED : 0;
+
+ if (!protocols->CanSetListeningTo())
+ {
+ mii.fState |= MFS_DISABLED;
+ }
+
+ SetMenuItemInfo(submenu, ID_CONTEXTPOPUP_ENABLELISTENINGTO, FALSE, &mii);
+
+ ClientToScreen(hwnd, &p);
+
+ int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
+ DestroyMenu(menu);
+
+ switch(ret)
+ {
+ case 1:
+ {
+ CallService(MS_MYDETAILS_SETMYAVATARUI, 0, (LPARAM) proto->GetName());
+ break;
+ }
+ case ID_AVATARPOPUP_SETMYAVATAR:
+ {
+ CallService(MS_MYDETAILS_SETMYAVATARUI, 0, 0);
+ break;
+ }
+ case 2:
+ {
+ CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, (LPARAM) proto->GetName());
+ break;
+ }
+ case ID_NICKPOPUP_SETMYNICKNAME:
+ {
+ CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, 0);
+ break;
+ }
+ case 3:
+ {
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, (LPARAM) proto->GetName());
+ break;
+ }
+ case 4:
+ {
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, (WPARAM) proto->GetStatus(), 0);
+ break;
+ }
+ case ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE:
+ {
+ CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, 0);
+ break;
+ }
+ case 5:
+ {
+ CallService(MS_LISTENINGTO_ENABLE, (LPARAM) proto->GetName(), !proto->ListeningToEnabled());
+ break;
+ }
+ case ID_CONTEXTPOPUP_ENABLELISTENINGTO:
+ {
+ CallService(MS_LISTENINGTO_ENABLE, 0, !protocols->ListeningToEnabled());
+ break;
+ }
+ case ID_SHOW_NEXT_PROTO:
+ {
+ CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
+ break;
+ }
+ case ID_SHOW_PREV_PROTO:
+ {
+ CallService(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, 0, 0);
+ break;
+ }
+ case ID_CYCLE_THROUGH_PROTOS:
+ {
+ CallService(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS, TRUE, 0);
+ break;
+ }
+ case ID_DONT_CYCLE_THROUGH_PROTOS:
+ {
+ CallService(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS, FALSE, 0);
+ break;
+ }
+ }
+ }
+
+ data->showing_menu = false;
+
+
+ break;
+ }
+
+ case WM_NCMOUSELEAVE:
+ case WM_MOUSELEAVE:
+ {
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+ data->tracking_exit = false;
+ }
+ case WM_NCMOUSEMOVE:
+ {
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+
+ bool changed = false;
+ for(size_t i = 0; i < data->items.size(); ++i)
+ changed = changed || data->items[i]->setMouseOver(NULL);
+
+ if (changed)
+ InvalidateRect(hwnd, NULL, FALSE);
+
+ break;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+ Protocol *proto = GetCurrentProtocol();
+ if (proto == NULL)
+ break;
+
+ if (!data->tracking_exit)
+ {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+
+ data->tracking_exit = true;
+ }
+
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+
+ bool changed = false;
+ for(size_t i = 0; i < data->items.size(); ++i)
+ changed = changed || data->items[i]->setMouseOver(&p);
+
+ if (changed)
+ InvalidateRect(hwnd, NULL, FALSE);
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR) lParam;
+
+ int i = (int) lpnmhdr->code;
+
+ switch (lpnmhdr->code) {
+ case TTN_GETDISPINFO:
+ {
+ MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+
+ LPNMTTDISPINFO lpttd = (LPNMTTDISPINFO) lpnmhdr;
+ SendMessage(lpnmhdr->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 300);
+
+ for(int i = 0; i < data->items.size(); i++)
+ {
+ lpttd->lpszText = (char *) data->items[i]->getToolTipFor(lpnmhdr->hwndFrom);
+ if (lpttd->lpszText != NULL)
+ break;
+ }
+
+ return 0;
+ }
+ }
+
+ break;
+ }
+
+ case WM_DESTROY:
+ {
+ KillTimer(hwnd, ID_FRAME_TIMER);
+
+ MyDetailsFrameData *tmp = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
+ if (tmp != NULL) delete tmp;
+
+ break;
+ }
+
+ // Custom Messages //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ case MWM_REFRESH:
+ {
+ KillTimer(hwnd, ID_RECALC_TIMER);
+ SetTimer(hwnd, ID_RECALC_TIMER, RECALC_TIME, NULL);
+ break;
+ }
+
+ case MWM_REFRESH_DATA:
+ {
+ Protocol *proto = GetCurrentProtocol(false);
+ if (proto)
+ {
+ proto->UpdateAll();
+ RedrawFrame();
+ }
+ break;
+ }
+ }
+
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+
+int ShowHideFrameFunc(WPARAM wParam, LPARAM lParam)
+{
+ if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ {
+ CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
+ }
+ else
+ {
+ if (MyDetailsFrameVisible())
+ {
+ SendMessage(hwnd_container, WM_CLOSE, 0, 0);
+ }
+ else
+ {
+ ShowWindow(hwnd_container, SW_SHOW);
+ DBWriteContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 1);
+ }
+
+ FixMainMenu();
+ }
+ return 0;
+}
+
+
+int ShowFrameFunc(WPARAM wParam, LPARAM lParam)
+{
+ if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ {
+ int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
+ if(!(flags & F_VISIBLE))
+ CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
+ }
+ else
+ {
+ if (!MyDetailsFrameVisible())
+ {
+ ShowWindow(hwnd_container, SW_SHOW);
+ DBWriteContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 1);
+
+ FixMainMenu();
+ }
+
+ }
+ return 0;
+}
+
+
+int HideFrameFunc(WPARAM wParam, LPARAM lParam)
+{
+ if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ {
+ int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
+ if (flags & F_VISIBLE)
+ CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
+ }
+ else
+ {
+ if (MyDetailsFrameVisible())
+ {
+ SendMessage(hwnd_container, WM_CLOSE, 0, 0);
+
+ FixMainMenu();
+ }
+ }
+ return 0;
+}
+
+
+void FixMainMenu()
+{
+ CLISTMENUITEM mi = {0};
+ mi.cbSize = sizeof(CLISTMENUITEM);
+ mi.flags = CMIM_NAME;
+
+ if(MyDetailsFrameVisible())
+ mi.pszName = Translate("Hide My Details");
+ else
+ mi.pszName = Translate("Show My Details");
+
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuShowHideFrame, (LPARAM)&mi);
+}
+
+#include <math.h>
+
+void RedrawFrame()
+{
+ if (frame_id == -1)
+ {
+ InvalidateRect(hwnd_container, NULL, TRUE);
+ }
+ else
+ {
+ CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)frame_id, (LPARAM)FU_TBREDRAW | FU_FMREDRAW);
+ }
+}
+
+void UpdateFrameData()
+{
+ if (hwnd_frame != NULL)
+ PostMessage(hwnd_frame, MWM_REFRESH, 0, 0);
+}
+
+// only used when no multiwindow functionality is available
+BOOL MyDetailsFrameVisible()
+{
+ return IsWindowVisible(hwnd_container) ? true : false;
+}
+
+void SetMyDetailsFrameVisible(BOOL visible)
+{
+ if (frame_id == -1 && hwnd_container != 0)
+ {
+ ShowWindow(hwnd_container, visible ? SW_SHOW : SW_HIDE);
+ }
+}
+
+void SetCycleTime()
+{
+ if (hwnd_frame != NULL)
+ SetCycleTime(hwnd_frame);
+}
+
+void SetCycleTime(HWND hwnd)
+{
+ KillTimer(hwnd, ID_FRAME_TIMER);
+
+ if (opts.cycle_through_protocols)
+ SetTimer(hwnd, ID_FRAME_TIMER, opts.seconds_to_show_protocol * 1000, 0);
+}
+
+void SetStatusMessageRefreshTime()
+{
+ if (hwnd_frame != NULL)
+ SetStatusMessageRefreshTime(hwnd_frame);
+}
+
+void SetStatusMessageRefreshTime(HWND hwnd)
+{
+ KillTimer(hwnd, ID_STATUSMESSAGE_TIMER);
+
+ opts.refresh_status_message_timer = DBGetContactSettingWord(NULL, "MyDetails", "RefreshStatusMessageTimer",5);
+ if (opts.refresh_status_message_timer > 0)
+ {
+ SetTimer(hwnd, ID_STATUSMESSAGE_TIMER, opts.refresh_status_message_timer * 1000, NULL);
+ }
+}
+
+int PluginCommand_ShowNextProtocol(WPARAM wParam,LPARAM lParam)
+{
+ if (hwnd_frame == NULL)
+ return -1;
+
+ SetCurrentProtocol(GetCurrentProtocolIndex() + 1);
+
+ SetCycleTime();
+
+ RedrawFrame();
+
+ return 0;
+}
+
+int PluginCommand_ShowPreviousProtocol(WPARAM wParam,LPARAM lParam)
+{
+ if (hwnd_frame == NULL)
+ return -1;
+
+ SetCurrentProtocol(GetCurrentProtocolIndex() - 1);
+
+ SetCycleTime();
+
+ RedrawFrame();
+
+ return 0;
+}
+
+int PluginCommand_ShowProtocol(WPARAM wParam,LPARAM lParam)
+{
+ char * proto = (char *)lParam;
+
+ if (proto == NULL)
+ return -1;
+
+ int proto_num = GetProtocolIndexByName(proto);
+ if (proto_num == -1)
+ return -2;
+
+ if (hwnd_frame == NULL)
+ return -3;
+
+ SetCurrentProtocol(proto_num);
+
+ SetCycleTime();
+
+ RedrawFrame();
+
+ return 0;
+}
+
+int SettingsChangedHook(WPARAM wParam, LPARAM lParam)
+{
+ if (hwnd_frame == NULL)
+ return 0;
+
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
+
+ if (wParam != NULL)
+ return 0;
+
+ if (strstr(cws->szModule,"Away"))
+ {
+ // Status message changed
+ UpdateFrameData();
+ return 0;
+ }
+
+ Protocol *proto = GetCurrentProtocol(false);
+ if (proto == NULL || strcmp(proto->GetName(), cws->szModule) != 0)
+ return 0;
+
+ if (!strcmp(cws->szSetting,"Status")
+ || !strcmp(cws->szSetting,"StatusMood")
+ || !strcmp(cws->szSetting,"XStatusName")
+ || !strcmp(cws->szSetting,"XStatusMsg")
+ || !strcmp(cws->szSetting,"XStatusId")
+ || ( proto->GetCustomStatus() != 0 && !strcmp(cws->szSetting, proto->GetCustomStatusNameKey()) )
+ || ( proto->GetCustomStatus() != 0 && !strcmp(cws->szSetting, proto->GetCustomStatusMessageKey()) ))
+ {
+ // Status changed
+ UpdateFrameData();
+ }
+ else if(!strcmp(cws->szSetting,"MyHandle")
+ || !strcmp(cws->szSetting,"UIN")
+ || !strcmp(cws->szSetting,"Nick")
+ || !strcmp(cws->szSetting,"FirstName")
+ || !strcmp(cws->szSetting,"e-mail")
+ || !strcmp(cws->szSetting,"LastName")
+ || !strcmp(cws->szSetting,"JID"))
+ {
+ // Name changed
+ UpdateFrameData();
+ }
+ else if (strcmp(cws->szSetting,"ListeningTo") == 0)
+ {
+ UpdateFrameData();
+ }
+ else if (strcmp(cws->szSetting,"LockMainStatus") == 0)
+ {
+ UpdateFrameData();
+ }
+
+ return 0;
+}
+
+int AvatarChangedHook(WPARAM wParam, LPARAM lParam)
+{
+ if (hwnd_frame == NULL)
+ return 0;
+
+ Protocol *proto = GetCurrentProtocol(false);
+ if (proto == NULL || strcmp(proto->GetName(), (const char *) wParam) != 0)
+ return 0;
+
+ UpdateFrameData();
+
+ return 0;
+}
+
+int ProtoAckHook(WPARAM wParam, LPARAM lParam)
+{
+ if (hwnd_frame == NULL)
+ return 0;
+
+ ACKDATA *ack = (ACKDATA*) lParam;
+ if (ack->hContact != NULL)
+ return 0;
+
+ Protocol *proto = GetCurrentProtocol(false);
+ if (proto == NULL || strcmp(proto->GetName(), ack->szModule) != 0)
+ return 0;
+
+ if (ack->type == ACKTYPE_STATUS)
+ {
+ UpdateFrameData();
+ }
+ else if (ack->type == ACKTYPE_AWAYMSG)
+ {
+ UpdateFrameData();
+ }
+ else if (ack->type == ACKTYPE_EMAIL)
+ {
+ UpdateFrameData();
+ }
+
+ return 0;
+}
+
+int ListeningtoEnableStateChangedHook(WPARAM wParam,LPARAM lParam)
+{
+ if (hwnd_frame == NULL)
+ return 0;
+
+ Protocol *proto = GetCurrentProtocol(false);
+ if (proto == NULL || strcmp(proto->GetName(), (const char *) wParam) != 0)
+ return 0;
+
+ UpdateFrameData();
+
+ return 0;
+}
+
+int AccListChanged(WPARAM wParam, LPARAM lParam)
+{
+ SetCurrentProtocol(0);
+
+ RedrawFrame();
+
+ return 0;
+}
diff --git a/plugins/MyDetails/frame.h b/plugins/MyDetails/frame.h
new file mode 100644
index 0000000000..58aa800090
--- /dev/null
+++ b/plugins/MyDetails/frame.h
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __FRAME_H__
+# define __FRAME_H__
+
+
+void InitFrames();
+void DeInitFrames();
+
+void UpdateFrameData();
+void RedrawFrame();
+
+void SetCycleTime();
+
+int PluginCommand_ShowNextProtocol(WPARAM wParam,LPARAM lParam);
+int PluginCommand_ShowPreviousProtocol(WPARAM wParam,LPARAM lParam);
+int PluginCommand_ShowProtocol(WPARAM wParam,LPARAM lParam);
+
+
+#endif // __FRAME_H__ \ No newline at end of file
diff --git a/plugins/MyDetails/mydetails.cpp b/plugins/MyDetails/mydetails.cpp
new file mode 100644
index 0000000000..9351765f6c
--- /dev/null
+++ b/plugins/MyDetails/mydetails.cpp
@@ -0,0 +1,992 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+#include "mydetails.h"
+
+
+// Prototypes /////////////////////////////////////////////////////////////////////////////////////
+
+
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ "My Details",
+ PLUGIN_MAKE_VERSION(0,0,2,6),
+ "Show and allows you to edit your details for all protocols.",
+ "Ricardo Pescuma Domenecci, Drugwash",
+ "",
+ "© 2005-2010 Ricardo Pescuma Domenecci, Drugwash",
+ "http://pescuma.org/miranda/mydetails",
+ 0, //not transient
+ 0, //doesn't replace anything built-in
+ { 0xa82baeb3, 0xa33c, 0x4036, { 0xb8, 0x37, 0x78, 0x3, 0xa5, 0xb6, 0xc2, 0xab } } // {A82BAEB3-A33C-4036-B837-7803A5B6C2AB}
+};
+
+
+struct MM_INTERFACE mmi;
+struct UTF8_INTERFACE utfi;
+struct SKIN_INTERFACE mski;
+
+
+HANDLE hTTB = NULL;
+
+// Hooks
+HANDLE hModulesLoadedHook = NULL;
+HANDLE hPreShutdownHook = NULL;
+HANDLE hColorChangedHook = NULL;
+
+long nickname_dialog_open;
+HWND hwndSetNickname;
+
+long status_msg_dialog_open;
+HWND hwndSetStatusMsg;
+
+SkinDialog *dialog;
+
+
+// Hook called after init
+static int MainInit(WPARAM wparam,LPARAM lparam);
+static int MainUninit(WPARAM wParam, LPARAM lParam);
+
+
+// Services
+static int PluginCommand_SetMyNicknameUI(WPARAM wParam,LPARAM lParam);
+static int PluginCommand_SetMyNickname(WPARAM wParam,LPARAM lParam);
+static int PluginCommand_GetMyNickname(WPARAM wParam,LPARAM lParam);
+static int PluginCommand_SetMyAvatarUI(WPARAM wParam,LPARAM lParam);
+static int PluginCommand_SetMyAvatar(WPARAM wParam,LPARAM lParam);
+static int PluginCommand_GetMyAvatar(WPARAM wParam,LPARAM lParam);
+static int PluginCommand_SetMyStatusMessageUI(WPARAM wParam,LPARAM lParam);
+static int PluginCommand_CicleThroughtProtocols(WPARAM wParam,LPARAM lParam);
+
+
+
+
+// Functions //////////////////////////////////////////////////////////////////////////////////////
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFO);
+ return (PLUGININFO*) &pluginInfo;
+}
+
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFOEX);
+ return &pluginInfo;
+}
+
+
+static const MUUID interfaces[] = { MIID_MDETAILS, MIID_LAST };
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+
+int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ // Copy data
+ pluginLink = link;
+
+ // CHECK_VERSION("My Details")
+
+ mir_getMMI(&mmi);
+ mir_getUTFI(&utfi);
+
+ init_list_interface();
+
+ // Hook event to load messages and show first one
+ hModulesLoadedHook = HookEvent(ME_SYSTEM_MODULESLOADED, MainInit);
+ hPreShutdownHook = HookEvent(ME_SYSTEM_PRESHUTDOWN, MainUninit);
+
+ nickname_dialog_open = 0;
+ status_msg_dialog_open = 0;
+
+ // Options
+ InitOptions();
+
+ // Register services
+ CreateServiceFunction(MS_MYDETAILS_SETMYNICKNAME, PluginCommand_SetMyNickname);
+ CreateServiceFunction(MS_MYDETAILS_SETMYNICKNAMEUI, PluginCommand_SetMyNicknameUI);
+ CreateServiceFunction(MS_MYDETAILS_SETMYAVATAR, PluginCommand_SetMyAvatar);
+ CreateServiceFunction(MS_MYDETAILS_SETMYAVATARUI, PluginCommand_SetMyAvatarUI);
+ CreateServiceFunction(MS_MYDETAILS_GETMYNICKNAME, PluginCommand_GetMyNickname);
+ CreateServiceFunction(MS_MYDETAILS_GETMYAVATAR, PluginCommand_GetMyAvatar);
+ CreateServiceFunction(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, PluginCommand_SetMyStatusMessageUI);
+ CreateServiceFunction(MS_MYDETAILS_SHOWNEXTPROTOCOL, PluginCommand_ShowNextProtocol);
+ CreateServiceFunction(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, PluginCommand_ShowPreviousProtocol);
+ CreateServiceFunction(MS_MYDETAILS_SHOWPROTOCOL, PluginCommand_ShowProtocol);
+ CreateServiceFunction(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS, PluginCommand_CicleThroughtProtocols);
+
+ return 0;
+}
+
+
+int __declspec(dllexport) Unload(void)
+{
+ DestroyServiceFunction(MS_MYDETAILS_SETMYNICKNAME);
+ DestroyServiceFunction(MS_MYDETAILS_SETMYNICKNAMEUI);
+ DestroyServiceFunction(MS_MYDETAILS_SETMYAVATAR);
+ DestroyServiceFunction(MS_MYDETAILS_SETMYAVATARUI);
+ DestroyServiceFunction(MS_MYDETAILS_GETMYNICKNAME);
+ DestroyServiceFunction(MS_MYDETAILS_GETMYAVATAR);
+ DestroyServiceFunction(MS_MYDETAILS_SETMYSTATUSMESSAGEUI);
+ DestroyServiceFunction(MS_MYDETAILS_SHOWNEXTPROTOCOL);
+ DestroyServiceFunction(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL);
+ DestroyServiceFunction(MS_MYDETAILS_SHOWPROTOCOL);
+ DestroyServiceFunction(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS);
+
+ if (hModulesLoadedHook) UnhookEvent(hModulesLoadedHook);
+
+ DeInitProtocolData();
+ DeInitOptions();
+
+ return 0;
+}
+
+
+static int Menu_SetMyAvatarUI(WPARAM wParam,LPARAM lParam)
+{
+ return PluginCommand_SetMyAvatarUI(0, 0);
+}
+static int Menu_SetMyNicknameUI(WPARAM wParam,LPARAM lParam)
+{
+ return PluginCommand_SetMyNicknameUI(0, 0);
+}
+static int Menu_SetMyStatusMessageUI(WPARAM wParam,LPARAM lParam)
+{
+ return PluginCommand_SetMyStatusMessageUI(0, 0);
+}
+
+static void SkinChanged(void *param, SKINNED_DIALOG dlg)
+{
+ RedrawFrame();
+}
+
+
+static int ColorChanged(WPARAM wparam, LPARAM lparam)
+{
+ ColourID cid = {0};
+ cid.cbSize = sizeof(ColourID);
+ lstrcpynA(cid.group, "My Details", sizeof(cid.group));
+ lstrcpynA(cid.name, "Background", sizeof(cid.name));
+
+ opts.bkg_color = (COLORREF) CallService(MS_COLOUR_GET, (WPARAM) &cid, 0);
+
+ RedrawFrame();
+
+ return 0;
+}
+
+
+// Hook called after init
+static int MainInit(WPARAM wparam,LPARAM lparam)
+{
+ if ( mir_skins_getInterface(&mski) != 0 )
+ {
+ MessageBox(NULL, _T("MyDetails needs Skins plugin in order to work"), _T("MyDetails"), MB_OK | MB_ICONERROR);
+ return 0;
+ }
+
+ if (CallService(MS_SKIN2_GETICON, 0, (LPARAM) "LISTENING_TO_ICON") == NULL)
+ {
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.ptszSection = "Contact List";
+ sid.ptszDescription = "Listening to";
+ sid.pszName = "LISTENING_TO_ICON";
+ sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_LISTENINGTO));
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ }
+
+ {
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.ptszSection = "My Details";
+ sid.ptszDescription = "Email";
+ sid.pszName = "MYDETAILS_EMAIL";
+ sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_EMAIL));
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ }
+
+ {
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.ptszSection = "My Details";
+ sid.ptszDescription = "Previous protocol";
+ sid.pszName = "MYDETAILS_PREV_PROTOCOL";
+ sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_LEFT_ARROW));
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ }
+
+ {
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.ptszSection = "My Details";
+ sid.ptszDescription = "Next protocol";
+ sid.pszName = "MYDETAILS_NEXT_PROTOCOL";
+ sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_RIGHT_ARROW));
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ }
+
+ {
+ ColourID cid = {0};
+ cid.cbSize = sizeof(ColourID);
+ lstrcpynA(cid.group, "My Details", sizeof(cid.group));
+ lstrcpynA(cid.name, "Background", sizeof(cid.name));
+ lstrcpynA(cid.dbSettingsGroup, MODULE_NAME, sizeof(cid.dbSettingsGroup));
+ lstrcpynA(cid.setting, "BackgroundColor", sizeof(cid.setting));
+ cid.defcolour = GetSysColor(COLOR_BTNFACE);
+
+ CallService(MS_COLOUR_REGISTER, (WPARAM) &cid, 0);
+
+ ColorChanged(0,0);
+
+ hColorChangedHook = HookEvent(ME_COLOUR_RELOAD, ColorChanged);
+ }
+
+ dialog = new SkinDialog("MyDetails", "My Details", MODULE_NAME);
+ if (!dialog->isValid())
+ {
+ MessageBox(NULL, _T("MyDetails could not create dialog. Check if default skin is installed"), _T("MyDetails"), MB_OK | MB_ICONERROR);
+ return 0;
+ }
+
+ dialog->addImageField("avatar", "Avatar");
+ dialog->addTextField("nickname", "Nickname");
+ dialog->addTextField("protocol", "Protocol");
+ dialog->addIconField("email_icon", "Unread Email Count Icon");
+ dialog->addTextField("email", "Unread Email Count");
+ dialog->addIconField("status_icon", "Status Icon");
+ dialog->addTextField("status_name", "Status");
+ dialog->addTextField("status_msg", "Status Message");
+ dialog->addIconField("listening_icon", "Listening To Icon");
+ dialog->addTextField("listening", "Listening To");
+ dialog->addIconField("next_proto", "Next Protocol");
+ dialog->addIconField("prev_proto", "Previous Protocol");
+ dialog->setSkinChangedCallback(SkinChanged, NULL);
+ dialog->finishedConfiguring();
+
+
+ InitProtocolData();
+
+ // Add options to menu
+ CLISTMENUITEM mi;
+
+ if (protocols->CanSetAvatars())
+ {
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = 0;
+ mi.popupPosition = 500050000;
+ mi.pszPopupName = Translate("My Details");
+ mi.position = 100001;
+ mi.pszName = Translate("Set My Avatar...");
+ CreateServiceFunction("MENU_" MS_MYDETAILS_SETMYAVATARUI, Menu_SetMyAvatarUI);
+ mi.pszService = "MENU_" MS_MYDETAILS_SETMYAVATARUI;
+
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+ }
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = 0;
+ mi.popupPosition = 500050000;
+ mi.pszPopupName = Translate("My Details");
+ mi.position = 100002;
+ mi.pszName = Translate("Set My Nickname...");
+ CreateServiceFunction("MENU_" MS_MYDETAILS_SETMYNICKNAMEUI, Menu_SetMyNicknameUI);
+ mi.pszService = "MENU_" MS_MYDETAILS_SETMYNICKNAMEUI;
+
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = 0;
+ mi.popupPosition = 500050000;
+ mi.pszPopupName = Translate("My Details");
+ mi.position = 100003;
+ mi.pszName = Translate("Set My Status Message...");
+ CreateServiceFunction("MENU_" MS_MYDETAILS_SETMYSTATUSMESSAGEUI, Menu_SetMyStatusMessageUI);
+ mi.pszService = "MENU_" MS_MYDETAILS_SETMYSTATUSMESSAGEUI;
+
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+
+ // Set protocols to show frame
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = 0;
+ mi.popupPosition = 500050000;
+ mi.pszPopupName = Translate("My Details");
+ mi.position = 200001;
+ mi.pszName = Translate("Show next protocol");
+ mi.pszService = MS_MYDETAILS_SHOWNEXTPROTOCOL;
+
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+
+ InitFrames();
+
+ // updater plugin support
+ if(ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update upd = {0};
+ char szCurrentVersion[30];
+
+ upd.cbSize = sizeof(upd);
+ upd.szComponentName = pluginInfo.shortName;
+
+ upd.szUpdateURL = UPDATER_AUTOREGISTER;
+
+ upd.szBetaVersionURL = "http://svn.berlios.de/svnroot/repos/mgoodies/trunk/mydetails/Docs/mydetails_version.txt";
+ upd.szBetaChangelogURL = "http://svn.berlios.de/svnroot/repos/mgoodies/trunk/mydetails/Docs/mydetails_changelog.txt";
+ upd.pbBetaVersionPrefix = (BYTE *)"My Details ";
+ upd.cpbBetaVersionPrefix = strlen((char *)upd.pbBetaVersionPrefix);
+ upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/mydetails.%VERSION%.zip";
+
+ upd.pbVersion = (BYTE *)CreateVersionStringPlugin((PLUGININFO*) &pluginInfo, szCurrentVersion);
+ upd.cpbVersion = strlen((char *)upd.pbVersion);
+
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
+ }
+
+ return 0;
+}
+
+static int MainUninit(WPARAM wParam, LPARAM lParam)
+{
+ DeInitFrames();
+
+ delete dialog;
+
+ return 0;
+}
+
+// Set nickname ///////////////////////////////////////////////////////////////////////////////////
+
+#define WMU_SETDATA (WM_USER+1)
+
+static BOOL CALLBACK DlgProcSetNickname(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch ( msg )
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ SendMessage(GetDlgItem(hwndDlg, IDC_NICKNAME), EM_LIMITTEXT,
+ MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE - 1, 0);
+
+ return TRUE;
+ }
+
+ case WMU_SETDATA:
+ {
+ int proto_num = (int)wParam;
+
+ SetWindowLong(hwndDlg, GWL_USERDATA, proto_num);
+
+ if (proto_num == -1)
+ {
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+
+ // All protos have the same nick?
+
+ std::vector<Protocol> protos;
+ GetProtocols(&protos);
+
+ int protosSize = protos.size();
+ if (protosSize > 0)
+ {
+ std::string nick = protos[0].GetNick();
+
+ bool foundDefNick = true;
+ for(int i = 1; i < protosSize; i++)
+ {
+ if (stricmp(protos[i].GetNick(), nick.c_str()) != 0)
+ {
+ foundDefNick = false;
+ break;
+ }
+ }
+
+ if (foundDefNick)
+ {
+ if (stricmp(protocols->default_nick, nick.c_str()) != 0)
+ lstrcpy(protocols->default_nick, nick.c_str());
+ }
+ }
+
+ SetDlgItemText(hwndDlg, IDC_NICKNAME, protocols->default_nick);
+ SendDlgItemMessage(hwndDlg, IDC_NICKNAME, EM_LIMITTEXT, MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE, 0);
+ }
+ else
+ {
+ Protocol proto = GetProtocolByIndex(proto_num);
+
+ char tmp[128];
+ mir_snprintf(tmp, sizeof(tmp), Translate("Set My Nickname for %s"), proto.GetDescription());
+
+ SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)tmp);
+
+ HICON hIcon = (HICON) proto.Call(PS_LOADICON, PLI_PROTOCOL);
+ if (hIcon != NULL)
+ {
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
+ DestroyIcon(hIcon);
+ }
+
+ SetDlgItemText(hwndDlg, IDC_NICKNAME, proto.GetNick());
+ SendDlgItemMessage(hwndDlg, IDC_NICKNAME, EM_LIMITTEXT,
+ min(MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE, proto.GetNickMaxLength()), 0);
+ }
+
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ switch(wParam)
+ {
+ case IDOK:
+ {
+ char tmp[MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE];
+ GetDlgItemText(hwndDlg, IDC_NICKNAME, tmp, sizeof(tmp));
+
+ int proto_num = (int) GetWindowLong(hwndDlg, GWL_USERDATA);
+ if (proto_num == -1)
+ {
+ protocols->SetNicks(tmp);
+ }
+ else
+ {
+ GetProtocolByIndex(proto_num).SetNick(tmp);
+ }
+
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ case IDCANCEL:
+ {
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ InterlockedExchange(&nickname_dialog_open, 0);
+ break;
+ }
+
+ return FALSE;
+}
+
+static int PluginCommand_SetMyNicknameUI(WPARAM wParam,LPARAM lParam)
+{
+ char * proto = (char *)lParam;
+ int proto_num = -1;
+
+ if (proto != NULL)
+ {
+ proto_num = GetProtocolIndexByName(proto);
+ if (proto_num == -1)
+ return -1;
+
+ if (!GetProtocolByIndex(proto_num).CanSetNick())
+ return -2;
+ }
+
+ if (!nickname_dialog_open)
+ {
+ InterlockedExchange(&nickname_dialog_open, 1);
+
+ hwndSetNickname = CreateDialog(hInst, MAKEINTRESOURCE( IDD_SETNICKNAME ), NULL, DlgProcSetNickname );
+
+ SendMessage(hwndSetNickname, WMU_SETDATA, proto_num, 0);
+ }
+
+ SetForegroundWindow( hwndSetNickname );
+ SetFocus( hwndSetNickname );
+ ShowWindow( hwndSetNickname, SW_SHOW );
+
+ return 0;
+}
+
+
+static int PluginCommand_SetMyNickname(WPARAM wParam,LPARAM lParam)
+{
+ char * proto = (char *)wParam;
+
+ if (proto != NULL)
+ {
+ Protocol protocol = GetProtocolByName(proto);
+ if (!protocol)
+ return -1;
+
+ if (!protocol.CanSetNick())
+ return -2;
+
+ protocol.SetNick((char *)lParam);
+ }
+ else
+ {
+ protocols->SetNicks((char *)lParam);
+ }
+
+ return 0;
+}
+
+
+static int PluginCommand_GetMyNickname(WPARAM wParam,LPARAM lParam)
+{
+ char * ret = (char *)lParam;
+ char * proto = (char *)wParam;
+
+ if (ret == NULL)
+ return -1;
+
+ if (proto == NULL)
+ {
+ if (protocols->default_nick != NULL)
+ lstrcpyn(ret, protocols->default_nick, MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE);
+ else
+ ret[0] = '\0';
+ }
+ else
+ {
+ Protocol protocol = GetProtocolByName(proto);
+ if (!protocol)
+ return -1;
+
+ lstrcpyn(ret, protocol.GetNick(), MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE);
+ }
+
+ return 0;
+}
+
+
+// Set avatar /////////////////////////////////////////////////////////////////////////////////////
+
+static int PluginCommand_SetMyAvatarUI(WPARAM wParam,LPARAM lParam)
+{
+ char * proto = (char *)lParam;
+ int proto_num = -1;
+
+ if (proto != NULL)
+ {
+ Protocol protocol = GetProtocolByName(proto);
+ if (!protocol)
+ return -1;
+
+ if (!protocol.CanSetAvatar())
+ return -2;
+
+ protocol.SetAvatar(NULL);
+ }
+ else
+ {
+ protocols->SetAvatars(NULL);
+ }
+
+ return 0;
+}
+
+
+static int PluginCommand_SetMyAvatar(WPARAM wParam,LPARAM lParam)
+{
+ char * proto = (char *)wParam;
+
+ if (proto != NULL)
+ {
+ Protocol protocol = GetProtocolByName(proto);
+ if (!protocol)
+ return -1;
+
+ if (!protocol.CanSetAvatar())
+ return -2;
+
+ protocol.SetAvatar((char *)lParam);
+ }
+ else
+ {
+ protocols->SetAvatars((char *)lParam);
+ }
+
+ return 0;
+}
+
+
+int Status2SkinIcon(int status)
+{
+ switch(status) {
+ case ID_STATUS_AWAY: return SKINICON_STATUS_AWAY;
+ case ID_STATUS_NA: return SKINICON_STATUS_NA;
+ case ID_STATUS_DND: return SKINICON_STATUS_DND;
+ case ID_STATUS_OCCUPIED: return SKINICON_STATUS_OCCUPIED;
+ case ID_STATUS_FREECHAT: return SKINICON_STATUS_FREE4CHAT;
+ case ID_STATUS_ONLINE: return SKINICON_STATUS_ONLINE;
+ case ID_STATUS_OFFLINE: return SKINICON_STATUS_OFFLINE;
+ case ID_STATUS_INVISIBLE: return SKINICON_STATUS_INVISIBLE;
+ case ID_STATUS_ONTHEPHONE: return SKINICON_STATUS_ONTHEPHONE;
+ case ID_STATUS_OUTTOLUNCH: return SKINICON_STATUS_OUTTOLUNCH;
+ case ID_STATUS_IDLE: return SKINICON_STATUS_AWAY;
+ }
+ return SKINICON_STATUS_OFFLINE;
+}
+
+
+
+static int PluginCommand_GetMyAvatar(WPARAM wParam,LPARAM lParam)
+{
+ char * ret = (char *)lParam;
+ char * proto = (char *)wParam;
+
+ if (ret == NULL)
+ return -1;
+
+ if (proto == NULL)
+ {
+ if (protocols->default_avatar_file != NULL)
+ lstrcpyn(ret, protocols->default_avatar_file, MS_MYDETAILS_GETMYAVATAR_BUFFER_SIZE);
+ else
+ ret[0] = '\0';
+ }
+ else
+ {
+ Protocol protocol = GetProtocolByName(proto);
+ if (!protocol)
+ return -1;
+
+ if (!protocol.CanGetAvatar())
+ return -2;
+
+ lstrcpyn(ret, protocol.GetAvatarFile(), MS_MYDETAILS_GETMYAVATAR_BUFFER_SIZE);
+ }
+
+ return 0;
+}
+
+static LRESULT CALLBACK StatusMsgEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_CHAR:
+ {
+ if(wParam == 0x0a && (GetKeyState(VK_CONTROL) & 0x8000) != 0) {
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+
+ break;
+ }
+ }
+
+ return CallWindowProc((WNDPROC) GetWindowLong(hwnd, GWL_USERDATA), hwnd, msg, wParam, lParam);
+}
+
+struct SetStatusMessageData {
+ int status;
+ int proto_num;
+};
+
+static BOOL CALLBACK DlgProcSetStatusMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch ( msg )
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ SendMessage(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), EM_LIMITTEXT,
+ MS_MYDETAILS_GETMYSTATUSMESSAGE_BUFFER_SIZE - 1, 0);
+
+ WNDPROC old_proc = (WNDPROC) SetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE),
+ GWL_WNDPROC, (LONG) StatusMsgEditSubclassProc);
+
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), GWL_USERDATA, (long) old_proc);
+
+ return TRUE;
+ }
+
+ case WMU_SETDATA:
+ {
+ SetStatusMessageData *data = (SetStatusMessageData *) malloc(sizeof(SetStatusMessageData));
+ data->status = (int)wParam;
+ data->proto_num = (int)lParam;
+
+ SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) data);
+
+ if (data->proto_num >= 0)
+ {
+ Protocol proto = GetProtocolByIndex(data->proto_num);
+
+ HICON hIcon = (HICON) proto.Call(PS_LOADICON, PLI_PROTOCOL);
+ if (hIcon != NULL)
+ {
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
+ DestroyIcon(hIcon);
+ }
+
+ char title[256];
+ mir_snprintf(title, sizeof(title), Translate("Set My Status Message for %s"),
+ proto.GetDescription());
+ SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)title);
+
+ SetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, proto.GetStatusMsg());
+ }
+ else if (data->status != 0)
+ {
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(Status2SkinIcon(data->status)));
+
+ char title[256];
+ mir_snprintf(title, sizeof(title), Translate("Set My Status Message for %s"),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, data->status, 0));
+ SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)title);
+
+ SetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, protocols->GetDefaultStatusMsg(data->status));
+ }
+ else
+ {
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+
+ SetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, protocols->GetDefaultStatusMsg());
+ }
+
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch(wParam)
+ {
+ case IDOK:
+ {
+ char tmp[MS_MYDETAILS_GETMYSTATUSMESSAGE_BUFFER_SIZE];
+ GetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, tmp, sizeof(tmp));
+
+ SetStatusMessageData *data = (SetStatusMessageData *) GetWindowLong(hwndDlg, GWL_USERDATA);
+
+ if (data->proto_num >= 0)
+ GetProtocolByIndex(data->proto_num).SetStatusMsg(tmp);
+ else if (data->status == 0)
+ protocols->SetStatusMsgs(tmp);
+ else
+ protocols->SetStatusMsgs(data->status, tmp);
+
+ // To force a refresh
+ UpdateFrameData();
+
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ case IDCANCEL:
+ {
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), GWL_WNDPROC,
+ GetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), GWL_USERDATA));
+ free((SetStatusMessageData *) GetWindowLong(hwndDlg, GWL_USERDATA));
+ InterlockedExchange(&status_msg_dialog_open, 0);
+ break;
+ }
+
+ return FALSE;
+}
+
+static int PluginCommand_SetMyStatusMessageUI(WPARAM wParam,LPARAM lParam)
+{
+ int status = (int)wParam;
+ char * proto_name = (char *)lParam;
+ int proto_num = -1;
+ Protocol proto(NULL);
+ TCHAR status_message[256];
+
+ if (status != 0 && (status < ID_STATUS_OFFLINE || status > ID_STATUS_OUTTOLUNCH))
+ return -10;
+
+ if (proto_name != NULL)
+ {
+ proto_num = GetProtocolIndexByName(proto_name);
+ if (proto_num == -1)
+ return -1;
+
+ proto = GetProtocolByIndex(proto_num);
+ if (!proto.CanSetStatusMsg())
+ return -2;
+ }
+
+ if (ServiceExists(MS_NAS_INVOKESTATUSWINDOW))
+ {
+ NAS_ISWINFO iswi;
+
+ ZeroMemory(&iswi, sizeof(iswi));
+
+ iswi.cbSize = sizeof(NAS_ISWINFO);
+
+ if (proto)
+ {
+ // Has to get the unparsed message
+ NAS_PROTOINFO pi;
+
+ ZeroMemory(&pi, sizeof(pi));
+ pi.cbSize = sizeof(NAS_PROTOINFO);
+ pi.szProto = (char *) proto.GetName();
+ pi.status = status;
+ pi.szMsg = NULL;
+
+ if (ServiceExists(MS_NAS_GETSTATE))
+ {
+ if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
+ {
+ if (pi.szMsg == NULL)
+ {
+ pi.szProto = NULL;
+
+ if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
+ {
+ if (pi.szMsg != NULL)
+ {
+ lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
+ mir_free(pi.szMsg);
+ }
+ }
+ }
+ else // if (pi.szMsg != NULL)
+ {
+ lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
+ mir_free(pi.szMsg);
+ }
+ }
+ }
+ // TODO: Remove when removing old NAS services support
+ else
+ {
+ NAS_PROTOINFO *pii = &pi;
+
+ // Old services
+ if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
+ {
+ if (pi.szMsg == NULL)
+ {
+ pi.szProto = NULL;
+
+ if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
+ {
+ if (pi.szMsg != NULL)
+ {
+ lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
+ mir_free(pi.szMsg);
+ }
+ }
+ }
+ else // if (pi.szMsg != NULL)
+ {
+ lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
+ mir_free(pi.szMsg);
+ }
+ }
+ }
+
+ iswi.szProto = (char *) proto.GetName();
+ iswi.szMsg = status_message;
+ }
+ else
+ {
+ iswi.szMsg = protocols->GetDefaultStatusMsg();
+ }
+
+ iswi.Flags = ISWF_NOCOUNTDOWN;
+
+ CallService(MS_NAS_INVOKESTATUSWINDOW, (WPARAM) &iswi, 0);
+
+ return 0;
+ }
+ else if (ServiceExists(MS_SA_SHOWSTATUSMSGDIALOG))
+ {
+ CallService(MS_SA_SHOWSTATUSMSGDIALOG, 0, (LPARAM) proto_name);
+ return 0;
+ }
+ else if (ServiceExists(MS_SA_CHANGESTATUSMSG))
+ {
+ if (!proto && status == 0)
+ {
+ CallService(MS_SA_CHANGESTATUSMSG, protocols->GetGlobalStatus(), NULL);
+ }
+ else if (status == 0)
+ {
+ CallService(MS_SA_CHANGESTATUSMSG, proto.GetStatus(), (LPARAM) proto_name);
+ }
+ else
+ {
+ CallService(MS_SA_CHANGESTATUSMSG, status, (LPARAM) proto_name);
+ }
+
+ return 0;
+ }
+ else if (!proto || proto.GetStatus() != ID_STATUS_OFFLINE)
+ {
+ if (!status_msg_dialog_open)
+ {
+ InterlockedExchange(&status_msg_dialog_open, 1);
+
+ hwndSetStatusMsg = CreateDialog(hInst, MAKEINTRESOURCE( IDD_SETSTATUSMESSAGE ), NULL, DlgProcSetStatusMessage );
+
+ SendMessage(hwndSetStatusMsg, WMU_SETDATA, status, proto_num);
+ }
+
+ SetForegroundWindow( hwndSetStatusMsg );
+ SetFocus( hwndSetStatusMsg );
+ ShowWindow( hwndSetStatusMsg, SW_SHOW );
+
+ return 0;
+ }
+
+ return -3;
+}
+
+
+static int PluginCommand_CicleThroughtProtocols(WPARAM wParam,LPARAM lParam)
+{
+ DBWriteContactSettingByte(NULL,"MyDetails","CicleThroughtProtocols", (BYTE) wParam);
+
+ LoadOptions();
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/MyDetails/mydetails.h b/plugins/MyDetails/mydetails.h
new file mode 100644
index 0000000000..0780f7335e
--- /dev/null
+++ b/plugins/MyDetails/mydetails.h
@@ -0,0 +1,42 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MYDETAILS_H__
+# define __MYDETAILS_H__
+
+
+extern "C"
+{
+
+// Dll init
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved);
+
+// Exports:
+__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion);
+int __declspec(dllexport) Load(PLUGINLINK *link);
+int __declspec(dllexport) Unload(void);
+
+
+}
+
+
+
+
+#endif // __MYDETAILS_H__ \ No newline at end of file
diff --git a/plugins/MyDetails/mydetails.vcproj b/plugins/MyDetails/mydetails.vcproj
new file mode 100644
index 0000000000..db4b4631a3
--- /dev/null
+++ b/plugins/MyDetails/mydetails.vcproj
@@ -0,0 +1,642 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="mydetails"
+ ProjectGUID="{A4855451-6447-437C-B024-B36C3C7901EA}"
+ SccProjectName="SAK"
+ SccAuxPath="SAK"
+ SccLocalPath="SAK"
+ SccProvider="SAK">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="1"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="../../include;sdk"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS"
+ StringPooling="TRUE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="commons.h"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/mydetails.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;sdk"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="commons.h"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib"
+ LinkIncremental="2"
+ SuppressStartupBanner="TRUE"
+ GenerateDebugInformation="TRUE"
+ GenerateMapFile="TRUE"
+ BaseAddress="0x3EC10000"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/mydetails.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="2057"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;sdk"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="commons.h"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib"
+ LinkIncremental="2"
+ SuppressStartupBanner="TRUE"
+ GenerateDebugInformation="TRUE"
+ GenerateMapFile="TRUE"
+ BaseAddress="0x3EC10000"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/mydetails.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="2057"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="1"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="../../include;sdk"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS"
+ StringPooling="TRUE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="commons.h"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib"
+ GenerateDebugInformation="TRUE"
+ GenerateMapFile="TRUE"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/mydetails.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath="data.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="frame.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\utils\mir_dblists.c">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\utils\mir_memory.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\utils\mir_options.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\utils\mir_smileys.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="mydetails.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="options.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath="resource.rc">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath="commons.h">
+ </File>
+ <File
+ RelativePath="data.h">
+ </File>
+ <File
+ RelativePath="frame.h">
+ </File>
+ <File
+ RelativePath="m_mydetails.h">
+ </File>
+ <File
+ RelativePath="m_simpleaway.h">
+ </File>
+ <File
+ RelativePath="..\utils\mir_dblists.h">
+ </File>
+ <File
+ RelativePath="..\utils\mir_memory.h">
+ </File>
+ <File
+ RelativePath="..\utils\mir_options.h">
+ </File>
+ <File
+ RelativePath="..\utils\mir_smileys.h">
+ </File>
+ <File
+ RelativePath="mydetails.h">
+ </File>
+ <File
+ RelativePath="options.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
+
diff --git a/plugins/MyDetails/options.cpp b/plugins/MyDetails/options.cpp
new file mode 100644
index 0000000000..c5c298c798
--- /dev/null
+++ b/plugins/MyDetails/options.cpp
@@ -0,0 +1,189 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+#include "options.h"
+
+
+
+// Prototypes /////////////////////////////////////////////////////////////////////////////////////
+
+Options opts;
+
+
+static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+// Functions //////////////////////////////////////////////////////////////////////////////////////
+
+
+
+static OptPageControl pageControls[] = {
+ { &opts.draw_text_rtl, CONTROL_CHECKBOX, IDC_TEXT_RTL, "TextRTL", (BYTE) 0 },
+ { &opts.cycle_through_protocols, CONTROL_CHECKBOX, IDC_CYCLE_THROUGH_PROTOS, "CicleThroughtProtocols", (BYTE) 1 },
+ { &opts.seconds_to_show_protocol, CONTROL_SPIN, IDC_CYCLE_TIME, "CicleTime", (WORD) 5, IDC_CYCLE_TIME_SPIN, (WORD) 1, (WORD) 255 },
+ { &opts.replace_smileys, CONTROL_CHECKBOX, IDC_REPLACE_SMILEYS, "ReplaceSmileys", (BYTE) 1 },
+ { &opts.resize_smileys, CONTROL_CHECKBOX, IDC_RESIZE_SMILEYS, "ResizeSmileys", (BYTE) 0 },
+ { &opts.use_contact_list_smileys, CONTROL_CHECKBOX, IDC_USE_CONTACT_LIST_SMILEYS, "UseContactListSmileys", (BYTE) 0 },
+ { &opts.global_on_avatar, CONTROL_CHECKBOX, IDC_GLOBAL_ON_AVATAR, "GlobalOnAvatar", (BYTE) 0 },
+ { &opts.global_on_nickname, CONTROL_CHECKBOX, IDC_GLOBAL_ON_NICKNAME, "GlobalOnNickname", (BYTE) 0 },
+ { &opts.global_on_status, CONTROL_CHECKBOX, IDC_GLOBAL_ON_STATUS, "GlobalOnStatus", (BYTE) 0 },
+ { &opts.global_on_status_message, CONTROL_CHECKBOX, IDC_GLOBAL_ON_STATUS_MESSAGE, "GlobalOnStatusMessage", (BYTE) 0 },
+ { &opts.draw_avatar_border, CONTROL_CHECKBOX, IDC_AVATAR_DRAW_BORDER, "AvatarDrawBorders", (BYTE) 0 },
+ { &opts.draw_avatar_border_color, CONTROL_COLOR, IDC_AVATAR_BORDER_COLOR, "AvatarBorderColor", (DWORD) RGB(0,0,0) },
+ { &opts.draw_avatar_round_corner, CONTROL_CHECKBOX, IDC_AVATAR_ROUND_CORNERS, "AvatarRoundCorners", (BYTE) 1 },
+ { &opts.draw_avatar_use_custom_corner_size, CONTROL_CHECKBOX, IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK, "AvatarUseCustomCornerSize", (BYTE) 0 },
+ { &opts.draw_avatar_custom_corner_size, CONTROL_SPIN, IDC_AVATAR_CUSTOM_CORNER_SIZE, "AvatarCustomCornerSize", (WORD) 4, IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN, (WORD) 1, (WORD) 255 },
+ { &opts.resize_frame, CONTROL_CHECKBOX, IDC_RESIZE_FRAME, "ResizeFrame", (BYTE) 0 },
+};
+
+
+// Initializations needed by options
+void LoadOptions()
+{
+ if (GetSystemMetrics(SM_MIDEASTENABLED))
+ pageControls[0].dwDefValue = TRUE;
+
+ LoadOpts(pageControls, MAX_REGS(pageControls), MODULE_NAME);
+
+ // This is created here to assert that this key always exists
+ opts.refresh_status_message_timer = DBGetContactSettingWord(NULL,"MyDetails","RefreshStatusMessageTimer",12);
+ DBWriteContactSettingWord(NULL,"MyDetails","RefreshStatusMessageTimer", opts.refresh_status_message_timer);
+
+ SetCycleTime();
+ RedrawFrame();
+}
+
+
+int InitOptionsCallback(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.position=-200000000;
+ odp.hInstance=hInst;
+ odp.pfnDlgProc=DlgProcOpts;
+ odp.pszTemplate=MAKEINTRESOURCE(IDD_OPTS);
+ odp.pszGroup=Translate("Customize");
+ odp.pszTitle=Translate("My Details");
+ odp.flags=ODPF_BOLDGROUPS;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+}
+
+
+void InitOptions()
+{
+ LoadOptions();
+
+ HookEvent(ME_OPT_INITIALISE, InitOptionsCallback);
+}
+
+// Deinitializations needed by options
+void DeInitOptions()
+{
+}
+
+
+static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ BOOL ret = SaveOptsDlgProc(pageControls, MAX_REGS(pageControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ if(!IsDlgButtonChecked(hwndDlg,IDC_AVATAR_DRAW_BORDER))
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR_L),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR),FALSE);
+ }
+ if(!IsDlgButtonChecked(hwndDlg,IDC_AVATAR_ROUND_CORNERS))
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN),FALSE);
+ }
+ if(!IsDlgButtonChecked(hwndDlg,IDC_SHOW_PROTO_NAME))
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_SHOW_CYCLE_PROTO_BUTTON),FALSE);
+ }
+ if (!ServiceExists(MS_SMILEYADD_BATCHPARSE))
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_REPLACE_SMILEYS),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_USE_CONTACT_LIST_SMILEYS),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_RESIZE_SMILEYS),FALSE);
+ }
+ if (!ServiceExists(MS_CLIST_FRAMES_SETFRAMEOPTIONS))
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_RESIZE_FRAME),FALSE);
+ }
+
+ break;
+ }
+ case WM_COMMAND:
+ {
+ if (LOWORD(wParam)==IDC_AVATAR_DRAW_BORDER)
+ {
+ BOOL enabled = IsDlgButtonChecked(hwndDlg,IDC_AVATAR_DRAW_BORDER);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR_L),enabled);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR),enabled);
+ }
+ else if (LOWORD(wParam)==IDC_AVATAR_ROUND_CORNERS)
+ {
+ BOOL enabled = IsDlgButtonChecked(hwndDlg,IDC_AVATAR_ROUND_CORNERS);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK),enabled);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE),enabled);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN),enabled);
+ }
+ else if (LOWORD(wParam)==IDC_SHOW_PROTO_NAME)
+ {
+ BOOL enabled = IsDlgButtonChecked(hwndDlg,IDC_SHOW_PROTO_NAME);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_SHOW_CYCLE_PROTO_BUTTON),enabled);
+ }
+
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ LoadOptions();
+
+ return TRUE;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/plugins/MyDetails/options.h b/plugins/MyDetails/options.h
new file mode 100644
index 0000000000..71d5f474c1
--- /dev/null
+++ b/plugins/MyDetails/options.h
@@ -0,0 +1,83 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __OPTIONS_H__
+# define __OPTIONS_H__
+
+
+#define TOP 0
+#define LEFT 1
+#define BOTTOM 2
+#define RIGHT 3
+
+struct Options
+{
+ bool cycle_through_protocols;
+ int seconds_to_show_protocol;
+ bool replace_smileys;
+ bool resize_smileys;
+ bool use_contact_list_smileys;
+
+ bool draw_text_rtl;
+// bool draw_text_align_right;
+
+// bool draw_show_protocol_name;
+// bool show_protocol_cycle_button;
+
+ bool global_on_avatar;
+ bool global_on_nickname;
+ bool global_on_status;
+ bool global_on_status_message;
+
+// bool draw_avatar_custom_size;
+// bool draw_avatar_allow_to_grow;
+// int draw_avatar_custom_size_pixels;
+ bool draw_avatar_border;
+ COLORREF draw_avatar_border_color;
+ bool draw_avatar_round_corner;
+ bool draw_avatar_use_custom_corner_size;
+ int draw_avatar_custom_corner_size;
+
+ COLORREF bkg_color;
+// int borders[4];
+
+// bool use_avatar_space_to_draw_text;
+
+ bool resize_frame;
+
+ int refresh_status_message_timer;
+};
+
+extern Options opts;
+
+
+// Initializations needed by options
+void InitOptions();
+
+// Deinitializations needed by options
+void DeInitOptions();
+
+
+// Loads the options from DB
+// It don't need to be called, except in some rare cases
+void LoadOptions();
+
+
+#endif // __OPTIONS_H__
diff --git a/plugins/MyDetails/res/leftarrow.ico b/plugins/MyDetails/res/leftarrow.ico
new file mode 100644
index 0000000000..4953e83bb5
--- /dev/null
+++ b/plugins/MyDetails/res/leftarrow.ico
Binary files differ
diff --git a/plugins/MyDetails/res/listening_to.ico b/plugins/MyDetails/res/listening_to.ico
new file mode 100644
index 0000000000..d359ec1a11
--- /dev/null
+++ b/plugins/MyDetails/res/listening_to.ico
Binary files differ
diff --git a/plugins/MyDetails/res/mail.ico b/plugins/MyDetails/res/mail.ico
new file mode 100644
index 0000000000..ba0e7d35de
--- /dev/null
+++ b/plugins/MyDetails/res/mail.ico
Binary files differ
diff --git a/plugins/MyDetails/res/rightarrow.ico b/plugins/MyDetails/res/rightarrow.ico
new file mode 100644
index 0000000000..2705830a79
--- /dev/null
+++ b/plugins/MyDetails/res/rightarrow.ico
Binary files differ
diff --git a/plugins/MyDetails/resource.h b/plugins/MyDetails/resource.h
new file mode 100644
index 0000000000..9bc277ea60
--- /dev/null
+++ b/plugins/MyDetails/resource.h
@@ -0,0 +1,72 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_SETNICKNAME 101
+#define IDD_OPTS 102
+#define IDD_SETSTATUSMESSAGE 103
+#define IDR_MENU1 104
+#define IDI_LISTENINGTO 105
+#define IDI_RIGHT_ARROW 106
+#define IDI_LEFT_ARROW 107
+#define IDI_EMAIL 111
+#define IDC_NICKNAME 1000
+#define IDC_SHOW_PROTO_NAME 1001
+#define IDC_CYCLE_THROUGH_PROTOS 1002
+#define IDC_TEXT_RTL 1003
+#define IDC_TEXT_ALIGN_RIGHT 1004
+#define IDC_REPLACE_SMILEYS 1005
+#define IDC_RESIZE_SMILEYS 1006
+#define IDC_RESIZE_FRAME 1007
+#define IDC_RESIZE_SMILEYS2 1008
+#define IDC_USE_CONTACT_LIST_SMILEYS 1008
+#define IDC_STATUSMESSAGE 1009
+#define IDC_GLOBAL_ON_NICKNAME 1009
+#define IDC_AVATAR_ALLOW_TO_GROW 1010
+#define IDC_GLOBAL_ON_STATUS_MESSAGE 1011
+#define IDC_GLOBAL_ON_STATUS 1012
+#define IDC_GLOBAL_ON_AVATAR 1013
+#define IDC_SHOW_CYCLE_PROTO_BUTTON 1014
+#define IDC_AVATAR_CUSTOM_CORNER_SIZE 1622
+#define IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN 1623
+#define IDC_BORDER_TOP 1624
+#define IDC_BORDER_TOP_SPIN 1625
+#define IDC_BORDER_LEFT 1626
+#define IDC_BORDER_LEFT_SPIN 1627
+#define IDC_BORDER_BOTTOM 1628
+#define IDC_BORDER_BOTTOM_SPIN 1629
+#define IDC_BORDER_RIGHT 1630
+#define IDC_BORDER_RIGHT_SPIN 1631
+#define IDC_CYCLE_TIME 1632
+#define IDC_CYCLE_TIME_SPIN 1633
+#define IDC_AVATAR_CUSTOM_SIZE 1634
+#define IDC_AVATAR_CUSTOM_SIZE_SPIN 1635
+#define IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK 1761
+#define IDC_AVATAR_DRAW_BORDER 1764
+#define IDC_AVATAR_CUSTOM_SIZE_CHK 1765
+#define IDC_AVATAR_ROUND_CORNERS 1800
+#define IDC_AVATAR_USE_FREE_SPACE 1801
+#define IDC_AVATAR_BORDER_COLOR_L 1839
+#define IDC_AVATAR_BORDER_COLOR 1840
+#define IDC_AVATAR_BKG_COLOR_L 1841
+#define IDC_AVATAR_BKG_COLOR 1842
+#define ID_CYCLE_THROUGH_PROTOS 40004
+#define ID_DONT_CYCLE_THROUGH_PROTOS 40005
+#define ID_SHOW_NEXT_PROTO 40006
+#define ID_SHOW_PREV_PROTO 40007
+#define ID_NICKPOPUP_SETMYNICKNAME 40008
+#define ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE 40009
+#define ID_AVATARPOPUP_SETMYAVATAR 40010
+#define ID_LISTENINGTOPOPUP_SENDLISTENINGTO 40011
+#define ID_CONTEXTPOPUP_ENABLELISTENINGTO 40012
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 112
+#define _APS_NEXT_COMMAND_VALUE 40013
+#define _APS_NEXT_CONTROL_VALUE 1011
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/MyDetails/resource.rc b/plugins/MyDetails/resource.rc
new file mode 100644
index 0000000000..5706422e8e
--- /dev/null
+++ b/plugins/MyDetails/resource.rc
@@ -0,0 +1,326 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "../../include/statusmodes.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_LISTENINGTO ICON DISCARDABLE "res\\listening_to.ico"
+IDI_RIGHT_ARROW ICON DISCARDABLE "res\\rightarrow.ico"
+IDI_LEFT_ARROW ICON DISCARDABLE "res\\leftarrow.ico"
+IDI_EMAIL ICON DISCARDABLE "res\\mail.ico"
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,1,11
+ PRODUCTVERSION 0,0,1,11
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080004b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", " \0"
+ VALUE "FileDescription", "MyDetails Miranda Plugin\0"
+ VALUE "FileVersion", "0, 0, 1, 11\0"
+ VALUE "InternalName", "mydetails\0"
+ VALUE "LegalCopyright", "Copyright © 2005-2008 Ricardo Pescuma Domenecci, Drugwash\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "mydetails.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "\0"
+ VALUE "ProductVersion", "0, 0, 1, 11\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x800, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SETNICKNAME DIALOG DISCARDABLE 0, 0, 283, 65
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Set My Nickname"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ RTEXT "Nickname:",IDC_STATIC,7,8,51,12
+ EDITTEXT IDC_NICKNAME,67,7,209,31,ES_MULTILINE | ES_AUTOVSCROLL |
+ WS_VSCROLL
+ DEFPUSHBUTTON "OK",IDOK,87,44,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,146,44,50,14
+END
+
+IDD_OPTS DIALOGEX 0, 0, 316, 246
+STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX " General ",IDC_STATIC,7,7,302,70
+ CONTROL "Cycle through protocols every:",
+ IDC_CYCLE_THROUGH_PROTOS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,18,114,14
+ EDITTEXT IDC_CYCLE_TIME,129,18,35,12,ES_NUMBER
+ CONTROL "",IDC_CYCLE_TIME_SPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS |
+ UDS_HOTTRACK,156,18,11,12
+ LTEXT "seconds",IDC_STATIC,171,21,32,11
+ CONTROL "Global on avatar",IDC_GLOBAL_ON_AVATAR,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,207,18,96,14
+ CONTROL "RTL",IDC_TEXT_RTL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 13,32,85,14
+ CONTROL "Global on nickname",IDC_GLOBAL_ON_NICKNAME,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,207,32,96,14
+ CONTROL "Auto-resize frame",IDC_RESIZE_FRAME,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,46,85,14
+ CONTROL "Use contact list smileys",IDC_USE_CONTACT_LIST_SMILEYS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,46,96,14
+ CONTROL "Global on status",IDC_GLOBAL_ON_STATUS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,207,46,96,14
+ CONTROL "Replace Smileys",IDC_REPLACE_SMILEYS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,60,85,14
+ CONTROL "Resize Smileys",IDC_RESIZE_SMILEYS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,105,60,96,14
+ CONTROL "Global on status message",IDC_GLOBAL_ON_STATUS_MESSAGE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,61,96,14
+ GROUPBOX " Avatar ",IDC_STATIC,7,80,302,59
+ CONTROL "Draw border on avatar",IDC_AVATAR_DRAW_BORDER,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,16,95,103,9
+ LTEXT "Border Color:",IDC_AVATAR_BORDER_COLOR_L,123,95,53,10
+ CONTROL "",IDC_AVATAR_BORDER_COLOR,"ColourPicker",WS_TABSTOP,180,
+ 92,17,13
+ CONTROL "Round corners of avatars",IDC_AVATAR_ROUND_CORNERS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,109,280,8
+ CONTROL "Custom corner size:",
+ IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,27,122,93,11
+ EDITTEXT IDC_AVATAR_CUSTOM_CORNER_SIZE,127,121,35,12,ES_NUMBER
+ CONTROL "",IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,165,121,11,12
+ LTEXT "pixels",IDC_STATIC,179,124,41,11
+END
+
+IDD_SETSTATUSMESSAGE DIALOG DISCARDABLE 0, 0, 283, 68
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Set My Status Message for All Status"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ RTEXT "Status Message:",IDC_STATIC,7,8,69,12
+ EDITTEXT IDC_STATUSMESSAGE,81,7,195,35,ES_MULTILINE |
+ ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
+ DEFPUSHBUTTON "OK",IDOK,87,47,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,146,47,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_SETNICKNAME, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 276
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 58
+ END
+
+ IDD_OPTS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 309
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 238
+ END
+
+ IDD_SETSTATUSMESSAGE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 276
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 61
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Portuguese (Brazil) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PTB)
+#ifdef _WIN32
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""../../include/statusmodes.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU DISCARDABLE
+BEGIN
+ POPUP "Status popup"
+ BEGIN
+ MENUITEM "&Offline", ID_STATUS_OFFLINE
+ MENUITEM "On&line", ID_STATUS_ONLINE
+ MENUITEM "&Away", ID_STATUS_AWAY
+ MENUITEM "&NA", ID_STATUS_NA
+ MENUITEM "Occ&upied", ID_STATUS_OCCUPIED
+ MENUITEM "&DND", ID_STATUS_DND
+ MENUITEM "&Free for chat", ID_STATUS_FREECHAT
+ MENUITEM "&Invisible", ID_STATUS_INVISIBLE
+ MENUITEM "On the &Phone", ID_STATUS_ONTHEPHONE
+ MENUITEM "Out to &Lunch", ID_STATUS_OUTTOLUNCH
+ END
+ POPUP "Context popup"
+ BEGIN
+ MENUITEM SEPARATOR
+ MENUITEM "Set My Avatar...", ID_AVATARPOPUP_SETMYAVATAR
+ MENUITEM "Set My Nickname...", ID_NICKPOPUP_SETMYNICKNAME
+ MENUITEM "Set My Status Message...", ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE
+
+ MENUITEM "Enable Listening To", ID_CONTEXTPOPUP_ENABLELISTENINGTO
+
+ MENUITEM SEPARATOR
+ MENUITEM "Show next protocol", ID_SHOW_NEXT_PROTO
+ MENUITEM "Show previous protocol", ID_SHOW_PREV_PROTO
+ MENUITEM SEPARATOR
+ MENUITEM "Cycle through protocols", ID_CYCLE_THROUGH_PROTOS
+ MENUITEM "Don't cycle through protocols",
+ ID_DONT_CYCLE_THROUGH_PROTOS
+ END
+ POPUP "Nick popup"
+ BEGIN
+ MENUITEM SEPARATOR
+ MENUITEM "Set My Nickname...", ID_NICKPOPUP_SETMYNICKNAME
+ END
+ POPUP "Status message popup"
+ BEGIN
+ MENUITEM SEPARATOR
+ MENUITEM "Set My Status Message...", ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE
+
+ END
+ POPUP "Avatar popup"
+ BEGIN
+ MENUITEM SEPARATOR
+ MENUITEM "Set My Avatar...", ID_AVATARPOPUP_SETMYAVATAR
+ END
+ POPUP "ListeningTo popup"
+ BEGIN
+ MENUITEM SEPARATOR
+ MENUITEM "Enable Listening To", ID_LISTENINGTOPOPUP_SENDLISTENINGTO
+
+ END
+END
+
+#endif // Portuguese (Brazil) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+