Пример #1
0
        internal static string ExpandParameters(string p, ExtendedScreenshot ss)
        {
            if (string.IsNullOrEmpty(p))
            {
                return(string.Empty);
            }

            return(Regex.Replace(p, @":[a-z]+", new MatchEvaluator(m =>
            {
                try
                {
                    switch (m.Value)
                    {
                    case ":w": return ss.WindowTitle;

                    case ":url": return ss.Remote.ImageLink;

                    case ":delete": return ss.Remote.DeleteLink;

                    case ":file": return string.IsNullOrEmpty(ss.SavedFileName) ? ss.InternalFileName : ss.SavedFileName;

                    case ":image": return "";

                    default: return ss.Date.ToString(m.Value.TrimStart(':'));
                    }
                }
                catch (FormatException fe)
                {
                    return m.Value;
                }
            }), RegexOptions.IgnoreCase));
        }
Пример #2
0
        internal static string ExpandParameters(string p, ExtendedScreenshot ss)
        {
            if (string.IsNullOrEmpty(p))
                return string.Empty;

            return Regex.Replace(p, @":[a-z]+", new MatchEvaluator(m =>
            {
                try
                {
                    switch (m.Value)
                    {
                        case ":w": return ss.WindowTitle;
                        case ":url": return ss.Remote.ImageLink;
                        case ":delete": return ss.Remote.DeleteLink;
                        case ":file": return string.IsNullOrEmpty(ss.SavedFileName) ? ss.InternalFileName : ss.SavedFileName;
                        case ":image": return "";
                        default: return ss.Date.ToString(m.Value.TrimStart(':'));
                    }
                }
                catch (FormatException fe)
                {
                    return m.Value;
                }
            }), RegexOptions.IgnoreCase);
        }
Пример #3
0
        private static void DoActionItem(ShortcutItem ActiveShortcutItem, int itemIndex, ExtendedScreenshot ActionItemScreenshot)
        {
            if (ActiveShortcutItem == null || itemIndex >= ActiveShortcutItem.ActionChain.ActionItems.Count)
            {
                Trace.WriteLine("No more action items to execute", string.Format("Program.DoActionItem [{0}]", System.Threading.Thread.CurrentThread.Name));

                //todo: Why can't the hook be reinstated on the action thread?
                Preview.BeginInvoke(new MethodInvoker(() => KeyboardHook.isPaused = false));
                IconAnimation.CancelAsync();

                return;
            }

            IActionItem CurrentActionItem = ActiveShortcutItem.ActionChain.ActionItems[itemIndex];

            //don't try and invoke the scrolling screenshot actions if they're the first type in the action chain (eg, solo items for their shortcuts) and there's no active scrolling screenshot happening
            //at least this solves flashing the icon whenever 'End' key is pressed during normal computer use
            if (!Program.isTakingScrollingScreenshot && (CurrentActionItem.ActionType == ActionTypes.ContinueScrollingScreenshot || CurrentActionItem.ActionType == ActionTypes.EndScrollingScreenshot) && itemIndex == 0)
                return;

            KeyboardHook.isPaused = true;

            Trace.WriteLine(CurrentActionItem.ActionType, string.Format("Program.DoActionItem [{0}]", System.Threading.Thread.CurrentThread.Name));

            //todo: figure out a better way to do these exclusions rather than harcoding behavior for scrolling screenshots
            if (!IconAnimation.IsBusy)
                if ((new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType) && isTakingScrollingScreenshot) || !new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType))
                    IconAnimation.RunWorkerAsync();

            Task.Factory.StartNew<ExtendedScreenshot>(() => CurrentActionItem.Invoke(ActionItemScreenshot))
                .ContinueWith(t => DoActionItem(ActiveShortcutItem, itemIndex + 1, t.Result));
        }
