Archive

Posts Tagged ‘UI’

Fix: make ownCloud installer display in English language

OwnCloud is an interesting solution for setting up a file sharing cloud for a group of people.

However,one issue I’ve found with its Windows desktop client’s current version (which looks clean of any viruses since I always check first) is that if your Windows 10 is configured with a preferred language that the desktop client’s installer doesn’t have localization support for, then it doesn’t show up in English as you’d expect, but in Czech or someother language that most of us don’t know how to read.

Screenshot (493)

So I tried running it’s MSI installer (ownCloud-2.6.1.13407.13049.msi) with –? parameter from the command-line and the /g languageCode parameter mentioned there looked promising, but trying /g en for English didn’t work. I guessed it needed some specific language code number (and not double-letter language code like en for English), since the help text was mentioning to see Windows Installer SDK for more help.

After a quick search I found an article that suggested passing the parameter Productlanguage=1033 to an msi installer on the command-line for it to ALWAYS show in English. And indeed it worked.

Screenshot (494)

To open a command window one can click the Search icon on the windows taskbar and type CMD then press ENTER.

Then they can drag-drop the .MSI file of ownCloud installer onto the black command-line window that opens up and type an extra space char and then Productlanguage=1033 before pressing ENTER to launch the ownCloud installer in English. After that they can close the command-line window at anytime.

Since many users may be uncomfortable with such instructions, one could provide an msiEnglish.bat file that just contains

%1 Productlanguage=1033

User could drag-drop the .msi they want onto that msiEnglish.bat file and it would run the msi installer being displayed in English language, irrespective of any preferred language settings at the Windows operating system.

Of course the best thing would be if ownCloud fixed their desktop client installer to fallback to the Engish language (set it as default) if it can’t find localization strings for the currently prefered language of the user. Have filed an issue at https://github.com/owncloud/client/issues/7825

Fix: WordPress administration UI content area showing up blank

Some time ago, at a WordPress 3.3 blog, a friend was getting a blank main area at the administration UI (just the menu was showing up there) when they visited the classic URL of the form http://somesite/wp-admin/. Here is a writeup of some notes I had kept while troubleshooting that issue and then upgrading to newer WordPress, with updated theme and plugins.

Visiting the problematic admin UI page online, I right-clicked and selected View Source in the browser and browsed to the bottom of it where it was showing: 

image

That div tag wasn’t not closed with a matching closing div. Obviously some PHP code that was outputing that tag failed at that point.

For starters, I copied all files via FTP (with the FireFtp Firefox plugin) from the remote server locally (into my Dropbox). Useful for backup too in case I messed up something.

