Changeset 80328fcaac52…
Parent 815c80cd092a…
by
Changes to 3 files · Browse files at 80328fcaac52 Showing diff from parent 815c80cd092a Diff from another changeset...
|
@@ -0,0 +1,31 @@ + # configure TortoiseHg shell extension settings
+
+import os
+import sys
+import gtk
+
+from tortoisehg.util.i18n import agettext as _
+from tortoisehg.util import paths
+from tortoisehg.hgtk import taskbarui
+# import hgtk for signal setup side-effects
+from tortoisehg.hgtk import hgtk
+
+if hasattr(sys, "frozen"):
+ # Insert PATH to binary installer gtk directory
+ gtkpath = os.path.join(paths.bin_path, 'gtk')
+ os.environ['PATH'] = os.pathsep.join([gtkpath, os.environ['PATH']])
+ # Give stdout/stderr closed attributes to prevent ui.py errors
+ sys.stdout.closed = True
+ sys.stderr.closed = True
+
+def main():
+ dlg = taskbarui.TaskBarUI()
+ dlg.show_all()
+ dlg.connect('destroy', gtk.main_quit)
+ gtk.gdk.threads_init()
+ gtk.gdk.threads_enter()
+ gtk.main()
+ gtk.gdk.threads_leave()
+
+if __name__=='__main__':
+ main()
|
|
|
@@ -1,5 +1,6 @@ # Creates a task-bar icon. Run from Python.exe to see the
-# messages printed.
+# messages printed. Takes an optional logfile as first command
+# line parameter
import gc
import os
@@ -28,16 +29,12 @@from tortoisehg.util import thread2, paths, shlib
if hasattr(sys, "frozen"):
- # Insert PATH to binary installer gtk directory
- gtkpath = os.path.join(paths.bin_path, 'gtk')
- os.environ['PATH'] = os.pathsep.join([gtkpath, os.environ['PATH']])
# Give stdout/stderr closed attributes to prevent ui.py errors
sys.stdout.closed = True
sys.stderr.closed = True
-APP_TITLE = _('TortoiseHg RPC server')
+APP_TITLE = _('TortoiseHg Overlay Icon Server')
-SHOWLOG_CMD = 1023
EXIT_CMD = 1025
def SetIcon(hwnd, name, add=False):
@@ -93,7 +90,6 @@ 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
0, 0, hinst, None)
UpdateWindow(self.hwnd)
- self.guithread = None
self._DoCreateIcons()
def _DoCreateIcons(self):
@@ -112,8 +108,7 @@ def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):
if lparam==win32con.WM_RBUTTONUP or lparam==win32con.WM_LBUTTONUP:
menu = CreatePopupMenu()
- AppendMenu(menu, win32con.MF_STRING, SHOWLOG_CMD, _('Options...'))
- AppendMenu(menu, win32con.MF_SEPARATOR, 0, '')
+ # AppendMenu(menu, win32con.MF_SEPARATOR, 0, '')
AppendMenu(menu, win32con.MF_STRING, EXIT_CMD, _('Exit'))
pos = GetCursorPos()
# See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp
@@ -127,12 +122,7 @@
def OnCommand(self, hwnd, msg, wparam, lparam):
id = LOWORD(wparam)
- if id == SHOWLOG_CMD:
- if not self.guithread or not self.guithread.isAlive():
- self.launchgui()
- else:
- print "TortoiseHG options dialog already running"
- elif id == EXIT_CMD:
+ if id == EXIT_CMD:
self.exit_application()
else:
print "Unknown command -", id
@@ -140,11 +130,8 @@ def exit_application(self):
if self.stop_pipe_server():
DestroyWindow(self.hwnd)
- if self.guithread and self.guithread.isAlive():
- import gobject
- gobject.idle_add(self.dialog.destroy)
print "Goodbye"
-
+
def stop_pipe_server(self):
print "Stopping pipe server..."
if not self.pipethread.isAlive():
@@ -170,25 +157,6 @@ else:
return True
- def launchgui(self):
- def launch():
- import gtk
- # Import hgtk for signal setup side-effects
- from tortoisehg.hgtk import hgtk
- from tortoisehg.hgtk import taskbarui
- dlg = taskbarui.TaskBarUI(logger.getqueue(), requests)
- dlg.show_all()
- dlg.connect('destroy', gtk.main_quit)
- self.dialog = dlg
- gtk.gdk.threads_init()
- gtk.gdk.threads_enter()
- gtk.main()
- gtk.gdk.threads_leave()
- logger.reset()
-
- self.guithread = thread2.Thread(target=launch)
- self.guithread.start()
-
def start_pipe_server(self):
def servepipe():
self.svc = PipeServer(self.hwnd)
@@ -205,19 +173,19 @@
class Logger():
def __init__(self):
- self.q = None
+ self.file = None
- def getqueue(self):
- self.q = Queue.Queue()
- return self.q
-
- def reset(self):
- self.q = None
+ def setfile(self, name):
+ self.file = open(name, 'wb')
+ self.msg('Logging to file started')
def msg(self, msg):
ts = '[%s] ' % time.strftime('%c')
- if self.q:
- self.q.put(ts + msg)
+ f = self.file
+ if f:
+ f.write(ts + msg + '\n')
+ f.flush()
+ os.fsync(f.fileno())
print 'L' + ts + msg
else:
print ts + msg
@@ -453,6 +421,7 @@RUNMUTEXNAME = 'thgtaskbar-' + GetUserName()
def main():
+ args = sys.argv[1:]
sa = win32security.SECURITY_ATTRIBUTES()
sa.SetSecurityDescriptorDacl(1, None, 0) # allow full access
runmutex = win32event.CreateMutex(sa, 1, RUNMUTEXNAME)
@@ -462,6 +431,8 @@ # see http://www.jrsoftware.org/iskb.php?mutexsessions
installmutex1 = win32event.CreateMutex(sa, 1, INSTALLMUTEXNAME)
installmutex2 = win32event.CreateMutex(sa, 1, 'Global\\' + INSTALLMUTEXNAME)
+ if len(args) >= 1:
+ logger.setfile(args[0])
w=MainWindow()
PumpMessages()
|
|
|
- # taskbarui.py - User interface for the TortoiseHg taskbar app
+# taskbarui.py - User interface for the TortoiseHg shell extension settings
#
# Copyright 2009 Steve Borho <steve@borho.org>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.
import os
import gtk
import gobject
from tortoisehg.util.i18n import _
from tortoisehg.util import hglib, settings, menuthg
from tortoisehg.hgtk import gtklib
shellcmds = '''about add clone commit datamine init log recovery
shelve synch status thgstatus userconf repoconf remove rename
revert serve update vdiff'''.split()
class TaskBarUI(gtk.Window):
'User interface for the TortoiseHg taskbar application'
- def __init__(self, inputq, requestq):
+ def __init__(self):
'Initialize the Dialog'
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
gtklib.set_tortoise_icon(self, 'hg.ico')
gtklib.set_tortoise_keys(self)
self.set_default_size(400, 520)
- self.set_title(_('TortoiseHg Taskbar'))
+ self.set_title(_('TortoiseHg Shell Configuration'))
about = gtk.Button(_('About'))
okay = gtk.Button(_('OK'))
cancel = gtk.Button(_('Cancel'))
self.apply = gtk.Button(_('Apply'))
vbox = gtk.VBox()
vbox.set_border_width(5)
self.add(vbox)
# Create a new notebook, place the position of the tabs
self.notebook = notebook = gtk.Notebook()
notebook.set_tab_pos(gtk.POS_TOP)
vbox.pack_start(notebook, True, True)
notebook.show()
self.show_tabs = True
self.show_border = True
# Options page
settingsframe = self.add_page(notebook, _('Options'))
settingsvbox = gtk.VBox()
settingsframe.add(settingsvbox)
## Overlays group
ovframe = gtk.Frame(_('Overlays'))
ovframe.set_border_width(2)
settingsvbox.pack_start(ovframe, False, False, 2)
ovcvbox = gtk.VBox()
ovframe.add(ovcvbox)
hbox = gtk.HBox()
ovcvbox.pack_start(hbox, False, False, 2)
self.ovenable = gtk.CheckButton(_('Enable overlays'))
hbox.pack_start(self.ovenable, False, False, 2)
self.lclonly = gtk.CheckButton(_('Local disks only'))
hbox.pack_start(self.lclonly, False, False, 2)
## Context Menu group
cmframe = gtk.Frame(_('Context Menu'))
cmframe.set_border_width(2)
settingsvbox.pack_start(cmframe, False, False, 2)
table = gtk.Table(2, 3)
cmframe.add(table)
def setcell(child, row, col):
table.attach(child, col, col + 1, row, row + 1, gtk.FILL|gtk.EXPAND, 0, 4, 2)
def withframe(widget):
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
scroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
scroll.add(widget)
return scroll
# Sub menus pane
label = gtk.Label(_('Sub menu items:'))
label.set_alignment(0, 0.5)
setcell(label, 0, 0)
# model: [0]hgcmd, [1]translated menu label
self.submmodel = model = gtk.ListStore(gobject.TYPE_STRING,
gobject.TYPE_STRING)
self.submlist = list = gtk.TreeView(model)
list.set_size_request(-1, 180)
list.set_headers_visible(False)
list.connect('row-activated', self.row_activated)
column = gtk.TreeViewColumn()
list.append_column(column)
cell = gtk.CellRendererText()
column.pack_start(cell, True)
column.add_attribute(cell, 'text', 1)
setcell(withframe(list), 1, 0)
# Top menus pane
label = gtk.Label(_('Top menu items:'))
label.set_alignment(0, 0.5)
setcell(label, 0, 2)
# model: [0]hgcmd, [1]translated menu label
self.topmmodel = model = gtk.ListStore(gobject.TYPE_STRING,
gobject.TYPE_STRING)
self.topmlist = list = gtk.TreeView(model)
list.set_size_request(-1, 180)
list.set_headers_visible(False)
list.connect('row-activated', self.row_activated)
column = gtk.TreeViewColumn()
list.append_column(column)
cell = gtk.CellRendererText()
column.pack_start(cell, True)
column.add_attribute(cell, 'text', 1)
setcell(withframe(list), 1, 2)
# move buttons
mbbox = gtk.VBox()
setcell(mbbox, 1, 1)
topbutton = gtk.Button(_('Top ->'))
topbutton.connect('clicked', self.top_clicked)
mbbox.add(topbutton)
subbutton = gtk.Button(_('<- Sub'))
subbutton.connect('clicked', self.sub_clicked)
mbbox.add(subbutton)
## Taskbar group
taskbarframe = gtk.Frame(_('Taskbar'))
taskbarframe.set_border_width(2)
settingsvbox.pack_start(taskbarframe, False, False, 2)
taskbarbox = gtk.VBox()
taskbarframe.add(taskbarbox)
hbox = gtk.HBox()
taskbarbox.pack_start(hbox, False, False, 2)
self.hgighlight_taskbaricon = gtk.CheckButton(_('Highlight Icon'))
hbox.pack_start(self.hgighlight_taskbaricon, False, False, 2)
# Tooltips
tips = gtk.Tooltips()
tooltip = _('Enable/Disable the overlay icons globally')
tips.set_tip(self.ovenable, tooltip)
self.ovenable.connect('toggled', self.ovenable_toggled)
tooltip = _('Only enable overlays on local disks')
tips.set_tip(self.lclonly, tooltip)
self.lclonly.connect('toggled', lambda x: self.apply.set_sensitive(True))
tooltip = _('Highlight the taskbar icon during activity')
tips.set_tip(self.hgighlight_taskbaricon, tooltip)
self.hgighlight_taskbaricon.connect('toggled', lambda x: self.apply.set_sensitive(True))
self.load_shell_configs()
- # Event log page
- frame = self.add_page(notebook, _('Event Log'))
- frame.set_border_width(2)
-
- scrolledwindow = gtk.ScrolledWindow()
- scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
- scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolledwindow.set_border_width(2)
- textview = gtk.TextView()
- textview.set_editable(False)
- scrolledwindow.add(textview)
- frame.add(scrolledwindow)
- gobject.timeout_add(100, self.pollq, inputq, textview)
-
accelgroup = gtk.AccelGroup()
self.add_accel_group(accelgroup)
# Padding
vbox.pack_start(gtk.HBox(), False, False, 3)
# Bottom buttons
bbox = gtk.HBox()
vbox.pack_start(bbox, False, False)
lefthbbox = gtk.HButtonBox()
lefthbbox.set_layout(gtk.BUTTONBOX_START)
lefthbbox.set_spacing(6)
bbox.pack_start(lefthbbox, False, False)
about.connect('clicked', self.about)
lefthbbox.pack_start(about, False, False)
bbox.pack_start(gtk.Label(''), True, True)
righthbbox = gtk.HButtonBox()
righthbbox.set_layout(gtk.BUTTONBOX_END)
righthbbox.set_spacing(6)
bbox.pack_start(righthbbox, False, False)
okay.connect('clicked', self.okay_clicked)
key, modifier = gtk.accelerator_parse('Return')
okay.add_accelerator('clicked', accelgroup, key, 0,
gtk.ACCEL_VISIBLE)
righthbbox.pack_start(okay, False, False)
cancel.connect('clicked', lambda x: self.destroy())
key, modifier = gtk.accelerator_parse('Escape')
cancel.add_accelerator('clicked', accelgroup, key, 0,
gtk.ACCEL_VISIBLE)
righthbbox.pack_start(cancel, False, False)
self.apply.connect('clicked', self.apply_clicked)
self.apply.set_sensitive(False)
righthbbox.pack_start(self.apply, False, False)
def add_page(self, notebook, tab):
frame = gtk.Frame()
frame.set_border_width(5)
frame.set_shadow_type(gtk.SHADOW_NONE)
frame.show()
label = gtk.Label(tab)
notebook.append_page(frame, label)
return frame
def about(self, button):
from tortoisehg.hgtk import about
dlg = about.AboutDialog()
dlg.show_all()
- def pollq(self, queue, textview):
- 'Poll the input queue'
- buf = textview.get_buffer()
- enditer = buf.get_end_iter()
- while queue.qsize():
- try:
- msg = queue.get(0)
- buf.insert(enditer, msg+'\n')
- textview.scroll_to_mark(buf.get_insert(), 0)
- except Queue.Empty:
- pass
- return True
-
def load_shell_configs(self):
overlayenable = True
localdisks = False
promoteditems = 'commit'
hgighlight_taskbaricon = True
try:
from _winreg import HKEY_CURRENT_USER, OpenKey, QueryValueEx
hkey = OpenKey(HKEY_CURRENT_USER, r'Software\TortoiseHg')
t = ('1', 'True')
try: overlayenable = QueryValueEx(hkey, 'EnableOverlays')[0] in t
except EnvironmentError: pass
try: localdisks = QueryValueEx(hkey, 'LocalDisksOnly')[0] in t
except EnvironmentError: pass
try: hgighlight_taskbaricon = QueryValueEx(hkey, 'HighlightTaskbarIcon')[0] in t
except EnvironmentError: pass
try: promoteditems = QueryValueEx(hkey, 'PromotedItems')[0]
except EnvironmentError: pass
except (ImportError, WindowsError):
pass
self.ovenable.set_active(overlayenable)
self.lclonly.set_active(localdisks)
self.lclonly.set_sensitive(overlayenable)
self.hgighlight_taskbaricon.set_active(hgighlight_taskbaricon)
promoted = [pi.strip() for pi in promoteditems.split(',')]
self.submmodel.clear()
self.topmmodel.clear()
for cmd, info in menuthg.thgcmenu.items():
label = info['label']['str']
if cmd in promoted:
self.topmmodel.append((cmd, label))
else:
self.submmodel.append((cmd, label))
self.submmodel.set_sort_column_id(1, gtk.SORT_ASCENDING)
self.topmmodel.set_sort_column_id(1, gtk.SORT_ASCENDING)
def store_shell_configs(self):
overlayenable = self.ovenable.get_active() and '1' or '0'
localdisks = self.lclonly.get_active() and '1' or '0'
hgighlight_taskbaricon = self.hgighlight_taskbaricon.get_active() and '1' or '0'
promoted = []
for row in self.topmmodel:
promoted.append(row[0])
try:
from _winreg import HKEY_CURRENT_USER, CreateKey, SetValueEx, REG_SZ
hkey = CreateKey(HKEY_CURRENT_USER, r"Software\TortoiseHg")
SetValueEx(hkey, 'EnableOverlays', 0, REG_SZ, overlayenable)
SetValueEx(hkey, 'LocalDisksOnly', 0, REG_SZ, localdisks)
SetValueEx(hkey, 'HighlightTaskbarIcon', 0, REG_SZ, hgighlight_taskbaricon)
SetValueEx(hkey, 'PromotedItems', 0, REG_SZ, ','.join(promoted))
except ImportError:
pass
def move_to_other(self, list, paths=None):
if paths == None:
model, paths = list.get_selection().get_selected_rows()
else:
model = list.get_model()
if list == self.submlist:
otherlist = self.topmlist
othermodel = self.topmmodel
else:
otherlist = self.submlist
othermodel = self.submmodel
for path in paths:
cmd, label = model[path]
model.remove(model.get_iter(path))
othermodel.append((cmd, label))
othermodel.set_sort_column_id(1, gtk.SORT_ASCENDING)
self.apply.set_sensitive(True)
def row_activated(self, list, path, column):
self.move_to_other(list, (path,))
def sub_clicked(self, button):
self.move_to_other(self.topmlist)
def top_clicked(self, button):
self.move_to_other(self.submlist)
def okay_clicked(self, button):
self.store_shell_configs()
self.destroy()
def apply_clicked(self, button):
self.store_shell_configs()
button.set_sensitive(False)
def ovenable_toggled(self, check):
self.lclonly.set_sensitive(check.get_active())
self.apply.set_sensitive(True)
|
Loading...