Пример #4
0
        public UploadedFileDetails(ExtendedScreenshot metadata)
        {
            InitializeComponent();

            this.BackColor = Color.Black;
            this.Paint    += new PaintEventHandler(UploadedFileDetails_Paint);
            this.Load     += new EventHandler(UploadedFileDetails_Load);

            this.Metadata = metadata;

            //Much more reliable than MouseLeave for the form
            MousePositionCheck.Tick += (s, e) =>
            {
                Rectangle b = this.Bounds;
                b.Inflate(10, 10);
                if (!b.Contains(MousePosition))
                {
                    MousePositionCheck.Enabled = false;
                    FadeClose(1500);
                }
                //else
                //    Opacity = MaxOpacity;
            };
            MousePositionCheck.Interval = 100;
            MousePositionCheck.Enabled  = true;
        }
Пример #5
0
        private void LoadScreenshot(ExtendedScreenshot targetWindow)
        {
            Trace.WriteLine("Loading image...", string.Format("PeekPreview.LoadScreenshot [{0}]", System.Threading.Thread.CurrentThread.Name));

            pbPreview.Image = null;

            tsmiRoundCorners.Checked = targetWindow.withBorderRounding;
            tsmiWindowShadow.Checked = targetWindow.withBorderShadow;
            tsmiMouseCursor.Checked  = targetWindow.withCursor;

            CurrentScreenshot = targetWindow;
            ReloadPreviewImage();

            ResetFadeCloseCountdown();
            GroomBackForwardIcons();
            GroomHeartIcon();

            pnUpload.BackgroundImage = CurrentScreenshot == null || string.IsNullOrEmpty(CurrentScreenshot.Remote.ImageLink) ? Resources.cloud_upload_32x32_black : Resources.cloud_upload_link_black_32x32;

            if (Configuration.PreviewDelayTime > 0)
            {
                FadeCloseCountdown.Interval = Configuration.PreviewDelayTime * 1000;
            }

            Opacity = 1;

            Trace.WriteLine("Done.", string.Format("PeekPreview.LoadScreenshot [{0}]", System.Threading.Thread.CurrentThread.Name));
        }
Пример #6
0
        public UploadedFileDetails(ExtendedScreenshot metadata)
        {
            InitializeComponent();

            this.BackColor = Color.Black;
            this.Paint += new PaintEventHandler(UploadedFileDetails_Paint);
            this.Load += new EventHandler(UploadedFileDetails_Load);

            this.Metadata = metadata;

            //Much more reliable than MouseLeave for the form
            MousePositionCheck.Tick += (s, e) =>
                {
                    Rectangle b = this.Bounds;
                    b.Inflate(10,10);
                    if (!b.Contains(MousePosition))
                    {
                        MousePositionCheck.Enabled = false;
                        FadeClose(1500);
                    }
                    //else
                    //    Opacity = MaxOpacity;
                };
            MousePositionCheck.Interval = 100;
            MousePositionCheck.Enabled = true;
        }
Пример #7
0
        public void Show(ExtendedScreenshot targetWindow = null)
        {
            Trace.WriteLine("Showing preview...", string.Format("PeekPreview.Show [{0}]", System.Threading.Thread.CurrentThread.Name));

            if (this.InvokeRequired)
            {
                Trace.WriteLine("Self invoking...", string.Format("PeekPreview.Show [{0}]", System.Threading.Thread.CurrentThread.Name));

                this.BeginInvoke(new MethodInvoker(() => this.Show(targetWindow)));
                return;
            }

            targetWindow = targetWindow ?? this.CurrentScreenshot ?? Program.History.LastOrDefault();
            if (targetWindow == null)
            {
                Trace.WriteLine("No screenshot to show", string.Format("PeekPreview.Show [{0}]", System.Threading.Thread.CurrentThread.Name));
                return;
            }

            this.LoadScreenshot(targetWindow);
            base.Show();
        }
