OSDN Git Service

Update copyright year
[radegast/radegast.git] / Radegast / GUI / Consoles / Assets / Notecard.cs
1 // 
2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2014, Radegast Development Team
4 // All rights reserved.
5 // 
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 
9 //     * Redistributions of source code must retain the above copyright notice,
10 //       this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above copyright
12 //       notice, this list of conditions and the following disclaimer in the
13 //       documentation and/or other materials provided with the distribution.
14 //     * Neither the name of the application "Radegast", nor the names of its
15 //       contributors may be used to endorse or promote products derived from
16 //       this software without specific prior written permission.
17 // 
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // $Id$
30 //
31 using System;
32 using System.Collections.Generic;
33 using System.Windows.Forms;
34 using OpenMetaverse;
35 using OpenMetaverse.Assets;
36
37 namespace Radegast
38 {
39     public partial class Notecard : DettachableControl
40     {
41         private RadegastInstance instance;
42         private GridClient client { get { return instance.Client; } }
43         private InventoryNotecard notecard;
44         private AssetNotecard receivedNotecard;
45         private Primitive prim;
46
47         public Notecard(RadegastInstance instance, InventoryNotecard notecard)
48             : this(instance, notecard, null)
49         {
50         }
51
52         public Notecard(RadegastInstance instance, InventoryNotecard notecard, Primitive prim)
53         {
54             InitializeComponent();
55             Disposed += new EventHandler(Notecard_Disposed);
56
57             this.instance = instance;
58             this.notecard = notecard;
59             this.prim = prim;
60
61             Text = notecard.Name;
62
63             rtbContent.DetectUrls = false;
64
65
66             if (notecard.AssetUUID == UUID.Zero)
67             {
68                 UpdateStatus("Blank");
69             }
70             else
71             {
72                 rtbContent.Text = " ";
73                 UpdateStatus("Loading...");
74
75                 if (prim == null)
76                 {
77                     client.Assets.RequestInventoryAsset(notecard, true, Assets_OnAssetReceived);
78                 }
79                 else
80                 {
81                     client.Assets.RequestInventoryAsset(notecard.AssetUUID, notecard.UUID, prim.ID, prim.OwnerID, notecard.AssetType, true, Assets_OnAssetReceived);
82                 }
83             }
84         }
85
86         void Notecard_Disposed(object sender, EventArgs e)
87         {
88         }
89
90         void Assets_OnAssetReceived(AssetDownload transfer, Asset asset)
91         {
92             if (InvokeRequired)
93             {
94                 if (!instance.MonoRuntime || IsHandleCreated)
95                     BeginInvoke(new MethodInvoker(() => Assets_OnAssetReceived(transfer, asset)));
96                 return;
97             }
98
99             if (transfer.Success)
100             {
101                 AssetNotecard n = (AssetNotecard)asset;
102                 n.Decode();
103                 receivedNotecard = n;
104
105                 string noteText = string.Empty;
106                 rtbContent.Clear();
107
108                 for (int i = 0; i < n.BodyText.Length; i++)
109                 {
110                     char c = n.BodyText[i];
111
112                     if ((int)c == 0xdbc0)
113                     {
114                         int index = (int)n.BodyText[++i] - 0xdc00;
115                         InventoryItem e = n.EmbeddedItems[index];
116                         rtbContent.AppendText(noteText);
117                         rtbContent.InsertLink(e.Name, string.Format("radegast://embeddedasset/{0}", index));
118                         noteText = string.Empty;
119                     }
120                     else
121                     {
122                         noteText += c;
123                     }
124                 }
125
126                 rtbContent.Text += noteText;
127
128                 if (n.EmbeddedItems != null && n.EmbeddedItems.Count > 0)
129                 {
130                     tbtnAttachments.Enabled = true;
131                     tbtnAttachments.Visible = true;
132                     foreach (InventoryItem item in n.EmbeddedItems)
133                     {
134                         int ix = InventoryConsole.GetItemImageIndex(item.AssetType.ToString().ToLower());
135                         ToolStripMenuItem titem = new ToolStripMenuItem(item.Name);
136
137                         if (ix != -1)
138                         {
139                             titem.Image = frmMain.ResourceImages.Images[ix];
140                             titem.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
141                         }
142                         else
143                         {
144                             titem.DisplayStyle = ToolStripItemDisplayStyle.Text;
145                         }
146
147                         titem.Name = item.UUID.ToString(); ;
148                         titem.Tag = item;
149                         titem.Click += new EventHandler(attachmentMenuItem_Click);
150
151                         var saveToInv = new ToolStripMenuItem("Save to inventory");
152                         saveToInv.Click += (object xsender, EventArgs xe) =>
153                             {
154                                 client.Inventory.RequestCopyItemFromNotecard(UUID.Zero,
155                                     notecard.UUID,
156                                     client.Inventory.FindFolderForType(item.AssetType),
157                                     item.UUID,
158                                     Inventory_OnInventoryItemCopied);
159                             };
160
161                         titem.DropDownItems.Add(saveToInv);
162                         tbtnAttachments.DropDownItems.Add(titem);
163                     }
164                 }
165                 UpdateStatus("OK");
166                 rtbContent.Focus();
167             }
168             else
169             {
170                 UpdateStatus("Failed");
171                 rtbContent.Text = "Failed to download notecard. " + transfer.Status;
172             }
173         }
174
175         private void Inventory_OnInventoryItemCopied(InventoryBase item)
176         {
177             if (InvokeRequired)
178             {
179                 if (!instance.MonoRuntime || IsHandleCreated)
180                     BeginInvoke(new MethodInvoker(() => Inventory_OnInventoryItemCopied(item)));
181                 return;
182             }
183
184             if (null == item) return;
185
186             instance.TabConsole.DisplayNotificationInChat(
187                 string.Format("{0} saved to inventory", item.Name),
188                 ChatBufferTextStyle.Invisible);
189
190             tlblStatus.Text = "Saved";
191             
192             if (item is InventoryNotecard)
193             {
194                 Notecard nc = new Notecard(instance, (InventoryNotecard)item);
195                 nc.pnlKeepDiscard.Visible = true;
196                 nc.ShowDetached();
197             }
198         }
199
200         void attachmentMenuItem_Click(object sender, EventArgs e)
201         {
202             if (sender is ToolStripMenuItem)
203             {
204                 ToolStripMenuItem titem = (ToolStripMenuItem)sender;
205                 InventoryItem item = (InventoryItem)titem.Tag;
206
207                 switch (item.AssetType)
208                 {
209                     case AssetType.Texture:
210                         SLImageHandler ih = new SLImageHandler(instance, item.AssetUUID, string.Empty);
211                         ih.Text = item.Name;
212                         ih.ShowDetached();
213                         break;
214
215                     case AssetType.Landmark:
216                         Landmark ln = new Landmark(instance, (InventoryLandmark)item);
217                         ln.ShowDetached();
218                         break;
219
220                     case AssetType.Notecard:
221                         client.Inventory.RequestCopyItemFromNotecard(UUID.Zero,
222                             notecard.UUID,
223                             notecard.ParentUUID,
224                             item.UUID,
225                             Inventory_OnInventoryItemCopied);
226                         break;
227                 }
228             }
229         }
230
231         private void btnRefresh_Click(object sender, EventArgs e)
232         {
233             if (notecard.AssetUUID == UUID.Zero) return;
234
235             rtbContent.Text = "Loading...";
236             client.Assets.RequestInventoryAsset(notecard, true, Assets_OnAssetReceived);
237         }
238
239         private void rtbContent_LinkClicked(object sender, LinkClickedEventArgs e)
240         {
241             //instance.MainForm.processLink(e.LinkText);
242         }
243
244
245         #region Detach/Attach
246         protected override void ControlIsNotRetachable()
247         {
248             tbtnAttach.Visible = false;
249         }
250
251         protected override void Detach()
252         {
253             base.Detach();
254             tbtnAttach.Text = "Attach";
255             tbtnExit.Enabled = true;
256         }
257
258         protected override void Retach()
259         {
260             base.Retach();
261             tbtnAttach.Text = "Detach";
262             tbtnExit.Enabled = false;
263         }
264
265         private void tbtnAttach_Click(object sender, EventArgs e)
266         {
267             if (Detached)
268             {
269                 Retach();
270             }
271             else
272             {
273                 Detach();
274             }
275         }
276         #endregion
277
278         private void tbtnExit_Click(object sender, EventArgs e)
279         {
280             if (Detached)
281             {
282                 FindForm().Close();
283             }
284         }
285
286         private void tbtnSave_Click(object sender, EventArgs e)
287         {
288             bool success = false;
289             string message = "";
290             AssetNotecard n = new AssetNotecard();
291             n.BodyText = rtbContent.Text;
292             n.EmbeddedItems = new List<InventoryItem>();
293
294             if (receivedNotecard != null)
295             {
296                 for (int i = 0; i < receivedNotecard.EmbeddedItems.Count; i++)
297                 {
298                     n.EmbeddedItems.Add(receivedNotecard.EmbeddedItems[i]);
299                     int indexChar = 0xdc00 + i;
300                     n.BodyText += (char)0xdbc0;
301                     n.BodyText += (char)indexChar;
302                 }
303             }
304
305             n.Encode();
306
307             UpdateStatus("Saving...");
308
309             InventoryManager.InventoryUploadedAssetCallback handler = delegate(bool uploadSuccess, string status, UUID itemID, UUID assetID)
310                     {
311                         success = uploadSuccess;
312                         if (itemID == notecard.UUID)
313                         {
314                             if (success)
315                             {
316                                 UpdateStatus("OK");
317                                 notecard.AssetUUID = assetID;
318                             }
319                             else
320                             {
321                                 UpdateStatus("Failed");
322                             }
323
324                         }
325                         message = status ?? "Unknown error uploading notecard asset";
326                     };
327
328             if (prim == null)
329             {
330                 client.Inventory.RequestUploadNotecardAsset(n.AssetData, notecard.UUID, handler);
331             }
332             else
333             {
334                 client.Inventory.RequestUpdateNotecardTask(n.AssetData, notecard.UUID, prim.ID, handler);
335             }
336         }
337
338         void UpdateStatus(string status)
339         {
340             if (InvokeRequired)
341             {
342                 if (!instance.MonoRuntime || IsHandleCreated)
343                     BeginInvoke(new MethodInvoker(() => UpdateStatus(status)));
344                 return;
345             }
346             instance.TabConsole.DisplayNotificationInChat("Notecard status: " + status, ChatBufferTextStyle.Invisible);
347             tlblStatus.Text = status;
348         }
349
350         private void rtbContent_KeyDown(object sender, KeyEventArgs e)
351         {
352             if (e.KeyCode == Keys.S && e.Control)
353             {
354                 if (e.Shift)
355                 {
356                 }
357                 else
358                 {
359                     tbtnSave_Click(this, EventArgs.Empty);
360                     e.Handled = e.SuppressKeyPress = true;
361                 }
362             }
363
364         }
365
366         private void rtbContent_Enter(object sender, EventArgs e)
367         {
368             instance.TabConsole.DisplayNotificationInChat("Editing notecard", ChatBufferTextStyle.Invisible);
369         }
370
371         private void btnKeep_Click(object sender, EventArgs e)
372         {
373             Retach();
374         }
375
376         private void btnDiscard_Click(object sender, EventArgs e)
377         {
378             client.Inventory.MoveItem(notecard.UUID, client.Inventory.FindFolderForType(AssetType.TrashFolder), notecard.Name);
379             Retach();
380         }
381     }
382 }