3
// Copyright (C) 2008 GNOME Do
5
// This program is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
20
using System.Collections.Generic;
30
using Do.Universe.Common;
32
using Do.Interface.CairoUtils;
34
using Docky.Interface.Menus;
35
using Docky.Utilities;
39
namespace Docky.Interface
43
public class ItemDockItem : WnckDockItem, IRightClickable
45
const string ErrorMessage = "Docky could not move the file to the requested Directory. " +
46
"Please check file name and permissions and try again";
52
Gdk.Pixbuf drag_pixbuf;
53
Gdk.Rectangle icon_region;
54
List<Wnck.Application> apps;
56
public event EventHandler RemoveClicked;
58
public override bool IsAcceptingDrops {
59
get { return accepting_drops; }
63
get { return element.Icon; }
67
get { return element; }
70
protected override IEnumerable<Wnck.Application> Applications {
74
public IEnumerable<int> Pids {
75
get { return apps.Select (win => win.Pid).ToArray (); }
78
public override int WindowCount {
79
get { return window_count; }
82
public ItemDockItem (Item element) : base ()
85
this.element = element;
86
apps = new List<Wnck.Application> ();
88
SetText (element.Name);
91
NeedsAttention = DetermineUrgencyStatus ();
93
if (element is IFileItem && Directory.Exists ((element as IFileItem).Path))
94
accepting_drops = true;
96
accepting_drops = false;
99
public override bool ReceiveItem (string item)
102
if (!IsAcceptingDrops)
105
if (item.StartsWith ("file://"))
106
item = item.Substring ("file://".Length);
108
if (File.Exists (item)) {
110
File.Move (item, System.IO.Path.Combine ((Element as IFileItem).Path, System.IO.Path.GetFileName (item)));
113
Services.Notifications.Notify ("Docky Error", ErrorMessage);
115
} else if (Directory.Exists (item)) {
117
Directory.Move (item, System.IO.Path.Combine ((Element as IFileItem).Path, System.IO.Path.GetFileName (item)));
120
Services.Notifications.Notify ("Docky Error", ErrorMessage);
126
public void UpdateApplication ()
128
UnregisterStateChangeEvents ();
130
if (element is IApplicationItem) {
131
apps = WindowUtils.GetApplicationList ((element as IApplicationItem).Exec);
132
window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count ();
135
RegisterStateChangeEvents ();
138
void RegisterStateChangeEvents ()
140
foreach (Application app in Applications) {
141
foreach (Wnck.Window w in app.Windows) {
142
if (!w.IsSkipTasklist)
143
w.StateChanged += OnWindowStateChanged;
148
void UnregisterStateChangeEvents ()
150
foreach (Application app in Applications) {
151
foreach (Wnck.Window w in app.Windows) {
153
w.StateChanged -= OnWindowStateChanged;
159
void OnWindowStateChanged (object o, StateChangedArgs args)
161
if (handle_timer > 0) return;
162
// we do this delayed so that we dont get a flood of these events. Certain windows behave badly.
163
handle_timer = GLib.Timeout.Add (100, HandleUpdate);
164
window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count ();
165
SetIconRegionFromCache ();
170
bool needed_attention = NeedsAttention;
171
NeedsAttention = DetermineUrgencyStatus ();
173
if (NeedsAttention != needed_attention) {
174
UpdateRequestType req;
176
req = UpdateRequestType.NeedsAttentionSet;
178
req = UpdateRequestType.NeedsAttentionUnset;
179
OnUpdateNeeded (new UpdateRequestArgs (this, req));
186
protected override Gdk.Pixbuf GetSurfacePixbuf (int size)
188
Gdk.Pixbuf pbuf = IconProvider.PixbufFromIconName (Icon, size);
189
if (pbuf.Height != size && pbuf.Width != size) {
190
double scale = (double)DockPreferences.FullIconSize / Math.Max (pbuf.Width, pbuf.Height);
191
Gdk.Pixbuf temp = pbuf.ScaleSimple ((int) (pbuf.Width * scale), (int) (pbuf.Height * scale), InterpType.Bilinear);
199
public override Pixbuf GetDragPixbuf ()
201
if (drag_pixbuf == null)
202
drag_pixbuf = IconProvider.PixbufFromIconName (Icon, DockPreferences.FullIconSize);
206
public override void HotSeatRequested ()
208
if (WindowCount == 0) return;
210
List<AbstractDockItem> dockitems = new List<AbstractDockItem> ();
212
foreach (Act act in ActionsForItem (element)) {
213
dockitems.Add (new ActionDockItem (act, element));
216
Docky.Core.DockServices.ItemsService.HotSeatItem (this, dockitems);
217
base.HotSeatRequested ();
220
protected override void Launch ()
222
if (Element is IFileItem)
223
Services.Core.PerformDefaultAction (Element as Item, new [] { typeof (OpenAction), });
225
Services.Core.PerformDefaultAction (Element as Item, Type.EmptyTypes);
228
public override void SetIconRegion (Gdk.Rectangle region)
230
if (icon_region == region) return;
231
icon_region = region;
232
SetIconRegionFromCache ();
235
void SetIconRegionFromCache ()
237
VisibleWindows.ForEach (w => w.SetIconGeometry (icon_region.X, icon_region.Y, icon_region.Width, icon_region.Height));
240
public override bool Equals (AbstractDockItem other)
242
if (other == null) return false;
244
ItemDockItem di = other as ItemDockItem;
245
return di != null && di.Element != null && Element != null && di.Element.UniqueId == Element.UniqueId;
248
#region IDisposable implementation
250
public override void Dispose ()
252
UnregisterStateChangeEvents ();
256
if (drag_pixbuf != null)
257
drag_pixbuf.Dispose ();
264
#region IRightClickable implementation
266
public IEnumerable<AbstractMenuArgs> GetMenuItems ()
268
bool hasApps = HasVisibleApps;
270
yield return new SeparatorMenuButtonArgs ();
273
foreach (Act act in ActionsForItem (element))
274
yield return new LaunchMenuButtonArgs (act, element, act.Name, act.Icon).AsDark ();
276
foreach (Act act in ActionsForItem (element))
277
yield return new LaunchMenuButtonArgs (act, element, act.Name, act.Icon);
281
foreach (Wnck.Window window in VisibleWindows) {
282
yield return new SeparatorMenuButtonArgs ();
283
yield return new WindowMenuButtonArgs (window, window.Name, Icon);