Пример #8
0
        internal static string ExpandParameters(string p, ExtendedScreenshot ss)
        {
            if (string.IsNullOrEmpty(p))
                return string.Empty;

            p = p.Replace(":yyyy", ss.Date.ToString("yyyy"));
            p = p.Replace(":yy", ss.Date.ToString("yy"));

            p = p.Replace(":MMMM", ss.Date.ToString("MMMM"));
            p = p.Replace(":MMM", ss.Date.ToString("MMM"));
            p = p.Replace(":MM", ss.Date.ToString("MM"));
            p = p.Replace(":M", ss.Date.ToString("M"));

            p = p.Replace(":dddd", ss.Date.ToString("dddd"));
            p = p.Replace(":ddd", ss.Date.ToString("ddd"));
            p = p.Replace(":dd", ss.Date.ToString("dd"));
            p = p.Replace(":d", ss.Date.ToString("d"));

            p = p.Replace(":hh", ss.Date.ToString("hh"));
            p = p.Replace(":HH", ss.Date.ToString("HH"));

            p = p.Replace(":mm", ss.Date.ToString("mm"));
            p = p.Replace(":m", ss.Date.ToString("m"));

            p = p.Replace(":ss", ss.Date.ToString("ss"));
            p = p.Replace(":s", ss.Date.ToString("s"));

            p = p.Replace(":tt", ss.Date.ToString("tt"));
            p = p.Replace(":t", ss.Date.ToString("t"));

            p = p.Replace(":zzz", ss.Date.ToString("zzz"));
            p = p.Replace(":zz", ss.Date.ToString("zz"));

            p = p.Replace(":w", ss.WindowTitle);

            return p;
        }
Пример #9
0
        private void LoadScreenshot(ExtendedScreenshot targetWindow)
        {
            Trace.WriteLine("Loading image...", string.Format("PeekPreview.LoadScreenshot [{0}]", System.Threading.Thread.CurrentThread.Name));

            pbPreview.Image = null;

            tsmiRoundCorners.Checked = targetWindow.withBorderRounding;
            tsmiWindowShadow.Checked = targetWindow.withBorderShadow;
            tsmiMouseCursor.Checked = targetWindow.withCursor;

            CurrentScreenshot = targetWindow;
            ReloadPreviewImage();

            ResetFadeCloseCountdown();
            GroomBackForwardIcons();
            GroomHeartIcon();

            pnUpload.BackgroundImage = CurrentScreenshot == null || string.IsNullOrEmpty(CurrentScreenshot.Remote.ImageLink) ? Resources.cloud_upload_32x32_black : Resources.cloud_upload_link_black_32x32;

            if (Configuration.PreviewDelayTime > 0)
                FadeCloseCountdown.Interval = Configuration.PreviewDelayTime * 1000;

            Opacity = 1;

            Trace.WriteLine("Done.", string.Format("PeekPreview.LoadScreenshot [{0}]", System.Threading.Thread.CurrentThread.Name));
        }
Пример #10
0
        public void Show(ExtendedScreenshot targetWindow = null)
        {
            Trace.WriteLine("Showing preview...", string.Format("PeekPreview.Show [{0}]", System.Threading.Thread.CurrentThread.Name));

            if (this.InvokeRequired)
            {
                Trace.WriteLine("Self invoking...", string.Format("PeekPreview.Show [{0}]", System.Threading.Thread.CurrentThread.Name));

                this.BeginInvoke(new MethodInvoker(() => this.Show(targetWindow)));
                return;
            }

            targetWindow = targetWindow ?? this.CurrentScreenshot ?? Program.History.LastOrDefault();
            if (targetWindow == null)
            {
                Trace.WriteLine("No screenshot to show", string.Format("PeekPreview.Show [{0}]", System.Threading.Thread.CurrentThread.Name));
                return;
            }

            this.LoadScreenshot(targetWindow);
            base.Show();
        }