Could use grepWin tool (http://stefanstools.sourceforge.net/grepWin.html) to search all locally copied php files for “contextual-help-sidebar” and see which one was outputing this (if that string was assigned to some variable could then search again where that variable was being used).

However, WordPress also has debugging mode, so I edited wp-config.php and uploaded the edited version to the server replacing the old file. I changed WP_DEBUG setting to true below: 

  image

At the problematic admin UI online page again, I right-clicked and selected View Source in the browser and browsed to the bottom of it, this time reading:

image

This led to indentifying the exact place in the PHP code that was causing this issue:

image

So, I commented out the buggy PHP code, converting it to an HTML comment block instead of a PHP block:

image

and the admin UI was working again after I pressed ENTER at the address bar again to refresh the admin UI (http://somesite/wp-admin/) and it was not showing up fine (F5 function key didn’t seem to really refresh the site when using Firefox btw, probably some caching issue).

Then installed (the free version) of the WP Database Backup plugin for WordPress:

http://www.wpseeds.com/documentation/docs/wp-database-backup/

by searching for “Backup” at

http://somesite/wp-admin/plugins.php

and evaluating the different backup plugins listed there (judging from both their votes and by checking out if WordPress wasn’t saying at the details page of a plugin that it hasn’t been tested with that [old] 3.3 WordPress version that was on that site) and backed up from Tools/WP-DB Backup menu:

http://somesite/wp-admin/tools.php?page=wp-database-backup

Then Downloaded the MySQL backup (.sql) file, so now I could update Themes, then Plugins, then update WordPress to new Core from

http://somesite/wp-admin/update-core.php

Did keep copies of the wp-content/themes and wp-content/plugins folders before and after updating them of course.

After WP updated, it asked to update the DB, all went ok

Then did backup up again the database via the WP-DB Backup tool and went again to

http://somesite/wp-admin/update-core.php

and installed an update for one of the plugins (can also do update per-plugin from http://somesite/wp-admin/plugins.php)

Then backed up again every file (db not included there) via FTP and done.

HowTo: Hide HTML markup from non-signedin users at MonoX Social CMS

At MonoX Social CMS, which I use at both ClipFlair Social and Trafilm websites, I was in the need of hiding some HTML markup when the user is not signed-in.

The solution for this is to add runat="server" to the HMTL element one wants to hide and then set the Visible property that the object acquires due to the runat clause. The Visible property is set using some special syntax to access the MonoX API like below:

<ul runat="server"
      Visible="<% $Code: Page.User.Identity.IsAuthenticated %>"  >

</ul>

Categories: Posts Tags: , , , , , , ,

HowTo: Drop files onto Silverlight controls

I was recently adding drop-files support to ClipFlair Studio, so I had to do some research on the related API that is available to Silverlight apps.

Silverlight supports a limited set of Drag-and-Drop interaction with the operating system (supposedly for security reasons, but most probably because of the classic cross-platform implementation pains).

For example it allows you to drop a collections of file objects from the operating system’s file explorer (or other similar application) onto a Silverlight drop target, but not the other way around.

Also, it doesn’t allow dropping other flavors of content, like text, images etc., only collections of file objects.

To allow dropping files onto a Silverlight control you set AllowDrop property to true and handle the Drop and optionally the DragEnter/DragOver/DragLeave events to provide visual feedback during the drop operation (mostly when over the drop target, unless you do Mouse Capturing).

<RichTextBox
  x:Name="rtb"
  …
  AllowDrop="True" 
  Drop="rtb_Drop"
  DragEnter="rtb_DragEnter"
  DragOver="rtb_DragOver"
  DragLeave="rtb_DragLeave"

  />

 

  #region DragAndDrop

    private void rtb_Drop(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "Normal", true);

      //the Drop event passes in an array of FileInfo objects for the list of files that were selected and drag-dropped onto the RichTextBox.
      if (e.Data == null)
        return;

     IDataObject f = e.Data as IDataObject;
      if (f != null) //checks if the dropped objects are files

      {
        object data = f.GetData(DataFormats.FileDrop); //Silverlight only supports FileDrop
        FileInfo[] files = data as FileInfo[]; //…GetData returns null if format is not supported

        e.Handled = true;

        if (files != null)

          //Walk through the list of FileInfo objects of the selected and drag-dropped files and parse the .txt and .docx files
          //and insert their content in the RichTextBox.
          foreach (FileInfo file in files)
            Load(file, false);
      }

    }

    private void rtb_DragEnter(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "DragOver", true);
      e.Handled = true;
    }
   
    private void rtb_DragOver(object sender, System.Windows.DragEventArgs e)
    {
      e.Handled = true;
      //NOP
    }

    private void rtb_DragLeave(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "Normal", true);
      e.Handled = true;
    }

    #endregion

 

For the visual feedback you can use VisualStateManager and respective VisualStates at say a Grid that wraps the drop target in the XAML layout.

<Grid x:Name="LayoutRoot">
   <VisualStateManager.VisualStateGroups>
     <VisualStateGroup x:Name="DragStates">
       <VisualStateGroup.Transitions>
         <VisualTransition GeneratedDuration="0:0:0.3">
           <VisualTransition.GeneratedEasingFunction>
             <CircleEase EasingMode="EaseIn"/>
           </VisualTransition.GeneratedEasingFunction>
         </VisualTransition>
       </VisualStateGroup.Transitions>
       <VisualState x:Name="Normal"/>
       <VisualState x:Name="DragOver">
         <Storyboard>
           <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" Storyboard.TargetName="rtb">
             <EasingColorKeyFrame KeyTime="0" Value="#FFFFF7D1"/>
           </ColorAnimationUsingKeyFrames>
         </Storyboard>
       </VisualState>
     </VisualStateGroup>
   </VisualStateManager.VisualStateGroups>

 

Note that on MacOS-X Safari doesn’t pass drop events automatically to plugins and you have to catch them via Javascript and pass them to Silverlight, plus I’ve read that in MacOS-X Firefox doesn’t support this at all.

Even worse, Microsoft’s workaround article has a typo in the Javascript (should call dragDrop instead of drop) and there is a chance it doesn’t work in latest version of Safari. For more see:

http://msdn.microsoft.com/en-us/library/ee670998%28v=vs.95%29.aspx

http://social.msdn.microsoft.com/Forums/silverlight/en-US/42a6b672-7d26-4690-be80-2149da755020/silverlight-4-detect-file-drop-event-on-mac?forum=silverlightarchieve&prof=required

http://community.rightpoint.com/blogs/viewpoint/archive/2011/03/27/silverlight-4-file-drag-and-drop-on-firefox-on-mac.aspx

http://www.telerik.com/forums/dropping-files-using-safari-on-mac (this says one can use HTML5 events and the Silverlight HTML/Javascript Bridge to notify Silverlight)

http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/

Gotcha: OnLostMouseCapture always called by CaptureMouse at WPF

