# -*- coding: utf-8 -*-
# coding=utf-8
# Copyright (C) 2007 daelstorm. All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Original copyright below
# Copyright (c) 2003-2004 Hyriand. All rights reserved.
import gtk
import gobject
import locale
import re
import webbrowser
from dirchooser import *
from utils import InputDialog, InitialiseColumns, recode, recode2, popupWarning, ImportWinSlskConfig, Humanize, OpenUri
from entrydialog import *
from pynicotine import upnp
from pynicotine.logfacility import log
import os, sys
win32 = sys.platform.startswith("win")
if win32:
pass
else:
import pwd
from pynicotine.utils import _
dir_location = os.path.dirname(os.path.realpath(__file__))
class buildFrame:
def __init__(self, window):
self.frame = self.p.frame
#self.tooltips = self.frame.tooltips
self.wTree = gtk.glade.XML(os.path.join(dir_location, "nicotine-settings.glade" ), window, "nicotine" )
widgets = self.wTree.get_widget_prefix("")
for i in widgets:
name = gtk.glade.get_widget_name(i)
self.__dict__[name] = i
self.__dict__[window].remove(self.Main)
self.__dict__[window].destroy()
self.wTree.signal_autoconnect(self)
class ServerFrame(buildFrame):
def __init__(self, parent, encodings):
self.p = parent
buildFrame.__init__(self, "ServerFrame")
self.Server_List = gtk.ListStore(gobject.TYPE_STRING)
self.Server.set_model(self.Server_List)
self.Server.set_text_column(0)
#self.Server.append_text("server.slsknet.org:2242")
#self.Server.append_text("server.slsknet.org:2240")
self.Elist = {}
self.EncodingStore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
#self.Encoding.set_size_request(100, -1)
self.Encoding.set_model(self.EncodingStore)
#cell1 = gtk.CellRendererText()
#cell1.set_property("xalign", 0)
#self.Encoding.pack_start(cell1, True)
#self.Encoding.add_attribute(cell1, 'text', 0)
self.Encoding.set_text_column(0)
cell2 = gtk.CellRendererText()
self.Encoding.pack_start(cell2, True)
self.Encoding.add_attribute(cell2, 'text', 1)
for item in encodings:
self.Elist[item[1]] = self.EncodingStore.append([item[1], item[0] ])
self.options = {"server": { "server": None, "serverlist": self.Server, "login": self.Login, "passw": self.Password, "enc": self.Encoding.child, "portrange": None, "firewalled": self.DirectConnection, "upnp": self.UseUPnP, "ctcpmsgs": self.ctcptogglebutton } }
def SetSettings(self, config):
self.p.SetWidgetsData(config, self.options)
self.Server.get_model().clear()
server = config["server"]
if server["server"] is not None:
self.Server.child.set_text("%s:%i" % (server["server"][0], server["server"][1]))
else:
self.Server.child.set_text("server.slsknet.org:2242")
for servername in server["serverlist"]:
self.Server.append_text(servername)
if self.frame.np.waitport is None:
self.CurrentPort.set_markup(_("Client port is not set"))
else:
self.CurrentPort.set_markup(_("Client port is %(port)s") % {"port": self.frame.np.waitport})
if self.frame.np.ipaddress is None:
self.YourIP.set_markup(_("Your IP address has not been retrieved from the server"))
else:
self.YourIP.set_markup(_("Your IP address is %(ip)s") % {"ip": self.frame.np.ipaddress})
if server["login"] is not None:
self.Login.set_text(server["login"])
if server["passw"] is not None:
self.Password.set_text(server["passw"])
if server["enc"] is not None:
self.Encoding.child.set_text(server["enc"])
if server["portrange"] is not None:
self.FirstPort.set_value(server["portrange"][0])
self.LastPort.set_value(server["portrange"][1])
else:
self.p.Hilight(self.FirstPort)
self.p.Hilight(self.LastPort)
if server["firewalled"] is not None:
self.DirectConnection.set_active(not server["firewalled"])
if server["ctcpmsgs"] is not None:
self.ctcptogglebutton.set_active(not server["ctcpmsgs"])
self.UseUPnP.set_active(server["upnp"] and upnp.upnppossible)
self.UseUPnP.set_sensitive(upnp.upnppossible)
self.labelRequirementsUPnP.set_sensitive(not upnp.upnppossible)
self.OnUPnPToggled(None)
def GetSettings(self):
try:
server = self.Server.child.get_text().split(":")
server[1] = int(server[1])
server = tuple(server)
except:
server = None
serverlist=[]
servername = self.Server.child.get_text()
if servername not in serverlist:
serverlist.append(servername)
iter = self.Server.get_model().get_iter_root()
while iter is not None:
servername = self.Server.get_model().get_value(iter, 0)
if servername not in serverlist:
serverlist.append(servername)
iter = self.Server.get_model().iter_next(iter)
serverlist = serverlist[:10]
if str(self.Login.get_text()) == "None":
popupWarning(self.p.SettingsWindow, _("Warning: Bad Username"), _("Username 'None' is not a good one, please pick another."), self.frame.images["n"] )
raise UserWarning
try:
firstport = min(self.FirstPort.get_value_as_int(), self.LastPort.get_value_as_int())
lastport = max(self.FirstPort.get_value_as_int(), self.LastPort.get_value_as_int())
portrange = (firstport, lastport)
except:
portrange = None
popupWarning(self.p.SettingsWindow, _("Warning: Invalid ports"), _("Client ports are invalid."), self.frame.images["n"] )
raise UserWarning
if self.UseUPnP.get_active():
firewalled = False
else:
firewalled = not self.DirectConnection.get_active()
return {
"server": {
"server": server,
"serverlist": serverlist,
"login": self.Login.get_text(),
"passw": self.Password.get_text(),
"enc": self.Encoding.child.get_text(),
"portrange": portrange,
"firewalled": firewalled,
"upnp": self.UseUPnP.get_active(),
"ctcpmsgs": not self.ctcptogglebutton.get_active(),
}
}
def OnChangePassword(self, widget):
self.frame.OnChangePassword(self.Password.get_text())
def OnCheckPort(self, widget):
OpenUri('='.join(['http://tools.slsknet.org/porttest.php?port', str(self.frame.np.waitport)]))
def OnUPnPToggled(self, widget):
if self.UseUPnP.get_active():
self.Requirement.set_sensitive(False)
self.DirectConnection.set_sensitive(False)
self.DirectConnection.set_active(True)
else:
self.Requirement.set_sensitive(True)
self.DirectConnection.set_sensitive(True)
class DownloadsFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "DownloadsFrame")
self.needrescan = 0
self.options = {"transfers": {"incompletedir": self.IncompleteDir, "downloaddir": self.DownloadDir, "sharedownloaddir": self.ShareDownloadDir, "downloadfilters": self.FilterView, "enablefilters": self.DownloadFilter, "downloadlimit": self.DownloadSpeed} }
self.filterlist = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN )
self.downloadfilters = []
cols = InitialiseColumns(self.FilterView,
[_("Filter"), 250, "text"],
[_("Escaped"), 40, "toggle"],
)
cols[0].set_sort_column_id(0)
cols[1].set_sort_column_id(1)
renderers = cols[1].get_cell_renderers()
for render in renderers:
render.connect('toggled', self.cell_toggle_callback, self.filterlist, 1)
self.FilterView.set_model(self.filterlist)
self.FilterView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.DownloadFilters.connect("activate", self.OnExpand)
self.DownloadDir.connect("changed", self.DownloadDirChanged)
def OnExpand(self, widget):
if widget.get_expanded():
self.DownloadsVbox.set_child_packing(widget, False, False, 0, 0)
else:
self.DownloadsVbox.set_child_packing(widget, True, True, 0, 0)
def DownloadDirChanged(self, widget):
transfers = self.frame.np.config.sections["transfers"]
if transfers["uploaddir"] is not None and transfers["uploaddir"] != "":
return
self.UploadDir.set_text(os.sep.join([self.DownloadDir.get_text(), _("Buddy Uploads")]))
def SetSettings(self, config):
transfers = config["transfers"]
self.p.SetWidgetsData(config, self.options)
if transfers["incompletedir"]:
self.ChooseIncompleteDir.set_current_folder(transfers["incompletedir"])
if transfers["downloaddir"]:
self.ChooseDownloadDir.set_current_folder(transfers["downloaddir"])
self.filtersiters = {}
self.filterlist.clear()
if transfers["downloadfilters"] != []:
for dfilter in transfers["downloadfilters"]:
filter, escaped = dfilter
self.filtersiters[filter] = self.filterlist.append([filter, escaped])
else:
self.p.Hilight(self.FilterView)
self.OnEnableFiltersToggle(self.DownloadFilter)
self.needrescan = 0
def GetSettings(self):
if win32:
place = "Windows"
homedir = "C:\windows"
else:
place = "Home"
homedir = pwd.getpwuid(os.getuid())[5]
if homedir == recode2(self.DownloadDir.get_text()) and self.ShareDownloadDir.get_active():
popupWarning(self.p.SettingsWindow, _("Warning"),_("Security Risk: you should not share your %s directory!") %place, self.frame.images["n"])
raise UserWarning
return {
"transfers": {
"incompletedir": recode2(self.IncompleteDir.get_text()),
"downloaddir": recode2(self.DownloadDir.get_text()),
"sharedownloaddir": self.ShareDownloadDir.get_active(),
"downloadfilters": self.GetFilterList(),
"enablefilters": self.DownloadFilter.get_active(),
"downloadlimit": self.DownloadSpeed.get_value_as_int(),
}
}
def GetNeedRescan(self):
return self.needrescan
def OnChooseIncompleteDir(self, widget):
directory = self.ChooseIncompleteDir.get_current_folder()
if directory is not None:
self.incompletedir = directory
self.IncompleteDir.set_text(recode(directory))
def OnChooseDownloadDir(self, widget):
directory = self.ChooseDownloadDir.get_current_folder()
if directory is not None:
self.incompletedir = directory
self.DownloadDir.set_text(recode(directory))
if self.ShareDownloadDir.get_active():
# This function will be called upon creating the settings window, so only
# force a scan if the user changes his donwload directory
if directory != self.frame.np.config.sections["transfers"]["downloaddir"]:
self.needrescan = 1
def OnShareDownloadDirToggled(self, widget):
self.needrescan = 1
def OnEnableFiltersToggle(self, widget):
sensitive = widget.get_active()
self.VerifyFilters.set_sensitive(sensitive)
self.VerifiedLabel.set_sensitive(sensitive)
self.DefaultFilters.set_sensitive(sensitive)
self.RemoveFilter.set_sensitive(sensitive)
self.EditFilter.set_sensitive(sensitive)
self.AddFilter.set_sensitive(sensitive)
self.FilterView.set_sensitive(sensitive)
def OnAddFilter(self, widget):
response = input_box(self.frame, title=_('Nicotine+: Add a download filter'), message=_('Enter a new download filter:'),
default_text='', option=True, optionvalue=True, optionmessage="Escape this filter?", droplist=self.filtersiters.keys())
if type(response) is list:
filter = response[0]
escaped = response[1]
if filter in self.filtersiters:
self.filterlist.set(self.filtersiters[filter], 0, filter, 1, escaped)
else:
self.filtersiters[filter] = self.filterlist.append([filter, escaped])
self.OnVerifyFilter(self.VerifyFilters)
def GetFilterList(self):
self.downloadfilters = []
df = list(self.filtersiters.keys())
df.sort()
for filter in df :
iter = self.filtersiters[filter]
dfilter = self.filterlist.get_value(iter, 0)
escaped = self.filterlist.get_value(iter, 1)
self.downloadfilters.append([dfilter, int(escaped)])
return self.downloadfilters
def OnEditFilter(self, widget):
dfilter = self.GetSelectedFilter()
if dfilter:
iter = self.filtersiters[dfilter]
escapedvalue = self.filterlist.get_value(iter, 1)
response = input_box(self.frame, title=_('Nicotine+: Edit a download filter'), message=_('Modify this download filter:'),
default_text=dfilter, option=True, optionvalue=escapedvalue, optionmessage="Escape this filter?", droplist=self.filtersiters.keys())
if type(response) is list:
filter, escaped = response
if filter in self.filtersiters:
self.filterlist.set(self.filtersiters[filter], 0, filter, 1, escaped)
else:
self.filtersiters[filter] = self.filterlist.append([filter, escaped])
del self.filtersiters[dfilter]
self.filterlist.remove(iter)
self.OnVerifyFilter(self.VerifyFilters)
def _SelectedFilter(self, model, path, iter, list):
list.append(iter)
def GetSelectedFilter(self):
iters = []
self.FilterView.get_selection().selected_foreach(self._SelectedFilter, iters)
if iters == []:
return None
dfilter = self.filterlist.get_value(iters[0], 0)
return dfilter
def OnRemoveFilter(self, widget):
dfilter = self.GetSelectedFilter()
if dfilter:
iter = self.filtersiters[dfilter]
self.filterlist.remove(iter)
del self.filtersiters[dfilter]
self.OnVerifyFilter(self.VerifyFilters)
def OnDefaultFilters(self, widget):
self.filtersiters = {}
self.filterlist.clear()
default_filters = [["desktop.ini", 1], ["folder.jpg", 1], ["*.url", 1], ["thumbs.db", 1], ["albumart(_{........-....-....-....-............}_)?(_?(large|small))?\.jpg", 0]]
for dfilter in default_filters:
filter, escaped = dfilter
self.filtersiters[filter] = self.filterlist.append([filter, escaped])
self.OnVerifyFilter(self.VerifyFilters)
def OnVerifyFilter(self, widget):
outfilter = "(\\\\("
df = list(self.filtersiters.keys())
df.sort()
proccessedfilters = []
failed = {}
for filter in df :
iter = self.filtersiters[filter]
dfilter = self.filterlist.get_value(iter, 0)
escaped = self.filterlist.get_value(iter, 1)
if escaped:
dfilter = re.escape(dfilter)
dfilter = dfilter.replace("\*", ".*")
try:
re.compile("("+dfilter+")")
outfilter += dfilter
proccessedfilters.append(dfilter)
except Exception, e:
failed[dfilter] = e
if filter is not df[-1]:
outfilter += "|"
outfilter += ")$)"
try:
re.compile(outfilter)
except Exception, e:
failed[outfilter] = e
if len(failed.keys()) >= 1:
errors = ""
for filter, error in failed.items():
errors += "Filter: %(filter)s Error: %(error)s " % {'filter':filter, 'error':error}
error = _("%(num)d Failed! %(error)s " %{'num':len(failed.keys()), 'error':errors} )
self.VerifiedLabel.set_markup("%s" % error)
else:
self.VerifiedLabel.set_markup("Filters Successful")
def cell_toggle_callback(self, widget, index, treeview, pos):
iter = self.filterlist.get_iter(index)
#user = self.usersmodel.get_value(iter, 1)
value = self.filterlist.get_value(iter, pos)
self.filterlist.set(iter, pos, not value)
self.OnVerifyFilter(self.VerifyFilters)
class SharesFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "SharesFrame")
self.needrescan = 0
# last column is the raw byte/unicode object for the folder (not shown)
self.shareslist = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
self.shareddirs = []
# last column is the raw byte/unicode object for the folder (not shown)
self.bshareslist = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
self.bshareddirs = []
column = gtk.TreeViewColumn("Shared dirs", gtk.CellRendererText(), text = 0)
columns = InitialiseColumns(self.Shares,
[_("Virtual Directory"), 0, "text"],
[_("Directory"), 0, "text"],
[_("Size"), 0, "text"],
)
self.Shares.set_model(self.shareslist)
self.Shares.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
bcolumns = InitialiseColumns(self.BuddyShares,
[_("Virtual Directory"), 0, "text"],
[_("Directory"), 0, "text"],
[_("Size"), 0, "text"],
)
self.BuddyShares.set_model(self.bshareslist)
self.BuddyShares.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.options = {"transfers": {"shared": self.Shares,
"friendsonly": self.FriendsOnly,
"rescanonstartup": self.RescanOnStartup, "buddyshared": self.BuddyShares, "enablebuddyshares": self.enableBuddyShares} }
def DownloadDirChanged(self, widget):
transfers = self.frame.np.config.sections["transfers"]
if transfers["uploaddir"] is not None and transfers["uploaddir"] != "":
return
self.UploadDir.set_text(os.sep.join([self.DownloadDir.get_text(), _("Buddy Uploads")]))
def SetSettings(self, config):
transfers = config["transfers"]
self.shareslist.clear()
self.bshareslist.clear()
self.p.SetWidgetsData(config, self.options)
self.OnEnabledBuddySharesToggled(self.enableBuddyShares)
#self.OnFriendsOnlyToggled(self.FriendsOnly)
if transfers["shared"] is not None:
for (virtual, actual) in transfers["shared"]:
self.shareslist.append([virtual, recode(actual), '-1', actual])
self.shareddirs = transfers["shared"][:]
else:
self.p.Hilight(self.Shares)
if transfers["buddyshared"] is not None:
for (virtual, actual) in transfers["buddyshared"]:
self.bshareslist.append([virtual, recode(actual), '-1', actual])
self.bshareddirs = transfers["buddyshared"][:]
else:
self.p.Hilight(self.BuddyShares)
self.needrescan = 0
def GetSettings(self):
if win32:
place = "Windows"
homedir = "C:\windows"
else:
place = "Home"
homedir = pwd.getpwuid(os.getuid())[5]
for share in self.shareddirs+self.bshareddirs:
if homedir == share:
popupWarning(self.p.SettingsWindow, _("Warning"),_("Security Risk: you should not share your %s directory!") %place, self.frame.images["n"])
raise UserWarning
return {
"transfers": {
"shared": self.shareddirs[:],
"rescanonstartup": self.RescanOnStartup.get_active(),
"buddyshared": self.bshareddirs[:],
"enablebuddyshares": self.enableBuddyShares.get_active(),
"friendsonly": self.FriendsOnly.get_active(),
}
}
def OnEnabledBuddySharesToggled(self, widget):
self.OnFriendsOnlyToggled(widget)
def OnFriendsOnlyToggled(self, widget):
sensitive = self.FriendsOnly.get_active()
buddiesonly = self.enableBuddyShares.get_active()
self.Shares.set_sensitive(not (sensitive and buddiesonly))
self.addSharesButton.set_sensitive(not (sensitive and buddiesonly))
self.removeSharesButton.set_sensitive(not (sensitive and buddiesonly))
self.BuddyShares.set_sensitive(buddiesonly)
self.addBuddySharesButton.set_sensitive(buddiesonly)
self.removeBuddySharesButton.set_sensitive(buddiesonly)
def GetNeedRescan(self):
return self.needrescan
def OnAddSharedDir(self, widget):
dir1 = ChooseDir(self.Main.get_toplevel(), title=_("Nicotine+")+": "+_("Add a shared directory"))
if dir1 is not None:
for directory in dir1:
if directory not in self.shareddirs:
virtual = input_box(self.frame, title=_("Virtual name"), message=_("Enter virtual name for '%(dir)s':") % {'dir': directory})
self.shareslist.append([virtual, recode(directory), '-2', directory])
self.shareddirs.append((virtual, directory))
self.needrescan = 1
def OnAddSharedBuddyDir(self, widget):
dir1 = ChooseDir(self.Main.get_toplevel(), title=_("Nicotine+")+": "+_("Add a shared buddy directory"))
if dir1 is not None:
for directory in dir1:
if directory not in self.bshareddirs:
virtual = input_box(self.frame, title=_("Virtual name"), message=_("Enter virtual name for '%(dir)s':") % {'dir': directory})
self.bshareslist.append([virtual, recode(directory), '-4', directory])
self.bshareddirs.append((virtual, directory))
self.needrescan = True
def _RemoveSharedDir(self, model, path, iter, list):
list.append(iter)
def OnRenameVirtuals(self, widget):
iters = []
self.Shares.get_selection().selected_foreach(self._RemoveSharedDir, iters)
for iter in iters:
oldvirtual = self.shareslist.get_value(iter, 0)
directory = self.shareslist.get_value(iter, 3)
oldmapping = (oldvirtual, directory)
virtual = input_box(self.frame, title=_("Virtual name"), message=_("Enter new virtual name for '%(dir)s':") % {'dir': directory})
newmapping = (virtual, directory)
self.shareslist.set_value(iter, 0, virtual)
self.shareddirs.remove(oldmapping)
self.shareddirs.append(newmapping)
self.needrescan = True
def OnRemoveSharedDir(self, widget):
iters = []
self.Shares.get_selection().selected_foreach(self._RemoveSharedDir, iters)
for iter in iters:
virtual = self.shareslist.get_value(iter, 0)
actual = self.shareslist.get_value(iter, 3)
mapping = (virtual, actual)
print("Mapping: " + repr(mapping))
self.shareddirs.remove(mapping)
self.shareslist.remove(iter)
if iters:
self.needrescan =1
def OnRemoveSharedBuddyDir(self, widget):
iters = []
self.BuddyShares.get_selection().selected_foreach(self._RemoveSharedDir, iters)
for iter in iters:
virtual = self.bshareslist.get_value(iter, 0)
actual = self.bshareslist.get_value(iter, 3)
mapping = (virtual, actual)
print("Mapping: " + repr(mapping))
self.bshareddirs.remove(mapping)
self.bshareslist.remove(iter)
if iters:
self.needrescan =1
class TransfersFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "TransfersFrame")
self.UploadsAllowed_List = gtk.ListStore(gobject.TYPE_STRING)
self.UploadsAllowed.set_model(self.UploadsAllowed_List)
self.options = {
"transfers": {"uploadbandwidth": self.QueueBandwidth, "useupslots": self.QueueUseSlots,
"uploadslots": self.QueueSlots, "uselimit": self.Limit, "uploadlimit": self.LimitSpeed,
"fifoqueue": self.FirstInFirstOut, "limitby": self.LimitTotalTransfers,
"queuelimit": self.MaxUserQueue, "filelimit": self.MaxUserFiles,
"friendsnolimits": self.FriendsNoLimits,
"preferfriends": self.PreferFriends, "lock":self.LockIncoming,
"reverseorder":self.DownloadReverseOrder, "prioritize":self.DownloadChecksumsFirst,
"remotedownloads": self.RemoteDownloads, "uploadallowed": self.UploadsAllowed,
"uploaddir": self.UploadDir
}
}
self.UploadsAllowed_List.clear()
self.alloweduserslist = [_("No one"), _("Everyone"), _("Users in list"), _("Trusted Users")]
for item in self.alloweduserslist:
self.UploadsAllowed_List.append([item])
#self.Uploads.connect("activate", self.OnExpand)
def SetSettings(self, config):
transfers = config["transfers"]
server = config["server"]
self.p.SetWidgetsData(config, self.options)
self.OnQueueUseSlotsToggled(self.QueueUseSlots)
self.OnLimitToggled(self.Limit)
if transfers["uploaddir"]:
self.ChooseUploadDir.set_current_folder(transfers["uploaddir"])
if transfers["uploadallowed"] is not None:
self.UploadsAllowed.set_active(transfers["uploadallowed"])
else:
self.p.Hilight(self.UploadsAllowed)
self.UploadsAllowed.set_sensitive(self.RemoteDownloads.get_active())
def GetSettings(self):
try:
uploadallowed = self.UploadsAllowed.get_active()
except:
uploadallowed = 0
if not self.RemoteDownloads.get_active():
uploadallowed = 0
return {
"transfers": {
"uploadbandwidth": self.QueueBandwidth.get_value_as_int(),
"useupslots": self.QueueUseSlots.get_active(),
"uploadslots": self.QueueSlots.get_value_as_int(),
"uselimit": self.Limit.get_active(),
"uploadlimit": self.LimitSpeed.get_value_as_int(),
"fifoqueue": self.FirstInFirstOut.get_active(),
"limitby": self.LimitTotalTransfers.get_active(),
"queuelimit": self.MaxUserQueue.get_value_as_int(),
"filelimit": self.MaxUserFiles.get_value_as_int(),
"friendsnolimits": self.FriendsNoLimits.get_active(),
"preferfriends": self.PreferFriends.get_active(),
"lock": self.LockIncoming.get_active(),
"reverseorder":self.DownloadReverseOrder.get_active(),
"prioritize":self.DownloadChecksumsFirst.get_active(),
"remotedownloads": self.RemoteDownloads.get_active(),
"uploadallowed": uploadallowed,
"uploaddir": recode2(self.UploadDir.get_text()),
},
}
def OnChooseUploadDir(self, widget):
directory = self.ChooseUploadDir.get_current_folder()
if directory is not None:
self.UploadDir.set_text(recode(directory))
def OnRemoteDownloads(self, widget):
sensitive = widget.get_active()
self.UploadsAllowed.set_sensitive(sensitive)
def OnQueueUseSlotsToggled(self, widget):
sensitive = widget.get_active()
self.QueueSlots.set_sensitive(sensitive)
self.QueueBandwidth.set_sensitive(not sensitive)
self.label185.set_sensitive(not sensitive)
self.label186.set_sensitive(not sensitive)
def OnLimitToggled(self, widget):
sensitive = widget.get_active()
for w in self.LimitSpeed, self.LimitPerTransfer, self.LimitTotalTransfers:
w.set_sensitive(sensitive)
class GeoBlockFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "GeoBlockFrame")
self.options = {"transfers": { "geoblock": self.GeoBlock, "geopanic": self.GeoPanic, "geoblockcc": self.GeoBlockCC,} }
try:
import GeoIP
except ImportError:
try:
import _GeoIP
except ImportError:
self.GeoBlock.set_sensitive(False)
self.GeoPanic.set_sensitive(False)
self.GeoBlockCC.set_sensitive(False)
self.CountryCodesLabel.set_sensitive(False)
def SetSettings(self, config):
transfers = config["transfers"]
self.p.SetWidgetsData(config, self.options)
if transfers["geoblockcc"] is not None:
self.GeoBlockCC.set_text(transfers["geoblockcc"][0])
self.OnGeoBlockToggled(self.GeoBlock)
def GetSettings(self):
return {
"transfers": {
"geoblock": self.GeoBlock.get_active(),
"geopanic": self.GeoPanic.get_active(),
"geoblockcc": [self.GeoBlockCC.get_text().upper()],
}
}
def OnGeoBlockToggled(self, widget):
sensitive = widget.get_active()
self.GeoPanic.set_sensitive(sensitive)
self.GeoBlockCC.set_sensitive(sensitive)
class UserinfoFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "UserinfoFrame")
self.options = {"userinfo": {"descr":None, "pic": self.Image, "descrutf8": None } }
self.Image.connect("changed", self.GetImageSize)
def SetSettings(self, config):
self.p.SetWidgetsData(config, self.options)
userinfo = config["userinfo"]
if userinfo["descr"] is not None:
descr = eval(userinfo["descr"], {})
self.Description.get_buffer().set_text(descr)
else:
self.p.Hilight(self.Description)
self.GetImageSize()
def GetImageSize(self, widget=None):
if os.path.exists(self.Image.get_text()):
size = os.stat(self.Image.get_text())[6]
self.ImageSize.set_text(_("Size: %s KB") % Humanize(size/1024))
else:
self.ImageSize.set_text(_("Size: %s KB") % 0)
self.p.Hilight(self.Image)
def GetSettings(self):
buffer = self.Description.get_buffer()
start = buffer.get_start_iter()
end = buffer.get_end_iter()
descr = buffer.get_text(start, end).replace("; ", ", ").__repr__()
return {
"userinfo": {
"descr": descr,
"pic": recode2(self.Image.get_text()),
"descrutf8": 1,
}
}
def OnChooseImage(self, widget):
dlg = ChooseImage(initialfile=self.Image.get_text(), title=_("Nicotine+")+": "+_("Choose a user info image"))
if dlg:
for file in dlg:
self.Image.set_text(file)
break
self.GetImageSize()
class IgnoreFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "IgnoreFrame")
self.options = {"server": { "ignorelist": self.IgnoredUsers, "ipignorelist": self.IgnoredIPs} }
self.ignored_users = []
self.ignorelist = gtk.ListStore(gobject.TYPE_STRING)
column = gtk.TreeViewColumn(_("Users"), gtk.CellRendererText(), text = 0)
self.IgnoredUsers.append_column(column)
self.IgnoredUsers.set_model(self.ignorelist)
self.IgnoredUsers.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.ignored_ips = {}
self.ignored_ips_list = gtk.ListStore(str, str)
cols = InitialiseColumns(self.IgnoredIPs,
[_("Addresses"), -1, "text", self.frame.CellDataFunc],
[_("Users"), -1, "text", self.frame.CellDataFunc],
)
cols[0].set_sort_column_id(0)
cols[1].set_sort_column_id(1)
self.IgnoredIPs.set_model(self.ignored_ips_list)
self.IgnoredIPs.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
def SetSettings(self, config):
server = config["server"]
transfers = config["transfers"]
self.ignorelist.clear()
self.ignored_ips_list.clear()
self.ignored_users = []
self.ignored_ips = {}
self.p.SetWidgetsData(config, self.options)
if server["ignorelist"] is not None:
self.ignored_users = server["ignorelist"][:]
else:
self.p.Hilight(self.IgnoredUsers)
if server["ipignorelist"] is not None:
self.ignored_ips = server["ipignorelist"].copy()
for ip, user in self.ignored_ips.items():
self.ignored_ips_list.append([ip, user ])
else:
self.p.Hilight(self.IgnoredIPs)
def GetSettings(self):
return {
"server": {
"ignorelist": self.ignored_users[:],
"ipignorelist": self.ignored_ips.copy(),
},
}
def _AppendItem(self, model, path, iter, l):
l.append(iter)
def OnAddIgnored(self, widget):
user = InputDialog(self.Main.get_toplevel(), _("Ignore user..."), _("User:") )
if user and user not in self.ignored_users:
self.ignored_users.append(user)
self.ignorelist.append([user])
def OnRemoveIgnored(self, widget):
iters = []
self.IgnoredUsers.get_selection().selected_foreach(self._AppendItem, iters)
for iter in iters:
user = self.ignorelist.get_value(iter, 0)
self.ignored_users.remove(user)
self.ignorelist.remove(iter)
def OnClearIgnored(self, widget):
self.ignored_users = []
self.ignorelist.clear()
def OnAddIgnoredIP(self, widget):
ip = InputDialog(self.Main.get_toplevel(), _("Ignore IP Address..."), _("IP:")+" "+_("* is a wildcard") )
if ip is None or ip == "" or ip.count(".") != 3:
return
for chars in ip.split("."):
if chars == "*":
continue
if not chars.isdigit():
return
try:
if int(chars) > 255:
return
except:
return
if ip not in self.ignored_ips:
self.ignored_ips[ip] = ""
self.ignored_ips_list.append([ip, ""])
def OnRemoveIgnoredIP(self, widget):
iters = []
self.IgnoredIPs.get_selection().selected_foreach(self._AppendItem, iters)
for iter in iters:
ip = self.ignored_ips_list.get_value(iter, 0)
del self.ignored_ips[ip]
self.ignored_ips_list.remove(iter)
def OnClearIgnoredIP(self, widget):
self.ignored_ips = {}
self.ignored_ips_list.clear()
class BanFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "BanFrame")
self.options = {"server": { "banlist" : self.Banned, "ipblocklist": self.Blocked},
"transfers": {"usecustomban": self.UseCustomBan, "customban": self.CustomBan,}
}
self.banned = []
self.banlist = gtk.ListStore(gobject.TYPE_STRING)
column = gtk.TreeViewColumn(_("Users"), gtk.CellRendererText(), text = 0)
self.Banned.append_column(column)
self.Banned.set_model(self.banlist)
self.Banned.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.blocked = {}
self.blockedlist = gtk.ListStore(str, str)
cols = InitialiseColumns(self.Blocked,
[_("Addresses"), -1, "text", self.frame.CellDataFunc],
[_("Users"), -1, "text", self.frame.CellDataFunc],
)
cols[0].set_sort_column_id(0)
cols[1].set_sort_column_id(1)
self.Blocked.set_model(self.blockedlist)
self.Blocked.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
def SetSettings(self, config):
server = config["server"]
transfers = config["transfers"]
self.banlist.clear()
self.blockedlist.clear()
self.banned = server["banlist"][:]
self.p.SetWidgetsData(config, self.options)
if server["banlist"] is None:
self.p.Hilight(self.Banned)
if server["ipblocklist"] is not None:
self.blocked = server["ipblocklist"].copy()
for blocked, user in server["ipblocklist"].items():
self.blockedlist.append([blocked, user ])
else:
self.p.Hilight(self.Blocked)
if transfers["usecustomban"] is not None:
self.UseCustomBan.set_active(transfers["usecustomban"])
if transfers["customban"] is not None:
self.CustomBan.set_text(transfers["customban"])
self.OnUseCustomBanToggled(self.UseCustomBan)
def GetSettings(self):
return {
"server": {
"banlist": self.banned[:],
"ipblocklist": self.blocked.copy(),
},
"transfers": {
"usecustomban": self.UseCustomBan.get_active(),
"customban": self.CustomBan.get_text(),
}
}
def OnAddBanned(self, widget):
user = InputDialog(self.Main.get_toplevel(), _("Ban user..."), _("User:") )
if user and user not in self.banned:
self.banned.append(user)
self.banlist.append([user])
def _AppendItem(self, model, path, iter, l):
l.append(iter)
def OnRemoveBanned(self, widget):
iters = []
self.Banned.get_selection().selected_foreach(self._AppendItem, iters)
for iter in iters:
user = self.banlist.get_value(iter, 0)
self.banned.remove(user)
self.banlist.remove(iter)
def OnClearBanned(self, widget):
self.banned = []
self.banlist.clear()
def OnUseCustomBanToggled(self, widget):
self.CustomBan.set_sensitive(widget.get_active())
def OnAddBlocked(self, widget):
ip = InputDialog(self.Main.get_toplevel(), _("Block IP Address..."), _("IP:")+" "+_("* is a wildcard") )
if ip is None or ip == "" or ip.count(".") != 3:
return
for chars in ip.split("."):
if chars == "*":
continue
if not chars.isdigit():
return
try:
if int(chars) > 255:
return
except:
return
if ip not in self.blocked:
self.blocked[ip] = ""
self.blockedlist.append([ip, ""])
def OnRemoveBlocked(self, widget):
iters = []
self.Blocked.get_selection().selected_foreach(self._AppendItem, iters)
for iter in iters:
ip = self.blockedlist.get_value(iter, 0)
del self.blocked[ip]
self.blockedlist.remove(iter)
def OnClearBlocked(self, widget):
self.blocked = {}
self.blockedlist.clear()
class SoundsFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "SoundsFrame")
self.audioPlayerCombo_List = gtk.ListStore(gobject.TYPE_STRING)
self.audioPlayerCombo.set_model(self.audioPlayerCombo_List)
self.audioPlayerCombo.set_text_column(0)
self.TTSCommand_List = gtk.ListStore(gobject.TYPE_STRING)
self.TTSCommand.set_model(self.TTSCommand_List)
self.TTSCommand.set_text_column(0)
self.SoundCommand_List = gtk.ListStore(gobject.TYPE_STRING)
self.SoundCommand.set_model(self.SoundCommand_List)
self.SoundCommand.set_text_column(0)
self.options = {"ui": {"soundcommand": self.SoundCommand, "soundtheme": self.SoundDirectory, "soundenabled": self.SoundCheck, "speechenabled": self.TextToSpeech, "speechcommand": self.TTSCommand, "speechrooms": self.RoomMessage, "speechprivate": self.PrivateMessage},
"players": {"default": self.audioPlayerCombo}}
for executable in ["xmms -e $", "audacious -e $", "amarok -a $", 'exaile $']:
self.audioPlayerCombo.append_text( executable )
for executable in ["flite -t $", "echo $ | festival --tts"]:
self.TTSCommand.append_text( executable )
for item in ["play -q", "ogg123 -q", "Gstreamer (gst-python)"]:
self.SoundCommand.append_text(item)
self.SoundButton.connect("clicked", self.OnChooseSoundDir)
self.DefaultSoundCommand.connect("clicked", self.DefaultSound)
self.DefaultTTSCommand.connect("clicked", self.DefaultTTS)
self.DefaultPrivateMessage.connect("clicked", self.DefaultPrivate)
self.DefaultRoomMessage.connect("clicked", self.DefaultRooms)
def OnSoundCheckToggled(self, widget):
sensitive = self.SoundCheck.get_active()
self.SoundCommand.set_sensitive(sensitive)
self.SoundDirectory.set_sensitive(sensitive)
self.SoundButton.set_sensitive(sensitive)
self.DefaultSoundCommand.set_sensitive(sensitive)
self.sndcmdLabel.set_sensitive(sensitive)
self.snddirLabel.set_sensitive(sensitive)
def DefaultPrivate(self, widget):
self.PrivateMessage.set_text("%(user)s told you.. %(message)s")
def DefaultRooms(self, widget):
self.RoomMessage.set_text("In %(room)s, %(user)s said %(message)s")
def DefaultTTS(self, widget):
self.TTSCommand.child.set_text("flite -t \"%s\"")
def DefaultSound(self, widget):
self.SoundCommand.child.set_text("play -q")
def OnTextToSpeechToggled(self, widget):
sensitive = self.TextToSpeech.get_active()
#for widget in [self.SoundCommand, self.SoundDirectory, self.SoundButton, self.DefaultSoundCommand, self.sndcmdLabel, self.snddirLabel]:
# widget.set_sensitive(not sensitive and self.SoundCheck.get_active())
for widget in [self.roomMessageBox, self.privateMessageBox, self.ttsCommandBox]:
widget.set_sensitive(sensitive)
def SetSettings(self, config):
self.p.SetWidgetsData(config, self.options)
for i in ["%(user)s", "%(message)s"]:
if i not in config["ui"]["speechprivate"]:
self.DefaultPrivate(None)
if i not in config["ui"]["speechrooms"]:
self.DefaultRooms(None)
self.OnSoundCheckToggled(self.SoundCheck)
self.OnTextToSpeechToggled(self.TextToSpeech)
def GetSettings(self):
soundcommand = self.SoundCommand.child.get_text()
if soundcommand == "Gstreamer (gst-python)":
if self.frame.gstreamer.player is None:
popupWarning(self.p.SettingsWindow, _("Warning"), _("Gstreamer-python is not installed") , self.frame.images["n"] )
raise UserWarning
return {
"ui": {
"soundcommand": soundcommand,
"soundtheme": self.SoundDirectory.get_text(),
"soundenabled": self.SoundCheck.get_active(),
"speechenabled": self.TextToSpeech.get_active(),
"speechcommand": self.TTSCommand.child.get_text(),
"speechrooms": self.RoomMessage.get_text(),
"speechprivate": self.PrivateMessage.get_text(),
},
"players": {
"default": self.audioPlayerCombo.child.get_text(),
},
}
def OnChooseSoundDir(self, widget):
dir = ChooseDir(self.Main.get_toplevel(), self.SoundDirectory.get_text(), title=_("Nicotine+")+": "+_("Choose a sound effects directory"))
if dir is not None:
for directory in dir: # iterate over selected files
self.SoundDirectory.set_text(recode(directory))
class IconsFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "IconsFrame")
self.options = {"ui": {"icontheme": self.IconTheme, "trayicon": self.TrayiconCheck, "exitdialog": None} }
self.ThemeButton.connect("clicked", self.OnChooseThemeDir)
self.DefaultTheme.connect("clicked", self.OnDefaultTheme)
self.N.set_from_pixbuf(self.frame.images["n"])
self.Away.set_from_pixbuf(self.frame.images["away"])
self.Away2.set_from_pixbuf(self.frame.images["away2"])
self.Online.set_from_pixbuf(self.frame.images["online"])
self.Offline.set_from_pixbuf(self.frame.images["offline"])
self.Hilite.set_from_pixbuf(self.frame.images["hilite"])
self.Hilite2.set_from_pixbuf(self.frame.images["hilite2"])
self.Hilite3.set_from_pixbuf(self.frame.images["hilite3"])
self.Connect.set_from_pixbuf(self.frame.images["connect"])
self.Disconnect.set_from_pixbuf(self.frame.images["disconnect"])
self.Notify.set_from_pixbuf(self.frame.images["notify"])
def SetSettings(self, config):
ui = config["ui"]
self.p.SetWidgetsData(config, self.options)
if ui["exitdialog"] is not None:
exitdialog = int( ui["exitdialog"] )
if exitdialog == 1:
self.DialogOnClose.set_active(True)
elif exitdialog == 2:
self.SendToTrayOnClose.set_active(True)
elif exitdialog == 0:
self.QuitOnClose.set_active(True)
else:
self.p.Hilight(self.DialogOnClose)
self.p.Hilight(self.SendToTrayOnClose)
self.p.Hilight(self.QuitOnClose)
def OnDefaultTheme(self, widget):
self.IconTheme.set_text("")
def OnChooseThemeDir(self, widget):
dir = ChooseDir(self.Main.get_toplevel(), self.IconTheme.get_text(), title=_("Nicotine+")+": "+_("Choose an icon theme directory"))
if dir is not None:
for directory in dir: # iterate over selected files
self.IconTheme.set_text(recode(directory))
def GetSettings(self):
mainwindow_close = 0
widgets = [ self.QuitOnClose, self.DialogOnClose, self.SendToTrayOnClose]
for i in widgets:
if i.get_active():
mainwindow_close = widgets.index(i)
break
return {
"ui": {
"icontheme": self.IconTheme.get_text(),
"trayicon": self.TrayiconCheck.get_active(),
"exitdialog": mainwindow_close,
},
}
class ColoursFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "ColoursFrame")
self.UsernameStyle_List = gtk.ListStore(gobject.TYPE_STRING)
self.UsernameStyle.set_model(self.UsernameStyle_List)
self.UsernameStyle.set_text_column(0)
self.needcolors = 0
self.options = { "ui": {"chatlocal":self.Local,
"chatremote": self.Remote, "chatme": self.Me, "chathilite": self.Highlight,
"textbg":self.BackgroundColor, "inputcolor": self.InputColor, "search": self.Immediate,
"searchq": self.Queue, "searchoffline": self.OfflineSearchEntry, "useraway": self.AwayColor,
"useronline": self.OnlineColor, "useroffline": self.OfflineColor,
"usernamehotspots": self.UsernameHotspots, "usernamestyle": self.UsernameStyle,
"showaway": self.DisplayAwayColours, "urlcolor": self.URL,
"enabletrans": self.EnableTransparent, "transtint": self.TintColor, "transalpha": self.TintAlpha,
"tab_default": self.DefaultTab, "tab_hilite": self.HighlightTab, "tab_changed": self.ChangedTab,
},
}
self.colorsd = { "ui": {"chatlocal":self.Drawing_Local,
"chatremote": self.Drawing_Remote, "chatme": self.Drawing_Me, "chathilite": self.Drawing_Highlight,
"textbg":self.Drawing_BackgroundColor, "inputcolor": self.Drawing_InputColor, "search": self.Drawing_Immediate,
"searchq": self.Drawing_Queue, "searchoffline": self.Drawing_OfflineSearchEntry, "useraway": self.Drawing_AwayColor,
"useronline": self.Drawing_OnlineColor, "useroffline": self.Drawing_OfflineColor,
"showaway": self.DisplayAwayColours, "urlcolor": self.Drawing_URL,
"enabletrans": self.EnableTransparent, "transtint": self.Drawing_TintColor,
"tab_default": self.Drawing_DefaultTab, "tab_hilite": self.Drawing_HighlightTab, "tab_changed": self.Drawing_ChangedTab }, }
self.colors = ["chatlocal", "chatremote", "urlcolor", "chatme", "chathilite", "textbg", "inputcolor", "search", "searchq", "searchoffline", "useraway", "useronline", "useroffline", "tab_default", "tab_changed", "tab_hilite", "transtint"]
for item in ["bold", "italic", "underline", "normal"]:
self.UsernameStyle.append_text(item)
self.UsernameStyle.child.set_editable(False)
self.PickRemote.connect("clicked", self.PickColour, self.Remote, self.Drawing_Remote)
self.PickLocal.connect("clicked", self.PickColour, self.Local, self.Drawing_Local)
self.PickMe.connect("clicked", self.PickColour, self.Me, self.Drawing_Me)
self.PickHighlight.connect("clicked", self.PickColour, self.Highlight, self.Drawing_Highlight)
self.PickImmediate.connect("clicked", self.PickColour, self.Immediate, self.Drawing_Immediate)
self.PickQueue.connect("clicked", self.PickColour, self.Queue, self.Drawing_Queue)
self.PickAway.connect("clicked", self.PickColour, self.AwayColor, self.Drawing_AwayColor)
self.PickOnline.connect("clicked", self.PickColour, self.OnlineColor, self.Drawing_OnlineColor)
self.PickOffline.connect("clicked", self.PickColour, self.OfflineColor, self.Drawing_OfflineColor)
self.PickOfflineSearch.connect("clicked", self.PickColour, self.OfflineSearchEntry, self.Drawing_OfflineSearchEntry)
self.PickURL.connect("clicked", self.PickColour, self.URL, self.Drawing_URL)
self.DefaultURL.connect("clicked", self.DefaultColour, self.URL)
self.DefaultAway.connect("clicked", self.DefaultColour, self.AwayColor)
self.DefaultOnline.connect("clicked", self.DefaultColour, self.OnlineColor)
self.DefaultOffline.connect("clicked", self.DefaultColour, self.OfflineColor)
self.PickBackground.connect("clicked", self.PickColour, self.BackgroundColor, self.Drawing_BackgroundColor)
self.DefaultBackground.connect("clicked", self.DefaultColour, self.BackgroundColor)
self.PickInput.connect("clicked", self.PickColour, self.InputColor, self.Drawing_InputColor)
self.DefaultInput.connect("clicked", self.DefaultColour, self.InputColor)
self.DefaultRemote.connect("clicked", self.DefaultColour, self.Remote)
self.DefaultLocal.connect("clicked", self.DefaultColour, self.Local)
self.DefaultMe.connect("clicked", self.DefaultColour, self.Me)
self.DefaultHighlight.connect("clicked", self.DefaultColour, self.Highlight)
self.DefaultImmediate.connect("clicked", self.DefaultColour, self.Immediate)
self.DefaultQueue.connect("clicked", self.DefaultColour, self.Queue)
self.DefaultColours.connect("clicked", self.OnDefaultColours)
self.ClearAllColours.connect("clicked", self.OnClearAllColours)
self.DisplayAwayColours.connect("toggled", self.ToggledAwayColours)
self.DefaultOfflineSearch.connect("clicked", self.DefaultColour, self.OfflineSearchEntry)
self.PickHighlightTab.connect("clicked", self.PickColour, self.HighlightTab, self.Drawing_HighlightTab)
self.PickDefaultTab.connect("clicked", self.PickColour, self.DefaultTab, self.Drawing_DefaultTab)
self.PickChangedTab.connect("clicked", self.PickColour, self.ChangedTab, self.Drawing_ChangedTab)
self.DefaultHighlightTab.connect("clicked", self.DefaultColour, self.HighlightTab)
self.DefaultChangedTab.connect("clicked", self.DefaultColour, self.ChangedTab)
self.ClearDefaultTab.connect("clicked", self.DefaultColour, self.DefaultTab)
# To set needcolors flag
self.Local.connect("changed", self.FontsColorsChanged)
self.Remote.connect("changed", self.FontsColorsChanged)
self.Me.connect("changed", self.FontsColorsChanged)
self.Highlight.connect("changed", self.FontsColorsChanged)
self.BackgroundColor.connect("changed", self.FontsColorsChanged)
self.Immediate.connect("changed", self.FontsColorsChanged)
self.Queue.connect("changed", self.FontsColorsChanged)
self.OfflineSearchEntry.connect("changed", self.FontsColorsChanged)
self.AwayColor.connect("changed", self.FontsColorsChanged)
self.OnlineColor.connect("changed", self.FontsColorsChanged)
self.OfflineColor.connect("changed", self.FontsColorsChanged)
self.UsernameStyle.child.connect("changed", self.FontsColorsChanged)
self.InputColor.connect("changed", self.FontsColorsChanged)
# Tint
self.PickTint.connect("clicked", self.PickColour, self.TintColor, self.Drawing_TintColor)
self.DefaultTint.connect("clicked", self.DefaultColour, self.TintColor)
def SetSettings(self, config):
self.settingup = 1
self.p.SetWidgetsData(config, self.options)
for option in self.colors:
for key, value in self.colorsd.items():
if option in value:
drawingarea = self.colorsd[key][option]
try:
colour = gtk.gdk.color_parse(config[key][option])
except:
colour = None
drawingarea.modify_bg(gtk.STATE_NORMAL, colour)
break
try:
self.TintAlpha.set_value(config['ui']['transalpha'])
except KeyError:
pass
self.ToggledAwayColours(self.DisplayAwayColours)
self.OnEnableTransparentToggled(self.EnableTransparent)
self.ColourScale("")
self.settingup = 0
self.needcolors = 0
def OnExpand(self, widget):
if self.ListExpander.get_property("expanded"):
self.vboxColours.set_child_packing(self.ListExpander, False, False, 0, 0)
else:
self.vboxColours.set_child_packing(self.ListExpander, False, True, 0, 0)
if self.ChatExpander.get_property("expanded"):
self.vboxColours.set_child_packing(self.ChatExpander, False, False, 0, 0)
else:
self.vboxColours.set_child_packing(self.ChatExpander, False, True, 0, 0)
if self.TransparentExpander.get_property("expanded"):
self.vboxColours.set_child_packing(self.TransparentExpander, False, False, 0, 0)
else:
self.vboxColours.set_child_packing(self.TransparentExpander, False, True, 0, 0)
def GetSettings(self):
return {
"ui": {
"chatlocal": self.Local.get_text(),
"chatremote": self.Remote.get_text(),
"chatme": self.Me.get_text(),
"chathilite": self.Highlight.get_text(),
"urlcolor": self.URL.get_text(),
"textbg": self.BackgroundColor.get_text(),
"inputcolor": self.InputColor.get_text(),
"search": self.Immediate.get_text(),
"searchq": self.Queue.get_text(),
"searchoffline": self.OfflineSearchEntry.get_text(),
"showaway": int(self.DisplayAwayColours.get_active()),
"useraway": self.AwayColor.get_text(),
"useronline": self.OnlineColor.get_text(),
"useroffline": self.OfflineColor.get_text(),
"usernamehotspots": self.UsernameHotspots.get_active(),
"usernamestyle": self.UsernameStyle.child.get_text(),
"enabletrans": self.EnableTransparent.get_active(),
"transtint": self.TintColor.get_text(),
"transalpha": self.TintAlpha.get_value(),
"tab_hilite": self.HighlightTab.get_text(),
"tab_default": self.DefaultTab.get_text(),
"tab_changed": self.ChangedTab.get_text(),
}
}
def ToggledAwayColours(self, widget):
sensitive = widget.get_active()
self.AwayColor.set_sensitive(sensitive)
self.PickAway.set_sensitive(sensitive)
self.DefaultAway.set_sensitive(sensitive)
def OnDefaultColours(self, widget):
for option in self.colors:
self.SetDefaultColor(option)
def SetDefaultColor(self, option):
defaults = self.frame.np.config.defaults
for key, value in self.options.items():
if option in value:
widget = self.options[key][option]
if type(widget) is gtk.Entry:
widget.set_text(defaults[key][option])
elif type(widget) is gtk.SpinButton:
widget.set_value_as_int(defaults[key][option])
elif type(widget) is gtk.CheckButton:
widget.set_active(defaults[key][option])
elif type(widget) is gtk.ComboBoxEntry:
widget.child.set_text(defaults[key][option])
for key, value in self.colorsd.items():
if option in value:
drawingarea = self.colorsd[key][option]
try:
colour = gtk.gdk.color_parse(defaults[key][option])
except:
colour = None
drawingarea.modify_bg(gtk.STATE_NORMAL, colour)
break
def OnClearAllColours(self, widget):
for option in self.colors:
for section, value in self.options.items():
if option in value:
widget = self.options[section][option]
if type(widget) is gtk.Entry:
widget.set_text("")
elif type(widget) is gtk.SpinButton:
widget.set_value_as_int(0)
elif type(widget) is gtk.CheckButton:
widget.set_active(0)
elif type(widget) is gtk.ComboBoxEntry:
widget.child.set_text("")
for section, value in self.colorsd.items():
if option in value:
drawingarea = self.colorsd[section][option]
drawingarea.modify_bg(gtk.STATE_NORMAL, None)
def FontsColorsChanged(self, widget):
self.needcolors = 1
def OnEnableTransparentToggled(self, widget):
sensitive = widget.get_active()
self.PickTint.set_sensitive(sensitive)
self.TintAlpha.set_sensitive(sensitive)
self.DefaultTint.set_sensitive(sensitive)
self.TintColor.set_sensitive(sensitive)
self.Blue.set_sensitive(sensitive)
self.Red.set_sensitive(sensitive)
self.Green.set_sensitive(sensitive)
self.label346.set_sensitive(sensitive)
self.label348.set_sensitive(sensitive)
self.label349.set_sensitive(sensitive)
self.label347.set_sensitive(sensitive)
def OnUsernameHotspotsToggled(self, widget):
sensitive = widget.get_active()
self.AwayColor.set_sensitive(sensitive and self.DisplayAwayColours.get_active())
self.OnlineColor.set_sensitive(sensitive)
self.OfflineColor.set_sensitive(sensitive)
self.DefaultAway.set_sensitive(sensitive)
self.DefaultOnline.set_sensitive(sensitive)
self.DefaultOffline.set_sensitive(sensitive)
self.PickAway.set_sensitive(sensitive)
self.PickOnline.set_sensitive(sensitive)
self.PickOffline.set_sensitive(sensitive)
def PickColour(self, widget, entry, drawingarea):
dlg = gtk.ColorSelectionDialog(_("Pick a colour, any colour"))
colour = entry.get_text()
if entry is self.TintColor:
dlg.colorsel.set_has_opacity_control(True)
dlg.colorsel.set_current_alpha(int(self.TintAlpha.get_value()) * 256)
if colour != None and colour !='':
try:
colour = gtk.gdk.color_parse(colour)
except:
self.p.Hilight(entry)
dlg.destroy()
return
else:
dlg.colorsel.set_current_color(colour)
if dlg.run() == gtk.RESPONSE_OK:
colour = dlg.colorsel.get_current_color()
#print colour.red, colour.red / 256, colour.green, colour.green / 256, colour.blue, colour.blue / 256
colourtext = "#%02X%02X%02X" % (colour.red / 256, colour.green / 256, colour.blue / 256)
entry.set_text(colourtext)
for section in self.options.keys():
if section not in self.colorsd:
continue
for key, value in self.options[section].items():
if key not in self.colorsd[section]:
continue
if entry is value:
drawingarea = self.colorsd[section][key]
drawingarea.modify_bg(gtk.STATE_NORMAL, colour)
break
if entry is self.TintColor:
alpha = dlg.colorsel.get_current_alpha()
self.TintAlpha.set_value(alpha /256)
self.ColourScale("")
dlg.destroy()
def ColourScale(self, widget):
tint = self.TintColor.get_text()
if tint != "":
if tint[0] == "#" and len(tint) == 7:
try:
red = int(tint[1:3], 16)
green = int(tint[3:5], 16)
blue = int(tint[5:], 16)
self.Red.set_value(red)
self.Blue.set_value(blue)
self.Green.set_value(green)
except Exception, e:
print e
def ScaleColour(self, widget):
if self.settingup:
return
red = int(self.Red.get_value() )
green = int(self.Green.get_value())
blue = int(self.Blue.get_value())
colour = "#%02X%02X%02X" % (red, green, blue)
self.TintColor.set_text(colour)
self.Drawing_TintColor.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(colour))
def DefaultColour(self, widget, entry):
for section in self.options.keys():
for key, value in self.options[section].items():
if value is entry:
self.SetDefaultColor(key)
return
entry.set_text("")
class NotebookFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "NotebookFrame")
self.NotificationIcon.set_from_pixbuf(self.frame.images["online"])
self.options = { "ui": {
"tabmain": self.MainPosition, "tabrooms": self.ChatRoomsPosition, "tabprivate": self.PrivateChatPosition, "tabinfo": self.UserInfoPosition, "tabbrowse": self.UserBrowsePosition, "tabsearch": self.SearchPosition,
"labelmain": self.MainAngleSpin, "labelrooms": self.ChatRoomsAngleSpin, "labelprivate": self.PrivateChatAngleSpin, "labelinfo": self.UserInfoAngleSpin, "labelbrowse": self.UserBrowseAngleSpin, "labelsearch": self.SearchAngleSpin,
"tabclosers": self.TabClosers, "tab_icons": self.TabIcons, "tab_colors": self.TabColours, "tab_reorderable": self.TabReorderable, "tab_status_icons": self.TabStatusIcons}
}
def SetSettings(self, config):
self.p.SetWidgetsData(config, self.options)
def GetSettings(self):
return {
"ui": {
"tabmain": self.MainPosition.get_active_text(),
"tabrooms": self.ChatRoomsPosition.get_active_text(),
"tabprivate": self.PrivateChatPosition.get_active_text(),
"tabinfo": self.UserInfoPosition.get_active_text(),
"tabbrowse": self.UserBrowsePosition.get_active_text(),
"tabsearch": self.SearchPosition.get_active_text(),
"labelmain": self.MainAngleSpin.get_value_as_int(),
"labelrooms": self.ChatRoomsAngleSpin.get_value_as_int(),
"labelprivate": self.PrivateChatAngleSpin.get_value_as_int(),
"labelinfo": self.UserInfoAngleSpin.get_value_as_int(),
"labelbrowse": self.UserBrowseAngleSpin.get_value_as_int(),
"labelsearch": self.SearchAngleSpin.get_value_as_int(),
"tabclosers": self.TabClosers.get_active(),
"tab_icons": self.TabIcons.get_active(),
"tab_colors": self.TabColours.get_active(),
"tab_reorderable": self.TabReorderable.get_active(),
"tab_status_icons": self.TabStatusIcons.get_active(),
}
}
class BloatFrame(buildFrame):
languagelookup = [
('Dansk (Danish)','da'),
('Deutsch (German)','de'),
('Español (Spanish)','es'),
('Euskara (Bask)','eu'),
('Français (French)','fr'),
('Italiano (Italian)','it'),
('Lietuvių kalba (Lithuanian)','lt'),
('Magyar nyelv (Hungarian)','hu'),
('Nederlands (Dutch)','nl'),
('Polszczyzna (Polish)','pl'),
('Português brasileiro (Brazilian Portuguese)','pt_BR'),
('Slovenčina (Slovak)','sk'),
('Svenska (Swedish)','sv'),
('Suomi (Finnish)','fi'),]
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "BloatFrame")
self.TranslationCombo_List = gtk.ListStore(gobject.TYPE_STRING)
self.TranslationCombo.set_model(self.TranslationCombo_List)
cell = gtk.CellRendererText()
self.TranslationCombo.pack_start(cell, True)
self.TranslationCombo.add_attribute(cell, 'text', 0)
self.DecimalSep_List = gtk.ListStore(gobject.TYPE_STRING)
self.DecimalSep.set_model(self.DecimalSep_List)
self.options = {
"ui": { "chatfont":self.SelectChatFont, "listfont": self.SelectListFont, "searchfont": self.SelectSearchFont, "transfersfont": self.SelectTransfersFont, "browserfont": self.SelectBrowserFont, "decimalsep": self.DecimalSep, "spellcheck": self.SpellCheck, "tooltips": self.ShowTooltips,
},
"transfers": {"enabletransferbuttons": self.ShowTransferButtons},
"language": {"setlanguage": self.TranslationCheck, "language": self.TranslationCombo},
}
for item in ["", ",", ".", ""]:
self.DecimalSep.append_text(item)
for name, code in self.languagelookup:
self.TranslationCombo.append_text(name)
self.DefaultFont.connect("clicked", self.OnDefaultFont)
self.SelectChatFont.connect("font-set", self.FontsColorsChanged)
self.DefaultListFont.connect("clicked", self.OnDefaultListFont)
self.SelectListFont.connect("font-set", self.FontsColorsChanged)
self.DefaultSearchFont.connect("clicked", self.OnDefaultSearchFont)
self.SelectSearchFont.connect("font-set", self.FontsColorsChanged)
self.DefaultTransfersFont.connect("clicked", self.OnDefaultTransfersFont)
self.SelectTransfersFont.connect("font-set", self.FontsColorsChanged)
self.DefaultBrowserFont.connect("clicked", self.OnDefaultBrowserFont)
self.SelectBrowserFont.connect("font-set", self.FontsColorsChanged)
self.needcolors = 0
def SetSettings(self, config):
self.needcolors = 0
ui = config["ui"]
transfers = config["transfers"]
language = config["language"]
self.SpellCheck.set_sensitive(self.frame.SEXY)
self.p.SetWidgetsData(config, self.options)
for i in xrange(0, len(self.languagelookup)):
name, code = self.languagelookup[i]
if language['language'] == code:
self.TranslationCombo.set_active(i)
break
self.OnTranslationCheckToggled(self.TranslationCheck)
def GetSettings(self):
language = self.languagelookup[self.TranslationCombo.get_active()][1]
try:
import gettext
message = ""
if self.TranslationCheck.get_active():
langTranslation = gettext.translation('nicotine', languages=[language])
langTranslation.install()
except IOError, e:
message = _("Translation not found for '%s': %s") % (language, e)
langTranslation = gettext
except IndexError, e:
message = _("Translation was corrupted for '%s': %s") % (language, e)
langTranslation = gettext
except KeyError, e:
message = _("Lookup failed for '%(language)s': %(error)s") % {'language':language, 'error':e}
langTranslation = gettext
if message is not None and message != "":
popupWarning(self.p.SettingsWindow, _("Warning: Missing translation"), _("Nicotine+ could not find your selected translation.\n%s") % message, self.frame.images["n"] )
raise UserWarning
return {
"ui": {
"decimalsep": self.DecimalSep.child.get_text(),
"spellcheck": self.SpellCheck.get_active(),
"chatfont": self.SelectChatFont.get_font_name(),
"listfont": self.SelectListFont.get_font_name(),
"searchfont": self.SelectSearchFont.get_font_name(),
"transfersfont": self.SelectTransfersFont.get_font_name(),
"browserfont": self.SelectBrowserFont.get_font_name(),
"tooltips": self.ShowTooltips.get_active(),
},
"transfers": {
"enabletransferbuttons": self.ShowTransferButtons.get_active(),
},
"language": {
"setlanguage": self.TranslationCheck.get_active(),
"language": language,
}
}
def OnTranslationCheckToggled(self, widget):
sensitive = widget.get_active()
self.TranslationCombo.set_sensitive(sensitive)
def OnDefaultFont(self, widget):
self.SelectChatFont.set_font_name("")
self.needcolors = 1
def OnDefaultBrowserFont(self, widget):
self.SelectBrowserFont.set_font_name("")
self.needcolors = 1
def OnDefaultListFont(self, widget):
self.SelectListFont.set_font_name("")
self.needcolors = 1
def OnDefaultSearchFont(self, widget):
self.SelectSearchFont.set_font_name("")
self.needcolors = 1
def OnDefaultTransfersFont(self, widget):
self.SelectTransfersFont.set_font_name("")
self.needcolors = 1
def FontsColorsChanged(self, widget):
self.needcolors = 1
class LogFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "LogFrame")
self.options = {"logging": { "privatechat": self.LogPrivate, "chatrooms": self.LogRooms, "logsdir": self.LogDir, "roomlogsdir": self.RoomLogDir, "privatelogsdir": self.PrivateLogDir, "transfers": self.LogTransfers, "rooms_timestamp":self.ChatRoomFormat, "private_timestamp":self.PrivateChatFormat, "log_timestamp": self.LogFileFormat, "timestamps": self.ShowTimeStamps, "readroomlines": self.RoomLogLines, "readprivatelines": self.PrivateLogLines, "readroomlogs": self.ReadRoomLogs},
"privatechat": {"store": self.ReopenPrivateChats},}
def SetSettings(self, config):
self.p.SetWidgetsData(config, self.options)
def GetSettings(self):
return {
"logging": {
"privatechat": self.LogPrivate.get_active(),
"chatrooms": self.LogRooms.get_active(),
"logsdir": recode2(self.LogDir.get_text()),
"roomlogsdir": recode2(self.RoomLogDir.get_text()),
"privatelogsdir": recode2(self.PrivateLogDir.get_text()),
"readroomlogs": self.ReadRoomLogs.get_active(),
"readroomlines": self.RoomLogLines.get_value_as_int(),
"readprivatelines": self.PrivateLogLines.get_value_as_int(),
"transfers": self.LogTransfers.get_active(),
"private_timestamp": self.PrivateChatFormat.get_text(),
"rooms_timestamp": self.ChatRoomFormat.get_text(),
"log_timestamp": self.LogFileFormat.get_text(),
"timestamps": self.ShowTimeStamps.get_active(),
},
"privatechat": {
"store": self.ReopenPrivateChats.get_active(),
},
}
def OnChooseLogDir(self, widget):
dir = ChooseDir(self.Main.get_toplevel(), self.LogDir.get_text(), title=_("Nicotine+")+": "+_("Choose a directory to save your log files"))
if dir is not None:
for directory in dir: # iterate over selected files
self.LogDir.set_text(recode(directory))
def OnChooseRoomLogDir(self, widget):
dir = ChooseDir(self.Main.get_toplevel(), self.RoomLogDir.get_text(), title=_("Nicotine+")+": "+_("Choose a directory to save your log files"))
if dir is not None:
for directory in dir: # iterate over selected files
self.RoomLogDir.set_text(recode(directory))
def OnChoosePrivateLogDir(self, widget):
dir = ChooseDir(self.Main.get_toplevel(), self.PrivateLogDir.get_text(), title=_("Nicotine+")+": "+_("Choose a directory to save your log files"))
if dir is not None:
for directory in dir: # iterate over selected files
self.PrivateLogDir.set_text(recode(directory))
def OnDefaultTimestamp(self, widget):
defaults = self.frame.np.config.defaults
self.LogFileFormat.set_text(defaults["logging"]["log_timestamp"])
def OnRoomDefaultTimestamp(self, widget):
defaults = self.frame.np.config.defaults
self.ChatRoomFormat.set_text(defaults["logging"]["rooms_timestamp"])
def OnPrivateDefaultTimestamp(self, widget):
defaults = self.frame.np.config.defaults
self.PrivateChatFormat.set_text(defaults["logging"]["private_timestamp"])
class SearchFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "SearchFrame")
self.options = {"searches": {"maxresults": self.MaxResults, "enablefilters": self.EnableFilters, "re_filter": self.RegexpFilters, "defilter": None, "distrib_timer": self.ToggleDistributed, "distrib_ignore": self.ToggleDistributedInterval, "reopen_tabs": self.ReopenTabs, "search_results": self.ToggleResults, "max_displayed_results": self.MaxDisplayedResults, "max_stored_results": self.MaxStoredResults }}
def SetSettings(self, config):
try:
searches = config["searches"]
except:
searches = None
self.p.SetWidgetsData(config, self.options)
if searches["defilter"] is not None:
self.FilterIn.set_text(searches["defilter"][0])
self.FilterOut.set_text(searches["defilter"][1])
self.FilterSize.set_text(searches["defilter"][2])
self.FilterBR.set_text(searches["defilter"][3])
self.FilterFree.set_active(searches["defilter"][4])
if(len(searches["defilter"]) > 5):
self.FilterCC.set_text(searches["defilter"][5])
else:
self.p.Hilight(self.FilterIn)
self.p.Hilight(self.FilterOut)
self.p.Hilight(self.FilterSize)
self.p.Hilight(self.FilterBR)
self.p.Hilight(self.FilterFree)
self.p.Hilight(self.FilterCC)
self.OnEnableSearchResults(self.ToggleResults)
def GetSettings(self):
maxresults = self.MaxResults.get_value_as_int()
return {
"searches": {
"maxresults": maxresults,
"enablefilters": self.EnableFilters.get_active(),
"re_filter": self.RegexpFilters.get_active(),
"defilter": [
self.FilterIn.get_text(),
self.FilterOut.get_text(),
self.FilterSize.get_text(),
self.FilterBR.get_text(),
self.FilterFree.get_active(),
self.FilterCC.get_text(),
],
"distrib_timer": self.ToggleDistributed.get_active(),
"distrib_ignore": self.ToggleDistributedInterval.get_value_as_int(),
"reopen_tabs": self.ReopenTabs.get_active(),
"search_results": self.ToggleResults.get_active(),
"max_displayed_results": self.MaxDisplayedResults.get_value_as_int(),
"max_stored_results": self.MaxStoredResults.get_value_as_int(),
}
}
def OnEnableFiltersToggled(self, widget):
active = widget.get_active()
for w in self.FilterIn, self.FilterOut, self.FilterSize, self.FilterBR, self.FilterFree:
w.set_sensitive(active)
def OnEnableSearchResults(self, widget):
active = widget.get_active()
for w in self.MaxResults, self.MaxResultsL1, self.MaxResultsL2,self.ToggleDistributed, self.ToggleDistributedInterval, self.secondsLabel:
w.set_sensitive(active)
class AwayFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "AwayFrame")
self.options = {"server": {"autoaway": self.AutoAway, "autoreply": self.AutoReply}}
def SetSettings(self, config):
server = config["server"]
self.p.SetWidgetsData(config, self.options)
def GetSettings(self):
try:
autoaway = self.AutoAway.get_value_as_int()
except:
autoaway = None
return {
"server": {
"autoaway": autoaway,
"autoreply": self.AutoReply.get_text(),
}
}
class EventsFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "EventsFrame")
self.FileManagerCombo_List = gtk.ListStore(gobject.TYPE_STRING)
self.FileManagerCombo.set_model(self.FileManagerCombo_List)
self.FileManagerCombo.set_text_column(0)
self.options = {"transfers": { "shownotification": self.ShowNotification, "shownotificationperfolder": self.ShowNotificationPerFolder, "afterfinish": self.AfterDownload, "afterfolder": self.AfterFolder, "download_doubleclick": self.DownloadDoubleClick, "upload_doubleclick": self.UploadDoubleClick, },
"ui": {"filemanager": self.FileManagerCombo.child },}
for executable in ["rox $", "konqueror $", "nautilus --no-desktop $", "thunar $", "xterm -e mc $", "emelfm2 -1 $", "krusader --left $", "gentoo -1 $" ]:
self.FileManagerCombo.append_text( executable )
def SetSettings(self, config):
if self.frame.pynotify is not None:
self.ShowNotification.set_sensitive(True)
self.ShowNotificationPerFolder.set_sensitive(True)
else:
self.ShowNotification.set_sensitive(False)
self.ShowNotificationPerFolder.set_sensitive(False)
self.p.SetWidgetsData(config, self.options)
def GetSettings(self):
return {
"transfers": {
"shownotification" : self.ShowNotification.get_active(),
"shownotificationperfolder": self.ShowNotificationPerFolder.get_active(),
"afterfinish": self.AfterDownload.get_text(),
"afterfolder": self.AfterFolder.get_text(),
"download_doubleclick": self.DownloadDoubleClick.get_active(),
"upload_doubleclick": self.UploadDoubleClick.get_active(),
},
"ui": {
"filemanager": self.FileManagerCombo.child.get_text(),
},
}
class ImportFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "ImportFrame")
self.options = {}
self.ImportPath.connect("activate", self.CheckPath)
self.ImportPath.connect("changed", self.CheckPath)
def SetSettings(self, config):
self.config = self.frame.np.config
path = "C:\Program Files\SoulSeek"
if os.path.exists(path):
self.ImportPath.set_text(path)
else:
self.CheckPath(self.ImportPath)
def CheckPath(self, widget):
if not os.path.exists(widget.get_text()):
self.p.SetTextBG(self.ImportPath, "red", "white")
else:
self.p.SetTextBG(widget, "", "")
def GetSettings(self):
return {}
def OnImportDirectory(self, widget):
dir1 = ChooseDir(self.Main.get_toplevel(), self.ImportPath.get_text(), title=_("Nicotine+")+": "+_("Import Soulseek config from directory"))
if dir1 is not None:
for directory in dir1: # iterate over selected files
self.ImportPath.set_text(recode(directory))
directory = self.ImportPath.get_text()
if not os.path.exists(directory):
self.p.Hilight(self.ImportPath)
def OnImportConfig(self, widget):
Path = self.ImportPath.get_text()
Queue = self.ImportQueue.get_active()
Login = self.ImportLogin.get_active()
Rooms = self.ImportRooms.get_active()
BuddyList = self.ImportBuddyList.get_active()
BanList = self.ImportBanList.get_active()
IgnoreList = self.ImportIgnoreList.get_active()
UserInfo = self.ImportUserInfo.get_active()
UserImage = self.ImportUserImage.get_active()
Import = ImportWinSlskConfig(self.config, Path, Queue, Login, Rooms, BuddyList, BanList, IgnoreList, UserInfo, UserImage)
response = Import.Run()
if response == 0:
popupWarning(self.p.SettingsWindow, _("Nothing Imported"), _("Config files for the official Soulseek client not found in \"%s\"") % Path , self.frame.images["n"])
elif response == 1:
popupWarning(self.p.SettingsWindow, _("Imported Soulseek Config"), _("Config was imported. You may need to restart for changes to take effect. If you changed your user name, buddy list or queue then you should restart immediately."), self.frame.images["n"] )
self.p.SetSettings(self.frame.np.config.sections)
elif response == 2:
popupWarning(self.p.SettingsWindow, _("Nothing Imported"), _("No options were selected") , self.frame.images["n"])
class UrlCatchFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "UrlCatchFrame")
self.options = {"urls": { "urlcatching": self.URLCatching, "humanizeurls": self.HumanizeURLs, "protocols": None}, "ui": {"mozembed": self.EnableMozEmbed, "open_in_mozembed": self.EnableMozEmbedURLs, }, }
self.protocolmodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.protocols = {}
cols = InitialiseColumns(self.ProtocolHandlers,
[_("Protocol"), -1, "text"],
[_("Handler"), -1, "combo"],
)
cols[0].set_sort_column_id(0)
cols[1].set_sort_column_id(1)
self.ProtocolHandlers.set_model(self.protocolmodel)
self.ProtocolHandlers.get_selection().connect("changed", self.OnSelect)
self.OnToggleMozembed(self.EnableMozEmbed)
renderers = cols[1].get_cell_renderers()
for render in renderers:
render.connect('edited', self.cell_edited_callback, self.ProtocolHandlers, 1)
self.handlermodel = gtk.ListStore(gobject.TYPE_STRING)
for item in ["xdg-open $", "firefox $", "firefox -a firefox --remote \"openURL($,new-tab)\"", "mozilla $", "opera $", "links -g $", "dillo $", "konqueror $", "\"c:\Program Files\Mozilla Firefox\Firefox.exe\" $"]:
self.handlermodel.append([item])
self.Handler.set_model(self.handlermodel)
self.Handler.set_text_column(0)
renderers = cols[1].get_cell_renderers()
for render in renderers:
render.set_property("model", self.handlermodel)
self.protomodel = gtk.ListStore(gobject.TYPE_STRING)
for item in ["http", "https", "ftp", "sftp", "news", "irc"]:
self.protomodel.append([item])
self.ProtocolCombo.set_model(self.protomodel)
self.ProtocolCombo.set_text_column(0)
def cell_edited_callback(self, widget, index, value, treeview, pos):
#print index, value, treeview, pos
store = treeview.get_model()
iter = store.get_iter(index)
#print iter, index, value
store.set(iter, pos, value)
def OnToggleMozembed(self, widget):
self.EnableMozEmbedURLs.set_sensitive(widget.get_active())
def SetSettings(self, config):
self.protocolmodel.clear()
self.protocols.clear()
self.p.SetWidgetsData(config, self.options)
urls = config["urls"]
if urls["protocols"] is not None:
for key in urls["protocols"].keys():
if urls["protocols"][key][-1:] == "&":
command = urls["protocols"][key][:-1].rstrip()
else:
command = urls["protocols"][key]
iter = self.protocolmodel.append([key, command])
self.protocols[key] = iter
else:
self.p.Hilight(self.ProtocolHandlers)
self.OnURLCatchingToggled(self.URLCatching)
selection = self.ProtocolHandlers.get_selection()
selection.unselect_all()
for key, iter in self.protocols.items():
if iter is not None:
selection.select_iter(iter)
break
def GetSettings(self):
protocols = {}
try:
iter = self.protocolmodel.get_iter_root()
while iter is not None:
protocol = self.protocolmodel.get_value(iter, 0)
handler = self.protocolmodel.get_value(iter, 1)
protocols[protocol] = handler
iter = self.protocolmodel.iter_next(iter)
except:
pass
return {
"ui" : {
"mozembed": self.EnableMozEmbed.get_active(),
"open_in_mozembed": self.EnableMozEmbedURLs.get_active(),
},
"urls": {
"urlcatching": self.URLCatching.get_active(),
"humanizeurls": self.HumanizeURLs.get_active(),
"protocols": protocols,
}
}
def OnURLCatchingToggled(self, widget):
self.HumanizeURLs.set_active(widget.get_active())
act = self.URLCatching.get_active()
self.RemoveHandler.set_sensitive(act)
self.addButton.set_sensitive(act)
self.HumanizeURLs.set_sensitive(act)
self.ProtocolHandlers.set_sensitive(act)
self.ProtocolCombo.set_sensitive(act)
self.Handler.set_sensitive(act)
def OnSelect(self, selection):
model, iter = selection.get_selected()
if iter == None:
self.ProtocolCombo.child.set_text("")
else:
protocol = model.get_value(iter, 0)
handler = model.get_value(iter, 1)
self.ProtocolCombo.child.set_text(protocol)
self.Handler.child.set_text(handler)
def OnAdd(self, widget):
protocol = self.ProtocolCombo.child.get_text()
command = self.Handler.child.get_text()
if protocol in self.protocols:
iter = self.protocols[protocol]
if iter is not None:
self.protocolmodel.set(iter, 1, command)
else:
iter = self.protocolmodel.append([protocol, command])
self.protocols[protocol] = iter
def OnRemove(self, widget):
selection = self.ProtocolHandlers.get_selection()
model, iter = selection.get_selected()
if iter is not None:
protocol = self.protocolmodel.get_value(iter, 0)
self.protocolmodel.remove(iter)
del self.protocols[protocol]
class CensorFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "CensorFrame")
self.options = {"words": {"censorfill": self.CensorReplaceCombo.child, "censored": self.CensorList, "censorwords": self.CensorCheck, }}
self.censorlist = gtk.ListStore(gobject.TYPE_STRING)
cols = InitialiseColumns(self.CensorList,
[_("Pattern"), -1, "edit", self.frame.CellDataFunc],
)
cols[0].set_sort_column_id(0)
self.CensorList.set_model(self.censorlist)
self.CensorReplaceCombo_List = gtk.ListStore(gobject.TYPE_STRING)
self.CensorReplaceCombo.set_model(self.CensorReplaceCombo_List)
self.CensorReplaceCombo.set_text_column(0)
renderers = cols[0].get_cell_renderers()
for render in renderers:
render.connect('edited', self.cell_edited_callback, self.CensorList, 0)
for letter in ["#", "$", "!", " ", "x", "*" ]:
self.CensorReplaceCombo.append_text( letter )
def cell_edited_callback(self, widget, index, value, treeview, pos):
#print index, value, treeview, pos
store = treeview.get_model()
iter = store.get_iter(index)
#print iter, index, value
if value != "" and not value.isspace() and len(value) > 2:
store.set(iter, pos, value)
else:
store.remove(iter)
def SetSettings(self, config):
self.censorlist.clear()
self.p.SetWidgetsData(config, self.options)
words = config["words"]
#if words["censored"] is not None:
#for word in words["censored"]:
#self.censorlist.append([word])
#else:
#self.p.Hilight(self.CensorList)
self.OnCensorCheck(self.CensorCheck)
def OnCensorCheck(self, widget):
sensitive = widget.get_active()
self.CensorList.set_sensitive(sensitive)
self.RemoveCensor.set_sensitive(sensitive)
self.AddCensor.set_sensitive(sensitive)
self.ClearCensors.set_sensitive(sensitive)
self.CensorReplaceCombo.set_sensitive(sensitive)
def GetSettings(self):
censored = []
try:
iter = self.censorlist.get_iter_root()
while iter is not None:
word = self.censorlist.get_value(iter, 0)
censored.append(word)
iter = self.censorlist.iter_next(iter)
except:
pass
return {
"words": {
"censorfill": self.CensorReplaceCombo.child.get_text(),
"censored": censored,
"censorwords": self.CensorCheck.get_active(),
}
}
def OnAdd(self, widget):
iter = self.censorlist.append([""])
selection = self.CensorList.get_selection()
selection.unselect_all()
selection.select_iter(iter)
col = self.CensorList.get_column(0)
render = col.get_cell_renderers()[0]
self.CensorList.set_cursor(self.censorlist.get_path(iter), focus_column=col, start_editing=True)
def OnRemove(self, widget):
selection = self.CensorList.get_selection()
iter = selection.get_selected()[1]
if iter is not None:
self.censorlist.remove(iter)
def OnClear(self, widget):
self.censorlist.clear()
class AutoReplaceFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "AutoReplaceFrame")
self.options = {"words": {"autoreplaced": self.ReplacementList, "replacewords": self.ReplaceCheck,} }
self.replacelist = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
cols = InitialiseColumns(self.ReplacementList,
[_("Pattern"), 150, "edit", self.frame.CellDataFunc],
[_("Replacement"), -1, "edit", self.frame.CellDataFunc],
)
cols[0].set_sort_column_id(0)
cols[1].set_sort_column_id(1)
self.ReplacementList.set_model(self.replacelist)
for column in cols:
renderers = column.get_cell_renderers()
for render in renderers:
render.connect('edited', self.cell_edited_callback, self.ReplacementList, cols.index(column))
def cell_edited_callback(self, widget, index, value, treeview, pos):
store = treeview.get_model()
iter = store.get_iter(index)
store.set(iter, pos, value)
if pos == 0:
treeview.set_cursor(store.get_path(iter), treeview.get_column(1), start_editing=True)
def SetSettings(self, config):
self.replacelist.clear()
self.p.SetWidgetsData(config, self.options)
words = config["words"]
if words["autoreplaced"] is not None:
for word, replacement in words["autoreplaced"].items():
self.replacelist.append([word, replacement])
else:
self.p.Hilight(self.ReplacementList)
self.OnReplaceCheck(self.ReplaceCheck)
def OnReplaceCheck(self, widget):
sensitive = widget.get_active()
self.ReplacementList.set_sensitive(sensitive)
self.RemoveReplacement.set_sensitive(sensitive)
self.AddReplacement.set_sensitive(sensitive)
self.ClearReplacements.set_sensitive(sensitive)
self.DefaultReplacements.set_sensitive(sensitive)
def GetSettings(self):
autoreplaced = {}
try:
iter = self.replacelist.get_iter_root()
while iter is not None:
word = self.replacelist.get_value(iter, 0)
replacement = self.replacelist.get_value(iter, 1)
autoreplaced[word] = replacement
iter = self.replacelist.iter_next(iter)
except:
autoreplaced.clear()
return {
"words": {
"autoreplaced": autoreplaced,
"replacewords": self.ReplaceCheck.get_active(),
}
}
def OnAdd(self, widget):
iter = self.replacelist.append(["", ""])
selection = self.ReplacementList.get_selection()
selection.unselect_all()
selection.select_iter(iter)
col = self.ReplacementList.get_column(0)
render = col.get_cell_renderers()[0]
self.ReplacementList.set_cursor(self.replacelist.get_path(iter), focus_column=col, start_editing=True)
def OnRemove(self, widget):
selection = self.ReplacementList.get_selection()
iter = selection.get_selected()[1]
if iter is not None:
self.replacelist.remove(iter)
def OnClear(self, widget):
self.replacelist.clear()
def OnDefaults(self, widget):
self.replacelist.clear()
defaults = {"teh ": "the ", "taht ": "that ", "tihng": "thing", "youre": "you're", "jsut": "just", "thier": "their", "tihs": "this"}
for word, replacement in defaults.items():
self.replacelist.append([word, replacement])
class CompletionFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "CompletionFrame")
self.options = {"words": {
"tab": self.CompletionTabCheck, "cycle": self.CompletionCycleCheck,
"dropdown": self.CompletionDropdownCheck, "characters": self.CharactersCompletion,
"roomnames": self.CompleteRoomNamesCheck, "buddies": self.CompleteBuddiesCheck,
"roomusers": self.CompleteUsersInRoomsCheck, "commands": self.CompleteCommandsCheck,
"aliases": self.CompleteAliasesCheck, "onematch": self.OneMatchCheck,}
}
self.CompletionTabCheck.connect("toggled", self.OnCompletionDropdownCheck)
self.CompletionCycleCheck.connect("toggled", self.OnCompletionCycleCheck)
self.CompletionDropdownCheck.connect("toggled", self.OnCompletionDropdownCheck)
self.CharactersCompletion.connect("changed", self.OnCompletionChanged)
self.CompleteAliasesCheck.connect("toggled", self.OnCompletionChanged)
self.CompleteCommandsCheck.connect("toggled", self.OnCompletionChanged)
self.CompleteUsersInRoomsCheck.connect("toggled", self.OnCompletionChanged)
self.CompleteBuddiesCheck.connect("toggled", self.OnCompletionChanged)
self.CompleteRoomNamesCheck.connect("toggled", self.OnCompletionChanged)
def SetSettings(self, config):
completion = config["words"]
self.needcompletion = 0
self.p.SetWidgetsData(config, self.options)
def OnCompletionChanged(self, widget):
self.needcompletion = 1
def OnCompletionDropdownCheck(self, widget):
sensitive = self.CompletionTabCheck.get_active()
self.needcompletion = 1
self.CompletionCycleCheck.set_sensitive(sensitive)
self.CompleteRoomNamesCheck.set_sensitive(sensitive)
self.CompleteBuddiesCheck.set_sensitive(sensitive)
self.CompleteUsersInRoomsCheck.set_sensitive(sensitive)
self.CompleteCommandsCheck.set_sensitive(sensitive)
self.CompleteAliasesCheck.set_sensitive(sensitive)
self.CompletionDropdownCheck.set_sensitive(sensitive)
self.OnCompletionCycleCheck(widget)
def OnCompletionCycleCheck(self, widget):
sensitive = (self.CompletionTabCheck.get_active() and not self.CompletionCycleCheck.get_active())
self.CompletionDropdownCheck.set_sensitive(sensitive)
self.CharactersCompletion.set_sensitive(sensitive)
self.OneMatchCheck.set_sensitive(sensitive)
def GetSettings(self):
return { "words": {
"tab": self.CompletionTabCheck.get_active(),
"cycle": self.CompletionCycleCheck.get_active(),
"dropdown": self.CompletionDropdownCheck.get_active(),
"characters": self.CharactersCompletion.get_value_as_int(),
"roomnames": self.CompleteRoomNamesCheck.get_active(),
"buddies": self.CompleteBuddiesCheck.get_active(),
"roomusers": self.CompleteUsersInRoomsCheck.get_active(),
"commands": self.CompleteCommandsCheck.get_active(),
"aliases": self.CompleteAliasesCheck.get_active(),
"onematch": self.OneMatchCheck.get_active(),
},
}
class buildDialog(gtk.Dialog):
def __init__(self, parent ):
window = "PluginProperties"
self.settings = parent.p
#self.tooltips = self.settings.tooltips
self.wTree = gtk.glade.XML(os.path.join(dir_location, "nicotine-settings.glade" ), window, "nicotine" )
widgets = self.wTree.get_widget_prefix("")
for i in widgets:
name = gtk.glade.get_widget_name(i)
self.__dict__[name] = i
self.wTree.signal_autoconnect(self)
self.PluginProperties.set_icon(self.settings.frame.images["n"])
self.PluginProperties.set_transient_for(self.settings.SettingsWindow)
self.tw = {}
self.options = {}
self.plugin = None
def GenerateLabel(self, text):
label = gtk.Label(text)
label.set_line_wrap(True)
return label
def GenerateTreeView(self, name, description, value, c=0):
self.tw["box%d"%c] = gtk.VBox(False, 5)
self.tw[name+"SW"] = gtk.ScrolledWindow()
self.tw[name+"SW"].set_shadow_type(gtk.SHADOW_IN)
self.tw[name+"SW"].set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.tw[name] = gtk.TreeView()
self.tw[name].set_model(gtk.ListStore(gobject.TYPE_STRING))
self.tw[name+"SW"].add(self.tw[name])
self.tw["box%d"%c ].pack_start(self.tw[name+"SW"], True, 5)
cols = InitialiseColumns(self.tw[name], [description, 150, "edit"], )
try:
self.settings.SetWidget(self.tw[name], value )
except:
pass
self.addButton = gtk.Button(_("Add"), gtk.STOCK_ADD)
self.removeButton = gtk.Button(_("Remove"), gtk.STOCK_REMOVE)
self.tw["vbox%d"%c]= gtk.HBox(False, 5)
self.tw["vbox%d"%c].pack_start(self.addButton, False, False)
self.tw["vbox%d"%c].pack_start(self.removeButton, False, False)
self.Main.pack_start(self.tw["box%d" %c], True, True)
self.Main.pack_start(self.tw["vbox%d"%c], False, False)
renderers = cols[0].get_cell_renderers()
for render in renderers:
render.connect('edited', self.cell_edited_callback, self.tw[name])
self.addButton.connect("clicked", self.OnAdd, self.tw[name])
self.removeButton.connect("clicked", self.OnRemove, self.tw[name])
def cell_edited_callback(self, widget, index, value, treeview):
store = treeview.get_model()
iter = store.get_iter(index)
store.set(iter, 0, value)
def OnAdd(self, widget, treeview):
iter = treeview.get_model().append([""])
col = treeview.get_column(0)
#path = treeview.get_model().get_path(iter)
#if path is not None:
#sel.select_path(path)
#treeview.scroll_to_cell(path, None, True, 0.5, 0.5)
treeview.set_cursor(treeview.get_model().get_path(iter), focus_column=col, start_editing=True)
def OnRemove(self, widget, treeview):
selection = treeview.get_selection()
iter = selection.get_selected()[1]
if iter is not None:
treeview.get_model().remove(iter)
def addOptions(self, plugin, options = {}):
for i in self.tw:
self.tw[i].destroy()
self.options = options
self.plugin = plugin
self.PluginLabel.set_markup("%s" % plugin)
c = 0
for name, data in options.items():
if plugin not in self.settings.frame.np.config.sections["plugins"] or name not in self.settings.frame.np.config.sections["plugins"][plugin]:
if plugin not in self.settings.frame.np.config.sections["plugins"]:
print "No1 " + plugin + ", " + repr(self.settings.frame.np.config.sections["plugins"].keys())
elif name not in self.settings.frame.np.config.sections["plugins"][plugin]:
print "No2 " + name + ", " + repr(self.settings.frame.np.config.sections["plugins"][plugin].keys())
continue
""" We currently support SpinButtons, TreeView (one per plugin), and Checkboxes, but there's no reason more widgets cannot be added, and we can use self.settings.SetWidget and self.settings.GetWidgetData to set and get values
Todo: gtk.ComboBox, and gtk.RadioButton
"""
value = self.settings.frame.np.config.sections["plugins"][plugin][name]
if data["type"] in ("integer", "int"):
self.tw["box%d"%c] = gtk.HBox(False, 5)
self.tw["label%d"%c] = self.GenerateLabel(data["description"])
self.tw["box%d"%c].pack_start(self.tw["label%d"%c], False, False)
self.tw[name] = gtk.SpinButton(gtk.Adjustment(0, 0, 99999, 1, 10, 0))
self.settings.SetWidget(self.tw[name], self.settings.frame.np.config.sections["plugins"][plugin][name])
self.tw["box%d"%c ].pack_start(self.tw[name], False, False)
self.Main.pack_start(self.tw["box%d" %c], False, False)
elif data["type"] in ("bool",):
self.tw["box%d"%c] = gtk.HBox(False, 5)
self.tw["label%d"%c] = self.GenerateLabel(data["description"])
self.tw["box%d"%c].pack_start(self.tw["label%d"%c], False, False)
self.tw[name] = gtk.CheckButton()
self.settings.SetWidget(self.tw[name], self.settings.frame.np.config.sections["plugins"][plugin][name])
self.tw["box%d"%c ].pack_start(self.tw[name], False, False)
self.Main.pack_start(self.tw["box%d" %c], False, False)
elif data['type'] in ('str', 'string', 'file'):
self.tw["box%d"%c] = gtk.HBox(False, 5)
self.tw["label%d"%c] = self.GenerateLabel(data["description"])
self.tw["box%d"%c].pack_start(self.tw["label%d"%c], False, False)
self.tw[name] = gtk.Entry()
self.settings.SetWidget(self.tw[name], self.settings.frame.np.config.sections["plugins"][plugin][name])
self.tw["box%d"%c ].pack_start(self.tw[name], False, False)
self.Main.pack_start(self.tw["box%d" %c], False, False)
elif data["type"] in ("list string",):
self.GenerateTreeView(name, data["description"], value, c)
else:
print "Unknown setting type '%s', data '%s'" % (name, data)
c += 1
self.PluginProperties.show_all()
def OnCancel(self, widget):
self.PluginProperties.hide()
def OnOkay(self, widget):
for name in self.options:
#print self.tw[name],
value = self.settings.GetWidgetData(self.tw[name])
if value is not None:
self.settings.frame.np.config.sections["plugins"][self.plugin][name] = value
self.PluginProperties.hide()
self.settings.frame.pluginhandler.plugin_settings(self.settings.frame.pluginhandler.loaded_plugins[self.plugin].PLUGIN)
def Show(self):
self.PluginProperties.show()
class PluginFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "PluginFrame")
self.options = {"plugins": {"enable": self.PluginsEnable} }
self.pluginlist = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING )
self.plugins = []
self.pluginsiters = {}
self.selected_plugin = None
cols = InitialiseColumns(self.PluginTreeView,
[_("Plugins"), 150, "text"],
[_("Enabled"), 40, "toggle"],
)
cols[0].set_sort_column_id(0)
cols[1].set_sort_column_id(1)
renderers = cols[1].get_cell_renderers()
for render in renderers:
render.connect('toggled', self.cell_toggle_callback, self.PluginTreeView, 1)
self.PluginTreeView.set_model(self.pluginlist)
#self.PluginTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.PluginTreeView.get_selection().connect("changed", self.OnSelectPlugin)
self.dialog = buildDialog(self)
def OnPluginProperties(self, widget):
if self.selected_plugin is None:
return
self.dialog.addOptions(self.selected_plugin, self.frame.pluginhandler.get_plugin_settings(self.selected_plugin))
self.dialog.Show()
def OnSelectPlugin(self, selection):
model, iter = selection.get_selected()
if iter is None:
self.selected_plugin = None
return
self.selected_plugin = model.get_value(iter, 2)
info = self.frame.pluginhandler.get_plugin_info(self.selected_plugin)
self.PluginVersion.set_markup("%(version)s" % { "version": info['Version']})
self.PluginName.set_markup("%(name)s" % {"name": info['Name']} )
self.PluginDescription.get_buffer().set_text("%(description)s" % { "description": info['Description'].replace(r'\n', "\n")})
self.PluginAuthor.set_markup("%(author)s" % { "author": ", ".join(info['Authors'])})
self.PluginImage.set_from_pixbuf(self.frame.images["plugin"])
settings = self.frame.pluginhandler.get_plugin_settings(self.selected_plugin)
if settings is not None:
self.PluginProperties.set_sensitive(True)
else:
self.PluginProperties.set_sensitive(False)
def cell_toggle_callback(self, widget, index, treeview, pos):
iter = self.pluginlist.get_iter(index)
plugin = self.pluginlist.get_value(iter, 2)
value = self.pluginlist.get_value(iter, 1)
self.pluginlist.set(iter, pos, not value)
if not value:
if not self.frame.pluginhandler.enable_plugin(plugin):
log.add(_('Could not enable plugin.'))
return
else:
if not self.frame.pluginhandler.disable_plugin(plugin):
log.add(_('Could not disable plugin.'))
return
def SetSettings(self, config):
#for (module, plugin) in self.frame.pluginhandler.plugins:
#print plugin.__name__, plugin.__version__, plugin.settings
self.p.SetWidgetsData(config, self.options)
self.OnPluginsEnable(None)
self.pluginsiters = {}
self.pluginlist.clear()
plugins = self.frame.pluginhandler.list_installed_plugins()
plugins.sort()
for plugin in plugins:
try:
info = self.frame.pluginhandler.get_plugin_info(plugin)
except IOError:
continue
enabled = (plugin in self.frame.pluginhandler.enabled_plugins)
self.pluginsiters[filter] = self.pluginlist.append([info['Name'], enabled, plugin])
#else:
#self.p.Hilight(self.PluginTreeView)
return {}
def OnPluginsEnable(self, widget):
self.notebook1.set_sensitive(self.PluginsEnable.get_active())
def GetSettings(self):
return { "plugins": {
"enable": self.PluginsEnable.get_active(),
"enabled": self.frame.pluginhandler.enabled_plugins.keys() },
}
class ChatFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "ChatFrame")
self.options = {}
def SetSettings(self, config):
return {}
def GetSettings(self):
return {}
class MiscFrame(buildFrame):
def __init__(self, parent):
self.p = parent
buildFrame.__init__(self, "MiscFrame")
self.options = {}
def SetSettings(self, config):
return {}
def GetSettings(self):
return {}
class SettingsWindow:
def __init__(self, frame):
self.frame = frame
#self.tooltips = self.frame.tooltips
self.wTree = gtk.glade.XML(os.path.join(dir_location, "nicotine-settings.glade" ), "SettingsWindow", "nicotine" )
widgets = self.wTree.get_widget_prefix("")
for i in widgets:
name = gtk.glade.get_widget_name(i)
self.__dict__[name] = i
self.wTree.signal_autoconnect(self)
gobject.signal_new("settings-closed", gtk.Window, gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,))
self.SettingsWindow.set_transient_for(frame.MainWindow)
self.SettingsWindow.set_geometry_hints(None, min_width=600, min_height=400)
self.SettingsWindow.set_default_size(700, 550)
self.SettingsWindow.connect("delete-event", self.OnDelete)
self.empty_label = gtk.Label("")
self.empty_label.show()
self.viewport1.add(self.empty_label)
self.tree = {}
self.pages = p = {}
self.handler_ids = {}
model = gtk.TreeStore(str, str)
self.tree["Server"] = model.append(None, [_("Server"), "Server"])
self.tree["Shares"] = model.append(None, [_("Shares"), "Shares"])
self.tree["Transfers"] = row = model.append(None, [_("Transfers"), "Transfers"])
self.tree["Downloads"] = model.append(row, [_("Downloads"), "Downloads"])
self.tree["Ban List"] = model.append(row, [_("Ban List"), "Ban List"])
self.tree["Events"] = model.append(row, [_("Events"), "Events"])
self.tree["Geo Block"] = model.append(row, [_("Geo Block"), "Geo Block"])
self.tree["Interface"] = row = model.append(None, [_("Interface"), "Interface"])
self.tree["Colours"] = model.append(row, [_("Colours"), "Colours"])
self.tree["Icons"] = model.append(row, [_("Icons"), "Icons"])
self.tree["Notebook Tabs"] = model.append(row, [_("Notebook Tabs"), "Notebook Tabs"])
self.tree["Chat"] = row = model.append(None, [_("Chat"), "Chat"])
self.tree["Away mode"] = model.append(row, [_("Away mode"), "Away mode"])
self.tree["Logging"] = model.append(row, [_("Logging"), "Logging"])
self.tree["Ignore List"] = model.append(row, [_("Ignore List"), "Ignore List"])
self.tree["Censor List"] = model.append(row, [_("Censor List"), "Censor List"])
self.tree["Auto-Replace"] = model.append(row, [_("Auto-Replace"), "Auto-Replace"])
self.tree["URL Catching"] = model.append(row, [_("URL Catching"), "URL Catching"])
self.tree["Completion"] = model.append(row, [_("Completion"), "Completion"])
self.tree["Misc"] = row = model.append(None, [_("Misc"), "Misc"])
self.tree["Plugins"] = model.append(row, [_("Plugins"), "Plugins"])
self.tree["Sounds"] = model.append(row, [_("Sounds"), "Sounds"])
self.tree["Searches"] = model.append(row, [_("Searches"), "Searches"])
self.tree["User info"] = model.append(row, [_("User info"), "User info"])
self.tree["Import Config"] = model.append(row, [_("Import Config"), "Import Config"])
p["Server"] = ServerFrame(self, frame.np.getencodings())
p["Shares"] = SharesFrame(self)
p["Transfers"] = TransfersFrame(self)
p["Downloads"] = DownloadsFrame(self)
p["Geo Block"] = GeoBlockFrame(self)
p["User info"] = UserinfoFrame(self)
p["Ban List"] = BanFrame(self)
p["Ignore List"] = IgnoreFrame(self)
p["Interface"] = BloatFrame(self)
p["Colours"] = ColoursFrame(self)
p["Notebook Tabs"] = NotebookFrame(self)
p["Sounds"] = SoundsFrame(self)
p["Icons"] = IconsFrame(self)
p["URL Catching"] = UrlCatchFrame(self)
p["Completion"] = CompletionFrame(self)
p["Logging"] = LogFrame(self)
p["Searches"] = SearchFrame(self)
p["Away mode"] = AwayFrame(self)
p["Censor List"] = CensorFrame(self)
p["Auto-Replace"] = AutoReplaceFrame(self)
p["Chat"] = ChatFrame(self)
p["Events"] = EventsFrame(self)
p["Import Config"] = ImportFrame(self)
p["Plugins"] = PluginFrame(self)
p["Misc"] = MiscFrame(self)
column = gtk.TreeViewColumn(_("Categories"), gtk.CellRendererText(), text = 0)
self.SettingsTreeview.set_model(model)
self.SettingsTreeview.append_column(column)
self.SettingsTreeview.expand_row((0,), True)
self.SettingsTreeview.expand_row((1,), True)
self.SettingsTreeview.expand_row((2,), True)
self.SettingsTreeview.expand_row((3,), True)
self.SettingsTreeview.expand_row((4,), True)
self.SettingsTreeview.expand_row((5,), True)
self.SettingsTreeview.get_selection().connect("changed", self.switch_page)
self.UpdateColours()
def Hilight(self, widget):
if type(widget) is gtk.Entry:
self.Dehilight(widget)
self.handler_ids[widget] = []
self.handler_ids[widget].append(widget.connect("activate", self.Dehilight))
self.handler_ids[widget].append(widget.connect("changed", self.Dehilight))
elif type(widget) is gtk.SpinButton:
self.Dehilight(widget)
self.handler_ids[widget] = []
self.handler_ids[widget].append(widget.connect("activate", self.Dehilight))
self.handler_ids[widget].append(widget.connect("value-changed", self.Dehilight))
elif type(widget) is gtk.CheckButton:
self.Dehilight(widget)
self.handler_ids[widget] = []
self.handler_ids[widget].append(widget.connect("toggled", self.Dehilight))
elif type(widget) is gtk.TreeView:
model = widget.get_model()
self.Dehilight(widget)
self.handler_ids[widget] = []
self.handler_ids[widget].append(model.connect("row-inserted", self.DehilightTree))
self.SetTextBG(widget, "red", "white")
def DehilightTree(self, model, *args):
for widget in self.handler_ids.keys():
if type(widget) is gtk.TreeView and widget.get_model() is model:
self.Dehilight(widget)
break
def Dehilight(self, widget, *args):
self.SetTextBG(widget, "", "")
if widget not in self.handler_ids:
return
for handler_id in self.handler_ids[widget][:]:
if type(widget) is gtk.TreeView:
widget.get_model().disconnect(handler_id)
else:
widget.disconnect(handler_id)
self.handler_ids[widget].remove(handler_id)
def ColourWidgets(self, widget):
if type(widget) in (gtk.Entry, gtk.SpinButton, gtk.TextView, gtk.TreeView, gtk.CheckButton, gtk.RadioButton):
self.SetTextBG(widget)
if type(widget) is gtk.TreeView:
self.frame.ChangeListFont(widget, self.frame.np.config.sections["ui"]["listfont"])
def UpdateColours(self):
for widget in self.__dict__.values():
#if type(widget) in (gtk.Entry, gtk.SpinButton, gtk.TextView, gtk.TreeView, gtk.CheckButton, gtk.RadioButton):
self.ColourWidgets(widget)
for name, page in self.pages.items():
for widget in page.__dict__.values():
self.ColourWidgets(widget)
def SetTextBG(self, widget, bgcolor="", fgcolor=""):
self.frame.SetTextBG(widget, bgcolor, fgcolor)
def switch_page(self, widget):
child = self.viewport1.get_child()
if child:
self.viewport1.remove(child)
model, iter = widget.get_selected()
if iter is None:
self.viewport1.add(self.empty_label)
return
page = model.get_value(iter, 1)
if page in self.pages:
self.viewport1.add(self.pages[page].Main)
else:
self.viewport1.add(self.empty_label)
def SwitchToPage(self, page):
#if not self.SettingsWindow.get_property("visible"):
#self.SettingsWindow.show()
self.SettingsWindow.deiconify()
child = self.viewport1.get_child()
if child:
self.viewport1.remove(child)
if self.tree[page] is None:
self.viewport1.add(self.empty_label)
return
model = self.SettingsTreeview.get_model()
sel = self.SettingsTreeview.get_selection()
sel.unselect_all()
path = model.get_path(self.tree[page])
self.SettingsTreeview.expand_to_path(path)
if path is not None:
sel.select_path(path)
def OnApply(self, widget):
self.SettingsWindow.emit("settings-closed", "apply")
def OnOk(self, widget):
self.SettingsWindow.emit("settings-closed", "ok")
def OnCancel(self, widget):
self.SettingsWindow.emit("settings-closed", "cancel")
def OnDelete(self, widget, event):
self.OnCancel(widget)
widget.emit_stop_by_name("delete-event")
return True
def GetPosition(self, combobox, option):
iter = combobox.get_model().get_iter_root()
while iter is not None:
word = combobox.get_model().get_value(iter, 0)
if word.lower() == option or word == option:
combobox.set_active_iter(iter)
break
iter = combobox.get_model().iter_next(iter)
def SetWidgetsData(self, config, options):
for section, keys in options.items():
if section not in config:
continue
for key in keys:
widget = options[section][key]
if widget is None:
continue
if config[section][key] is None:
self.Hilight(widget)
self.ClearWidget(widget)
else:
self.SetWidget(widget, config[section][key])
self.Dehilight(widget)
def GetWidgetData(self, widget):
if type(widget) is gtk.Entry:
return widget.get_text()
elif type(widget) is gtk.SpinButton:
return int(widget.get_value())
elif type(widget) is gtk.CheckButton:
return widget.get_active()
elif type(widget) is gtk.RadioButton:
return widget.get_active()
elif type(widget) is gtk.ComboBoxEntry:
return widget.child.get_text()
elif type(widget) is gtk.ComboBox:
return widget.get_active_text()
elif type(widget) is gtk.FontButton:
widget.get_font_name()
elif type(widget) is gtk.TreeView and widget.get_model().get_n_columns() == 1:
wlist = []
iter = widget.get_model().get_iter_root()
while iter:
word = widget.get_model().get_value(iter, 0)
if word is not None:
wlist.append(word)
iter = widget.get_model().iter_next(iter)
return wlist
def ClearWidget(self, widget):
if type(widget) is gtk.Entry:
widget.set_text("")
elif type(widget) is gtk.SpinButton:
widget.set_value(0)
elif type(widget) is gtk.CheckButton:
widget.set_active(0)
elif type(widget) is gtk.RadioButton:
widget.set_active(0)
elif type(widget) is gtk.ComboBoxEntry:
widget.child.set_text("")
elif type(widget) is gtk.ComboBox:
self.GetPosition(widget, "")
elif type(widget) is gtk.FontButton:
widget.set_font_name("")
def SetWidget(self, widget, value):
if type(widget) is gtk.Entry:
if type(value) in ( int,str):
widget.set_text(value)
elif type(widget) is gtk.SpinButton:
widget.set_value(int(value))
elif type(widget) is gtk.CheckButton:
widget.set_active(value)
elif type(widget) is gtk.RadioButton:
widget.set_active(value)
elif type(widget) is gtk.ComboBoxEntry:
if type(value) in ( int,str):
widget.child.set_text(value)
elif type(widget) is gtk.ComboBox:
if type(value) is str:
self.GetPosition(widget, value)
elif type(value) is int:
widget.set_active(value)
elif type(widget) is gtk.FontButton:
widget.set_font_name(value)
elif type(widget) is gtk.TreeView and type(value) is list and widget.get_model().get_n_columns() == 1:
for item in value:
widget.get_model().append([item])
#else:
#print "Undefined widget type:", widget, value
def InvalidSettings(self, domain, key):
for name, page in self.pages.items():
if domain in page.options:
if key in page.options[domain]:
self.SwitchToPage(name)
break
def SetSettings(self, config):
for page in self.pages.values():
page.SetSettings(config)
def GetSettings(self):
try:
config = {
"server": {},
"transfers": {},
"userinfo": {},
"logging": {},
"searches": {},
"privatechat": {},
"ui": {},
"urls": {},
"players": {},
"words": {},
"language": {},
"plugins": {},
}
for page in self.pages.values():
sub = page.GetSettings()
for (key,data) in sub.items():
config[key].update(data)
return self.pages["Shares"].GetNeedRescan(), (self.pages["Colours"].needcolors or self.pages["Interface"].needcolors) , self.pages["Completion"].needcompletion, config
except UserWarning, warning:
return None