Пример #11
0
        private static void DoActionItem(ShortcutItem ActiveShortcutItem, int itemIndex, ExtendedScreenshot ActionItemScreenshot)
        {
            if (ActiveShortcutItem == null || itemIndex >= ActiveShortcutItem.ActionChain.ActionItems.Count)
            {
                Trace.WriteLine("No more action items to execute", string.Format("Program.DoActionItem [{0}]", System.Threading.Thread.CurrentThread.Name));

                //todo: Why can't the hook be reinstated on the action thread?
                Preview.BeginInvoke(new MethodInvoker(() => KeyboardHook.isPaused = false));
                IconAnimation.CancelAsync();

                return;
            }

            IActionItem CurrentActionItem = ActiveShortcutItem.ActionChain.ActionItems[itemIndex];

            //don't try and invoke the scrolling screenshot actions if they're the first type in the action chain (eg, solo items for their shortcuts) and there's no active scrolling screenshot happening
            //at least this solves flashing the icon whenever 'End' key is pressed during normal computer use
            if (!Program.isTakingScrollingScreenshot && (CurrentActionItem.ActionType == ActionTypes.ContinueScrollingScreenshot || CurrentActionItem.ActionType == ActionTypes.EndScrollingScreenshot) && itemIndex == 0)
            {
                return;
            }

            KeyboardHook.isPaused = true;

            Trace.WriteLine(CurrentActionItem.ActionType, string.Format("Program.DoActionItem [{0}]", System.Threading.Thread.CurrentThread.Name));

            //todo: figure out a better way to do these exclusions rather than harcoding behavior for scrolling screenshots
            if (!IconAnimation.IsBusy)
            {
                if ((new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType) && isTakingScrollingScreenshot) || !new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType))
                {
                    IconAnimation.RunWorkerAsync();
                }
            }

            Task.Factory.StartNew <ExtendedScreenshot>(() => CurrentActionItem.Invoke(ActionItemScreenshot))
            .ContinueWith(t => DoActionItem(ActiveShortcutItem, itemIndex + 1, t.Result));
        }
