how can I add another textlabel and buttons to a cell in a tableView in rubymotion? - rubymotion

I use the following methods to create a cell and populate data in it(adapted from the tweets app example)
Now I want to add a new label displaying the selected event date and a button that will perform another action.
Here comes the 2 methods:
def self.cellForEvent(event, inTableView:tableView)
cell = tableView.dequeueReusableCellWithIdentifier(EventCell::CellId) || EventCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:CellId)
cell.fillWithEvent(event, inTableView:tableView)
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton
cell
end
Populate data into the cell
def fillWithEvent(event, inTableView:tableView)
self.textLabel.text = event.name
puts event.image
unless event.image
self.imageView.image = nil
Dispatch::Queue.concurrent.async do
event_image_data = NSData.alloc.initWithContentsOfURL(NSURL.URLWithString(event.image_url))
if event_image_data
event.image = UIImage.alloc.initWithData(event_image_data)
Dispatch::Queue.main.sync do
self.imageView.image = event.image
tableView.delegate.reloadRowForEvent(event)
end
end
end
else
self.imageView.image = event.image
end
end

railsdog's recommendation is not without merit. You could make a #reference to the cell you want to edit, and make changes to it later. But this is kind of dangerous - lots of pitfalls: What happens it the cell is moved off screen? Reused elsewhere? Tricky.
Instead, I would recommend adding some of the fillWithEvent:inTableView code into the cellForEvent method, that way you can call tableView.reloadRowsAtIndexPaths:withRowAnimation: and that method will be called. This moves the complications I mentioned above onto the back of the Cocoa framework, and that's a good thing :-)
The downside is that you'll need to keep the indexPath handy (or calculatable), and always keep in mind that the event associated with the cell is transient, because the cells are reused. Your code above doesn't seem to keep a reference to event, which is a good thing!
# in fetchImageForEvent:tableView:
# ...
event.image = UIImage.alloc.initWithData(event_image_data)
Dispatch::Queue.main.sync do
# instead of this:
# self.imageView.image = event.image
# tell the tableView to reload. unfortunately, we don't have the index
# path. not sure how you're calculating it, but if you've got a list of
# events, this should be easy.
# I'm just assuming section 0, row 1 here.
path = NSIndexPath.indexPathWithIndex(0).indexPathByAddingIndex(1)
tableView.reloadRowsAtIndexPaths([path], withRowAnimation:UITableViewRowAnimationAutomatic)
end

Related

This cell duplicates image in that cell in spreadsheet?

Very simple. Cell A1 has an image in it, which I supply through Insert:Picture:From File...
Now I want Cell A3 to automatically show the same picture. I simply can't find a way-- certainly the "=" doesn't work. At this point, I don't care if the images are "links" or embedded, I just want it to work. Can it? Thx.
Edit, 09-01-17, based on Jim K's idea, here's macro code I have installed:
REM ***** BASIC *****
Private oListener as Object
Private cellA1 as Object
Sub AddListener
Dim Doc, Sheet, Cell as Object
Doc = ThisComponent
Sheet = Doc.Sheets.getByName("Sheet1")
cellA1 = Sheet.getCellrangeByName("A1")
'create a listener
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener")
'register the listener
cellA1.addModifyListener(oListener)
End Sub
Sub Modify_disposing(oEv)
End Sub
Sub RmvListener
cellA1.removeModifyListener(oListener)
End Sub
' macro jumps here when oListener detects modification of Sheet
Sub Modify_modified(oEv)
Doc = ThisComponent
Sheet = Doc.Sheets.getByIndex(0)
originCell = Sheet.getCellByPosition(0,0)
originValue = originCell.Value
if originValue then
print "originValue is " & originValue
else
print "originValue zero"
end if
End Sub
The problem, ironically, is that it works. It works for integers and {non-value}, I mean an empty cell.
So any integer not zero prints TRUE, zero prints FALSE, and empty cell prints FALSE.
But that's where it quits working-- any kind of string "asdf" also returns FALSE.
Maybe that could be fixed, but there's something a lot worse: When I paste an image in the cell, or use the Insert/Image/From File... menu, or Cut an existing image... Nothing happens! The Sheet Modified business does not trigger the expected routine.
Any hope? Thx.
As you discovered, the solution in my comment does not work, because the Content changed event will not trigger when images are added. I looked into other events as well, but they did not work either.
So instead, we can set up a function that runs periodically. Each time it runs, it checks the count of images, and if any have been added or removed, it calls update_copied_images() below, which currently simply reports the value of cell A1, as in your code.
As explained here, I have not gotten a timer loop to work in Basic without crashing, so we can use Python instead (a better language, so this is not a drawback in my opinion).
import time
from threading import Thread
import uno
COLUMN_A, COLUMN_B, COLUMN_C = 0, 1, 2
FIRST_ROW = 0
def start_counting_images(action_event=None):
t = Thread(target = keep_counting_images)
t.start()
def keep_counting_images():
oDoc = XSCRIPTCONTEXT.getDocument()
oSheet = oDoc.getSheets().getByIndex(0)
oDrawPage = oSheet.getDrawPage()
messageCell = oSheet.getCellByPosition(COLUMN_C, FIRST_ROW)
messageCell.setString("Starting...")
prevCount = -1
while hasattr(oDoc, 'calculateAll'): # keep going until document is closed
count = oDrawPage.Count
if prevCount == -1 or prevCount != count:
prevCount = count
messageCell.setString("Number of Images: " + str(prevCount))
update_copied_images(oSheet)
time.sleep(1)
def update_copied_images(oSheet):
originCell = oSheet.getCellByPosition(COLUMN_A, FIRST_ROW)
originString = originCell.getString()
messageCell = oSheet.getCellByPosition(COLUMN_B, FIRST_ROW)
if len(originString):
messageCell.setString("originString '" + originString + "'")
else:
messageCell.setString("originString length is zero")
g_exportedScripts = start_counting_images,
To run, go to Tools -> Macros -> Run Macro, find the .py file under My Macros where you put this code, and run start_counting_images.