It seems that CaptureMouse is behaving differently in WPF and Silverlight, in that in the former one it immediately calls OnLostMouseCapture at a Visual, whereas in Silverlight it doesn’t get called if the element didn’t have the mouse capture already (btw, in Silverlight that method is at a UIElement – there is no Visual ancestor as in WPF).

    #region --- Events ---

    private void OnMouseLeftButtonDown(object source, MouseButtonEventArgs e)
    {
      if (IsMoveToPointEnabled)
      {
        MoveThumbToPoint(e.GetPosition(this));
        CaptureMouse(); //must do before setting dragging=true, since WPF seems
//to be always calling OnLostMouseCapture on all
//controls, even if they didn't have the mouse capture
dragging = true; //always set, we might not make it to capture the mouse } } private void OnMouseLeftButtonUp(object source, MouseButtonEventArgs e) { ReleaseMouseCapture(); dragging = false; //always clear, in case we never had the mouse capture } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (dragging && IsMoveToPointEnabled) MoveThumbToPoint(e.GetPosition(this)); } protected override void OnLostMouseCapture(MouseEventArgs e) { base.OnLostMouseCapture(e); dragging = false; //set dragging to false whatever the value of
//IsMoveToPointEnabled (may have changed while dragging)
} #endregion

 

The rest of the code of the SliderExt class that I’ve just added to ClipFlair codebase is below, where … is where the code region that was quoted above goes. This class is a descendent of Slider and implements IsMoveToPointEnabled property for Silverlight (in WPF that property exists), plus in WPF it fixes the behavior of the control so that when that property is set, it not only supports moving the slider thumb to the point on its track where mouse button was held down (instead of stepping up/down as is usually done in scrollbars), but also supports dragging from any point in the slider track which WPF’s implementation of IsMouseToPointEnabled didn’t do (it only allowed to drag from the thumb).

//Project: ClipFlair (http://ClipFlair.codeplex.com)
//Filename: SliderExt.cs
//Version: 20140313

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace SliderExtLib
{
  public class SliderExt : Slider
  {

    public SliderExt()
    {

      //peek into mouse button events (even handled ones)
AddHandler(MouseLeftButtonDownEvent,
new MouseButtonEventHandler(OnMouseLeftButtonDown), true); AddHandler(MouseLeftButtonUpEvent,
new MouseButtonEventHandler(OnMouseLeftButtonUp), true); } #region --- Fields --- protected bool dragging; #endregion #region --- Properties --- public bool IsMoveToPointEnabled //WPF has this prop (hiding it), doesn't
//implement move to point if you click and drag on the track instead of thumb
{ get { return (bool)GetValue(IsMoveToPointEnabledProperty); } set { SetValue(IsMoveToPointEnabledProperty, value); } } public static readonly DependencyProperty IsMoveToPointEnabledProperty = DependencyProperty.RegisterAttached("IsMoveToPointEnabled", typeof(bool), typeof(SliderExt),
new PropertyMetadata(false)); #endregion #region --- Methods --- private void MoveThumbToPoint(Point p) { if (Orientation == Orientation.Horizontal) Value = p.X / ActualWidth * Maximum; else //if (Orientation == Orientation.Vertical) Value = p.Y / ActualHeight * Maximum; } #endregion




...



}
}

The incentive of making such a slider was for using it at the ColorPicker control I’ve just added to the ClipFlair codebase.

HowTo: find max ZIndex from a collection of UIElements with LINQ

Based on a relevant answer at

http://stackoverflow.com/questions/1101841/linq-how-to-perform-max-on-a-property-of-all-objects-in-a-collection-and-ret

and some digging into LINQ’s Aggregate method documentation is what I’ve just added to my enhanced version of SilverFlow library’s FloatingWindowHost (copying from FloatingWindowHost.cs at http://clipflair.codeplex.com source code)

        /// <summary>
        /// Sets the specified UIElement topmost.
        /// </summary>
        /// <param name="element">UIElement to set topmost.</param>
        /// <exception cref="ArgumentNullException">UIElement is null</exception>
        private void SetTopmost(UIElement element)
        {
            if (element == null)
                throw new ArgumentNullException("element");

            Canvas.SetZIndex(element, MaxZIndex + 1);
        }

        public int MaxZIndex
        {
          get {
            return FloatingWindows.Aggregate(-1, (maxZIndex, window) => {
              int w = Canvas.GetZIndex(window);
              return (w > maxZIndex) ? w : maxZIndex; 
            });  //Math.Max would be cleaner, but slower to call
          }
        }

Worth noting regarding the code above is that Canvas.ZIndex is an attached property available for UIElements in various containers, not just used when being hosted in a Canvas (see http://stackoverflow.com/questions/569751/controlling-rendering-order-zorder-in-silverlight-without-using-the-canvas-con)

Guess one could even make a SetTopmost and SetBottomMost static extension method for UIElement easily by adapting this code.

%d bloggers like this: