Preserve the position of User Forms VBA - forms

I'd like to preserve the position of a number of forms in the centre of the application, forms will be different sizes so below FormTop/FormLeft snippet can't be run again and again with the same effect. To do this I'm setting a public variable with the form's .top and .left values.
I get an error "Object Doesn't support this property or method", which seems odd as I was under the impression that the equation to make FormLeft would evaluate to a double data type. Both the lines work fine in the second section of code, what am I doing wrong?
Public FormTop As Double
Public FormLeft As Double
sub main()
CentreForm UserForm2
end sub
Sub CentreForm(UForm As UserForm)
With UForm
If FormTop = 0 And FormLeft = 0 Then
'*********Errors appear on the below two lines******************
FormLeft = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
FormTop = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
Debug.Print FormLeft, FormTop
End If
.StartUpPosition = 0
.Left = FormLeft
.Top = FormTop
End With
End Sub
sub IWork()
With UserForm2
.Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
.Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
end with
end sub

If you can't solve your problem based on comment suggestion please change this line:
Sub CentreForm(UForm As UserForm)
into
Sub CentreForm(UForm As Object)

Related

Macro for giving all shapes on a page a common border

I am using CorelDraw X7. I have a page containing many shapes and I wish to construct a macro to change it,
so that the bounding rectangle of alle shapes (the smallest one containing them all)
will have a common border of a given size.
I can find the size of the bounding rectangle and have tried to use the ActiveSelection.AlignAndDistribute sub
to move the shapes, but this sub has a lot of parameters, which I do not understand ("Help" does not help me).
My idea is this:
Specify the border, say pgBorder.
Get the width and height of the bounding rectangle, say shpsWidth and shpsHeight.
Move the shapes so that the lower left corner of the new bounding rectangle will have coordinates (pgBorder, pgBorder).
Reset the page size to shpsWidth + 2 * pgBorder resp. shpsHeight + 2 * pgBorder.
The shape bounding rectangle should now be surrounded with a border of size pgBorder.
This is what I have so far:
Sub GivePageCommonBorder()
Dim pgBorder As Double, shpsWidth As Double, shpsHeight As Double
Dim doc As Document
Dim pg As Page
Set doc = ActiveDocument
doc.Unit = cdrMillimeter
pgBorder = 20
Set pg = doc.ActivePage
' Select all shapes on the page
pg.Shapes.All.CreateSelection
shpsWidth = ActiveSelection.SizeWidth
shpsHeight = ActiveSelection.SizeHeight
' This is what I am lacking:
' Move the selection so its lower left corner has coordinates (pgBorder,pgBorder)
' Adjust page size
pg.SizeWidth = shpsWidth + 2 * pgBorder
pg.SizeHeight = shpsHeight + 2 * pgBorder
End Sub
Best wishes
Holger
I just stumbled upon the .Move method and constructed the following solution:
Sub GivePageCommonBorder()
Dim pgBorder As Double
Dim doc As Document
Dim pg As Page
Set doc = ActiveDocument
doc.Unit = cdrMillimeter
pgBorder = 5
Set pg = doc.ActivePage
pg.Shapes.All.CreateSelection
With ActiveSelection
pg.SizeWidth = .SizeWidth + 2 * pgBorder
pg.SizeHeight = .SizeHeight + 2 * pgBorder
.Move pgBorder - .LeftX, pgBorder - .BottomY
End With
End Sub
Holger

in Ipython a function named display gives me an error

# Kepler's Laws.py
# plots the orbit of a planet in an eccentric orbit to illustrate
# the sweeping out of equal areas in equal times, with sun at focus
# The eccentricity of the orbit is random and determined by the initial velocity
# program uses normalised units (G =1)
# program by Peter Borcherds, University of Birmingham, England
from vpython import *
from random import random
from IPython import display
import pandas as pd
def MonthStep(time, offset=20, whole=1): # mark the end of each "month"
global ccolor # have to make it global, since label uses it before it is updated
if whole:
Ltext = str(int(time * 2 + dt)) # end of 'month', printing twice time gives about 12 'months' in 'year'
else:
Ltext = duration + str(time * 2) + ' "months"\n Initial speed: ' + str(round(speed, 3))
ccolor = color.white
label(pos=planet.pos, text=Ltext, color=ccolor,
xoffset=offset * planet.pos.x, yoffset=offset * planet.pos.y)
ccolor = (0.5 * (1 + random()), random(), random()) # randomise colour of radial vector
return ccolor
scene = display(title="Kepler's law of equal areas", width=1000, height=1000, range=3.2)
duration = 'Period: '
sun = sphere(color=color.yellow, radius=0.1) # motion of sun is ignored (or centre of mass coordinates)
scale = 1.0
poss = vector(0, scale, 0)
planet = sphere(pos=poss, color=color.cyan, radius=0.02)
while 1:
velocity = -vector(0.7 + 0.5 * random(), 0, 0) # gives a satisfactory range of eccentricities
##velocity = -vector(0.984,0,0) # gives period of 12.0 "months"
speed = mag(velocity)
steps = 20
dt = 0.5 / float(steps)
step = 0
time = 0
ccolor = color.white
oldpos = vector(planet.pos)
ccolor = MonthStep(time)
curve(pos=[sun.pos, planet.pos], color=ccolor)
while not (oldpos.x > 0 and planet.pos.x < 0):
rate(steps * 2) # keep rate down so that development of orbit can be followed
time += dt
oldpos = vector(planet.pos) # construction vector(planet.pos) makes oldpos a varible in its own right
# oldpos = planet.pos makes "oldposs" point to "planet.pos"
# oldposs = planet.pos[:] does not work, because vector does not permit slicing
denom = mag(planet.pos) ** 3
velocity -= planet.pos * dt / denom # inverse square law; force points toward sun
planet.pos += velocity * dt
# plot orbit
curve(pos=[oldpos, planet.pos], color=color.red)
step += 1
if step == steps:
step = 0
ccolor = MonthStep(time)
curve(pos=[sun.pos, planet.pos], color=color.white)
else:
# plot radius vector
curve(pos=[sun.pos, planet.pos], color=ccolor)
if scene.kb.keys:
print
"key pressed"
duration = 'Duration: '
break
MonthStep(time, 50, 0)
label(pos=(2.5, -2.5, 0), text='Click for another orbit')
scene.mouse.getclick()
for obj in scene.objects:
if obj is sun or obj is planet: continue
obj.visible = 0 # clear the screen to do it again
I copied Kepler's Laws code in google and compiled it on pycharm.
But there is an error that
scene = display(title="Kepler's law of equal areas", width=1000, height=1000, range=3.2)
TypeError: 'module' object is not callable
I found some information on google that "pandas" library can improve this error so I tried it but I can't improve this error.
What should I do?
Replace "display" with "canvas", which is the correct name of this entity.

SetSimpleColumn not aligning after 10th line

I am using the iTextSharp assembly version 5.5.10 and think to face a bug. When I position my SetSimpleColumns for some unknown reason the 11th till the 14t column remain on the same line.
I first thought it was related to margins, but my rectangles with the same coordinates position correct.
This is how the result looks like:
The code is as follow:
Dim iADsPerPage As Integer = 14
Dim iRow As Integer = 0
dBottom = 760 'Next Line (one line = 15)
For Each oRow As DataRow In dtADs.Rows
iRow = iRow + 1
dBottom = dBottom - 43.6 'Next Line (one line = 15)
myText = New Phrase(oRow("BulletinReference").ToString, oFont)
dLeftSide = 102.0
dCellSize = 106.0
ct.SetSimpleColumn(myText, dLeftSide, dBottom + dFontLine, dLeftSide + dCellSize, dCellSize, 0, Element.ALIGN_CENTER)
ct.Go()
myText = New Phrase(Left(oRow("BulletinReference").ToString, 40), oFont)
dLeftSide = 210.0
dCellSize = 302.0
cb.Rectangle(dLeftSide, dBottom, dCellSize, dCellHeight)
cb.Stroke()
Response.Write(">" & " " & dLeftSide & " " & dBottom + dFontLine & " " & dLeftSide + dCellSize & " " & dCellSize & "<<br>")
ct.SetSimpleColumn(myText, dLeftSide, dBottom + dFontLine, dLeftSide + dCellSize, dCellSize, 0, Element.ALIGN_LEFT)
ct.Go()
If iRow = 11 Then 'force position as test
myText = New Phrase("hello world!!!!!!!!!!!!!!!!!", oFont)
ct.SetSimpleColumn(myText, 210, 100, 210 + 302, 302, 0, Element.ALIGN_LEFT)
ct.Go()
End If
Next
You use the wrong value in the fifth argument of SetSimpleColumn (and also in the third but that is not quite as wrong):
ct.SetSimpleColumn(myText, dLeftSide, dBottom + dFontLine, dLeftSide + dCellSize, dCellSize, 0, Element.ALIGN_CENTER)
As you see you always use dCellSize there, probably assuming that argument to be the height of the area, but the method is defined as:
/**
* Simplified method for rectangular columns.
* #param phrase a <CODE>Phrase</CODE>
* #param llx the lower left x corner
* #param lly the lower left y corner
* #param urx the upper right x corner
* #param ury the upper right y corner
* #param leading the leading
* #param alignment the column alignment
*/
virtual public void SetSimpleColumn(Phrase phrase, float llx, float lly, float urx, float ury, float leading, int alignment)
I.e. the fifth parameter should have been the upper y coordinate of the area (obviously not a constant).
Effectively your "upper y" for the first lines actually denoted the bottom y and your "lower y" the top y. With the "correction" by adding dFontLine that created the desired results.
As soon as your "lower y" actually started denoting the bottom y, the top y remained constant, so all entries from there on were printed at the same height.
This also explains your observation from a comment:
Something I noticed is that is seems to work when I put the last coordinate to 0 instead of 302.
That way your "upper y" remains the bottom of the page. Thus, "upper" and "lower" remain switched but consistently so.
I assume you want something along this line:
ct.SetSimpleColumn(myText, dLeftSide, dBottom, dLeftSide + dCellSize, dBottom + dCellHeight, 0, Element.ALIGN_CENTER)

Calculate distance between 2 set of lon and lat

As my question states that's I am looking for a function/formula that can calculate a distance between two points. Now I have looked at example and found great functions but none of them seem to work they all return 0 when I supply 2 sets of points. Basically I will need to pass the function the following (lat1,lon1,lat2,lon2) and get back the distance. From this distance I can check a check if another point is close by.
UPDATE
Okay so I am now using the following function,
BEGIN
DECLARE pi, q1, q2, q3 , roundedVal FLOAT ;
DECLARE rads FLOAT DEFAULT 0;
SET pi = PI();
SET lat1 = lat1 * pi / 180;
SET lon1 = lon1 * pi / 180;
SET lat2 = lat2 * pi / 180;
SET lon2 = lon2 * pi / 180;
SET q1 = COS(lon1-lon2);
SET q2 = COS(lat1-lat2);
SET q3 = COS(lat1+lat2);
SET rads = ACOS( 0.5*((1.0+q1)*q2 - (1.0-q1)*q3) );
RETURN FORMAT((6371 * rads) , 1);
END
This works fine with Kilometres, but what I am looking for is meters. So I know I have the change the numbers in that function but which ones and what to. Any help ?
I have used this webiste in the past and it has worked for me. Has lots of useful formulas and gives examples in javascript.
http://www.movable-type.co.uk/scripts/latlong.html
I'd recommend you take a look at a spacial extention to MySQL.
http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html
If you don't fancy that, this blog might have some use to you:
http://zcentric.com/2010/03/11/calculate-distance-in-mysql-with-latitude-and-longitude/
Try this query
$qry = "SELECT *,(((acos(sin((".$latitude."*pi()/180)) *
sin((`Latitude`*pi()/180))+cos((".$latitude."*pi()/180)) * cos((`Latitude`*pi()/180))*
cos(((".$longitude."- `Longitude`)*pi()/180))))*180/pi())*60*1.1515) as distance FROM
'MyTable` WHERE distance >= ".$distance."
apply this on the values
double theta = src_longitude - dest_longitude;
double min_distance = (Math.sin(Math.toRadians(src_latitude)) * Math.sin(Math.toRadians(dest_latitude))) +(Math.cos(Math.toRadians(src_latitude)) * Math.cos(Math.toRadians(dest_latitude)) * Math.cos(Math.toRadians(theta)));
min_distance = Math.acos(min_distance);
min_distance = Math.toDegrees(min_distance);
min_distance = min_distance * 60 * 1.1515 * 1.609344;

refresh drawing area in gtk

I have a bunch of drawing areas (they are actually cairo surfaces, but I don't think it matters too much) in a scrolled window, and I would like to refresh the drawings. However, when I redraw the images, they are not shown till I scroll the window up and down. After that the figures are correct, so I have to conclude that the drawing routine itself is proper. I have also included a
while Gtk.events_pending():
Gtk.main_iteration()
loop to wait for all pending operations, but that does not solve the problem. Could someone point out to me what else is missing?
Thanks,
v923z
OK, so the larger chunks of the code. First, a class defining the a drawing area onto which I am going to paint (note that the body is not indented properly! I don't know how to indent larger pieces of code here):
class Preview:
def __init__(self):
self.frame = Gtk.Frame()
self.frame.set_shadow_type(Gtk.ShadowType.IN)
self.frame.show()
self.da = Gtk.DrawingArea()
self.da.set_size_request(200, 300)
self.da.connect('configure-event', self.configure_event)
self.da.connect('draw', self.on_draw)
self.frame.add(self.da)
self.da.show()
def configure_event(self, da, event):
allocation = da.get_allocation()
self.surface = da.get_window().create_similar_surface(cairo.CONTENT_COLOR,
allocation.width,
allocation.height)
cairo_ctx = cairo.Context(self.surface)
cairo_ctx.set_source_rgb(1, 1, 1)
cairo_ctx.paint()
return True
def on_draw(self, da, cairo_ctx):
cairo_ctx.set_source_surface(self.surface, 0, 0)
cairo_ctx.paint()
return True
pass
Next, the point where I actually create the drawing area. viewport_preview is a viewport created in glade.
self.previews = []
self.widget('viewport_preview').remove(self.vbox_preview)
self.vbox_preview = Gtk.VBox(homogeneous=False, spacing=8)
self.widget('viewport_preview').add(self.vbox_preview)
self.vbox_preview.show()
for page in self.pages:
preview = Preview()
self.vbox_preview.pack_start(preview.frame, False, False, 10)
self.previews.append(preview)
while Gtk.events_pending():
Gtk.main_iteration()
self.draw_preview(None)
return True
Then the function drawing the previews. This is really just a wrapper for the next function, and I needed this only because if I delete one entry in the previews, then I have to handle that case. I believe, the while loop at the end of this function is not necessary, for it will be at the end of the next one anyway.
def draw_preview(self, counter=None):
if counter is not None:
self.vbox_preview.remove(self.previews[counter].frame)
self.previews.pop(counter)
self.pages.pop(counter)
self.vbox_preview.show()
while Gtk.events_pending():
Gtk.main_iteration()
for i in range(len(self.pages)):
self.draw_note(self.previews[i].da, self.previews[i].surface, self.pages[i])
while Gtk.events_pending():
Gtk.main_iteration()
Finally, the drawing function itself:
def draw_note(self, widget, surface, page):
list_pos = '%d/%d'%(self.page + 1, len(self.pages))
self.widget('label_status').set_text(list_pos)
cairo_ctx = cairo.Context(surface)
cairo_ctx.set_source_rgb(page.background[0], page.background[1], page.background[2])
cairo_ctx.paint()
width, height = widget.get_size_request()
xmin, xmax, ymin, ymax = fujitsu.page_size(page)
factor = min(height / (2.0 * self.margin + ymax - ymin), width / (2.0 * self.margin + xmax - xmin))
factor *= 0.8
page.scale = factor
value = self.widget('adjustment_smooth').get_value()
#print value
for pen in page.pagecontent:
x = self.margin + pen.path[0][0] - xmin
y = self.margin + pen.path[0][1] - ymin
cairo_ctx.move_to(x * factor, y * factor)
if self.widget('checkbutton_smooth').get_active() == False:
[cairo_ctx.line_to((self.margin + x - xmin) * factor,
(self.margin + y - ymin) * factor) for x, y in pen.path]
else:
bezier_curve = bezier.expand_coords(pen.path, value)
x = self.margin + bezier_curve[0][0][0] - xmin
y = self.margin + bezier_curve[0][0][1] - ymin
cairo_ctx.move_to(x * factor, y * factor)
[cairo_ctx.curve_to((self.margin + control[1][0] - xmin) * factor,
(self.margin + control[1][1] - ymin) * factor,
(self.margin + control[2][0] - xmin) * factor,
(self.margin + control[2][1] - ymin) * factor,
(self.margin + control[3][0] - xmin) * factor,
(self.margin + control[3][1] - ymin) * factor)
for control in bezier_curve]
cairo_ctx.set_line_width(pen.thickness * self.zoom_factor)
cairo_ctx.set_source_rgba(pen.colour[0], pen.colour[1], pen.colour[2], pen.colour[3])
cairo_ctx.stroke()
cairo_ctx.rectangle(0, height * 0.96, width, height)
cairo_ctx.set_source_rgba(page.banner_text[0][0], page.banner_text[0][1], page.banner_text[0][2], page.banner_text[0][3])
cairo_ctx.fill()
cairo_ctx.move_to(width * 0.05, height * 0.99)
cairo_ctx.show_text(self.filename + ' ' + list_pos)
cairo_ctx.set_font_size(self.zoom_factor * 10.0)
xbearing, ybearing, twidth, theight, xadvance, yadvance = (cairo_ctx.text_extents(page.banner_text[3]))
cairo_ctx.move_to(width - 1.03 * twidth, height * 0.99)
cairo_ctx.show_text(page.banner_text[3])
cairo_ctx.set_source_rgba(0, 0, 0.9, 0.90)
cairo_ctx.stroke()
rect = widget.get_allocation()
widget.get_window().invalidate_rect(rect, False)
while Gtk.events_pending():
Gtk.main_iteration()
I think that's about it.
You could use gtk_widget_queue_draw_area or gdk_window_invalidate_rect.This will mark the widget (or rectangle) as dirty and once the main loop is idle expose event will be received where in you can redraw. From you description it appears the updates are happening on expose event so these APIs might be of use. Also you can check this sample from the cairo site where in you can see the usage of gtk_widget_queue_draw_area.
I have not used pygtk but from Google I found that the corresponding call for gtk_widget_queue_draw_area is gtk.Widget.queue_draw_area & for gdk_window_invalidate_rect is gtk.gdk.Window.invalidate_rect
Hope this helps!