GoogleSheet script editor - onEdit event with conditions / if statement

guys!
I'm new to this website and also not good with coding. So I would really appreciate some help.
Right now I'm in need of a specific code to make a google sheet work perfectly.
To further explain:
I have a google sheet that a few information will be input by other co-workers. What I need is a code that will register the date in a specific cell and by whom the input was made on another cell.
So far this is what I have:
function onEdit(event) {
var sheet = event.source.getSheetByName("Input");
// Note: actRng = return the last cell of the row modified
var actRng = event.source.getActiveRange();
var index = actRng.getRowIndex();
var cindex = actRng.getColumnIndex();
// Note: date = return date
// Note: user = return the user email
var userCell = sheet.getRange(index,14);
var dateCell = sheet.getRange(index,2);
var inputdate = Utilities.formatDate(new Date(), "GMT+0200", "yyyy-MM-dd");
// Note(with hour): var inputdate = Utilities.formatDate(new Date(), "GMT+0200", "yy-MM-dd HH:mm");
//var user = event.user; // Note: event.user will not give you collaborator's Id
var user = Session.getEffectiveUser();
// Note: setValue = Insert in the cell the date when this row was modified
if (userCell.Value == null) {
userCell.setValue(user);
dateCell.setValue(inputdate)
}
}
My main problems/questions are:
I don't exactly need the last modifier, but the person who first input info on the cells. Therefore I tried that last IF (If the cell that is supposed to have the last modifier e-mail is blank, it means that nobody changed that row before, so the code should add the user on the userCell), although it is not working since every change I make it ignores the verification.
I also want to add that the event will only happen if you add values, if you delete them, nothing happens. (so far even when I delete cells, it counts as modification)
Most of the sheet is protected to avoid that people by accident erase some of the formulas, so the cells that this code changes are also protected. Is there a way to make the code bypass cell protection?
Please, help me identify what I'm doing wrong and hopefully I'll get this working perfectly! Thanks for the help !
If you want to prevent the script from firing when a cell is deleted, try:
var editedCell = SpreadsheetApp.getActiveSheet().getRange(e.range.getRow(), e.range.getColumn());
if (editedCell == "") {
return;
}
I would change Session.getEffectiveUser() to session.getActiveUser().
The last if statement is unnecessary. You want whoever most recently edited the field to be identified, along with the date.

Checkbuttons using dictionary will not update values

