diff --git a/sharepoint_browser.py b/sharepoint_browser.py index 1046bed..b8c0036 100644 --- a/sharepoint_browser.py +++ b/sharepoint_browser.py @@ -29,7 +29,8 @@ def load_settings(): "temp_dir": "C:\\Temp_SP", "language": "da", # da eller en "favorites": [], # Liste over {id, name, type, drive_id, site_id, path} - "fav_visible": True + "fav_visible": True, + "license_key": "" } if not os.path.exists(SETTINGS_FILE): with open(SETTINGS_FILE, 'w', encoding='utf-8') as f: @@ -58,15 +59,15 @@ CURRENT_LANG = settings.get("language", "da") STRINGS = { "da": { "title": "SharePoint Explorer", - "btn_back": "← Tilbage", - "btn_home": "🏠 Hjem", - "btn_save_changes": "💾 Gem ændringer i SharePoint", + "btn_back": "Tilbage", + "btn_home": "Hjem", + "btn_save_changes": "Gem ændringer i SharePoint", "btn_login": "Log ind", "btn_logged_in": "Logget ind", - "btn_refresh": "🔄 Opdater", - "btn_upload_file": "📤 Upload Fil", - "btn_upload_folder": "📁 Upload Mappe", - "btn_new_folder": "➕ Ny Mappe", + "btn_refresh": "Opdater", + "btn_upload_file": "Upload Fil", + "btn_upload_folder": "Upload Mappe", + "btn_new_folder": "Ny Mappe", "col_name": "Navn", "col_type": "Type", "col_size": "Størrelse", @@ -124,7 +125,7 @@ STRINGS = { "msg_update_failed_code": "Upload fejlede: {code}", "msg_unknown_error": "Ukendt fejl", "type_unknown": "Ukendt", - "btn_settings": "⚙️ Indstillinger", + "btn_settings": "Indstillinger", "settings_title": "Indstillinger", "settings_auth_group": "Authentication / API", "settings_client_id": "App (Client) ID:", @@ -140,22 +141,25 @@ STRINGS = { "msg_settings_saved": "Indstillingerne er gemt.", "msg_restart_required": "Visse ændringer (f.eks. ID'er) træder først i kraft efter genstart.", "status_login_needed": "Session udløbet. Log ind igen.", - "btn_add_fav": "⭐ Tilføj til favoritter", - "btn_remove_fav": "❌ Fjern fra favoritter", - "label_favorites": "⭐ Favoritter", - "msg_fav_exists": "'{name}' er allerede i favoritter." + "btn_add_fav": "Tilføj til favoritter", + "btn_remove_fav": "Fjern fra favoritter", + "label_favorites": "Favoritter", + "msg_fav_exists": "'{name}' er allerede i favoritter.", + "settings_license_group": "Licens / Aktivering", + "settings_license_key": "Licensnøgle:", + "settings_license_status": "Status: Ikke aktiveret" }, "en": { "title": "SharePoint Explorer", - "btn_back": "← Back", - "btn_home": "🏠 Home", - "btn_save_changes": "💾 Save changes to SharePoint", + "btn_back": "Back", + "btn_home": "Home", + "btn_save_changes": "Save changes to SharePoint", "btn_login": "Login", "btn_logged_in": "Logged in", - "btn_refresh": "🔄 Refresh", - "btn_upload_file": "📤 Upload File", - "btn_upload_folder": "📁 Upload Folder", - "btn_new_folder": "➕ New Folder", + "btn_refresh": "Refresh", + "btn_upload_file": "Upload File", + "btn_upload_folder": "Upload Folder", + "btn_new_folder": "New Folder", "col_name": "Name", "col_type": "Type", "col_size": "Size", @@ -213,7 +217,7 @@ STRINGS = { "msg_update_failed_code": "Upload failed: {code}", "msg_unknown_error": "Unknown error", "type_unknown": "Unknown", - "btn_settings": "⚙️ Settings", + "btn_settings": "Settings", "settings_title": "Settings", "settings_auth_group": "Authentication / API", "settings_client_id": "App (Client) ID:", @@ -229,10 +233,13 @@ STRINGS = { "msg_settings_saved": "Settings saved.", "msg_restart_required": "Some changes (e.g., IDs) only take effect after restart.", "status_login_needed": "Session expired. Please login again.", - "btn_add_fav": "⭐ Add to favorites", - "btn_remove_fav": "❌ Remove from favorites", - "label_favorites": "⭐ Favorites", - "msg_fav_exists": "'{name}' is already in favorites." + "btn_add_fav": "Add to favorites", + "btn_remove_fav": "Remove from favorites", + "label_favorites": "Favorites", + "msg_fav_exists": "'{name}' is already in favorites.", + "settings_license_group": "License / Activation", + "settings_license_key": "License Key:", + "settings_license_status": "Status: Not activated" } } @@ -291,7 +298,7 @@ class SettingsDialog(wx.Dialog): def __init__(self, parent, current_settings): lang = current_settings.get("language", "da") title = STRINGS[lang].get("settings_title", "Settings") - super().__init__(parent, title=title, size=(520, 620)) + super().__init__(parent, title=title, size=(520, 720)) self.settings = current_settings.copy() self.lang = lang @@ -345,6 +352,20 @@ class SettingsDialog(wx.Dialog): inner_vbox.Add(path_sizer, 0, wx.EXPAND | wx.ALL, 10) + # --- Group: License --- + lic_box = wx.StaticBox(panel, label=self.get_txt("settings_license_group")) + lic_sizer = wx.StaticBoxSizer(lic_box, wx.VERTICAL) + + lic_sizer.Add(wx.StaticText(panel, label=self.get_txt("settings_license_key")), 0, wx.BOTTOM, 5) + self.license_ctrl = wx.TextCtrl(panel, value=self.settings.get("license_key", "")) + lic_sizer.Add(self.license_ctrl, 0, wx.EXPAND | wx.BOTTOM, 5) + + status_txt = wx.StaticText(panel, label=self.get_txt("settings_license_status")) + status_txt.SetForegroundColour(wx.RED) + lic_sizer.Add(status_txt, 0, wx.TOP, 5) + + inner_vbox.Add(lic_sizer, 0, wx.EXPAND | wx.ALL, 10) + # --- Group: Language --- lang_box = wx.StaticBox(panel, label=self.get_txt("settings_lang_group")) lang_sizer = wx.StaticBoxSizer(lang_box, wx.HORIZONTAL) @@ -384,6 +405,7 @@ class SettingsDialog(wx.Dialog): self.settings["tenant_id"] = self.tenant_id_ctrl.GetValue().strip() self.settings["temp_dir"] = self.temp_dir_picker.GetPath() self.settings["language"] = "da" if self.lang_choice.GetSelection() == 0 else "en" + self.settings["license_key"] = self.license_ctrl.GetValue().strip() if not self.settings["client_id"] or not self.settings["tenant_id"]: wx.MessageBox("Client ID og Tenant ID skal udfyldes.", "Fejl", wx.OK | wx.ICON_ERROR) @@ -415,12 +437,13 @@ class SharePointApp(wx.Frame): self.favorites = settings.get("favorites", []) self.fav_visible = settings.get("fav_visible", True) - # System Ikoner (ArtProvider - mest basale for kompatibilitet) + # System Ikoner (Brug ART_CMN_DIALOG eller ART_TOOLBAR for mere farve på Windows) self.image_list = wx.ImageList(16, 16) - self.idx_site = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_GO_HOME, wx.ART_OTHER, (16, 16))) # Site (Hus ikon) - self.idx_drive = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_HARDDISK, wx.ART_OTHER, (16, 16))) # Drive - self.idx_folder = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))) # Folder - self.idx_file = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16, 16))) # File + self.idx_site = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_GO_HOME, wx.ART_CMN_DIALOG, (16, 16))) # Site + self.idx_drive = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_HARDDISK, wx.ART_CMN_DIALOG, (16, 16))) # Drive + self.idx_folder = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_CMN_DIALOG, (16, 16))) # Folder + self.idx_file = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_CMN_DIALOG, (16, 16))) # File + self.idx_star = self.image_list.Add(wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_CMN_DIALOG, (16, 16))) # Favorit stjerne # Threading/Sync til filredigering @@ -469,55 +492,73 @@ class SharePointApp(wx.Frame): nav_panel = wx.Panel(panel) nav_hbox = wx.BoxSizer(wx.HORIZONTAL) - self.back_btn = wx.Button(nav_panel, label=self.get_txt("btn_back"), size=(100, 30)) + self.back_btn = wx.Button(nav_panel, label=self.get_txt("btn_back"), size=(110, 30)) + self.back_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_GO_BACK, wx.ART_BUTTON, (16, 16))) + self.back_btn.SetBitmapMargins((12, 0)) self.back_btn.Disable() self.back_btn.Bind(wx.EVT_BUTTON, self.go_back) nav_hbox.Add(self.back_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 10) - self.home_btn = wx.Button(nav_panel, label=self.get_txt("btn_home"), size=(100, 30)) + self.home_btn = wx.Button(nav_panel, label=self.get_txt("btn_home"), size=(110, 30)) + self.home_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_GO_HOME, wx.ART_BUTTON, (16, 16))) + self.home_btn.SetBitmapMargins((12, 0)) self.home_btn.Disable() self.home_btn.Bind(wx.EVT_BUTTON, self.load_sites) nav_hbox.Add(self.home_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) - self.refresh_btn = wx.Button(nav_panel, label=self.get_txt("btn_refresh"), size=(100, 30)) + self.refresh_btn = wx.Button(nav_panel, label=self.get_txt("btn_refresh"), size=(110, 30)) + self.refresh_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_REDO, wx.ART_BUTTON, (16, 16))) + self.refresh_btn.SetBitmapMargins((12, 0)) self.refresh_btn.Disable() self.refresh_btn.Bind(wx.EVT_BUTTON, self.on_refresh) nav_hbox.Add(self.refresh_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) # NY KNAP: Gem ændringer (Vises kun ved redigering) - self.done_btn = wx.Button(nav_panel, label=self.get_txt("btn_save_changes"), size=(200, 30)) + self.done_btn = wx.Button(nav_panel, label=self.get_txt("btn_save_changes"), size=(250, 30)) self.done_btn.SetBackgroundColour(wx.Colour(255, 69, 0)) # OrangeRed self.done_btn.SetForegroundColour(wx.WHITE) + self.done_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_BUTTON, (16, 16))) + self.done_btn.SetBitmapMargins((12, 0)) self.done_btn.Hide() self.done_btn.Bind(wx.EVT_BUTTON, self.on_done_editing_clicked) nav_hbox.Add(self.done_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 10) # NYE KNAPPER: Upload og Ny Mappe (Vises kun når man er inde i et drev/mappe) - self.upload_btn = wx.Button(nav_panel, label=self.get_txt("btn_upload_file"), size=(120, 30)) + self.upload_btn = wx.Button(nav_panel, label=self.get_txt("btn_upload_file"), size=(130, 30)) + self.upload_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_BUTTON, (16, 16))) + self.upload_btn.SetBitmapMargins((12, 0)) self.upload_btn.Hide() self.upload_btn.Bind(wx.EVT_BUTTON, self.on_upload_clicked) nav_hbox.Add(self.upload_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) - self.upload_folder_btn = wx.Button(nav_panel, label=self.get_txt("btn_upload_folder"), size=(120, 30)) + self.upload_folder_btn = wx.Button(nav_panel, label=self.get_txt("btn_upload_folder"), size=(130, 30)) + self.upload_folder_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_BUTTON, (16, 16))) + self.upload_folder_btn.SetBitmapMargins((12, 0)) self.upload_folder_btn.Hide() self.upload_folder_btn.Bind(wx.EVT_BUTTON, self.on_upload_folder_clicked) nav_hbox.Add(self.upload_folder_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) - self.new_folder_btn = wx.Button(nav_panel, label=self.get_txt("btn_new_folder"), size=(100, 30)) + self.new_folder_btn = wx.Button(nav_panel, label=self.get_txt("btn_new_folder"), size=(120, 30)) + self.new_folder_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_NEW_DIR, wx.ART_BUTTON, (16, 16))) + self.new_folder_btn.SetBitmapMargins((12, 0)) self.new_folder_btn.Hide() self.new_folder_btn.Bind(wx.EVT_BUTTON, self.on_new_folder_clicked) nav_hbox.Add(self.new_folder_btn, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) nav_hbox.AddStretchSpacer(1) - self.login_btn = wx.Button(nav_panel, label=self.get_txt("btn_login"), size=(120, 30)) + self.login_btn = wx.Button(nav_panel, label=self.get_txt("btn_login"), size=(130, 30)) self.login_btn.SetBackgroundColour(wx.Colour(40, 167, 69)) # Grøn self.login_btn.SetForegroundColour(wx.WHITE) + self.login_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_GO_FORWARD, wx.ART_TOOLBAR, (16, 16))) + self.login_btn.SetBitmapMargins((12, 0)) self.login_btn.Bind(wx.EVT_BUTTON, self.login) nav_hbox.Add(self.login_btn, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 10) # INDSTILLINGER KNAP - self.settings_btn = wx.Button(nav_panel, label=self.get_txt("btn_settings"), size=(120, 30)) + self.settings_btn = wx.Button(nav_panel, label=self.get_txt("btn_settings"), size=(130, 30)) + self.settings_btn.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_REPORT_VIEW, wx.ART_TOOLBAR, (16, 16))) + self.settings_btn.SetBitmapMargins((12, 0)) self.settings_btn.Bind(wx.EVT_BUTTON, self.on_settings_clicked) nav_hbox.Add(self.settings_btn, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 10) @@ -558,6 +599,11 @@ class SharePointApp(wx.Frame): self.fav_header.SetBackgroundColour(wx.Colour(240, 240, 240)) h_hbox = wx.BoxSizer(wx.HORIZONTAL) + # Star Icon + star_bmp = wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_MENU, (16, 16)) + self.fav_icon = wx.StaticBitmap(self.fav_header, bitmap=star_bmp) + h_hbox.Add(self.fav_icon, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5) + self.fav_label = wx.StaticText(self.fav_header, label=self.get_txt("label_favorites")) self.fav_label.SetFont(wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)) h_hbox.Add(self.fav_label, 1, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5) @@ -630,33 +676,41 @@ class SharePointApp(wx.Frame): if item['type'] in ["FOLDER", "DRIVE", "SITE"]: fav_item = menu.Append(wx.ID_ANY, self.get_txt("btn_add_fav")) + fav_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, lambda e, i=item: self.add_favorite(i), fav_item) menu.AppendSeparator() if item['type'] == "FILE": edit_item = menu.Append(wx.ID_ANY, self.get_txt("msg_edit_file")) + edit_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_EDIT, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, lambda e, i=item: self.open_file(i), edit_item) if item['type'] in ["FILE", "FOLDER"]: rename_item = menu.Append(wx.ID_ANY, f"{self.get_txt('msg_rename')} '{item['name']}'") + rename_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_REPORT_VIEW, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, lambda e: self.on_rename_clicked(item), rename_item) delete_item = menu.Append(wx.ID_ANY, f"{self.get_txt('msg_delete')} '{item['name']}'") + delete_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, lambda e: self.on_delete_items_clicked(selected_items), delete_item) else: # Flere emner valgt delete_items = menu.Append(wx.ID_ANY, f"{self.get_txt('msg_delete')} {len(selected_indices)} " + ("emner" if self.lang == "da" else "items")) + delete_items.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, lambda e: self.on_delete_items_clicked(selected_items), delete_items) else: # Menu for selve mappen (hvis man trykker på det tomme felt) if self.current_drive_id: upload_item = menu.Append(wx.ID_ANY, self.get_txt("msg_upload_here")) + upload_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, self.on_upload_clicked, upload_item) upload_dir_item = menu.Append(wx.ID_ANY, self.get_txt("msg_upload_folder_here")) + upload_dir_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, self.on_upload_folder_clicked, upload_dir_item) new_folder_item = menu.Append(wx.ID_ANY, self.get_txt("msg_new_folder_here")) + new_folder_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_NEW_DIR, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, self.on_new_folder_clicked, new_folder_item) # Tilføj altid opdater punkt til sidst @@ -664,6 +718,7 @@ class SharePointApp(wx.Frame): menu.AppendSeparator() refresh_item = menu.Append(wx.ID_ANY, self.get_txt("btn_refresh")) + refresh_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_REDO, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, self.on_refresh, refresh_item) self.PopupMenu(menu) @@ -679,10 +734,12 @@ class SharePointApp(wx.Frame): menu = wx.Menu() if data: fav_item = menu.Append(wx.ID_ANY, self.get_txt("btn_add_fav")) + fav_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, lambda e, d=data: self.add_favorite(d), fav_item) menu.AppendSeparator() refresh_item = menu.Append(wx.ID_ANY, self.get_txt("btn_refresh")) + refresh_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_REDO, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, self.on_refresh, refresh_item) self.PopupMenu(menu) menu.Destroy() @@ -720,9 +777,10 @@ class SharePointApp(wx.Frame): def refresh_fav_list(self): self.fav_list.DeleteAllItems() for i, fav in enumerate(self.favorites): - img_idx = self.idx_folder + img_idx = self.idx_star if fav['type'] == "DRIVE": img_idx = self.idx_drive elif fav['type'] == "SITE": img_idx = self.idx_site + elif fav['type'] == "FOLDER": img_idx = self.idx_folder self.fav_list.InsertItem(i, fav['name'], img_idx) self.fav_list.SetItemData(i, i) # Store index @@ -758,6 +816,7 @@ class SharePointApp(wx.Frame): menu = wx.Menu() remove_item = menu.Append(wx.ID_ANY, self.get_txt("btn_remove_fav")) + remove_item.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_DEL_BOOKMARK, wx.ART_MENU, (16, 16))) self.Bind(wx.EVT_MENU, lambda e: self.remove_favorite(fav['id']), remove_item) self.PopupMenu(menu) menu.Destroy()