Пример #12
0
        private static void DoActionItem(ShortcutItem ActiveShortcutItem, int itemIndex)
        {
            if (ActiveShortcutItem == null || itemIndex >= ActiveShortcutItem.ActionChain.ActionItems.Count)
            {
                Trace.WriteLine("No more action items to execute", string.Format("Program.DoActionItem [{0}]", Thread.CurrentThread.Name));

                //todo: Why can't the hook be reinstated on the action thread?
                Preview.BeginInvoke(new MethodInvoker(() => KeyboardHook.isPaused = false));
                IconAnimation.CancelAsync();

                return;
            }

            KeyboardHook.isPaused = true;

            IActionItem CurrentActionItem = ActiveShortcutItem.ActionChain.ActionItems[itemIndex];
            Trace.WriteLine(CurrentActionItem.ActionType, string.Format("Program.DoActionItem [{0}]", Thread.CurrentThread.Name));

            //todo: figure out a better way to do these exclusions rather than harcoding behavior for scrolling screenshots
            if (!IconAnimation.IsBusy)
                if ((new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType) && isTakingScrollingScreenshot) || !new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType))
                    IconAnimation.RunWorkerAsync();

            switch (CurrentActionItem.ActionType)
            {
                case ActionTypes.TakeForegroundScreenshot:
                    {
                        var CurrentActionConfig = CurrentActionItem as TakeForegroundScreenshotAction;

                        try
                        {
                            var ForegroundWindowScreenshot = new ExtendedScreenshot(CurrentActionConfig.Method, CurrentActionConfig.SolidGlass);
                            History.Add(ForegroundWindowScreenshot);
                        }
                        catch (Exception e)
                        {
                            Trace.WriteLine(string.Format("Exception in TakeForegroundScreenshot: {0}", e.GetBaseException()), string.Format("Program.DoActionItem [{0}]", Thread.CurrentThread.Name));

                            ReportListener reporter = Trace.Listeners.Cast<TraceListener>().Where(tl => tl is ReportListener).FirstOrDefault() as ReportListener;
                            File.WriteAllText(Path.Combine(Configuration.LocalPath, "report.txt"), string.Join("\n", reporter.Messages.Select(m => string.Format("{0} {1}: {2}", m.Timestamp, m.Category, m.Message)).ToArray()));
                        }

                        DoActionItem(ActiveShortcutItem, itemIndex + 1);
                    } break;

                case ActionTypes.TakeRegionScreenshot:
                    {
                        var CurrentActionConfig = CurrentActionItem as TakeRegionScreenshotAction;
                        Rectangle SelectedRegion = CurrentActionConfig.Region;

                        try
                        {
                            if (CurrentActionConfig.UseRegionSelector)
                            {
                                lock (_actionlock)
                                {
                                    var e = new PreviewEventArgs() { ActionItem = CurrentActionItem };
                                    ShowPreviewEvent(null, e);

                                    Monitor.Wait(_actionlock);
                                    SelectedRegion = (Rectangle)e.Result;
                                }
                            }

                            if (!SelectedRegion.IsEmpty)
                            {
                                var RegionScreenshot = new ExtendedScreenshot(SelectedRegion);
                                History.Add(RegionScreenshot);

                                DoActionItem(ActiveShortcutItem, itemIndex + 1);
                            }
                            else
                            {
                                DoActionItem(null, itemIndex + 1);
                            }
                        }
                        catch (Exception e)
                        {
                            Trace.WriteLine(string.Format("Exception in TakeRegionScreenshot: {0}", e.GetBaseException()), string.Format("Program.DoActionItem [{0}]", Thread.CurrentThread.Name));

                            ReportListener reporter = Trace.Listeners.Cast<TraceListener>().Where(tl => tl is ReportListener).FirstOrDefault() as ReportListener;
                            File.WriteAllText(Path.Combine(Configuration.LocalPath, "report.txt"), string.Join("\n", reporter.Messages.Select(m => string.Format("{0} {1}: {2}", m.Timestamp, m.Category, m.Message)).ToArray()));

                            DoActionItem(null, itemIndex + 1);

                        }
                    } break;

                case ActionTypes.ShowPreview:
                    {
                        if (Configuration.PreviewDelayTime != 0 && History.Count > 0)
                            ShowPreviewEvent(History.Last(), new PreviewEventArgs());

                        DoActionItem(ActiveShortcutItem, itemIndex + 1);
                    } break;
                case ActionTypes.Heart:
                    {
                        var LatestScreenshot = History.LastOrDefault();
                        if (LatestScreenshot != null)
                        {
                            lock (_actionlock)
                            {
                                ShowPreviewEvent(LatestScreenshot, new PreviewEventArgs() { ActionItem = CurrentActionItem });
                                Monitor.Wait(_actionlock);
                                DoActionItem(ActiveShortcutItem, itemIndex + 1);
                            }
                        }
                    } break;
                case ActionTypes.Save:
                    {
                        var LatestScreenshot = History.LastOrDefault();
                        if (LatestScreenshot != null)
                        {
                            var Save = CurrentActionItem as SaveAction;
                            Trace.WriteLine(string.Format("Prompting for save: {0}", Save.Prompt), string.Format("Program.DoActionItem Save [{0}]", Thread.CurrentThread.Name));

                            if (Save.Prompt)
                            {
                                lock (_actionlock)
                                {
                                    ShowPreviewEvent(LatestScreenshot, new PreviewEventArgs() { ActionItem = CurrentActionItem });
                                    Monitor.Wait(_actionlock);
                                    DoActionItem(ActiveShortcutItem, itemIndex + 1);
                                }
                            }
                            else
                            {
                                string FileName = Environment.ExpandEnvironmentVariables(Helper.ExpandParameters(Save.FilePath, LatestScreenshot));
                                if (!string.IsNullOrEmpty(FileName))
                                {
                                    try
                                    {
                                        var dir = Path.GetDirectoryName(FileName);
                                        if (!Directory.Exists(dir))
                                        {
                                            Trace.WriteLine("Attempting to create directory...", string.Format("Program.DoActionItem Save [{0}]", Thread.CurrentThread.Name));
                                            Directory.CreateDirectory(dir);
                                        }

                                        LatestScreenshot.ComposedScreenshotImage.Save(FileName, Helper.ExtToImageFormat(Path.GetExtension(FileName)));
                                        LatestScreenshot.SavedFileName = FileName;
                                    }
                                    catch (Exception e)
                                    {
                                        MessageBox.Show(string.Format("There was a problem saving your screenshot:\r\n\r\n{0}", e.GetBaseException().Message), "ProSnap", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                                    }
                                }
                                else
                                {
                                    MessageBox.Show(string.Format("There was a problem saving your screenshot:\r\n\r\n{0}", "No file name has been provided."), "ProSnap", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                                }

                                DoActionItem(ActiveShortcutItem, itemIndex + 1);
                            }
                        }
                    } break;

                case ActionTypes.Upload:
                    {
                        var LatestScreenshot = History.LastOrDefault();
                        if (LatestScreenshot != null)
                        {
                            lock (_actionlock)
                            {
                                ShowPreviewEvent(LatestScreenshot, new PreviewEventArgs() { ActionItem = CurrentActionItem });
                                Monitor.Wait(_actionlock);
                                DoActionItem(ActiveShortcutItem, itemIndex + 1);
                            }
                        }
                    } break;

                case ActionTypes.ApplyEdits:
                    {
                        var LatestScreenshot = History.LastOrDefault();
                        if (LatestScreenshot != null)
                        {
                            var CurrentActionConfig = CurrentActionItem as ApplyEditsAction;

                            switch (CurrentActionConfig.DefaultBorderRounding)
                            {
                                case ApplyEditsAction.ApplicationMode.Automatic: LatestScreenshot.withBorderRounding = !LatestScreenshot.isMaximized && LatestScreenshot.isRounded && !(FMUtils.WinApi.Helper.OperatingSystem == FMUtils.WinApi.Helper.OperatingSystems.Win8); break;
                                case ApplyEditsAction.ApplicationMode.On: LatestScreenshot.withBorderRounding = true; break;
                                case ApplyEditsAction.ApplicationMode.Off: LatestScreenshot.withBorderRounding = false; break;
                            }

                            switch (CurrentActionConfig.DefaultBorderShadow)
                            {
                                case ApplyEditsAction.ApplicationMode.Automatic: LatestScreenshot.withBorderShadow = !LatestScreenshot.isMaximized; break;
                                case ApplyEditsAction.ApplicationMode.On: LatestScreenshot.withBorderShadow = true; break;
                                case ApplyEditsAction.ApplicationMode.Off: LatestScreenshot.withBorderShadow = false; break;
                            }

                            switch (CurrentActionConfig.ShowMouseCursor)
                            {
                                case ApplyEditsAction.ApplicationMode.Automatic: LatestScreenshot.withCursor = LatestScreenshot.CompositionRect.Contains(LatestScreenshot.CursorLocation); break;
                                case ApplyEditsAction.ApplicationMode.On: LatestScreenshot.withCursor = true; break;
                                case ApplyEditsAction.ApplicationMode.Off: LatestScreenshot.withCursor = false; break;
                            }
                        }

                        DoActionItem(ActiveShortcutItem, itemIndex + 1);
                    } break;

                case ActionTypes.Run:
                    {
                        var LatestScreenshot = History.LastOrDefault();
                        if (LatestScreenshot != null)
                        {
                            var Run = CurrentActionItem as RunAction;

                            if (!File.Exists(LatestScreenshot.InternalFileName))
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(LatestScreenshot.InternalFileName));
                                LatestScreenshot.ComposedScreenshotImage.Save(LatestScreenshot.InternalFileName, ImageFormat.Png);
                            }

                            var parameters = Helper.ExpandParameters(Run.Parameters, LatestScreenshot).Replace(":file", LatestScreenshot.InternalFileName);
                            var working = Environment.ExpandEnvironmentVariables(Helper.ExpandParameters(Run.WorkingDirectory, LatestScreenshot));

                            switch (Run.Mode)
                            {
                                case RunAction.Modes.ShellVerb:
                                    {
                                        Windowing.ShellExecute(IntPtr.Zero, Run.ShellVerb, LatestScreenshot.InternalFileName, parameters, working, Windowing.ShowCommands.SW_NORMAL);
                                    } break;
                                case RunAction.Modes.FilePath:
                                    {
                                        var psi = new ProcessStartInfo(Environment.ExpandEnvironmentVariables(Helper.ExpandParameters(Run.ApplicationPath, LatestScreenshot)), parameters) { UseShellExecute = false };
                                        if (!string.IsNullOrEmpty(working))
                                            psi.WorkingDirectory = working;

                                        Process.Start(psi);
                                    } break;
                            }
                        }

                        DoActionItem(ActiveShortcutItem, itemIndex + 1);
                    } break;

                case ActionTypes.Delete:
                    {
                        var LatestScreenshot = History.LastOrDefault();
                        if (LatestScreenshot != null)
                        {
                            lock (_actionlock)
                            {
                                ShowPreviewEvent(LatestScreenshot, new PreviewEventArgs() { ActionItem = CurrentActionItem });
                                Monitor.Wait(_actionlock);
                                DoActionItem(ActiveShortcutItem, itemIndex + 1);
                            }
                        }
                    } break;

                case ActionTypes.HidePreview:
                    {
                        lock (_actionlock)
                        {
                            ShowPreviewEvent(null, new PreviewEventArgs() { ActionItem = CurrentActionItem });
                            Monitor.Wait(_actionlock);
                            DoActionItem(ActiveShortcutItem, itemIndex + 1);
                        }
                    } break;

                case ActionTypes.BeginScrollingScreenshot:
                    {
                        isTakingScrollingScreenshot = true;

                        timelapse.Clear();
                        timelapse.Add(new ExtendedScreenshot());

                        DoActionItem(ActiveShortcutItem, itemIndex + 1);
                    } break;

                case ActionTypes.ContinueScrollingScreenshot:
                    {
                        if (isTakingScrollingScreenshot)
                            timelapse.Add(new ExtendedScreenshot());

                        DoActionItem(ActiveShortcutItem, itemIndex + 1);
                    } break;

                case ActionTypes.EndScrollingScreenshot:
                    {
                        if (isTakingScrollingScreenshot)
                        {
                            isTakingScrollingScreenshot = false;

                            Bitmap final = null;

                            Bitmap b = new Bitmap(timelapse.First().BaseScreenshotImage.Width, timelapse.First().BaseScreenshotImage.Height * timelapse.Count);
                            Graphics g = Graphics.FromImage(b);
                            int yoffset = 0;
                            int working_height = 0;

                            int ignore_header = 100;
                            int ignore_footer = 10;

                            var offsets = new Dictionary<int, int>();

                            //foreach (var ss in timelapse)
                            for (int c = 0; c < timelapse.Count; c++)
                            {
                                var debug = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), @"prosnap-debug");
                                if (Directory.Exists(debug))
                                {
                                    timelapse[c].BaseScreenshotImage.Save(Path.Combine(debug, @"ss-" + c + ".png"), ImageFormat.Png);
                                }

                                if (c == 0)
                                {
                                    g.DrawImageUnscaled(timelapse[c].BaseScreenshotImage, new Point(0, 0));
                                    working_height = timelapse[c].BaseScreenshotImage.Height;
                                    offsets.Add(c, timelapse[c].BaseScreenshotImage.Height);
                                }
                                else
                                {
                                    int old_yoffset = yoffset;
                                    yoffset = GetYOffset(timelapse[c - 1].BaseScreenshotImage, timelapse[c].BaseScreenshotImage, ignore_header, ignore_footer, old_yoffset, working_height, c);

                                    offsets.Add(c, yoffset);

                                    int sum = 0;
                                    if (offsets.Count > 0)
                                        for (int k = offsets.First().Key; k <= offsets.Last().Key; k++)
                                            sum += offsets[k];

                                    working_height = sum;

                                    g.DrawImage(timelapse[c].BaseScreenshotImage, new RectangleF(0, working_height - (timelapse[c].BaseScreenshotImage.Height - ignore_header), timelapse[c].BaseScreenshotImage.Width, timelapse[c].BaseScreenshotImage.Height - ignore_header), new RectangleF(0, ignore_header, timelapse[c].BaseScreenshotImage.Width, timelapse[c].BaseScreenshotImage.Height - ignore_header), GraphicsUnit.Pixel);
                                }

                                g.Flush();
                                g.Save();

                                final = new Bitmap(b.Width, working_height);
                                Graphics gfinal = Graphics.FromImage(final);
                                gfinal.DrawImage(b, new Rectangle(0, 0, final.Width, final.Height), new Rectangle(0, 0, b.Width, working_height), GraphicsUnit.Pixel);

                                gfinal.Flush();
                                gfinal.Save();

                                if (Directory.Exists(debug))
                                {
                                    final.Save(Path.Combine(debug, @"final-" + c + ".png"), System.Drawing.Imaging.ImageFormat.Png);
                                }
                            }

                            timelapse.First().ReplaceWithBitmap(final);
                            History.Add(timelapse.First());

                            DoActionItem(ActiveShortcutItem, itemIndex + 1);
                        }
                        else
                        {
                            //Must call, so that the action chain is properly ended
                            DoActionItem(null, 0);
                        }
                    } break;
            }
        }