Folks,
So I've been working on a little GUI using Tkinter for a capstone project, and given the circumstances, I've only been programming for about two weeks before I was thrown into this, so I'm still a newbie.
My issue today is that I cannot manage to get my checkbutton dictionary to update values; the output for my checkbutton is always 0 or False. The code is as follows:
...
datatype= {'Joint Angle' : 0,
'Joint Acceleration' : 0,
'Ground Reaction Force' : 0,
'Muscle Activation' : 0
}
for measure in datatype:
datatype[measure] = IntVar()
dt_cb = Checkbutton(root, text=measure,
variable=datatype[measure],command = enable_location_state)
dt_cb.grid(column=0, sticky='W', padx=20)
dt1 = datatype['Joint Angle'].get()
dt2 = datatype['Joint Acceleration'].get()
dt3 = datatype['Ground Reaction Force'].get()
dt4 = datatype['Muscle Activation'].get()
...
So I tried periodically printing values throughout the code and I continued to get 0 as soon as I booted the GUI, and after that, no matter what I clicked, the numbers did not update. I read that I should try BooleanVar() and StringVar() instead, but neither of those worked. The code is based off of another bit of code I found somewhere on stackoverflow, though I cannot remember exactly where.
I tried making it a list rather than a dictionary in order to overcome my problem because I was successful with lists previously, but the list created only a single checkbutton for all of those and I was unable to differentiate what is what.
The command enable_location_state configures other checkbuttons, and is as follows:
def enable_location_state():
if dt1 == 1 or dt2 == 1:
ja_cb.configure(state=ACTIVE)
if dt3 == 1:
grf_cb.configure(state=ACTIVE)
if dt4 == 1:
emg_cb.configure(state=ACTIVE)
Your problem is that you are getting the values of the IntVar only once: at the same moment you create your buttons. Move your .get() statements to the beginning of the enable_location_state() function. That way, every time your checkbutton is clicked, the function will check on (i.e., .get()) the value of the IntVar.

Ultragrid Export Sort Order / Indicator

To make a long story short, we have a legacy application which displays an infragistics grid where users can export the grid display. The issue I'm having is that there's a particular order in which they want the export to occur, and if I set the order within the grid view prior to export, it retains this order, however if I try to force it "on export", it doesn't seem to work despite trying to set it. Here's my code (VB), as you can see just prior to import I try to set the "sortindicator", but I suspect I'm missing something.
Dim FileName As String
Dim I As Integer
I = 1
FileName = "C:\ReconciliationReport.xls"
While System.IO.File.Exists(FileName)
FileName = "C:\ReconciliationReport_" & I & ".xls"
I = I + 1
End While
grdReconciliationReport.DisplayLayout.Bands(0).Columns("ReconciliationOrder").SortIndicator = Infragistics.Win.UltraWinGrid.SortIndicator.Ascending
UltraGridExcelExporter.Export(grdReconciliationReport, FileName)
During the export of the grid UltraGridExcelExporter creates its own copy of the Layout. This is done exactly to allow you to sort, hide, delete and any other action in the layout without changing the actual grid. To sort the grid by any column you need to handle ExportStarted event. The event argument contains reference to the clonned layout. You can use code like this:
Private Sub UltraGridExcelExporter_ExportStarted(sender As Object, e As ExcelExport.ExportStartedEventArgs) Handles UltraGridExcelExporter1.ExportStarted
Dim sortedCol As UltraGridColumn = e.Layout.Bands(0).Columns(1)
e.Layout.Bands(0).SortedColumns.Add(sortedCol, False, False)
End Sub

Change label in tkinter inside a class? StringVar()?

I'm trying to construct a game where you can play five-in-row and when someone wins I want the label to change from like "Game is going on" to "Player 1 won" and this is where I am stuck.
The way I have constructed it all is like this. I have one class for the graphics (a Frame) and I have one class for all the Buttons that you can click on to set it to "X" or "O". And then I have one last class that checks if the grid has five of some value in a row, and that one runs after each successful click.
The label is of course set in the Frame class and first I had it like this just to make sure that I could see something
def __init__(self, master = None, rows = 10, cols = 10):
Frame.__init__(self, master)
Some other selfs....
self.inforad = Label(master, text = "Game is going on")
and this prints out nicely, just like I want it. Now I have been trying for hours to make this change when someone wins and I just can't make it work! The last thing I tried is to use the StringVar() and I did it like this
self.info = StringVar()
self.info.set("Game is going on")
self.inforad = Label(master, text = self.info)
and for starter this doesn't work at all, it prints out PY_VAR0. My plan was to define a method to call this during the game, like this
def disp(self, string):
self.info.set(string)
return self.info
And this doesn't work at all. Can someone help me with this? I am really new to programming, did my first code for like 3 weeks ago.
(If self.inforad is placed within the Frame subclass instance, self, its master should be self, not the master of self.)
As for your specific question, change Label(master, text = self.info) to Label(self, textvariable = self.info).