Пример #13
0
        private static void Program_ShowPreviewEvent(ExtendedScreenshot s, PreviewEventArgs e)
        {
            if (Preview.InvokeRequired)
            {
                Trace.WriteLine("Self invoking...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                Preview.BeginInvoke(new MethodInvoker(() => Program_ShowPreviewEvent(s, e)));
                return;
            }

            //It is much easier to simply invoke onto the preview thread for actions which have UI ramification, rather than managing cross thread status updates
            //Currently there are only a couple actions this really makes sense for: Heart, Save, Upload, Delete (because it potentially also hides the form)
            //Save doesn't really have a UI change, but doing it on the UI thread means the SFD is positioned correctly

            //The locking scheme is so that dispatched operations block the action thread until complete
            //So for example, an action chain with Upload followed by Run can use the uploaded image url as a parameter for itself

            if (s != null)
            {
                Trace.WriteLine("Loading preview screenshot...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));
                Preview.LoadScreenshot(s);
            }

            if (e.ActionItem == null)
            {
                Trace.WriteLine("Showing preview...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));
                Preview.Show();
            }

            if (e.ActionItem is HeartAction)
            {
                Trace.WriteLine("Applying HeartAction...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                lock (_actionlock)
                {
                    switch ((e.ActionItem as HeartAction).HeartMode)
                    {
                        case HeartAction.Modes.Toggle: s.isFlagged = !s.isFlagged; break;
                        case HeartAction.Modes.On: s.isFlagged = true; break;
                        case HeartAction.Modes.Off: s.isFlagged = false; break;
                    }

                    Preview.UpdateHeart();
                    Monitor.Pulse(_actionlock);
                }
            }

            if (e.ActionItem is SaveAction)
            {
                Trace.WriteLine("Applying SaveAction...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                Preview.SaveComplete += (ss, se) =>
                    {
                        lock (_actionlock)
                            Monitor.Pulse(_actionlock);
                    };

                lock (_actionlock)
                    Preview.Save();
            }

            if (e.ActionItem is UploadAction)
            {
                Trace.WriteLine("Applying UploadAction...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                Preview.UploadComplete += (us, ue) =>
                    {
                        lock (_actionlock)
                            Monitor.Pulse(_actionlock);
                    };

                lock (_actionlock)
                    Preview.Upload();
            }

            if (e.ActionItem is DeleteAction)
            {
                Trace.WriteLine("Applying DeleteAction...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                lock (_actionlock)
                {
                    Preview.Delete();
                    Monitor.Pulse(_actionlock);
                }
            }

            if (e.ActionItem is HidePreviewAction)
            {
                Trace.WriteLine("Applying HidePreviewAction...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                lock (_actionlock)
                {
                    Preview.FadeClose();
                    Monitor.Pulse(_actionlock);
                }
            }

            if (e.ActionItem is TakeRegionScreenshotAction)
            {
                Trace.WriteLine("Opening region selector...", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                var rs = new RegionSelector();
                rs.FormClosed += (ss, se) =>
                {
                    Trace.WriteLine("Closed region selector.", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));

                    lock (_actionlock)
                    {
                        e.Result = rs.DialogResult == DialogResult.OK ? rs.SnapshotRectangle : Rectangle.Empty;
                        Monitor.Pulse(_actionlock);
                    }
                };

                lock (_actionlock)
                    rs.Show();
            }

            Trace.WriteLine("Done.", string.Format("Program.Program_ShowPreviewEvent [{0}]", Thread.CurrentThread.Name));
        }